summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Dugeon <olivier.dugeon@orange.com>2018-01-19 15:04:41 +0100
committerOlivier Dugeon <olivier.dugeon@orange.com>2018-01-19 15:04:41 +0100
commitfd3b19f25200c2788d34bf25a62161927a123369 (patch)
tree2e4d9261eaa973f33abe618f508d2b56ff49310e
parentcf9b9f77f638923f5a44fdd14ce2725631ffa526 (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.rst102
-rw-r--r--ospfd/ospf_ext.c8
-rw-r--r--ospfd/ospf_sr.c62
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);