From fd3b19f25200c2788d34bf25a62161927a123369 Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Fri, 19 Jan 2018 15:04:41 +0100 Subject: [PATCH] OSPFD: Update Segment Routing implementation - ospf_ext.c: Correct deferred pointer raised by valgrind - ospf_sr.c: Correct deffered pointer raised by valgrind. Modify Segment Routing shutdown. This is due to the fact that RI LSA 4.0.0.0 is flush prior to 7.0.0.X & 8.0.0.X LSA. This trigger SR-Node deletion which also remove all Extended Link / Prefix leaving them unavailable when there are referenced by 7.0.0.X & 8.0.0.X LSA flushing. - doc/OSPF-SR.rst: Correct Restructured Text syntax and add Configuration example as well as Credit section Signed-off-by: Olivier Dugeon --- doc/OSPF-SR.rst | 102 ++++++++++++++++++++++++++++++++++------------- ospfd/ospf_ext.c | 8 ++++ ospfd/ospf_sr.c | 62 ++++++++++++++-------------- 3 files changed, 114 insertions(+), 58 deletions(-) diff --git a/doc/OSPF-SR.rst b/doc/OSPF-SR.rst index 8dcd88592a..f7ab742342 100644 --- a/doc/OSPF-SR.rst +++ b/doc/OSPF-SR.rst @@ -7,39 +7,49 @@ DON'T use it for production network. Implementation details ---------------------- -Segment Routing used 3 differents OPAQUE LSA in OSPF to carry the various information: - - Router Information: flood the Segment Routing capabilities of the node. This include - the supported algorithms, the Segment Routing Global Block (SRGB) and the Maximum Stack - Depth. +Segment Routing used 3 differents OPAQUE LSA in OSPF to carry the various +information: + + - Router Information: flood the Segment Routing capabilities of the node. + This include the supported algorithms, the Segment Routing Global Block + (SRGB) and the Maximum Stack Depth (MSD). - Extended Link: flood the Adjaceny and Lan Adjacency Segment Identifier - Extended Prefix: flood the Prefix Segment Identifier -The implementation follow previous TE and Router Information code. It used the OPAQUE LSA -functions define in ospf_opaque.[c,h] as well as the OSPF API. This latter is mandatory -for the implementation as it provides the Callback to Segment Routing functions (see below) -when an Extended Link / Prefix or Router Information is received. +The implementation follow previous TE and Router Information code. It used the +OPAQUE LSA functions define in ospf_opaque.[c,h] as well as the OSPF API. This +latter is mandatory for the implementation as it provides the Callback to +Segment Routing functions (see below) when an Extended Link / Prefix or Router +Information is received. Following files where modified or added: - ospd_ri.[c,h] have been modified to add the new TLVs for Segment Routing. - - ospf_ext.[c,h] implement RFC7684 as base support of Extended Link and Prefix Opaque LSA. - - ospf_sr.[c,h] implement the earth of Segment Routing. It adds a new Segment Routing database - to manage Segment Identifiers per Link and Prefix and Segment Routing enable node, Callback - functions to process incoming LSA and install MPLS FIB entry through Zebra. - -the figure below shows the relation between the various files: - - - ospf_sr.c centralized all the Segment Routing processing. It receives Opaque LSA - Router Information (4.0.0.0) from ospf_ri.c and Extended Prefix (7.0.0.X) Link (8.0.0.X) - from ospf_ext.c. Once received, it parse TLVs and SubTLVs and store information in SRDB - (which is defined in ospf_sr.h). For each received LSA, NHLFE is computed and send to - Zebra to add/remove new MPLS labels entries and FEC. New CLI configurations are also - centralized in ospf_sr.c. This CLI will trigger the flooding os new LSA Router Information - (4.0.0.0), Extended Prefix (7.0.0.X) and Link (8.0.0.X) by ospf_ri.c, respectively ospf_ext.c. - - ospf_ri.c send back to ospf_sr.c received Router Information LSA and update self Router - Information LSA with paramters provided by ospf_sr.c i.e. SRGB and MSD. It use ospf_opaque.c - functions to send / received these Opaque LSAs. - - ospf_ext.c send bacl to ospf_sr.c received Extended Prefix and Link Opaque LSA and send - self Extended Prefix and Link Opaque LSA through ospf_opaque.c functions. + - ospf_ext.[c,h] implement RFC7684 as base support of Extended Link and Prefix + Opaque LSA. + - ospf_sr.[c,h] implement the earth of Segment Routing. It adds a new Segment + Routing database to manage Segment Identifiers per Link and Prefix and + Segment Routing enable node, Callback functions to process incoming LSA and + install MPLS FIB entry through Zebra. + +The figure below shows the relation between the various files: + + - ospf_sr.c centralized all the Segment Routing processing. It receives Opaque + LSA Router Information (4.0.0.0) from ospf_ri.c and Extended Prefix + (7.0.0.X) Link (8.0.0.X) from ospf_ext.c. Once received, it parse TLVs and + SubTLVs and store information in SRDB (which is defined in ospf_sr.h). For + each received LSA, NHLFE is computed and send to Zebra to add/remove new + MPLS labels entries and FEC. New CLI configurations are also centralized in + ospf_sr.c. This CLI will trigger the flooding of new LSA Router Information + (4.0.0.0), Extended Prefix (7.0.0.X) and Link (8.0.0.X) by ospf_ri.c, + respectively ospf_ext.c. + - ospf_ri.c send back to ospf_sr.c received Router Information LSA and update + Self Router Information LSA with paramters provided by ospf_sr.c i.e. SRGB + and MSD. It use ospf_opaque.c functions to send/received these Opaque LSAs. + - ospf_ext.c send bacl to ospf_sr.c received Extended Prefix and Link Opaque + LSA and send self Extended Prefix and Link Opaque LSA through ospf_opaque.c + functions. + +:: +-----------+ +-------+ | | | | @@ -72,6 +82,33 @@ the figure below shows the relation between the various files: | | +---------------+ + Figure1: Overview of Segment Routing interaction + + +Configuration +------------- + +Here it is a simple example of configuration to enable Segment Routing. Note +that ``opaque capability`` must be set to activate Opaque LSA prior to Segment +Routing. + +:: + + router ospf + ospf router-id 192.168.1.11 + capability opaque + mpls-te on + mpls-te router-address 192.168.1.11 + router-info area 0.0.0.0 + segment-routing on + segment-routing global-block 10000 19999 + segment-routing node-msd 8 + segment-routing prefix 192.168.1.11/32 index 1100 + +The first segment-routing statement enable it. The Second one set the SRGB, +third line the MSD and finally, set the Prefix SID index for tha given prefix. +Note that only prefix of Loopback interface could be configured with a Prefix +SID. Known limitations ----------------- @@ -80,3 +117,14 @@ Known limitations - Only SPF algorithm is supported - Extended Prefix Range is not supported +Credits +------- + * Author: Anselme Sawadogo + * Author: Olivier Dugeon + * Copyright (C) 2016 - 2018 Orange Labs http://www.orange.com + +This work has been performed in the framework of the H2020-ICT-2014 +project 5GEx (Grant Agreement no. 671636), which is partially funded +by the European Commission. + + diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index e4dad990b7..0ed5800438 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -918,6 +918,10 @@ static struct ospf_lsa *ospf_ext_pref_lsa_new(struct ospf_area *area, u_int32_t tmp; u_int16_t length; + /* Sanity Check */ + if (exti == NULL) + return NULL; + /* Create a stream for LSA. */ if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) { zlog_warn("EXT: stream_new() error"); @@ -998,6 +1002,10 @@ static struct ospf_lsa *ospf_ext_link_lsa_new(struct ospf_area *area, u_int32_t tmp; u_int16_t length; + /* Sanity Check */ + if (exti == NULL) + return NULL; + /* Create a stream for LSA. */ if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) { zlog_warn("EXT: stream_new() error"); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index e827ccc30c..8ac1515463 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -99,9 +99,23 @@ static int sr_cmp(const void *p1, const void *p2) return (IPV4_ADDR_SAME(&srn->adv_router, rid)); } -/* Functions to free memory space, segment routing */ -static void del_sr_info(void *val) +/* Functions to remove an SR Link */ +static void del_sr_link(void *val) { + struct sr_link *srl = (struct sr_link *)val; + + del_sid_nhlfe(srl->nhlfe[0]); + del_sid_nhlfe(srl->nhlfe[1]); + XFREE(MTYPE_OSPF_SR_PARAMS, val); + return; +} + +/* Functions to remove an SR Prefix */ +static void del_sr_pref(void *val) +{ + struct sr_prefix *srp = (struct sr_prefix *)val; + + del_sid_nhlfe(srp->nhlfe); XFREE(MTYPE_OSPF_SR_PARAMS, val); return; } @@ -128,7 +142,7 @@ static struct sr_node *sr_node_new(struct in_addr *rid) /* Default Algorithm, SRGB and MSD */ for (int i = 0; i < ALGORITHM_COUNT; i++) - OspfSR.algo[i] = SR_ALGORITHM_UNSET; + new->algo[i] = SR_ALGORITHM_UNSET; new->srgb.range_size = 0; new->srgb.lower_bound = 0; @@ -137,8 +151,8 @@ static struct sr_node *sr_node_new(struct in_addr *rid) /* Create Link, Prefix and Range TLVs list */ new->ext_link = list_new(); new->ext_prefix = list_new(); - new->ext_link->del = del_sr_info; - new->ext_prefix->del = del_sr_info; + new->ext_link->del = del_sr_link; + new->ext_prefix->del = del_sr_pref; /* Check if list are correctly created */ if (new->ext_link == NULL || new->ext_prefix == NULL) { @@ -161,31 +175,15 @@ static struct sr_node *sr_node_new(struct in_addr *rid) /* Delete Segment Routing node */ static void sr_node_del(struct sr_node *srn) { - struct listnode *node; - struct sr_link *srl; - struct sr_prefix *srp; - /* Sanity Check */ if (srn == NULL) return; /* Clean Extended Link */ - if (listcount(srn->ext_link) != 0) { - for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) { - listnode_delete(srn->ext_link, srl); - XFREE(MTYPE_OSPF_SR_PARAMS, srl); - } - } - list_delete_original(srn->ext_link); + list_delete_and_null(&srn->ext_link); /* Clean Prefix List */ - if (listcount(srn->ext_prefix) != 0) { - for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) { - listnode_delete(srn->ext_prefix, srp); - XFREE(MTYPE_OSPF_SR_PARAMS, srp); - } - } - list_delete_original(srn->ext_prefix); + list_delete_and_null(&srn->ext_prefix); XFREE(MTYPE_OSPF_SR_PARAMS, srn); } @@ -1352,10 +1350,11 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa) srn = (struct sr_node *)hash_lookup(OspfSR.neighbors, (void *)&(lsah->adv_router)); - /* Sanity check */ + /* SR-Node may be NULL if it has been remove previously when + * processing Router Information LSA deletion */ if (srn == NULL) { - zlog_err( - "SR (ospf_sr_ext_link_lsa_delete): Abort! " + zlog_warn( + "SR (ospf_sr_ext_link_lsa_delete): Stop! " "no entry in SRDB for SR Node %s", inet_ntoa(lsah->adv_router)); return; @@ -1367,7 +1366,7 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa) break; /* Remove Segment Link if found */ - if (srl->instance == instance) { + if ((srl != NULL) && (srl->instance == instance)) { del_sid_nhlfe(srl->nhlfe[0]); del_sid_nhlfe(srl->nhlfe[1]); listnode_delete(srn->ext_link, srl); @@ -1467,10 +1466,11 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa) srn = (struct sr_node *)hash_lookup(OspfSR.neighbors, (void *)&(lsah->adv_router)); - /* Sanity check */ + /* SR-Node may be NULL if it has been remove previously when + * processing Router Information LSA deletion */ if (srn == NULL) { - zlog_err( - "SR (ospf_sr_ext_prefix_lsa_delete): Abort! " + zlog_warn( + "SR (ospf_sr_ext_prefix_lsa_delete): Stop! " "no entry in SRDB for SR Node %s", inet_ntoa(lsah->adv_router)); return; @@ -1482,7 +1482,7 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa) break; /* Remove Segment Link if found */ - if (srp->instance == instance) { + if ((srp != NULL) && (srp->instance == instance)) { del_sid_nhlfe(srp->nhlfe); listnode_delete(srn->ext_link, srp); XFREE(MTYPE_OSPF_SR_PARAMS, srp); -- 2.39.5