From: Olivier Dugeon Date: Sat, 3 Feb 2018 18:30:33 +0000 (+0100) Subject: OSPFd: Fix ospfd crash during CI X-Git-Tag: frr-4.0-dev~2^2~1 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=bcf4475ec3f3946a5b9b25d67077bc4cac504954;p=mirror_frr.git OSPFd: Fix ospfd crash during CI When preforming CI test, CLI command 'no router ospf' followed by a 'router ospf' is performed to clean up the previous configuration. Ospfd crash when configuring 'netwoark area'. This is due to opsf_opaque_term() introduce in previous commit that cause this crash. It remove not only Opaque LSA but also the list through the call to 'list_delete_and_null()' function. Same take place in 'ospf_mpls_te_term()', 'ospf_router_info_term()' and 'ospf_ext_term()' function. New set of 'ospf_XXX_finish()' has been introduced to solve this issue while keeping the possiblity to terminate properly the Opaque LSA and remove MPLS LFIB entries set by Segment Routing. Signed-off-by: Olivier Dugeon --- diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index afa70c0f1..819a695e0 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -168,17 +168,41 @@ int ospf_ext_init(void) /* * Extended Link/Prefix termination function * - * @param - node - * + * @param - none * @return - none */ void ospf_ext_term(void) { + if ((OspfEXT.scope != OSPF_OPAQUE_AREA_LSA) + || (OspfEXT.scope != OSPF_OPAQUE_AS_LSA)) + zlog_warn( + "EXT: Unable to unregister Extended Prefix " + "Opaque LSA functions: Wrong scope!"); + else + ospf_delete_opaque_functab(OspfEXT.scope, + OPAQUE_TYPE_EXTENDED_PREFIX_LSA); + + ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA, + OPAQUE_TYPE_EXTENDED_LINK_LSA); + list_delete_and_null(&OspfEXT.iflist); OspfEXT.scope = 0; OspfEXT.enabled = false; + return; +} + +/* + * Extended Link/Prefix finish function + * + * @param - none + * @return - none + */ +void ospf_ext_finish(void) +{ + // list_delete_all_node(OspfEXT.iflist); + OspfEXT.enabled = false; } /* diff --git a/ospfd/ospf_ext.h b/ospfd/ospf_ext.h index 3ebca7f5d..67280754d 100644 --- a/ospfd/ospf_ext.h +++ b/ospfd/ospf_ext.h @@ -191,6 +191,7 @@ struct ext_itf { /* Prototypes. */ extern int ospf_ext_init(void); extern void ospf_ext_term(void); +extern void ospf_ext_finish(void); extern void ospf_ext_update_sr(bool enable); extern uint32_t ospf_ext_schedule_prefix_index(struct interface *ifp, uint32_t index, diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 216492781..1c586d252 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -122,6 +122,15 @@ void ospf_opaque_term(void) return; } +void ospf_opaque_finish(void) +{ + ospf_router_info_finish(); + + ospf_ext_finish(); + + ospf_sr_finish(); +} + int ospf_opaque_type9_lsa_init(struct ospf_interface *oi) { if (oi->opaque_lsa_self != NULL) diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h index 323ad75b7..632b7b039 100644 --- a/ospfd/ospf_opaque.h +++ b/ospfd/ospf_opaque.h @@ -122,6 +122,7 @@ enum lsa_opcode { extern void ospf_opaque_init(void); extern void ospf_opaque_term(void); +extern void ospf_opaque_finish(void); extern int ospf_opaque_type9_lsa_init(struct ospf_interface *oi); extern void ospf_opaque_type9_lsa_term(struct ospf_interface *oi); extern int ospf_opaque_type10_lsa_init(struct ospf_area *area); diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 647234c58..a1d20fdd6 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -198,6 +198,23 @@ static int ospf_router_info_register(u_int8_t scope) return rc; } +static int ospf_router_info_unregister() +{ + + if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA) + && (OspfRI.scope != OSPF_OPAQUE_AREA_LSA)) { + zlog_warn( + "Unable to unregister Router Info functions: Wrong scope!"); + return -1; + } + + ospf_delete_opaque_functab(OspfRI.scope, + OPAQUE_TYPE_ROUTER_INFORMATION_LSA); + + OspfRI.registered = 0; + return 0; +} + void ospf_router_info_term(void) { @@ -206,9 +223,19 @@ void ospf_router_info_term(void) OspfRI.enabled = false; + ospf_router_info_unregister(); + return; } +void ospf_router_info_finish(void) +{ + list_delete_all_node(OspfRI.pce_info.pce_domain); + list_delete_all_node(OspfRI.pce_info.pce_neighbor); + + OspfRI.enabled = false; +} + static void del_pce_info(void *val) { XFREE(MTYPE_OSPF_PCE_PARAMS, val); diff --git a/ospfd/ospf_ri.h b/ospfd/ospf_ri.h index e63312ce1..39ebb7200 100644 --- a/ospfd/ospf_ri.h +++ b/ospfd/ospf_ri.h @@ -176,6 +176,7 @@ struct scope_info { /* Prototypes. */ extern int ospf_router_info_init(void); extern void ospf_router_info_term(void); +extern void ospf_router_info_finish(void); extern int ospf_router_info_enable(void); extern void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index d906a4ce5..5586f24f6 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -352,7 +352,6 @@ int ospf_sr_init(void) * Segment Routing termination function * * @param - nothing - * * @return - nothing */ void ospf_sr_term(void) @@ -369,6 +368,21 @@ void ospf_sr_term(void) if (OspfSR.prefix) route_table_finish(OspfSR.prefix); + OspfSR.enabled = false; + OspfSR.self = NULL; +} + +/* + * Segment Routing finish function + * + * @param - nothing + * @return - nothing + */ +void ospf_sr_finish(void) +{ + /* Stop Segment Routing */ + ospf_sr_stop(); + OspfSR.enabled = false; } diff --git a/ospfd/ospf_sr.h b/ospfd/ospf_sr.h index 172e8a536..cb7d0833e 100644 --- a/ospfd/ospf_sr.h +++ b/ospfd/ospf_sr.h @@ -299,6 +299,7 @@ struct sr_prefix { /* Segment Routing initialisation functions */ extern int ospf_sr_init(void); extern void ospf_sr_term(void); +extern void ospf_sr_finish(void); /* Segment Routing LSA update & delete functions */ extern void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa); extern void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa); diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index e11e89346..ab395207b 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -147,17 +147,46 @@ static int ospf_mpls_te_register(enum inter_as_mode mode) return rc; } +static int ospf_mpls_te_unregister() +{ + u_int8_t scope; + + if (OspfMplsTE.inter_as == Off) + return 0; + + if (OspfMplsTE.inter_as == AS) + scope = OSPF_OPAQUE_AS_LSA; + else + scope = OSPF_OPAQUE_AREA_LSA; + + ospf_delete_opaque_functab(scope, OPAQUE_TYPE_INTER_AS_LSA); + + return 0; +} + void ospf_mpls_te_term(void) { list_delete_and_null(&OspfMplsTE.iflist); + ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA, + OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); + OspfMplsTE.enabled = false; + ospf_mpls_te_unregister(); OspfMplsTE.inter_as = Off; return; } +void ospf_mpls_te_finish(void) +{ + // list_delete_all_node(OspfMplsTE.iflist); + + OspfMplsTE.enabled = false; + OspfMplsTE.inter_as = Off; +} + /*------------------------------------------------------------------------* * Followings are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/ @@ -2392,6 +2421,9 @@ DEFUN (no_ospf_mpls_te_inter_as, ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); } + /* Deregister the Callbacks for Inter-AS suport */ + ospf_mpls_te_unregister(); + return CMD_SUCCESS; } diff --git a/ospfd/ospf_te.h b/ospfd/ospf_te.h index 013421451..ed71e54f5 100644 --- a/ospfd/ospf_te.h +++ b/ospfd/ospf_te.h @@ -406,6 +406,7 @@ struct mpls_te_link { /* Prototypes. */ extern int ospf_mpls_te_init(void); extern void ospf_mpls_te_term(void); +extern void ospf_mpls_te_finish(void); extern struct ospf_mpls_te *get_ospf_mpls_te(void); extern void ospf_mpls_te_update_if(struct interface *); extern void ospf_mpls_te_lsa_schedule(struct mpls_te_link *, enum lsa_opcode); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index e53599462..86a3293d7 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -610,6 +610,8 @@ static void ospf_finish_final(struct ospf *ospf) ospf_opaque_type11_lsa_term(ospf); + ospf_opaque_finish(); + ospf_flush_self_originated_lsas_now(ospf); /* Unregister redistribution */ @@ -780,8 +782,6 @@ static void ospf_finish_final(struct ospf *ospf) if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) instance = ospf->instance; - ospf_opaque_term(); - ospf_delete(ospf); if (ospf->name) {