diff options
| author | Olivier Dugeon <olivier.dugeon@orange.com> | 2018-01-19 15:04:41 +0100 | 
|---|---|---|
| committer | Olivier Dugeon <olivier.dugeon@orange.com> | 2018-01-19 15:04:41 +0100 | 
| commit | fd3b19f25200c2788d34bf25a62161927a123369 (patch) | |
| tree | 2e4d9261eaa973f33abe618f508d2b56ff49310e | |
| parent | cf9b9f77f638923f5a44fdd14ce2725631ffa526 (diff) | |
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 <olivier.dugeon@orange.com>
| -rw-r--r-- | doc/OSPF-SR.rst | 102 | ||||
| -rw-r--r-- | ospfd/ospf_ext.c | 8 | ||||
| -rw-r--r-- | 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 <anselmesawadogo@gmail.com> + * Author: Olivier Dugeon <olivier.dugeon@orange.com> + * 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);  | 
