summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/developer/ospf-sr.rst19
-rw-r--r--doc/user/ospfd.rst12
-rw-r--r--ospfd/ospf_errors.c6
-rw-r--r--ospfd/ospf_errors.h1
-rw-r--r--ospfd/ospf_ext.c165
-rw-r--r--ospfd/ospf_ext.h1
-rw-r--r--ospfd/ospf_ri.c86
-rw-r--r--ospfd/ospf_ri.h10
-rw-r--r--ospfd/ospf_sr.c516
-rw-r--r--ospfd/ospf_sr.h70
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json24
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/ospfd.conf1
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json4
-rw-r--r--tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json30
-rw-r--r--tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json6
-rw-r--r--tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json16
-rw-r--r--tests/topotests/ospf-sr-topo1/r3/ospfd.conf1
-rw-r--r--tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json27
-rw-r--r--tests/topotests/ospf-sr-topo1/r4/ospfd.conf1
19 files changed, 792 insertions, 204 deletions
diff --git a/doc/developer/ospf-sr.rst b/doc/developer/ospf-sr.rst
index 070465db5b..efe9b1b12f 100644
--- a/doc/developer/ospf-sr.rst
+++ b/doc/developer/ospf-sr.rst
@@ -1,8 +1,7 @@
OSPF Segment Routing
====================
-This is an EXPERIMENTAL support of draft
-`draft-ietf-ospf-segment-routing-extensions-24`.
+This is an EXPERIMENTAL support of `RFC 8665`.
DON'T use it for production network.
Supported Features
@@ -10,12 +9,13 @@ Supported Features
* Automatic computation of Primary and Backup Adjacency SID with
Cisco experimental remote IP address
-* SRGB configuration
+* SRGB & SRLB configuration
* Prefix configuration for Node SID with optional NO-PHP flag (Linux
kernel support both mode)
* Node MSD configuration (with Linux Kernel >= 4.10 a maximum of 32 labels
could be stack)
* Automatic provisioning of MPLS table
+* Equal Cost Multi-Path (ECMP)
* Static route configuration with label stack up to 32 labels
Interoperability
@@ -243,16 +243,16 @@ 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 local-block 5000 5999
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 a given prefix.
+The first segment-routing statement enables it. The second and third one set
+the SRGB and SRLB respectively, fourth line the MSD and finally, set the
+Prefix SID index for a given prefix.
+
Note that only prefix of Loopback interface could be configured with a Prefix
SID. It is possible to add `no-php-flag` at the end of the prefix command to
disable Penultimate Hop Popping. This advertises to peers that they MUST NOT pop
@@ -265,9 +265,6 @@ Known limitations
* Only single Area is supported. ABR is not yet supported
* Only SPF algorithm is supported
* Extended Prefix Range is not supported
-* MPLS table are not flush at startup. Thus, restarting zebra process is
- mandatory to remove old MPLS entries in the data plane after a crash of
- ospfd daemon
* With NO Penultimate Hop Popping, it is not possible to express a Segment
Path with an Adjacency SID due to the impossibility for the Linux Kernel to
perform double POP instruction.
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index 16eaf3be2a..ef3eb38510 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -1071,8 +1071,8 @@ Router Information
Segment Routing
===============
-This is an EXPERIMENTAL support of Segment Routing as per draft
-`draft-ietf-ospf-segment-routing-extensions-24.txt` for MPLS dataplane.
+This is an EXPERIMENTAL support of Segment Routing as per `RFC 8665` for MPLS
+dataplane.
.. index:: [no] segment-routing on
.. clicmd:: [no] segment-routing on
@@ -1085,7 +1085,13 @@ This is an EXPERIMENTAL support of Segment Routing as per draft
.. clicmd:: [no] segment-routing global-block (0-1048575) (0-1048575)
Fix the Segment Routing Global Block i.e. the label range used by MPLS to
- store label in the MPLS FIB.
+ store label in the MPLS FIB for Prefix SID.
+
+.. index:: [no] segment-routing local-block (0-1048575) (0-1048575)
+.. clicmd:: [no] segment-routing local-block (0-1048575) (0-1048575)
+
+ Fix the Segment Routing Local Block i.e. the label range used by MPLS to
+ store label in the MPLS FIB for Adjacency SID.
.. index:: [no] segment-routing node-msd (1-16)
.. clicmd:: [no] segment-routing node-msd (1-16)
diff --git a/ospfd/ospf_errors.c b/ospfd/ospf_errors.c
index a985efc668..2de77a43f6 100644
--- a/ospfd/ospf_errors.c
+++ b/ospfd/ospf_errors.c
@@ -158,6 +158,12 @@ static struct log_ref ferr_ospf_err[] = {
.suggestion = "Restart OSPF instance, If the problem persists, report the problem for troubleshooting"
},
{
+ .code = EC_OSPF_SR_SID_OVERFLOW,
+ .title = "OSPF SR Segment-ID overflow",
+ .description = "OSPF Segment Routing ID index or label exceed Global or Local Block Range",
+ .suggestion = "Restart OSPF instance, If the problem persists, report the problem for troubleshooting"
+ },
+ {
.code = EC_OSPF_INVALID_ALGORITHM,
.title = "OSPF SR Invalid Algorithm",
.description = "OSPF Segment Routing invalid Algorithm",
diff --git a/ospfd/ospf_errors.h b/ospfd/ospf_errors.h
index 726f7d9c8b..df5bdaa491 100644
--- a/ospfd/ospf_errors.h
+++ b/ospfd/ospf_errors.h
@@ -31,6 +31,7 @@ enum ospf_log_refs {
EC_OSPF_SR_INVALID_DB,
EC_OSPF_SR_NODE_CREATE,
EC_OSPF_SR_INVALID_LSA_ID,
+ EC_OSPF_SR_SID_OVERFLOW,
EC_OSPF_INVALID_ALGORITHM,
EC_OSPF_FSM_INVALID_STATE,
EC_OSPF_SET_METRIC_PLUS,
diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c
index 6dd5d78bd0..8e4548f74d 100644
--- a/ospfd/ospf_ext.c
+++ b/ospfd/ospf_ext.c
@@ -98,6 +98,7 @@ static void ospf_ext_link_lsa_schedule(struct ext_itf *exti,
static void ospf_ext_lsa_schedule(struct ext_itf *exti, enum lsa_opcode op);
static int ospf_ext_link_lsa_update(struct ospf_lsa *lsa);
static int ospf_ext_pref_lsa_update(struct ospf_lsa *lsa);
+static void ospf_ext_link_delete_adj_sid(struct ext_itf *exti);
static void del_ext_info(void *val);
/*
@@ -434,6 +435,20 @@ static void set_lan_adj_sid(struct ext_itf *exti, bool backup, uint32_t value,
exti->lan_sid[index].neighbor_id = neighbor_id;
}
+static void unset_adjacency_sid(struct ext_itf *exti)
+{
+ /* Reset Adjacency TLV */
+ if (exti->type == ADJ_SID) {
+ TLV_TYPE(exti->adj_sid[0]) = 0;
+ TLV_TYPE(exti->adj_sid[1]) = 0;
+ }
+ /* or Lan-Adjacency TLV */
+ if (exti->type == LAN_ADJ_SID) {
+ TLV_TYPE(exti->lan_sid[0]) = 0;
+ TLV_TYPE(exti->lan_sid[1]) = 0;
+ }
+}
+
/* Experimental SubTLV from Cisco */
static void set_rmt_itf_addr(struct ext_itf *exti, struct in_addr rmtif)
{
@@ -452,7 +467,7 @@ static void ospf_extended_lsa_delete(struct ext_itf *exti)
return;
osr_debug("EXT (%s): Disable %s%s%s-SID on interface %s", __func__,
- exti->stype == PREF_SID ? "Prefix" : "",
+ exti->stype == LOCAL_SID ? "Prefix" : "",
exti->stype == ADJ_SID ? "Adjacency" : "",
exti->stype == LAN_ADJ_SID ? "LAN-Adjacency" : "",
exti->ifp->name);
@@ -465,8 +480,10 @@ static void ospf_extended_lsa_delete(struct ext_itf *exti)
/* De-activate this Extended Prefix/Link and remove corresponding
* Segment-Routing Prefix-SID or (LAN)-ADJ-SID */
- exti->flags = EXT_LPFLG_LSA_INACTIVE;
- ospf_sr_ext_itf_delete(exti);
+ if (exti->stype == ADJ_SID || exti->stype == LAN_ADJ_SID)
+ ospf_ext_link_delete_adj_sid(exti);
+ else
+ ospf_sr_ext_itf_delete(exti);
}
/*
@@ -521,6 +538,97 @@ uint32_t ospf_ext_schedule_prefix_index(struct interface *ifp, uint32_t index,
return SET_OPAQUE_LSID(exti->type, exti->instance);
}
+/**
+ * Update Adjacecny-SID for Extended Link LSA
+ *
+ * @param exti Extended Link information
+ */
+static void ospf_ext_link_update_adj_sid(struct ext_itf *exti)
+{
+ mpls_label_t label;
+ mpls_label_t bck_label;
+
+ /* Process only (LAN)Adjacency-SID Type */
+ if (exti->stype != ADJ_SID && exti->stype != LAN_ADJ_SID)
+ return;
+
+ /* Request Primary & Backup Labels from Label Manager */
+ bck_label = ospf_sr_local_block_request_label();
+ label = ospf_sr_local_block_request_label();
+ if (bck_label == MPLS_INVALID_LABEL || label == MPLS_INVALID_LABEL) {
+ if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
+ ospf_ext_lsa_schedule(exti, FLUSH_THIS_LSA);
+ return;
+ }
+
+ /* Set Adjacency-SID, backup first */
+ if (exti->stype == ADJ_SID) {
+ set_adj_sid(exti, true, bck_label, SID_LABEL);
+ set_adj_sid(exti, false, label, SID_LABEL);
+ } else {
+ set_lan_adj_sid(exti, true, bck_label, SID_LABEL,
+ exti->lan_sid[0].neighbor_id);
+ set_lan_adj_sid(exti, false, label, SID_LABEL,
+ exti->lan_sid[1].neighbor_id);
+ }
+
+ /* Finally, add corresponding SR Link in SRDB & MPLS LFIB */
+ SET_FLAG(exti->flags, EXT_LPFLG_FIB_ENTRY_SET);
+ ospf_sr_ext_itf_add(exti);
+}
+
+/**
+ * Delete Adjacecny-SID for Extended Link LSA
+ *
+ * @param exti Extended Link information
+ */
+static void ospf_ext_link_delete_adj_sid(struct ext_itf *exti)
+{
+ /* Process only (LAN)Adjacency-SID Type */
+ if (exti->stype != ADJ_SID && exti->stype != LAN_ADJ_SID)
+ return;
+
+ /* Release Primary & Backup Labels from Label Manager */
+ if (exti->stype == ADJ_SID) {
+ ospf_sr_local_block_release_label(exti->adj_sid[0].value);
+ ospf_sr_local_block_release_label(exti->adj_sid[1].value);
+ } else {
+ ospf_sr_local_block_release_label(exti->adj_sid[0].value);
+ ospf_sr_local_block_release_label(exti->adj_sid[1].value);
+ }
+ /* And reset corresponding TLV */
+ unset_adjacency_sid(exti);
+
+ /* Finally, remove corresponding SR Link in SRDB & MPLS LFIB */
+ UNSET_FLAG(exti->flags, EXT_LPFLG_FIB_ENTRY_SET);
+ ospf_sr_ext_itf_delete(exti);
+}
+
+/**
+ * Update Extended Link LSA once Segment Routing Label Block has been changed.
+ */
+void ospf_ext_link_srlb_update(void)
+{
+ struct listnode *node;
+ struct ext_itf *exti;
+
+
+ osr_debug("EXT (%s): Update Extended Links with new SRLB", __func__);
+
+ /* Update all Extended Link Adjaceny-SID */
+ for (ALL_LIST_ELEMENTS_RO(OspfEXT.iflist, node, exti)) {
+ /* Skip Extended Prefix */
+ if (exti->stype == PREF_SID || exti->stype == LOCAL_SID)
+ continue;
+
+ /* Skip inactive Extended Link */
+ if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE))
+ continue;
+
+ ospf_ext_link_update_adj_sid(exti);
+ }
+}
+
/*
* Used by Segment Routing to activate/deactivate Extended Link/Prefix flooding
*
@@ -541,10 +649,15 @@ void ospf_ext_update_sr(bool enable)
/* Refresh LSAs if already engaged or originate */
for (ALL_LIST_ELEMENTS_RO(OspfEXT.iflist, node, exti)) {
- /* Skip inactive Extended Link */
+ /* Skip Inactive Extended Link */
if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE))
continue;
+ /* Update Extended Link (LAN)Adj-SID if not set */
+ if (!CHECK_FLAG(exti->flags, EXT_LPFLG_FIB_ENTRY_SET))
+ ospf_ext_link_update_adj_sid(exti);
+
+ /* Finally, flood the extended Link */
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
ospf_ext_lsa_schedule(exti, REFRESH_THIS_LSA);
else
@@ -684,7 +797,6 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
{
struct ospf_interface *oi = nbr->oi;
struct ext_itf *exti;
- uint32_t label;
/* Process Link only when neighbor old or new state is NSM Full */
if (nbr->state != NSM_Full && old_status != NSM_Full)
@@ -709,7 +821,10 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
/* Remove Extended Link if Neighbor State goes Down or Deleted */
if (nbr->state == NSM_Down || nbr->state == NSM_Deleted) {
- ospf_extended_lsa_delete(exti);
+ ospf_ext_link_delete_adj_sid(exti);
+ if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
+ ospf_ext_link_lsa_schedule(exti, FLUSH_THIS_LSA);
+ exti->flags = EXT_LPFLG_LSA_INACTIVE;
return;
}
@@ -729,11 +844,6 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
set_ext_link(exti, OSPF_IFTYPE_POINTOPOINT, nbr->router_id,
oi->address->u.prefix4);
- /* Set Extended Link Adjacency SubTLVs, backup first */
- label = get_ext_link_label_value();
- set_adj_sid(exti, true, label, SID_LABEL);
- label = get_ext_link_label_value();
- set_adj_sid(exti, false, label, SID_LABEL);
/* And Remote Interface address */
set_rmt_itf_addr(exti, nbr->address.u.prefix4);
@@ -747,11 +857,9 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
set_ext_link(exti, OSPF_IFTYPE_BROADCAST, DR(oi),
oi->address->u.prefix4);
- /* Set Extended Link Adjacency SubTLVs, backup first */
- label = get_ext_link_label_value();
- set_lan_adj_sid(exti, true, label, SID_LABEL, nbr->router_id);
- label = get_ext_link_label_value();
- set_lan_adj_sid(exti, false, label, SID_LABEL, nbr->router_id);
+ /* Set Neighbor ID */
+ exti->lan_sid[0].neighbor_id = nbr->router_id;
+ exti->lan_sid[1].neighbor_id = nbr->router_id;
break;
@@ -764,36 +872,33 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
set_ext_link(exti, OSPF_IFTYPE_BROADCAST, DR(oi),
oi->address->u.prefix4);
- /* Set Extended Link Adjacency SubTLVs, backup first */
- label = get_ext_link_label_value();
- set_adj_sid(exti, true, label, SID_LABEL);
- label = get_ext_link_label_value();
- set_adj_sid(exti, false, label, SID_LABEL);
-
break;
default:
+ if (CHECK_FLAG(exti->flags, EXT_LPFLG_FIB_ENTRY_SET))
+ ospf_ext_link_delete_adj_sid(exti);
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
ospf_ext_link_lsa_schedule(exti, FLUSH_THIS_LSA);
exti->flags = EXT_LPFLG_LSA_INACTIVE;
return;
}
- osr_debug("EXT (%s): Complete %sAdjacency SID for interface %s ",
- __func__, exti->stype == ADJ_SID ? "" : "LAN-",
- oi->ifp->name);
-
- /* flood this links params if everything is ok */
SET_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE);
+
if (OspfEXT.enabled) {
+ osr_debug("EXT (%s): Set %sAdjacency SID for interface %s ",
+ __func__, exti->stype == ADJ_SID ? "" : "LAN-",
+ oi->ifp->name);
+
+ /* Update (LAN)Adjacency SID */
+ ospf_ext_link_update_adj_sid(exti);
+
+ /* flood this links params if everything is ok */
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
ospf_ext_link_lsa_schedule(exti, REFRESH_THIS_LSA);
else
ospf_ext_link_lsa_schedule(exti, REORIGINATE_THIS_LSA);
}
-
- /* Finally install (LAN)Adjacency-SID in the SRDB */
- ospf_sr_ext_itf_add(exti);
}
/* Callbacks to handle Extended Link Segment Routing LSA information */
diff --git a/ospfd/ospf_ext.h b/ospfd/ospf_ext.h
index 0071584e26..b1e4feb6df 100644
--- a/ospfd/ospf_ext.h
+++ b/ospfd/ospf_ext.h
@@ -189,6 +189,7 @@ 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 void ospf_ext_link_srlb_update(void);
extern uint32_t ospf_ext_schedule_prefix_index(struct interface *ifp,
uint32_t index,
struct prefix_ipv4 *p,
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index ececed0643..8eeaf7be3c 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -442,29 +442,52 @@ static void unset_sr_algorithm(uint8_t algo)
TLV_LEN(OspfRI.sr_info.algo) = htons(0);
}
-/* Segment Routing Global Block SubTLV - section 3.2 */
-static void set_sr_sid_label_range(struct sr_srgb srgb)
+/* Set Segment Routing Global Block SubTLV - section 3.2 */
+static void set_sr_global_label_range(struct sr_block srgb)
{
/* Set Header */
- TLV_TYPE(OspfRI.sr_info.range) = htons(RI_SR_TLV_SID_LABEL_RANGE);
- TLV_LEN(OspfRI.sr_info.range) =
+ TLV_TYPE(OspfRI.sr_info.srgb) = htons(RI_SR_TLV_SRGB_LABEL_RANGE);
+ TLV_LEN(OspfRI.sr_info.srgb) =
htons(SUBTLV_SID_LABEL_SIZE + sizeof(uint32_t));
/* Set Range Size */
- OspfRI.sr_info.range.size = htonl(SET_RANGE_SIZE(srgb.range_size));
+ OspfRI.sr_info.srgb.size = htonl(SET_RANGE_SIZE(srgb.range_size));
/* Set Lower bound label SubTLV */
- TLV_TYPE(OspfRI.sr_info.range.lower) = htons(SUBTLV_SID_LABEL);
- TLV_LEN(OspfRI.sr_info.range.lower) = htons(SID_RANGE_LABEL_LENGTH);
- OspfRI.sr_info.range.lower.value = htonl(SET_LABEL(srgb.lower_bound));
+ TLV_TYPE(OspfRI.sr_info.srgb.lower) = htons(SUBTLV_SID_LABEL);
+ TLV_LEN(OspfRI.sr_info.srgb.lower) = htons(SID_RANGE_LABEL_LENGTH);
+ OspfRI.sr_info.srgb.lower.value = htonl(SET_LABEL(srgb.lower_bound));
}
-/* Unset this SRGB SubTLV */
-static void unset_sr_sid_label_range(void)
+/* Unset Segment Routing Global Block SubTLV */
+static void unset_sr_global_label_range(void)
{
+ TLV_TYPE(OspfRI.sr_info.srgb) = htons(0);
+ TLV_LEN(OspfRI.sr_info.srgb) = htons(0);
+ TLV_TYPE(OspfRI.sr_info.srgb.lower) = htons(0);
+ TLV_LEN(OspfRI.sr_info.srgb.lower) = htons(0);
+}
- TLV_TYPE(OspfRI.sr_info.range) = htons(0);
- TLV_LEN(OspfRI.sr_info.range) = htons(0);
- TLV_TYPE(OspfRI.sr_info.range.lower) = htons(0);
- TLV_LEN(OspfRI.sr_info.range.lower) = htons(0);
+/* Set Segment Routing Local Block SubTLV - section 3.2 */
+static void set_sr_local_label_range(struct sr_block srlb)
+{
+ /* Set Header */
+ TLV_TYPE(OspfRI.sr_info.srlb) = htons(RI_SR_TLV_SRLB_LABEL_RANGE);
+ TLV_LEN(OspfRI.sr_info.srlb) =
+ htons(SUBTLV_SID_LABEL_SIZE + sizeof(uint32_t));
+ /* Set Range Size */
+ OspfRI.sr_info.srlb.size = htonl(SET_RANGE_SIZE(srlb.range_size));
+ /* Set Lower bound label SubTLV */
+ TLV_TYPE(OspfRI.sr_info.srlb.lower) = htons(SUBTLV_SID_LABEL);
+ TLV_LEN(OspfRI.sr_info.srlb.lower) = htons(SID_RANGE_LABEL_LENGTH);
+ OspfRI.sr_info.srlb.lower.value = htonl(SET_LABEL(srlb.lower_bound));
+}
+
+/* Unset Segment Routing Local Block SubTLV */
+static void unset_sr_local_label_range(void)
+{
+ TLV_TYPE(OspfRI.sr_info.srlb) = htons(0);
+ TLV_LEN(OspfRI.sr_info.srlb) = htons(0);
+ TLV_TYPE(OspfRI.sr_info.srlb.lower) = htons(0);
+ TLV_LEN(OspfRI.sr_info.srlb.lower) = htons(0);
}
/* Set Maximum Stack Depth for this router */
@@ -563,7 +586,7 @@ static int is_mandated_params_set(struct ospf_router_info ori)
return rc;
if ((ori.sr_info.enabled) && (ntohs(TLV_TYPE(ori.sr_info.algo)) == 0)
- && (ntohs(TLV_TYPE(ori.sr_info.range)) == 0))
+ && (ntohs(TLV_TYPE(ori.sr_info.srgb)) == 0))
return rc;
rc = 1;
@@ -575,13 +598,11 @@ static int is_mandated_params_set(struct ospf_router_info ori)
* Used by Segment Routing to set new TLVs and Sub-TLVs values
*
* @param enable To activate or not Segment Routing router Information flooding
- * @param size Size of Label Range i.e. SRGB size
- * @param lower Lower bound of the Label Range i.e. SRGB first label
- * @param msd Maximum label Stack Depth supported by the router
+ * @param srn Self Segment Routing node
*
* @return none
*/
-void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd)
+void ospf_router_info_update_sr(bool enable, struct sr_node *srn)
{
struct listnode *node, *nnode;
struct ospf_ri_area_info *ai;
@@ -612,15 +633,17 @@ void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd)
/* Unset or Set SR parameters */
if (!enable) {
unset_sr_algorithm(SR_ALGORITHM_SPF);
- unset_sr_sid_label_range();
+ unset_sr_global_label_range();
+ unset_sr_local_label_range();
unset_sr_node_msd();
OspfRI.sr_info.enabled = false;
} else {
// Only SR_ALGORITHM_SPF is supported
set_sr_algorithm(SR_ALGORITHM_SPF);
- set_sr_sid_label_range(srgb);
- if (msd != 0)
- set_sr_node_msd(msd);
+ set_sr_global_label_range(srn->srgb);
+ set_sr_local_label_range(srn->srlb);
+ if (srn->msd != 0)
+ set_sr_node_msd(srn->msd);
else
unset_sr_node_msd();
OspfRI.sr_info.enabled = true;
@@ -698,7 +721,9 @@ static void ospf_router_info_lsa_body_set(struct stream *s)
/* Build Algorithm TLV */
build_tlv(s, &TLV_HDR(OspfRI.sr_info.algo));
/* Build SRGB TLV */
- build_tlv(s, &TLV_HDR(OspfRI.sr_info.range));
+ build_tlv(s, &TLV_HDR(OspfRI.sr_info.srgb));
+ /* Build SRLB TLV */
+ build_tlv(s, &TLV_HDR(OspfRI.sr_info.srlb));
/* Build MSD TLV */
build_tlv(s, &TLV_HDR(OspfRI.sr_info.msd));
}
@@ -1409,16 +1434,22 @@ static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
if (vty != NULL) {
vty_out(vty,
- " Segment Routing Range TLV:\n"
+ " Segment Routing %s Range TLV:\n"
" Range Size = %d\n"
" SID Label = %d\n\n",
+ ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
+ ? "Global"
+ : "Local",
GET_RANGE_SIZE(ntohl(range->size)),
GET_LABEL(ntohl(range->lower.value)));
} else {
zlog_debug(
- " Segment Routing Range TLV:\n"
+ " Segment Routing %s Range TLV:\n"
" Range Size = %d\n"
" SID Label = %d\n\n",
+ ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
+ ? "Global"
+ : "Local",
GET_RANGE_SIZE(ntohl(range->size)),
GET_LABEL(ntohl(range->lower.value)));
}
@@ -1469,7 +1500,8 @@ static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
case RI_SR_TLV_SR_ALGORITHM:
sum += show_vty_sr_algorithm(vty, tlvh);
break;
- case RI_SR_TLV_SID_LABEL_RANGE:
+ case RI_SR_TLV_SRGB_LABEL_RANGE:
+ case RI_SR_TLV_SRLB_LABEL_RANGE:
sum += show_vty_sr_range(vty, tlvh);
break;
case RI_SR_TLV_NODE_MSD:
diff --git a/ospfd/ospf_ri.h b/ospfd/ospf_ri.h
index 84511ac5e7..4729677bca 100644
--- a/ospfd/ospf_ri.h
+++ b/ospfd/ospf_ri.h
@@ -201,7 +201,12 @@ struct ospf_ri_sr_info {
* Segment Routing Global Block i.e. label range
* Only one range supported in this code
*/
- struct ri_sr_tlv_sid_label_range range;
+ struct ri_sr_tlv_sid_label_range srgb;
+ /*
+ * Segment Routing Local Block.
+ * Only one block is authorized - see section 3.3
+ */
+ struct ri_sr_tlv_sid_label_range srlb;
/* Maximum SID Depth supported by the node */
struct ri_sr_tlv_node_msd msd;
};
@@ -242,7 +247,6 @@ 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);
+extern void ospf_router_info_update_sr(bool enable, struct sr_node *self);
extern struct scope_info ospf_router_info_get_flooding_scope(void);
#endif /* _ZEBRA_OSPF_ROUTER_INFO_H */
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index 5cc05e6727..ebc31a90f4 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -1,13 +1,14 @@
/*
* This is an implementation of Segment Routing
- * as per draft draft-ietf-ospf-segment-routing-extensions-24
+ * as per RFC 8665 - OSPF Extensions for Segment Routing
+ * and RFC 8476 - Signaling Maximum SID Depth (MSD) Using OSPF
*
* Module name: Segment Routing
*
* Author: Olivier Dugeon <olivier.dugeon@orange.com>
* Author: Anselme Sawadogo <anselmesawadogo@gmail.com>
*
- * Copyright (C) 2016 - 2018 Orange Labs http://www.orange.com
+ * Copyright (C) 2016 - 2020 Orange Labs http://www.orange.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -219,6 +220,182 @@ static struct sr_node *get_sr_node_by_nexthop(struct ospf *ospf,
}
/*
+ * Segment Routing Local Block management functions
+ */
+
+/**
+ * It is necessary to known which label is already allocated to manage the range
+ * of SRLB. This is particular useful when an interface flap (goes up / down
+ * frequently). Here, SR will release and then allocate label for the Adjacency
+ * for each concerned interface. If we don't care, there is a risk to run out of
+ * label.
+ *
+ * For that purpose, a similar principle as already provided to manage chunk of
+ * label is proposed. But, here, the label chunk has not a fix range of 64
+ * labels that could be easily manage with a single variable of 64 bits size.
+ * So, used_mark is used as a bit wise to mark label reserved (bit set) or not
+ * (bit unset). Its size is equal to the number of label of the SRLB range round
+ * up to 64 bits.
+ *
+ * - sr__local_block_init() computes the number of 64 bits variables that are
+ * needed to manage the SRLB range and allocates this number.
+ * - ospf_sr_local_block_request_label() pick up the first available label and
+ * set corresponding bit
+ * - ospf_sr_local_block_release_label() release label by reseting the
+ * corresponding bit and set the next label to the first free position
+ */
+
+/**
+ * Initialize Segment Routing Local Block from SRDB configuration and reserve
+ * block of bits to manage label allocation.
+ *
+ * @param lower_bound The lower bound of the SRLB range
+ * @param upper_bound The upper bound of the SRLB range
+ *
+ * @return 0 on success, -1 otherwise
+ */
+static int sr_local_block_init(uint32_t lower_bound, uint32_t upper_bound)
+{
+ struct sr_local_block *srlb = &OspfSR.srlb;
+ uint32_t size;
+
+ /* Check if SRLB is not already configured */
+ if (srlb->reserved)
+ return 0;
+
+ /*
+ * Request SRLB to the label manager. If the allocation fails, return
+ * an error to disable SR until a new SRLB is successfully allocated.
+ */
+ size = upper_bound - lower_bound + 1;
+ if (ospf_zebra_request_label_range(lower_bound, size)) {
+ srlb->reserved = false;
+ return -1;
+ }
+
+ osr_debug("SR (%s): Got new SRLB [%u/%u]", __func__, lower_bound,
+ upper_bound);
+
+ /* Initialize the SRLB */
+ srlb->start = lower_bound;
+ srlb->end = upper_bound;
+ srlb->current = 0;
+ /* Compute the needed Used Mark number and allocate them */
+ srlb->max_block = size / SRLB_BLOCK_SIZE;
+ if ((size % SRLB_BLOCK_SIZE) != 0)
+ srlb->max_block++;
+ srlb->used_mark = XCALLOC(MTYPE_OSPF_SR_PARAMS,
+ srlb->max_block * SRLB_BLOCK_SIZE);
+ srlb->reserved = true;
+
+ return 0;
+}
+
+/**
+ * Remove Segment Routing Local Block.
+ *
+ */
+static void sr_local_block_delete()
+{
+ struct sr_local_block *srlb = &OspfSR.srlb;
+
+ /* Check if SRLB is not already delete */
+ if (!srlb->reserved)
+ return;
+
+ osr_debug("SR (%s): Remove SRLB [%u/%u]", __func__, srlb->start,
+ srlb->end);
+
+ /* First release the label block */
+ ospf_zebra_release_label_range(srlb->start, srlb->end);
+
+ /* Then reset SRLB structure */
+ if (srlb->used_mark != NULL)
+ XFREE(MTYPE_OSPF_SR_PARAMS, srlb->used_mark);
+ srlb->reserved = false;
+}
+
+/**
+ * Request a label from the Segment Routing Local Block.
+ *
+ * @return First available label on success or MPLS_INVALID_LABEL if the
+ * block of labels is full
+ */
+mpls_label_t ospf_sr_local_block_request_label(void)
+{
+ struct sr_local_block *srlb = &OspfSR.srlb;
+ mpls_label_t label;
+ uint32_t index;
+ uint32_t pos;
+
+ /* Check if we ran out of available labels */
+ if (srlb->current >= srlb->end)
+ return MPLS_INVALID_LABEL;
+
+ /* Get first available label and mark it used */
+ label = srlb->current + srlb->start;
+ index = srlb->current / SRLB_BLOCK_SIZE;
+ pos = 1ULL << (srlb->current % SRLB_BLOCK_SIZE);
+ srlb->used_mark[index] |= pos;
+
+ /* Jump to the next free position */
+ srlb->current++;
+ pos = srlb->current % SRLB_BLOCK_SIZE;
+ while (srlb->current < srlb->end) {
+ if (pos == 0)
+ index++;
+ if (!((1ULL << pos) & srlb->used_mark[index]))
+ break;
+ else {
+ srlb->current++;
+ pos = srlb->current % SRLB_BLOCK_SIZE;
+ }
+ }
+
+ return label;
+}
+
+/**
+ * Release label in the Segment Routing Local Block.
+ *
+ * @param label Label to be release
+ *
+ * @return 0 on success or -1 if label falls outside SRLB
+ */
+int ospf_sr_local_block_release_label(mpls_label_t label)
+{
+ struct sr_local_block *srlb = &OspfSR.srlb;
+ uint32_t index;
+ uint32_t pos;
+
+ /* Check that label falls inside the SRLB */
+ if ((label < srlb->start) || (label > srlb->end)) {
+ flog_warn(EC_OSPF_SR_SID_OVERFLOW,
+ "%s: Returning label %u is outside SRLB [%u/%u]",
+ __func__, label, srlb->start, srlb->end);
+ return -1;
+ }
+
+ index = (label - srlb->start) / SRLB_BLOCK_SIZE;
+ pos = 1ULL << ((label - srlb->start) % SRLB_BLOCK_SIZE);
+ srlb->used_mark[index] &= ~pos;
+ /* Reset current to the first available position */
+ for (index = 0; index < srlb->max_block; index++) {
+ if (srlb->used_mark[index] != 0xFFFFFFFFFFFFFFFF) {
+ for (pos = 0; pos < SRLB_BLOCK_SIZE; pos++)
+ if (!((1ULL << pos) & srlb->used_mark[index])) {
+ srlb->current =
+ index * SRLB_BLOCK_SIZE + pos;
+ break;
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
* Segment Routing Initialization functions
*/
@@ -258,8 +435,10 @@ static int ospf_sr_start(struct ospf *ospf)
(void *)sr_node_new);
/* Complete & Store self SR Node */
- srn->srgb.range_size = OspfSR.srgb.range_size;
- srn->srgb.lower_bound = OspfSR.srgb.lower_bound;
+ srn->srgb.range_size = OspfSR.srgb.size;
+ srn->srgb.lower_bound = OspfSR.srgb.start;
+ srn->srlb.lower_bound = OspfSR.srlb.start;
+ srn->srlb.range_size = OspfSR.srlb.end - OspfSR.srlb.start + 1;
srn->algo[0] = OspfSR.algo[0];
srn->msd = OspfSR.msd;
OspfSR.self = srn;
@@ -276,18 +455,19 @@ static int ospf_sr_start(struct ospf *ospf)
}
/*
- * Request SGRB to the label manager if not already active. If the
- * allocation fails, return an error to disable SR until a new SRGB
- * is successfully allocated.
+ * Request SRLB & SGRB to the label manager if not already reserved.
+ * If the allocation fails, return an error to disable SR until a new
+ * SRLB and/or SRGB are successfully allocated.
*/
- if (!OspfSR.srgb_reserved) {
- if (ospf_zebra_request_label_range(OspfSR.srgb.lower_bound,
- OspfSR.srgb.range_size)
+ sr_local_block_init(OspfSR.srlb.start, OspfSR.srlb.end);
+ if (!OspfSR.srgb.reserved) {
+ if (ospf_zebra_request_label_range(OspfSR.srgb.start,
+ OspfSR.srgb.size)
< 0) {
- OspfSR.srgb_reserved = false;
+ OspfSR.srgb.reserved = false;
return -1;
} else
- OspfSR.srgb_reserved = true;
+ OspfSR.srgb.reserved = true;
}
/* SR is UP and ready to flood LSA */
@@ -296,7 +476,7 @@ static int ospf_sr_start(struct ospf *ospf)
/* Set Router Information SR parameters */
osr_debug("SR: Activate SR for Router Information LSA");
- ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
+ ospf_router_info_update_sr(true, OspfSR.self);
/* Update Ext LSA */
osr_debug("SR: Activate SR for Extended Link/Prefix LSA");
@@ -341,13 +521,22 @@ static void ospf_sr_stop(void)
/* Disable any re-attempt to connect to Label Manager */
THREAD_TIMER_OFF(OspfSR.t_start_lm);
- /* Release SRGB if active. */
- if (OspfSR.srgb_reserved) {
+ /* Release SRGB & SRLB if active. */
+ if (OspfSR.srgb.reserved)
ospf_zebra_release_label_range(
- OspfSR.srgb.lower_bound,
- OspfSR.srgb.lower_bound + OspfSR.srgb.range_size - 1);
- OspfSR.srgb_reserved = false;
- }
+ OspfSR.srgb.start,
+ OspfSR.srgb.start + OspfSR.srgb.size - 1);
+ sr_local_block_delete();
+
+ /* Revert SRGB, SRLB and MSD to default values */
+ OspfSR.srgb.size = DEFAULT_SRGB_SIZE;
+ OspfSR.srgb.start = DEFAULT_SRGB_LABEL;
+ OspfSR.srgb.reserved = false;
+
+ OspfSR.srlb.start = DEFAULT_SRLB_LABEL;
+ OspfSR.srlb.end = DEFAULT_SRLB_LABEL + DEFAULT_SRLB_SIZE - 1;
+ OspfSR.srlb.reserved = false;
+ OspfSR.msd = 0;
/*
* Remove all SR Nodes from the Hash table. Prefix and Link SID will
@@ -376,15 +565,19 @@ int ospf_sr_init(void)
/* Only AREA flooding is supported in this release */
OspfSR.scope = OSPF_OPAQUE_AREA_LSA;
- /* Initialize SRGB, Algorithms and MSD TLVs */
+ /* Initialize Algorithms, SRGB, SRLB and MSD TLVs */
/* Only Algorithm SPF is supported */
OspfSR.algo[0] = SR_ALGORITHM_SPF;
for (int i = 1; i < ALGORITHM_COUNT; i++)
OspfSR.algo[i] = SR_ALGORITHM_UNSET;
- OspfSR.srgb.range_size = MPLS_DEFAULT_MAX_SRGB_SIZE;
- OspfSR.srgb.lower_bound = MPLS_DEFAULT_MIN_SRGB_LABEL;
- OspfSR.srgb_reserved = false;
+ OspfSR.srgb.size = DEFAULT_SRGB_SIZE;
+ OspfSR.srgb.start = DEFAULT_SRGB_LABEL;
+ OspfSR.srgb.reserved = false;
+
+ OspfSR.srlb.start = DEFAULT_SRLB_LABEL;
+ OspfSR.srlb.end = DEFAULT_SRLB_LABEL + DEFAULT_SRLB_SIZE - 1;
+ OspfSR.srlb.reserved = false;
OspfSR.msd = 0;
/* Initialize Hash table for neighbor SR nodes */
@@ -443,7 +636,7 @@ void ospf_sr_finish(void)
*/
/* Compute label from index */
-static mpls_label_t index2label(uint32_t index, struct sr_srgb srgb)
+static mpls_label_t index2label(uint32_t index, struct sr_block srgb)
{
mpls_label_t label;
@@ -588,7 +781,7 @@ static int compute_prefix_nhlfe(struct sr_prefix *srp)
return rc;
/* Compute Input Label with self SRGB */
- srp->label_in = index2label(srp->sid, OspfSR.srgb);
+ srp->label_in = index2label(srp->sid, OspfSR.self->srgb);
rc = 0;
for (ALL_LIST_ELEMENTS_RO(srp->route->paths, node, path)) {
@@ -973,9 +1166,11 @@ static void update_in_nhlfe(struct hash_bucket *bucket, void *args)
if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_VFLG))
continue;
- /* OK. Compute new input label ... */
- srp->label_in = index2label(srp->sid, OspfSR.srgb);
- /* ... and update MPLS LFIB */
+ /* First, remove old MPLS table entries ... */
+ ospf_zebra_delete_prefix_sid(srp);
+ /* ... then compute new input label ... */
+ srp->label_in = index2label(srp->sid, OspfSR.self->srgb);
+ /* ... and install new MPLS LFIB */
ospf_zebra_update_prefix_sid(srp);
}
}
@@ -1024,8 +1219,9 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
struct tlv_header *tlvh;
struct lsa_header *lsah = lsa->data;
struct ri_sr_tlv_sid_label_range *ri_srgb = NULL;
+ struct ri_sr_tlv_sid_label_range *ri_srlb = NULL;
struct ri_sr_tlv_sr_algorithm *algo = NULL;
- struct sr_srgb srgb;
+ struct sr_block srgb;
uint16_t length = 0, sum = 0;
uint8_t msd = 0;
@@ -1061,10 +1257,14 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
algo = (struct ri_sr_tlv_sr_algorithm *)tlvh;
sum += TLV_SIZE(tlvh);
break;
- case RI_SR_TLV_SID_LABEL_RANGE:
+ case RI_SR_TLV_SRGB_LABEL_RANGE:
ri_srgb = (struct ri_sr_tlv_sid_label_range *)tlvh;
sum += TLV_SIZE(tlvh);
break;
+ case RI_SR_TLV_SRLB_LABEL_RANGE:
+ ri_srlb = (struct ri_sr_tlv_sid_label_range *)tlvh;
+ sum += TLV_SIZE(tlvh);
+ break;
case RI_SR_TLV_NODE_MSD:
msd = ((struct ri_sr_tlv_node_msd *)(tlvh))->value;
sum += TLV_SIZE(tlvh);
@@ -1121,9 +1321,12 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
}
/* update LSA ID */
srn->instance = ntohl(lsah->id.s_addr);
+ /* Copy SRGB */
+ srn->srgb.range_size = srgb.range_size;
+ srn->srgb.lower_bound = srgb.lower_bound;
}
- /* Set Algorithm */
+ /* Update Algorithm, SRLB and MSD if present */
if (algo != NULL) {
int i;
for (i = 0; i < ntohs(algo->header.length); i++)
@@ -1133,8 +1336,21 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
} else {
srn->algo[0] = SR_ALGORITHM_SPF;
}
-
srn->msd = msd;
+ if (ri_srlb != NULL) {
+ srn->srlb.range_size = GET_RANGE_SIZE(ntohl(ri_srlb->size));
+ srn->srlb.lower_bound = GET_LABEL(ntohl(ri_srlb->lower.value));
+ }
+
+ osr_debug(" |- Update SR-Node[%pI4], SRGB[%u/%u], SRLB[%u/%u], Algo[%u], MSD[%u]",
+ &srn->adv_router, srn->srgb.lower_bound, srn->srgb.range_size,
+ srn->srlb.lower_bound, srn->srlb.range_size, srn->algo[0],
+ srn->msd);
+
+ /* Check if SRGB has changed */
+ if ((srn->srgb.range_size == srgb.range_size)
+ && (srn->srgb.lower_bound == srgb.lower_bound))
+ return;
/* Copy SRGB */
srn->srgb.range_size = srgb.range_size;
@@ -1526,18 +1742,6 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa)
}
}
-/* Get Label for Extended Link SID */
-/* TODO: To be replace by Zebra Label Manager */
-uint32_t get_ext_link_label_value(void)
-{
- static uint32_t label = ADJ_SID_MIN - 1;
-
- if (label < ADJ_SID_MAX)
- label += 1;
-
- return label;
-}
-
/*
* Update Prefix SID. Call by ospf_ext_pref_ism_change to
* complete initial CLI command at startup.
@@ -1684,17 +1888,23 @@ void ospf_sr_config_write_router(struct vty *vty)
{
struct listnode *node;
struct sr_prefix *srp;
+ uint32_t upper;
- if (OspfSR.status != SR_OFF) {
+ if (OspfSR.status == SR_UP) {
vty_out(vty, " segment-routing on\n");
- if ((OspfSR.srgb.lower_bound != MPLS_DEFAULT_MIN_SRGB_LABEL)
- || (OspfSR.srgb.range_size != MPLS_DEFAULT_MAX_SRGB_SIZE)) {
+ upper = OspfSR.srgb.start + OspfSR.srgb.size - 1;
+ if ((OspfSR.srgb.start != DEFAULT_SRGB_LABEL)
+ || (OspfSR.srgb.size != DEFAULT_SRGB_SIZE))
vty_out(vty, " segment-routing global-block %u %u\n",
- OspfSR.srgb.lower_bound,
- OspfSR.srgb.lower_bound + OspfSR.srgb.range_size
- - 1);
- }
+ OspfSR.srgb.start, upper);
+
+ upper = DEFAULT_SRLB_LABEL + DEFAULT_SRLB_SIZE - 1;
+ if ((OspfSR.srlb.start != DEFAULT_SRLB_LABEL)
+ || (OspfSR.srlb.end != upper))
+ vty_out(vty, " segment-routing local-block %u %u\n",
+ OspfSR.srlb.start, OspfSR.srlb.end);
+
if (OspfSR.msd != 0)
vty_out(vty, " segment-routing node-msd %u\n",
OspfSR.msd);
@@ -1759,7 +1969,7 @@ DEFUN (no_ospf_sr_enable,
ospf_ext_update_sr(false);
/* then, disable Router Information SR parameters */
- ospf_router_info_update_sr(false, OspfSR.srgb, OspfSR.msd);
+ ospf_router_info_update_sr(false, OspfSR.self);
/* Finally, stop Segment Routing */
ospf_sr_stop();
@@ -1790,21 +2000,20 @@ static int update_srgb(uint32_t lower, uint32_t size)
{
/* Check if values have changed */
- if ((OspfSR.srgb.range_size == size)
- && (OspfSR.srgb.lower_bound == lower))
+ if ((OspfSR.srgb.size == size) && (OspfSR.srgb.start == lower))
return 0;
/* Release old SRGB if active. */
- if (OspfSR.srgb_reserved) {
+ if (OspfSR.srgb.reserved) {
ospf_zebra_release_label_range(
- OspfSR.srgb.lower_bound,
- OspfSR.srgb.lower_bound + OspfSR.srgb.range_size - 1);
- OspfSR.srgb_reserved = false;
+ OspfSR.srgb.start,
+ OspfSR.srgb.start + OspfSR.srgb.size - 1);
+ OspfSR.srgb.reserved = false;
}
/* Set new SRGB values */
- OspfSR.srgb.range_size = size;
- OspfSR.srgb.lower_bound = lower;
+ OspfSR.srgb.size = size;
+ OspfSR.srgb.start = lower;
if (OspfSR.self != NULL) {
OspfSR.self->srgb.range_size = size;
OspfSR.self->srgb.lower_bound = lower;
@@ -1818,15 +2027,19 @@ static int update_srgb(uint32_t lower, uint32_t size)
* Try to reserve the new block from the Label Manger. If the allocation
* fails, disable SR until a new SRGB is successfully allocated.
*/
- if (ospf_zebra_request_label_range(OspfSR.srgb.lower_bound,
- OspfSR.srgb.range_size) < 0) {
- OspfSR.srgb_reserved = false;
+ if (ospf_zebra_request_label_range(OspfSR.srgb.start,
+ OspfSR.srgb.size) < 0) {
+ OspfSR.srgb.reserved = false;
ospf_sr_stop();
return -1;
- }
+ } else
+ OspfSR.srgb.reserved = true;
+
+ osr_debug("SR(%s): Got new SRGB [%u/%u]", __func__, OspfSR.srgb.start,
+ OspfSR.srgb.start + OspfSR.srgb.size - 1);
/* SRGB is reserved, set Router Information parameters */
- ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
+ ospf_router_info_update_sr(true, OspfSR.self);
/* and update NHLFE entries */
hash_iterate(OspfSR.neighbors,
@@ -1836,8 +2049,8 @@ static int update_srgb(uint32_t lower, uint32_t size)
return 0;
}
-DEFUN (sr_sid_label_range,
- sr_sid_label_range_cmd,
+DEFUN (sr_global_label_range,
+ sr_global_label_range_cmd,
"segment-routing global-block (16-1048575) (16-1048575)",
SR_STR
"Segment Routing Global Block label range\n"
@@ -1858,32 +2071,158 @@ DEFUN (sr_sid_label_range,
upper = strtoul(argv[idx_up]->arg, NULL, 10);
size = upper - lower + 1;
+ /* Validate SRGB against SRLB */
+ if (!((upper < OspfSR.srlb.start) || (lower > OspfSR.srlb.end))) {
+ vty_out(vty,
+ "New SR Global Block (%u/%u) conflict with Local Block (%u/%u)\n",
+ lower, upper, OspfSR.srlb.end, OspfSR.srlb.start);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (update_srgb(lower, size) < 0)
return CMD_WARNING_CONFIG_FAILED;
else
return CMD_SUCCESS;
}
-DEFUN (no_sr_sid_label_range,
- no_sr_sid_label_range_cmd,
- "no segment-routing global-block [(0-1048575) (0-1048575)]",
+DEFUN (no_sr_global_label_range,
+ no_sr_global_label_range_cmd,
+ "no segment-routing global-block [(16-1048575) (16-1048575)]",
NO_STR
SR_STR
"Segment Routing Global Block label range\n"
- "Lower-bound range in decimal (0-1048575)\n"
- "Upper-bound range in decimal (0-1048575)\n")
+ "Lower-bound range in decimal (16-1048575)\n"
+ "Upper-bound range in decimal (16-1048575)\n")
{
if (!ospf_sr_enabled(vty))
return CMD_WARNING_CONFIG_FAILED;
- if (update_srgb(MPLS_DEFAULT_MIN_SRGB_SIZE,
- MPLS_DEFAULT_MIN_SRGB_LABEL) < 0)
+ /* Validate SRGB against SRLB */
+ uint32_t upper = DEFAULT_SRGB_LABEL + DEFAULT_SRGB_SIZE - 1;
+ if (!((upper < OspfSR.srlb.start)
+ || (DEFAULT_SRGB_LABEL > OspfSR.srlb.end))) {
+ vty_out(vty,
+ "New SR Global Block (%u/%u) conflict with Local Block (%u/%u)\n",
+ DEFAULT_SRGB_LABEL, upper, OspfSR.srlb.end,
+ OspfSR.srlb.start);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (update_srgb(DEFAULT_SRGB_LABEL, DEFAULT_SRGB_SIZE) < 0)
return CMD_WARNING_CONFIG_FAILED;
else
return CMD_SUCCESS;
}
+DEFUN (sr_local_label_range,
+ sr_local_label_range_cmd,
+ "segment-routing local-block (16-1048575) (16-1048575)",
+ SR_STR
+ "Segment Routing Local Block label range\n"
+ "Lower-bound range in decimal (16-1048575)\n"
+ "Upper-bound range in decimal (16-1048575)\n")
+{
+ uint32_t upper;
+ uint32_t lower;
+ uint32_t srgb_upper;
+ int idx_low = 2;
+ int idx_up = 3;
+
+ if (!ospf_sr_enabled(vty))
+ return CMD_WARNING_CONFIG_FAILED;
+
+ /* Get lower and upper bound */
+ lower = strtoul(argv[idx_low]->arg, NULL, 10);
+ upper = strtoul(argv[idx_up]->arg, NULL, 10);
+
+ /* Check if values have changed */
+ if ((OspfSR.srlb.start == lower)
+ && (OspfSR.srlb.end == upper))
+ return CMD_SUCCESS;
+
+ /* Validate SRLB against SRGB */
+ srgb_upper = OspfSR.srgb.start + OspfSR.srgb.size - 1;
+ if (!((upper < OspfSR.srgb.start) || (lower > srgb_upper))) {
+ vty_out(vty,
+ "New SR Local Block (%u/%u) conflict with Global Block (%u/%u)\n",
+ lower, upper, OspfSR.srgb.start, srgb_upper);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Remove old SRLB */
+ sr_local_block_delete();
+
+ /* Try to reserve the new block from the Label Manger. If the allocation
+ * fails, disable SR until a new SRLB is successfully allocated.
+ */
+ if (sr_local_block_init(lower, upper) != 0) {
+ ospf_sr_stop();
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* SRLB is reserved, Update Self SR-Node and Router Information LSA */
+ OspfSR.self->srlb.lower_bound = lower;
+ OspfSR.self->srlb.range_size = upper - lower + 1;
+ ospf_router_info_update_sr(true, OspfSR.self);
+
+ /* and update (LAN)-Adjacency SID */
+ ospf_ext_link_srlb_update();
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_sr_local_label_range,
+ no_sr_local_label_range_cmd,
+ "no segment-routing local-block [(16-1048575) (16-1048575)]",
+ NO_STR
+ SR_STR
+ "Segment Routing Local Block label range\n"
+ "Lower-bound range in decimal (16-1048575)\n"
+ "Upper-bound range in decimal (16-1048575)\n")
+{
+
+ uint32_t upper;
+ uint32_t srgb_end;
+
+ if (!ospf_sr_enabled(vty))
+ return CMD_WARNING_CONFIG_FAILED;
+
+ /* First, remove old SRLB */
+ sr_local_block_delete();
+
+ /* Validate SRLB against SRGB */
+ srgb_end = OspfSR.srgb.start + OspfSR.srgb.size - 1;
+ upper = DEFAULT_SRLB_LABEL + DEFAULT_SRLB_SIZE - 1;
+ if (!((upper < OspfSR.srgb.start) || (DEFAULT_SRLB_LABEL > srgb_end))) {
+ vty_out(vty,
+ "New SR Local Block (%u/%u) conflict with Global Block (%u/%u)\n",
+ DEFAULT_SRLB_LABEL, upper, OspfSR.srgb.start, srgb_end);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Then, initialize SRLB with default value and try to reserve the new
+ * block from the Label Manger. If the allocation fails, disable SR
+ * until a new SRLB is successfully allocated.
+ */
+ if (sr_local_block_init(DEFAULT_SRLB_LABEL, upper) != 0) {
+ ospf_sr_stop();
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* SRLB is reserved, Update Self SR-Node and Router Information LSA */
+ if (OspfSR.self != NULL) {
+ OspfSR.self->srlb.lower_bound = DEFAULT_SRLB_LABEL;
+ OspfSR.self->srlb.range_size = DEFAULT_SRLB_SIZE;
+ }
+ ospf_router_info_update_sr(true, OspfSR.self);
+
+ /* and update (LAN)-Adjacency SID */
+ ospf_ext_link_srlb_update();
+
+ return CMD_SUCCESS;
+}
+
DEFUN (sr_node_msd,
sr_node_msd_cmd,
"segment-routing node-msd (1-16)",
@@ -1917,7 +2256,7 @@ DEFUN (sr_node_msd,
/* Set Router Information parameters if SR is UP */
if (OspfSR.status == SR_UP)
- ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
+ ospf_router_info_update_sr(true, OspfSR.self);
return CMD_SUCCESS;
}
@@ -1941,7 +2280,7 @@ DEFUN (no_sr_node_msd,
/* Set Router Information parameters if SR is UP */
if (OspfSR.status == SR_UP)
- ospf_router_info_update_sr(true, OspfSR.srgb, 0);
+ ospf_router_info_update_sr(true, OspfSR.self);
return CMD_SUCCESS;
}
@@ -1976,9 +2315,9 @@ DEFUN (sr_prefix_sid,
/* Get & verify index value */
argv_find(argv, argc, "(0-65535)", &idx);
index = strtoul(argv[idx]->arg, NULL, 10);
- if (index > OspfSR.srgb.range_size - 1) {
+ if (index > OspfSR.srgb.size - 1) {
vty_out(vty, "Index %u must be lower than range size %u\n",
- index, OspfSR.srgb.range_size);
+ index, OspfSR.srgb.size);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -2263,6 +2602,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
char pref[19];
char sid[22];
char op[32];
+ uint32_t upper;
json_object *json_node = NULL, *json_algo, *json_obj;
json_object *json_prefix = NULL, *json_link = NULL;
@@ -2280,6 +2620,10 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
srn->srgb.range_size);
json_object_int_add(json_node, "srgbLabel",
srn->srgb.lower_bound);
+ json_object_int_add(json_node, "srlbSize",
+ srn->srlb.range_size);
+ json_object_int_add(json_node, "srlbLabel",
+ srn->srlb.lower_bound);
json_algo = json_object_new_array();
json_object_object_add(json_node, "algorithms", json_algo);
for (int i = 0; i < ALGORITHM_COUNT; i++) {
@@ -2299,9 +2643,13 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
json_object_int_add(json_node, "nodeMsd", srn->msd);
} else {
sbuf_push(&sbuf, 0, "SR-Node: %s", inet_ntoa(srn->adv_router));
- sbuf_push(&sbuf, 0, "\tSRGB (Size/Label): %u/%u",
- srn->srgb.range_size, srn->srgb.lower_bound);
- sbuf_push(&sbuf, 0, "\tAlgorithm(s): %s",
+ upper = srn->srgb.lower_bound + srn->srgb.range_size - 1;
+ sbuf_push(&sbuf, 0, "\tSRGB: [%u/%u]",
+ srn->srgb.lower_bound, upper);
+ upper = srn->srlb.lower_bound + srn->srlb.range_size - 1;
+ sbuf_push(&sbuf, 0, "\tSRLB: [%u/%u]",
+ srn->srlb.lower_bound, upper);
+ sbuf_push(&sbuf, 0, "\tAlgo.(s): %s",
srn->algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF");
for (int i = 1; i < ALGORITHM_COUNT; i++) {
if (srn->algo[i] == SR_ALGORITHM_UNSET)
@@ -2505,8 +2853,10 @@ void ospf_sr_register_vty(void)
install_element(OSPF_NODE, &ospf_sr_enable_cmd);
install_element(OSPF_NODE, &no_ospf_sr_enable_cmd);
- install_element(OSPF_NODE, &sr_sid_label_range_cmd);
- install_element(OSPF_NODE, &no_sr_sid_label_range_cmd);
+ install_element(OSPF_NODE, &sr_global_label_range_cmd);
+ install_element(OSPF_NODE, &no_sr_global_label_range_cmd);
+ install_element(OSPF_NODE, &sr_local_label_range_cmd);
+ install_element(OSPF_NODE, &no_sr_local_label_range_cmd);
install_element(OSPF_NODE, &sr_node_msd_cmd);
install_element(OSPF_NODE, &no_sr_node_msd_cmd);
install_element(OSPF_NODE, &sr_prefix_sid_cmd);
diff --git a/ospfd/ospf_sr.h b/ospfd/ospf_sr.h
index f30d7da395..c54d2dcc3c 100644
--- a/ospfd/ospf_sr.h
+++ b/ospfd/ospf_sr.h
@@ -1,13 +1,14 @@
/*
* This is an implementation of Segment Routing
- * as per draft draft-ietf-ospf-segment-routing-extensions-24
+ * as per RFC 8665 - OSPF Extensions for Segment Routing
+ * and RFC 8476 - Signaling Maximum SID Depth (MSD) Using OSPF
*
* Module name: Segment Routing header definitions
*
* Author: Olivier Dugeon <olivier.dugeon@orange.com>
* Author: Anselme Sawadogo <anselmesawadogo@gmail.com>
*
- * Copyright (C) 2016 - 2018 Orange Labs http://www.orange.com
+ * Copyright (C) 2016 - 2020 Orange Labs http://www.orange.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -37,13 +38,9 @@
#define SET_LABEL(label) ((label << 8) & SET_LABEL_MASK)
#define GET_LABEL(label) ((label >> 8) & GET_LABEL_MASK)
-/* Label range for Adj-SID attribution purpose. Start just right after SRGB */
-#define ADJ_SID_MIN MPLS_DEFAULT_MAX_SRGB_LABEL
-#define ADJ_SID_MAX (MPLS_DEFAULT_MAX_SRGB_LABEL + 1000)
-
#define OSPF_SR_DEFAULT_METRIC 1
-/* Segment Routing TLVs as per draft-ietf-ospf-segment-routing-extensions-19 */
+/* Segment Routing TLVs as per RFC 8665 */
/* Segment ID could be a Label (3 bytes) or an Index (4 bytes) */
#define SID_LABEL 3
@@ -88,8 +85,9 @@ struct ri_sr_tlv_sr_algorithm {
uint8_t value[ALGORITHM_COUNT];
};
-/* RI SID/Label Range TLV - section 3.2 */
-#define RI_SR_TLV_SID_LABEL_RANGE 9
+/* RI SID/Label Range TLV used for SRGB & SRLB - section 3.2 & 3.3 */
+#define RI_SR_TLV_SRGB_LABEL_RANGE 9
+#define RI_SR_TLV_SRLB_LABEL_RANGE 14
struct ri_sr_tlv_sid_label_range {
struct tlv_header header;
/* Only 24 upper most bits are significant */
@@ -99,7 +97,7 @@ struct ri_sr_tlv_sid_label_range {
struct subtlv_sid_label lower;
};
-/* RI Node/MSD TLV as per draft-ietf-ospf-segment-routing-msd-05 */
+/* RI Node/MSD TLV as per RFC 8476 */
#define RI_SR_TLV_NODE_MSD 12
struct ri_sr_tlv_node_msd {
struct tlv_header header;
@@ -183,13 +181,38 @@ struct ext_subtlv_lan_adj_sid {
* Following section define structure used to manage Segment Routing
* information and TLVs / SubTLVs
*/
+/* Default min and size of SR Global Block label range */
+#define DEFAULT_SRGB_LABEL 16000
+#define DEFAULT_SRGB_SIZE 8000
+
+/* Default min and size of SR Local Block label range */
+#define DEFAULT_SRLB_LABEL 15000
+#define DEFAULT_SRLB_SIZE 1000
-/* Structure aggregating SRGB info retrieved from an lsa */
-struct sr_srgb {
+/* Structure aggregating SR Range Block info retrieved from an lsa */
+struct sr_block {
uint32_t range_size;
uint32_t lower_bound;
};
+/* Segment Routing Global Block allocation */
+struct sr_global_block {
+ bool reserved;
+ uint32_t start;
+ uint32_t size;
+};
+
+/* Segment Routing Local Block allocation */
+struct sr_local_block {
+ bool reserved;
+ uint32_t start;
+ uint32_t end;
+ uint32_t current;
+ uint32_t max_block;
+ uint64_t *used_mark;
+};
+#define SRLB_BLOCK_SIZE 64
+
/* SID type to make difference between loopback interfaces and others */
enum sid_type { PREF_SID, LOCAL_SID, ADJ_SID, LAN_ADJ_SID };
@@ -221,16 +244,16 @@ struct ospf_sr_db {
* Segment Routing Global Block i.e. label range
* Only one range supported in this code
*/
- struct sr_srgb srgb;
+ struct sr_global_block srgb;
- /* Thread timer to start Label Manager */
- struct thread *t_start_lm;
-
- /* Status of SRGB: reserved within Label Manager or not */
- bool srgb_reserved;
+ /* Segment Routing Local Block */
+ struct sr_local_block srlb;
/* Maximum SID Depth supported by the node */
uint8_t msd;
+
+ /* Thread timer to start Label Manager */
+ struct thread *t_start_lm;
};
/* Structure aggregating all received SR info from LSAs by node */
@@ -240,9 +263,9 @@ struct sr_node {
uint32_t instance;
uint8_t algo[ALGORITHM_COUNT]; /* Algorithms supported by the node */
- /* Segment Routing Global Block i.e. label range */
- struct sr_srgb srgb;
- uint8_t msd; /* Maximum SID Depth */
+ struct sr_block srgb; /* Segment Routing Global Block */
+ struct sr_block srlb; /* Segment Routing Local Block */
+ uint8_t msd; /* Maximum SID Depth */
/* List of Prefix & Link advertise by this node */
struct list *ext_prefix; /* For Node SID */
@@ -252,7 +275,6 @@ struct sr_node {
struct sr_node *neighbor;
};
-
/* Segment Routing - NHLFE info: support IPv4 Only */
struct sr_nhlfe {
struct in_addr nexthop;
@@ -319,6 +341,9 @@ struct sr_prefix {
extern int ospf_sr_init(void);
extern void ospf_sr_term(void);
extern void ospf_sr_finish(void);
+/* Segment Routing label allocation functions */
+extern mpls_label_t ospf_sr_local_block_request_label(void);
+extern int ospf_sr_local_block_release_label(mpls_label_t label);
/* 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);
@@ -331,7 +356,6 @@ struct ext_itf;
extern void ospf_sr_ext_itf_add(struct ext_itf *exti);
extern void ospf_sr_ext_itf_delete(struct ext_itf *exti);
/* Segment Routing configuration functions */
-extern uint32_t get_ext_link_label_value(void);
extern void ospf_sr_config_write_router(struct vty *vty);
extern void ospf_sr_update_local_prefix(struct interface *ifp,
struct prefix *p);
diff --git a/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json
index 0416bd6ce2..57bcbaeffc 100644
--- a/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json
@@ -3,8 +3,10 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -34,6 +36,8 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -47,12 +51,12 @@
"inputLabel":20400,
"prefixRoute":[
{
- "outputLabel":8400,
+ "outputLabel":16400,
"interface":"r1-eth0",
"nexthop":"10.0.0.2"
},
{
- "outputLabel":8400,
+ "outputLabel":16400,
"interface":"r1-eth1",
"nexthop":"10.0.1.2"
}
@@ -64,8 +68,14 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":8,
"extendedPrefix":[
{
"prefix":"10.0.255.3\/32",
@@ -73,12 +83,12 @@
"inputLabel":20300,
"prefixRoute":[
{
- "outputLabel":8300,
+ "outputLabel":16300,
"interface":"r1-eth0",
"nexthop":"10.0.0.2"
},
{
- "outputLabel":8300,
+ "outputLabel":16300,
"interface":"r1-eth1",
"nexthop":"10.0.1.2"
}
@@ -90,6 +100,8 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
diff --git a/tests/topotests/ospf-sr-topo1/r1/ospfd.conf b/tests/topotests/ospf-sr-topo1/r1/ospfd.conf
index 292d4e6367..f8fac2428c 100644
--- a/tests/topotests/ospf-sr-topo1/r1/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r1/ospfd.conf
@@ -1,3 +1,4 @@
+debug ospf sr
!
interface lo
ip ospf area 0.0.0.0
diff --git a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
index dd42e326ce..fdf0886bcd 100644
--- a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
@@ -53,7 +53,7 @@
},
{
"type":"SR (OSPF)",
- "outLabel":8300,
+ "outLabel":16300,
"distance":150,
"installed":true,
"nexthop":"10.0.0.2"
@@ -76,7 +76,7 @@
},
{
"type":"SR (OSPF)",
- "outLabel":8400,
+ "outLabel":16400,
"distance":150,
"installed":true,
"nexthop":"10.0.0.2"
diff --git a/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json
index eb202b82cd..6ea0f0a0cf 100644
--- a/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json
@@ -3,8 +3,10 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -95,13 +97,19 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":12,
"extendedPrefix":[
{
"prefix":"10.0.255.4\/32",
"sid":400,
- "inputLabel":8400,
+ "inputLabel":16400,
"prefixRoute":[
{
"outputLabel":10400,
@@ -116,13 +124,19 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":8,
"extendedPrefix":[
{
"prefix":"10.0.255.3\/32",
"sid":300,
- "inputLabel":8300,
+ "inputLabel":16300,
"prefixRoute":[
{
"outputLabel":3,
@@ -137,13 +151,19 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":16,
"extendedPrefix":[
{
"prefix":"10.0.255.1\/32",
"sid":100,
- "inputLabel":8100,
+ "inputLabel":16100,
"prefixRoute":[
{
"outputLabel":20100,
diff --git a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
index f3462e239e..d343315f07 100644
--- a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
@@ -1,6 +1,6 @@
[
{
- "inLabel":8100,
+ "inLabel":16100,
"installed":true,
"nexthops":[
{
@@ -23,7 +23,7 @@
]
},
{
- "inLabel":8300,
+ "inLabel":16300,
"installed":true,
"nexthops":[
{
@@ -39,7 +39,7 @@
]
},
{
- "inLabel":8400,
+ "inLabel":16400,
"installed":true,
"nexthops":[
{
diff --git a/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json
index b36fe674ad..e7371ff593 100644
--- a/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json
@@ -3,8 +3,10 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -29,6 +31,8 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -42,7 +46,7 @@
"inputLabel":10400,
"prefixRoute":[
{
- "outputLabel":8400,
+ "outputLabel":16400,
"interface":"r3-eth0",
"nexthop":"10.0.3.2"
}
@@ -54,6 +58,8 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -97,6 +103,8 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -110,7 +118,7 @@
"inputLabel":10100,
"prefixRoute":[
{
- "outputLabel":8100,
+ "outputLabel":16100,
"interface":"r3-eth0",
"nexthop":"10.0.3.2"
}
diff --git a/tests/topotests/ospf-sr-topo1/r3/ospfd.conf b/tests/topotests/ospf-sr-topo1/r3/ospfd.conf
index cf274bed2e..38d525f34f 100644
--- a/tests/topotests/ospf-sr-topo1/r3/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r3/ospfd.conf
@@ -11,6 +11,7 @@ router ospf
capability opaque
router-info area 0.0.0.0
segment-routing on
+ segment-routing local-block 5000 5999
segment-routing global-block 10000 19999
segment-routing node-msd 8
segment-routing prefix 10.0.255.3/32 index 300
diff --git a/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json
index d92ec91c72..a241b32607 100644
--- a/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json
@@ -3,9 +3,14 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
"extendedPrefix":[
{
@@ -26,6 +31,8 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -69,8 +76,14 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":8,
"extendedPrefix":[
{
"prefix":"10.0.255.3\/32",
@@ -78,7 +91,7 @@
"inputLabel":10300,
"prefixRoute":[
{
- "outputLabel":8300,
+ "outputLabel":16300,
"interface":"r4-eth0",
"nexthop":"10.0.4.2"
}
@@ -90,8 +103,14 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":16,
"extendedPrefix":[
{
"prefix":"10.0.255.1\/32",
@@ -99,7 +118,7 @@
"inputLabel":10100,
"prefixRoute":[
{
- "outputLabel":8100,
+ "outputLabel":16100,
"interface":"r4-eth0",
"nexthop":"10.0.4.2"
}
diff --git a/tests/topotests/ospf-sr-topo1/r4/ospfd.conf b/tests/topotests/ospf-sr-topo1/r4/ospfd.conf
index 65fdce69f7..9d0d148812 100644
--- a/tests/topotests/ospf-sr-topo1/r4/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r4/ospfd.conf
@@ -12,6 +12,7 @@ router ospf
capability opaque
router-info area 0.0.0.0
segment-routing on
+ segment-routing local-block 5000 5999
segment-routing global-block 10000 19999
segment-routing node-msd 12
segment-routing prefix 10.0.255.4/32 index 400 no-php-flag