X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ospfd%2Fospfd.c;h=a18e2de72511b7d14429489e376ba4f8fd98be84;hb=01b4cb3ed6181d7200f66e0187b1e5c5db6c0e5a;hp=2298c2261a9af283c587dd5e29da86598cdb24e0;hpb=46a9c3af894f59e0304203a820046ca2a41e2649;p=mirror_frr.git diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 2298c2261..a18e2de72 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -38,6 +38,7 @@ #include "bfd.h" #include "libfrr.h" #include "defaults.h" +#include "lib_errors.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_network.h" @@ -51,10 +52,10 @@ #include "ospfd/ospf_spf.h" #include "ospfd/ospf_packet.h" #include "ospfd/ospf_dump.h" +#include "ospfd/ospf_route.h" #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_abr.h" #include "ospfd/ospf_flood.h" -#include "ospfd/ospf_route.h" #include "ospfd/ospf_ase.h" @@ -170,7 +171,7 @@ void ospf_router_id_update(struct ospf *ospf) /* Flush (inline) all external LSAs which now match the new router-id, - need to adjust the OSPF_LSA_SELF flag, so the flush doesnt + need to adjust the OSPF_LSA_SELF flag, so the flush doesn't hit asserts in ospf_refresher_unregister_lsa(). This step is needed @@ -233,12 +234,10 @@ static struct ospf *ospf_new(unsigned short instance, const char *name) new->instance = instance; new->router_id.s_addr = htonl(0); new->router_id_static.s_addr = htonl(0); - - if (name) { + if (name && !strmatch(name, VRF_DEFAULT_NAME)) { new->vrf_id = VRF_UNKNOWN; /* Freed in ospf_finish_final */ new->name = XSTRDUP(MTYPE_OSPF_TOP, name); - vrf = vrf_lookup_by_name(new->name); if (IS_DEBUG_OSPF_EVENT) zlog_debug( "%s: Create new ospf instance with vrf_name %s vrf_id %u", @@ -309,12 +308,8 @@ static struct ospf *ospf_new(unsigned short instance, const char *name) new->lsa_refresh_interval, &new->t_lsa_refresher); new->lsa_refresher_started = monotime(NULL); - if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1)) == NULL) { - zlog_err( - "ospf_new: fatal error: stream_new(%u) failed allocating ibuf", - OSPF_MAX_PACKET_SIZE + 1); - exit(1); - } + new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1); + new->t_read = NULL; new->oi_write_q = list_new(); new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT; @@ -329,7 +324,8 @@ static struct ospf *ospf_new(unsigned short instance, const char *name) new->fd = -1; if ((ospf_sock_init(new)) < 0) { if (new->vrf_id != VRF_UNKNOWN) - zlog_warn( + flog_err( + EC_LIB_SOCKET, "%s: ospf_sock_init is unable to open a socket", __func__); return new; @@ -380,6 +376,9 @@ struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name) struct ospf *ospf = NULL; struct listnode *node, *nnode; + if (name == NULL || strmatch(name, VRF_DEFAULT_NAME)) + return ospf_lookup_by_vrf_id(VRF_DEFAULT); + for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) { if ((ospf->instance == instance) && ((ospf->name == NULL && name == NULL) @@ -636,7 +635,7 @@ static void ospf_finish_final(struct ospf *ospf) for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data)) ospf_vl_delete(ospf, vl_data); - list_delete_and_null(&ospf->vlinks); + list_delete(&ospf->vlinks); /* Remove any ospf interface config params */ FOR_ALL_INTERFACES (vrf, ifp) { @@ -650,7 +649,7 @@ static void ospf_finish_final(struct ospf *ospf) /* Reset interface. */ for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) ospf_if_free(oi); - list_delete_and_null(&ospf->oiflist); + list_delete(&ospf->oiflist); /* De-Register VRF */ ospf_zebra_vrf_deregister(ospf); @@ -720,8 +719,6 @@ static void ospf_finish_final(struct ospf *ospf) ospf_lsdb_free(ospf->lsdb); for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) { - struct ospf_lsa *lsa; - if ((lsa = rn->info) != NULL) { ospf_lsa_unlock(&lsa); rn->info = NULL; @@ -752,12 +749,11 @@ static void ospf_finish_final(struct ospf *ospf) ospf_ase_external_lsas_finish(ospf->external_lsas); } - list_delete_and_null(&ospf->areas); - list_delete_and_null(&ospf->oi_write_q); + list_delete(&ospf->areas); + list_delete(&ospf->oi_write_q); for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) { struct list *ext_list; - struct listnode *node; struct ospf_external *ext; ext_list = ospf->external[i]; @@ -870,7 +866,7 @@ static void ospf_area_free(struct ospf_area *area) ospf_lsa_unlock(&area->router_lsa_self); route_table_finish(area->ranges); - list_delete_and_null(&area->oiflist); + list_delete(&area->oiflist); if (EXPORT_NAME(area)) free(EXPORT_NAME(area)); @@ -894,6 +890,7 @@ void ospf_area_check_free(struct ospf *ospf, struct in_addr area_id) area = ospf_area_lookup_by_area_id(ospf, area_id); if (area && listcount(area->oiflist) == 0 && area->ranges->top == NULL + && !ospf_vl_count(ospf, area) && area->shortcut_configured == OSPF_SHORTCUT_DEFAULT && area->external_routing == OSPF_AREA_DEFAULT && area->no_summary == 0 && area->default_cost == 1 @@ -1152,6 +1149,32 @@ void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp) update_redistributed(ospf, 0); /* interfaces possibly removed */ } +bool ospf_interface_area_is_already_set(struct ospf *ospf, + struct interface *ifp) +{ + struct route_node *rn_oi; + + if (!ospf) + return false; /* Ospf not ready yet */ + + /* Find interfaces that may need to be removed. */ + for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi; + rn_oi = route_next(rn_oi)) { + struct ospf_interface *oi = rn_oi->info; + + if (oi == NULL) + continue; + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + continue; + /* at least one route covered by interface + * that implies already done + */ + return true; + } + return false; +} + /* Check whether interface matches given network * returns: 1, true. 0, false */ @@ -1301,7 +1324,7 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi) if ((lst = (struct list *)rn->info)) { for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */ - list_delete_and_null(&lst); + list_delete(&lst); rn->info = NULL; } @@ -2077,6 +2100,10 @@ static int ospf_vrf_enable(struct vrf *vrf) ospf = ospf_lookup_by_name(vrf->name); if (ospf) { + if (ospf->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) { + XFREE(MTYPE_OSPF_TOP, ospf->name); + ospf->name = NULL; + } old_vrf_id = ospf->vrf_id; /* We have instance configured, link to VRF and make it "up". */ ospf_vrf_link(ospf, vrf); @@ -2087,25 +2114,17 @@ static int ospf_vrf_enable(struct vrf *vrf) old_vrf_id); if (old_vrf_id != ospf->vrf_id) { - if (ospfd_privs.change(ZPRIVS_RAISE)) { - zlog_err( - "ospf_sock_init: could not raise privs, %s", - safe_strerror(errno)); - } - - /* stop zebra redist to us for old vrf */ - zclient_send_dereg_requests(zclient, old_vrf_id); + frr_elevate_privs(&ospfd_privs) { + /* stop zebra redist to us for old vrf */ + zclient_send_dereg_requests(zclient, + old_vrf_id); - ospf_set_redist_vrf_bitmaps(ospf); + ospf_set_redist_vrf_bitmaps(ospf); - /* start zebra redist to us for new vrf */ - ospf_zebra_vrf_register(ospf); + /* start zebra redist to us for new vrf */ + ospf_zebra_vrf_register(ospf); - ret = ospf_sock_init(ospf); - if (ospfd_privs.change(ZPRIVS_LOWER)) { - zlog_err( - "ospf_sock_init: could not lower privs, %s", - safe_strerror(errno)); + ret = ospf_sock_init(ospf); } if (ret < 0 || ospf->fd <= 0) return 0; @@ -2156,7 +2175,7 @@ static int ospf_vrf_disable(struct vrf *vrf) void ospf_vrf_init(void) { vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable, - ospf_vrf_delete); + ospf_vrf_delete, NULL); } void ospf_vrf_terminate(void)