diff options
Diffstat (limited to 'ospfd/ospfd.c')
| -rw-r--r-- | ospfd/ospfd.c | 164 |
1 files changed, 82 insertions, 82 deletions
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 7e83714c0a..1d013b260e 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -60,7 +60,10 @@ struct ospf_master *om; unsigned short ospf_instance; extern struct zclient *zclient; +extern struct zclient *zclient_sync; +/* OSPF config processing timer thread */ +struct event *t_ospf_cfg; static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *); static void ospf_network_free(struct ospf *, struct ospf_network *); @@ -572,39 +575,12 @@ static struct ospf *ospf_lookup_by_name(const char *vrf_name) return NULL; } -/* Handle the second half of deferred shutdown. This is called either - * from the deferred-shutdown timer thread, or directly through - * ospf_deferred_shutdown_check. - * - * Function is to cleanup G-R state, if required then call ospf_finish_final - * to complete shutdown of this ospf instance. Possibly exit if the - * whole process is being shutdown and this was the last OSPF instance. - */ -static void ospf_deferred_shutdown_finish(struct ospf *ospf) -{ - ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; - EVENT_OFF(ospf->t_deferred_shutdown); - - ospf_finish_final(ospf); - - /* *ospf is now invalid */ - - /* ospfd being shut-down? If so, was this the last ospf instance? */ - if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN) - && (listcount(om->ospf) == 0)) { - frr_fini(); - exit(0); - } - - return; -} - -/* Timer thread for G-R */ +/* Timer thread for deferred shutdown */ static void ospf_deferred_shutdown_timer(struct event *t) { struct ospf *ospf = EVENT_ARG(t); - ospf_deferred_shutdown_finish(ospf); + ospf_finish_final(ospf); } /* Check whether deferred-shutdown must be scheduled, otherwise call @@ -631,15 +607,12 @@ static void ospf_deferred_shutdown_check(struct ospf *ospf) ospf_router_lsa_update_area(area); } timeout = ospf->stub_router_shutdown_time; + OSPF_TIMER_ON(ospf->t_deferred_shutdown, + ospf_deferred_shutdown_timer, timeout); } else { /* No timer needed */ - ospf_deferred_shutdown_finish(ospf); - return; + ospf_finish_final(ospf); } - - OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer, - timeout); - return; } /* Shut down the entire process */ @@ -654,10 +627,6 @@ void ospf_terminate(void) SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN); - /* Skip some steps if OSPF not actually running */ - if (listcount(om->ospf) == 0) - goto done; - for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) ospf_finish(ospf); @@ -675,27 +644,31 @@ void ospf_terminate(void) /* Cleanup vrf info */ ospf_vrf_terminate(); + keychain_terminate(); + + ospf_opaque_term(); + list_delete(&om->ospf); + /* Deliberately go back up, hopefully to thread scheduler, as * One or more ospf_finish()'s may have deferred shutdown to a timer * thread */ zclient_stop(zclient); zclient_free(zclient); + zclient_stop(zclient_sync); + zclient_free(zclient_sync); -done: frr_fini(); } void ospf_finish(struct ospf *ospf) { - /* let deferred shutdown decide */ - ospf_deferred_shutdown_check(ospf); - - /* if ospf_deferred_shutdown returns, then ospf_finish_final is - * deferred to expiry of G-S timer thread. Return back up, hopefully - * to thread scheduler. - */ - return; + if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) + ospf_finish_final(ospf); + else { + /* let deferred shutdown decide */ + ospf_deferred_shutdown_check(ospf); + } } /* Final cleanup of ospf instance */ @@ -720,6 +693,7 @@ static void ospf_finish_final(struct ospf *ospf) if (!ospf->gr_info.prepare_in_progress) ospf_flush_self_originated_lsas_now(ospf); + XFREE(MTYPE_TMP, ospf->gr_info.exit_reason); /* Unregister redistribution */ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { @@ -800,25 +774,6 @@ static void ospf_finish_final(struct ospf *ospf) ospf_area_free(area); } - /* Cancel all timers. */ - EVENT_OFF(ospf->t_read); - EVENT_OFF(ospf->t_write); - EVENT_OFF(ospf->t_spf_calc); - EVENT_OFF(ospf->t_ase_calc); - EVENT_OFF(ospf->t_maxage); - EVENT_OFF(ospf->t_maxage_walker); - EVENT_OFF(ospf->t_abr_task); - EVENT_OFF(ospf->t_abr_fr); - EVENT_OFF(ospf->t_asbr_check); - EVENT_OFF(ospf->t_asbr_nssa_redist_update); - EVENT_OFF(ospf->t_distribute_update); - EVENT_OFF(ospf->t_lsa_refresher); - EVENT_OFF(ospf->t_opaque_lsa_self); - EVENT_OFF(ospf->t_sr_update); - EVENT_OFF(ospf->t_default_routemap_timer); - EVENT_OFF(ospf->t_external_aggr); - EVENT_OFF(ospf->gr_info.t_grace_period); - LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa) ospf_discard_from_db(ospf, ospf->lsdb, lsa); LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) @@ -906,8 +861,27 @@ static void ospf_finish_final(struct ospf *ospf) } } - route_table_finish(ospf->rt_aggr_tbl); + /* Cancel all timers. */ + EVENT_OFF(ospf->t_read); + EVENT_OFF(ospf->t_write); + EVENT_OFF(ospf->t_spf_calc); + EVENT_OFF(ospf->t_ase_calc); + EVENT_OFF(ospf->t_maxage); + EVENT_OFF(ospf->t_maxage_walker); + EVENT_OFF(ospf->t_deferred_shutdown); + EVENT_OFF(ospf->t_abr_task); + EVENT_OFF(ospf->t_abr_fr); + EVENT_OFF(ospf->t_asbr_check); + EVENT_OFF(ospf->t_asbr_redist_update); + EVENT_OFF(ospf->t_distribute_update); + EVENT_OFF(ospf->t_lsa_refresher); + EVENT_OFF(ospf->t_opaque_lsa_self); + EVENT_OFF(ospf->t_sr_update); + EVENT_OFF(ospf->t_default_routemap_timer); + EVENT_OFF(ospf->t_external_aggr); + EVENT_OFF(ospf->gr_info.t_grace_period); + route_table_finish(ospf->rt_aggr_tbl); ospf_free_refresh_queue(ospf); @@ -930,6 +904,15 @@ static void ospf_finish_final(struct ospf *ospf) XFREE(MTYPE_OSPF_TOP, ospf); } +static void ospf_range_table_node_destroy(route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) +{ + XFREE(MTYPE_OSPF_AREA_RANGE, node->info); + XFREE(MTYPE_ROUTE_NODE, node); +} + +route_table_delegate_t ospf_range_table_delegate = {.create_node = route_node_create, + .destroy_node = ospf_range_table_node_destroy}; /* allocate new OSPF Area object */ struct ospf_area *ospf_area_new(struct ospf *ospf, struct in_addr area_id) @@ -966,8 +949,8 @@ struct ospf_area *ospf_area_new(struct ospf *ospf, struct in_addr area_id) ospf_opaque_type10_lsa_init(new); new->oiflist = list_new(); - new->ranges = route_table_init(); - new->nssa_ranges = route_table_init(); + new->ranges = route_table_init_with_delegate(&ospf_range_table_delegate); + new->nssa_ranges = route_table_init_with_delegate(&ospf_range_table_delegate); if (area_id.s_addr == OSPF_AREA_BACKBONE) ospf->backbone = new; @@ -1112,6 +1095,8 @@ struct ospf_interface *add_ospf_interface(struct connected *co, skip network type setting. */ oi->type = IF_DEF_PARAMS(co->ifp)->type; oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn; + oi->p2mp_delay_reflood = IF_DEF_PARAMS(co->ifp)->p2mp_delay_reflood; + oi->p2mp_non_broadcast = IF_DEF_PARAMS(co->ifp)->p2mp_non_broadcast; /* Add pseudo neighbor. */ ospf_nbr_self_reset(oi, oi->ospf->router_id); @@ -1131,6 +1116,17 @@ struct ospf_interface *add_ospf_interface(struct connected *co, && if_is_operative(co->ifp)) ospf_if_up(oi); + /* + * RFC 3623 - Section 5 ("Unplanned Outages"): + * "The grace-LSAs are encapsulated in Link State Update Packets + * and sent out to all interfaces, even though the restarted + * router has no adjacencies and no knowledge of previous + * adjacencies". + */ + if (oi->ospf->gr_info.restart_in_progress && + oi->ospf->gr_info.reason == OSPF_GR_UNKNOWN_RESTART) + ospf_gr_unplanned_start_interface(oi); + return oi; } @@ -1231,8 +1227,9 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p, { struct route_node *rn; struct ospf_network *network; - struct listnode *node, *nnode; + struct listnode *node; struct ospf_interface *oi; + struct list *ospf_oiflist = NULL; rn = route_node_lookup(ospf->networks, (struct prefix *)p); if (rn == NULL) @@ -1247,8 +1244,9 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p, rn->info = NULL; route_unlock_node(rn); /* initial reference */ - /* Find interfaces that are not configured already. */ - for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { + ospf_oiflist = list_dup(ospf->oiflist); + /* Find interfaces that are not configured already. */ + for (ALL_LIST_ELEMENTS_RO(ospf_oiflist, node, oi)) { if (oi->type == OSPF_IFTYPE_VIRTUALLINK) continue; @@ -1256,6 +1254,8 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p, ospf_network_run_subnet(ospf, oi->connected, NULL, NULL); } + list_delete(&ospf_oiflist); + /* Update connected redistribute. */ update_redistributed(ospf, 0); /* interfaces possibly removed */ ospf_area_check_free(ospf, area_id); @@ -1263,6 +1263,7 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p, return 1; } + /* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means * there might not be any 'router ospf' config. * @@ -1411,7 +1412,6 @@ static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp, struct prefix *p, struct ospf_area *given_area) { - struct listnode *cnode; struct connected *co; if (memcmp(ifp->name, "VLINK", 5) == 0) @@ -1423,7 +1423,7 @@ static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp, /* if interface prefix is match specified prefix, then create socket and join multicast group. */ - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co)) + frr_each (if_connected, ifp->connected, co) ospf_network_run_subnet(ospf, co, p, given_area); } @@ -1990,7 +1990,7 @@ static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma, struct route_node *rn; struct prefix p; - if (oi->type != OSPF_IFTYPE_NBMA) + if (!OSPF_IF_NON_BROADCAST(oi)) return; if (nbr_nbma->nbr != NULL) @@ -2037,7 +2037,7 @@ void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi) struct route_node *rn; struct prefix_ipv4 p; - if (oi->type != OSPF_IFTYPE_NBMA) + if (!OSPF_IF_NON_BROADCAST(oi)) return; for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) @@ -2096,7 +2096,7 @@ int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr) rn->info = nbr_nbma; for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { - if (oi->type == OSPF_IFTYPE_NBMA) + if (OSPF_IF_NON_BROADCAST(oi)) if (prefix_match(oi->address, (struct prefix *)&p)) { ospf_nbr_nbma_add(nbr_nbma, oi); break; @@ -2269,20 +2269,20 @@ static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf, bool set) "%s: setting redist vrf %d bitmap for type %d", __func__, ospf->vrf_id, type); if (set) - vrf_bitmap_set(zclient->redist[AFI_IP][type], + vrf_bitmap_set(&zclient->redist[AFI_IP][type], ospf->vrf_id); else - vrf_bitmap_unset(zclient->redist[AFI_IP][type], + vrf_bitmap_unset(&zclient->redist[AFI_IP][type], ospf->vrf_id); } red_list = ospf->redist[DEFAULT_ROUTE]; if (red_list) { if (set) - vrf_bitmap_set(zclient->default_information[AFI_IP], + vrf_bitmap_set(&zclient->default_information[AFI_IP], ospf->vrf_id); else - vrf_bitmap_unset(zclient->default_information[AFI_IP], + vrf_bitmap_unset(&zclient->default_information[AFI_IP], ospf->vrf_id); } } |
