summaryrefslogtreecommitdiff
path: root/ospfd/ospf_sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_sr.c')
-rw-r--r--ospfd/ospf_sr.c1093
1 files changed, 592 insertions, 501 deletions
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index 2a35bd2ef9..1a65bfa411 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <zebra.h>
+#include "printfrr.h"
#include "command.h"
#include "hash.h"
#include "if.h"
@@ -51,6 +52,7 @@
#include "thread.h"
#include "vty.h"
#include "zclient.h"
+#include "sbuf.h"
#include <lib/json.h>
#include "ospf_errors.h"
@@ -79,7 +81,7 @@
*/
static struct ospf_sr_db OspfSR;
static void ospf_sr_register_vty(void);
-static inline void del_sid_nhlfe(struct sr_nhlfe nhlfe);
+static inline void del_adj_sid(struct sr_nhlfe nhlfe);
/*
* Segment Routing Data Base functions
@@ -107,8 +109,8 @@ 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]);
+ del_adj_sid(srl->nhlfe[0]);
+ del_adj_sid(srl->nhlfe[1]);
XFREE(MTYPE_OSPF_SR_PARAMS, val);
}
@@ -117,7 +119,7 @@ static void del_sr_pref(void *val)
{
struct sr_prefix *srp = (struct sr_prefix *)val;
- del_sid_nhlfe(srp->nhlfe);
+ ospf_zebra_delete_prefix_sid(srp);
XFREE(MTYPE_OSPF_SR_PARAMS, val);
}
@@ -151,9 +153,7 @@ static struct sr_node *sr_node_new(struct in_addr *rid)
new->neighbor = NULL;
new->instance = 0;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Created new SR node for %s",
- inet_ntoa(new->adv_router));
+ osr_debug(" |- Created new SR node for %pI4", &new->adv_router);
return new;
}
@@ -164,6 +164,8 @@ static void sr_node_del(struct sr_node *srn)
if (srn == NULL)
return;
+ osr_debug(" |- Delete SR node for %pI4", &srn->adv_router);
+
/* Clean Extended Link */
list_delete(&srn->ext_link);
@@ -188,9 +190,7 @@ static struct sr_node *get_sr_node_by_nexthop(struct ospf *ospf,
if (OspfSR.neighbors == NULL)
return NULL;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Search SR-Node for nexthop %s",
- inet_ntoa(nexthop));
+ osr_debug(" |- Search SR-Node for nexthop %pI4", &nexthop);
/* First, search neighbor Router ID for this nexthop */
found = false;
@@ -209,9 +209,8 @@ static struct sr_node *get_sr_node_by_nexthop(struct ospf *ospf,
if (!found)
return NULL;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Found nexthop Router ID %s",
- inet_ntoa(nbr->router_id));
+ osr_debug(" |- Found nexthop Router ID %pI4", &nbr->router_id);
+
/* Then, search SR Node */
srn = (struct sr_node *)hash_lookup(OspfSR.neighbors, &nbr->router_id);
@@ -230,8 +229,7 @@ static int ospf_sr_start(struct ospf *ospf)
struct sr_node *srn;
int rc = 0;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Start Segment Routing", __func__);
+ osr_debug("SR (%s): Start Segment Routing", __func__);
/* Initialize self SR Node */
srn = hash_get(OspfSR.neighbors, (void *)&(ospf->router_id),
@@ -244,8 +242,7 @@ static int ospf_sr_start(struct ospf *ospf)
srn->msd = OspfSR.msd;
OspfSR.self = srn;
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("SR (%s): Update SR-DB from LSDB", __func__);
+ osr_debug("SR (%s): Update SR-DB from LSDB", __func__);
/* Start by looking to Router Info & Extended LSA in lsdb */
if ((ospf != NULL) && (ospf->backbone != NULL)) {
@@ -278,14 +275,15 @@ static int ospf_sr_start(struct ospf *ospf)
static void ospf_sr_stop(void)
{
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Stop Segment Routing", __func__);
+ osr_debug("SR (%s): Stop Segment Routing", __func__);
/*
* Remove all SR Nodes from the Hash table. Prefix and Link SID will
* be remove though list_delete() call. See sr_node_del()
*/
hash_clean(OspfSR.neighbors, (void *)sr_node_del);
+ OspfSR.self = NULL;
+ OspfSR.enabled = false;
}
/*
@@ -299,8 +297,7 @@ int ospf_sr_init(void)
{
int rc = -1;
- if (IS_DEBUG_OSPF_SR)
- zlog_info("SR (%s): Initialize SR Data Base", __func__);
+ osr_debug("SR (%s): Initialize SR Data Base", __func__);
memset(&OspfSR, 0, sizeof(struct ospf_sr_db));
OspfSR.enabled = false;
@@ -353,9 +350,6 @@ void ospf_sr_term(void)
/* Clear Prefix Table */
if (OspfSR.prefix)
route_table_finish(OspfSR.prefix);
-
- OspfSR.enabled = false;
- OspfSR.self = NULL;
}
/*
@@ -368,8 +362,6 @@ void ospf_sr_finish(void)
{
/* Stop Segment Routing */
ospf_sr_stop();
-
- OspfSR.enabled = false;
}
/*
@@ -417,21 +409,17 @@ static struct ospf_neighbor *get_neighbor_by_addr(struct ospf *top,
}
/* Get OSPF Path from address */
-static struct ospf_path *get_nexthop_by_addr(struct ospf *top,
- struct prefix_ipv4 p)
+static struct ospf_route *get_nexthop_by_addr(struct ospf *top,
+ struct prefix_ipv4 p)
{
- struct ospf_route * or ;
- struct ospf_path *path;
- struct listnode *node;
struct route_node *rn;
/* Sanity Check */
if (top == NULL)
return NULL;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Search Nexthop for prefix %s/%u",
- inet_ntoa(p.prefix), p.prefixlen);
+ osr_debug(" |- Search Nexthop for prefix %pFX",
+ (struct prefix *)&p);
rn = route_node_lookup(top->new_table, (struct prefix *)&p);
@@ -443,16 +431,7 @@ static struct ospf_path *get_nexthop_by_addr(struct ospf *top,
return NULL;
route_unlock_node(rn);
- or = rn->info;
- if (or == NULL)
- return NULL;
-
- /* Then search path from this route */
- for (ALL_LIST_ELEMENTS_RO(or->paths, node, path))
- if (path->nexthop.s_addr != INADDR_ANY || path->ifindex != 0)
- return path;
-
- return NULL;
+ return rn->info;
}
/* Compute NHLFE entry for Extended Link */
@@ -462,10 +441,7 @@ static int compute_link_nhlfe(struct sr_link *srl)
struct ospf_neighbor *nh;
int rc = 0;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Compute NHLFE for link %s/%u",
- inet_ntoa(srl->nhlfe[0].prefv4.prefix),
- srl->nhlfe[0].prefv4.prefixlen);
+ osr_debug(" |- Compute NHLFE for link %pI4", &srl->itf_addr);
/* First determine the OSPF Neighbor */
nh = get_neighbor_by_addr(top, srl->nhlfe[0].nexthop);
@@ -477,9 +453,7 @@ static int compute_link_nhlfe(struct sr_link *srl)
if (nh == NULL)
return rc;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Found nexthop NHLFE %s",
- inet_ntoa(nh->router_id));
+ osr_debug(" |- Found nexthop %pI4", &nh->router_id);
/* Set ifindex for this neighbor */
srl->nhlfe[0].ifindex = nh->oi->ifp->ifindex;
@@ -515,150 +489,108 @@ static int compute_link_nhlfe(struct sr_link *srl)
*
* @param srp - Segment Routing Prefix
*
- * @return -1 if next hop is not found, 0 if nexthop has not changed
- * and 1 if success
+ * @return -1 if no route is found, 0 if there is no SR route ready
+ * and 1 if success or update
*/
static int compute_prefix_nhlfe(struct sr_prefix *srp)
{
struct ospf *top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
- struct ospf_path *nh = NULL;
+ struct ospf_path *path;
+ struct listnode *node;
struct sr_node *srnext;
int rc = -1;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Compute NHLFE for prefix %s/%u",
- inet_ntoa(srp->nhlfe.prefv4.prefix),
- srp->nhlfe.prefv4.prefixlen);
+ osr_debug(" |- Compute NHLFE for prefix %pFX",
+ (struct prefix *)&srp->prefv4);
+
/* First determine the nexthop */
- nh = get_nexthop_by_addr(top, srp->nhlfe.prefv4);
+ srp->route = get_nexthop_by_addr(top, srp->prefv4);
/* Nexthop could be not found when OSPF Adjacency just fire up
* because SPF don't yet populate routing table. This NHLFE will
* be fixed later when SR SPF schedule will be called.
*/
- if (nh == NULL)
+ if (srp->route == NULL)
return rc;
- /* Check if NextHop has changed when call after running a new SPF */
- if (IPV4_ADDR_SAME(&nh->nexthop, &srp->nhlfe.nexthop)
- && (nh->ifindex == srp->nhlfe.ifindex))
- return 0;
-
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Found new next hop for this NHLFE: %s",
- inet_ntoa(nh->nexthop));
+ /* Compute Input Label with self SRGB */
+ srp->label_in = index2label(srp->sid, OspfSR.srgb);
- /*
- * Get SR-Node for this nexthop. Could be not yet available
- * as Extende Link / Prefix and Router Information are flooded
- * after LSA Type 1 & 2 which populate the OSPF Route Table
- */
- srnext = get_sr_node_by_nexthop(top, nh->nexthop);
- if (srnext == NULL)
- return rc;
+ rc = 0;
+ for (ALL_LIST_ELEMENTS_RO(srp->route->paths, node, path)) {
- /* And store this information for later update if SR Node is found */
- srnext->neighbor = OspfSR.self;
- if (IPV4_ADDR_SAME(&srnext->adv_router, &srp->adv_router))
- srp->nexthop = NULL;
- else
- srp->nexthop = srnext;
+ osr_debug(" |- Process new route via %pI4 for this prefix",
+ &path->nexthop);
- /*
- * SR Node could be known, but SRGB could be not initialize
- * This is due to the fact that Extended Link / Prefix could
- * be received before corresponding Router Information LSA
- */
- if ((srnext == NULL) || (srnext->srgb.lower_bound == 0)
- || (srnext->srgb.range_size == 0))
- return rc;
+ /*
+ * Get SR-Node for this nexthop. Could be not yet available
+ * as Extended Link / Prefix and Router Information are flooded
+ * after LSA Type 1 & 2 which populate the OSPF Route Table
+ */
+ srnext = get_sr_node_by_nexthop(top, path->nexthop);
+ if (srnext == NULL)
+ continue;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Found SRGB %u/%u for next hop SR-Node %s",
- srnext->srgb.range_size, srnext->srgb.lower_bound,
- inet_ntoa(srnext->adv_router));
+ /* And store this information for later update */
+ srnext->neighbor = OspfSR.self;
+ if (IPV4_ADDR_SAME(&srnext->adv_router, &srp->adv_router))
+ path->srni.nexthop = NULL;
+ else
+ path->srni.nexthop = srnext;
- /* Set ip addr & ifindex for this neighbor */
- IPV4_ADDR_COPY(&srp->nhlfe.nexthop, &nh->nexthop);
- srp->nhlfe.ifindex = nh->ifindex;
+ /*
+ * SR Node could be known, but SRGB could be not initialize
+ * This is due to the fact that Extended Link / Prefix could
+ * be received before corresponding Router Information LSA
+ */
+ if (srnext == NULL || srnext->srgb.lower_bound == 0
+ || srnext->srgb.range_size == 0)
+ continue;
- /* Compute Input Label with self SRGB */
- srp->nhlfe.label_in = index2label(srp->sid, OspfSR.srgb);
- /*
- * and Output Label with Next hop SR Node SRGB or Implicit Null label
- * if next hop is the destination and request PHP
- */
- if ((srp->nexthop == NULL)
- && (!CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG)))
- srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL;
- else if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_VFLG))
- srp->nhlfe.label_out = srp->sid;
- else
- srp->nhlfe.label_out = index2label(srp->sid, srnext->srgb);
+ osr_debug(" |- Found SRGB %u/%u for next hop SR-Node %pI4",
+ srnext->srgb.range_size, srnext->srgb.lower_bound,
+ &srnext->adv_router);
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Computed new labels in: %u out: %u",
- srp->nhlfe.label_in, srp->nhlfe.label_out);
+ /*
+ * Compute Output Label with Nexthop SR Node SRGB or Implicit
+ * Null label if next hop is the destination and request PHP
+ */
+ if ((path->srni.nexthop == NULL)
+ && (!CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG)))
+ path->srni.label_out = MPLS_LABEL_IMPLICIT_NULL;
+ else if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_VFLG))
+ path->srni.label_out = srp->sid;
+ else
+ path->srni.label_out =
+ index2label(srp->sid, srnext->srgb);
- rc = 1;
+ osr_debug(" |- Computed new labels in: %u out: %u",
+ srp->label_in, path->srni.label_out);
+ rc = 1;
+ }
return rc;
}
-/* Send MPLS Label entry to Zebra for installation or deletion */
-static int ospf_zebra_send_mpls_labels(int cmd, struct sr_nhlfe nhlfe)
-{
- struct zapi_labels zl = {};
- struct zapi_nexthop *znh;
-
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- %s LSP %u/%u for %s/%u via %u",
- cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete",
- nhlfe.label_in, nhlfe.label_out,
- inet_ntoa(nhlfe.prefv4.prefix),
- nhlfe.prefv4.prefixlen, nhlfe.ifindex);
-
- zl.type = ZEBRA_LSP_OSPF_SR;
- zl.local_label = nhlfe.label_in;
-
- SET_FLAG(zl.message, ZAPI_LABELS_FTN);
- zl.route.prefix.family = nhlfe.prefv4.family;
- zl.route.prefix.prefixlen = nhlfe.prefv4.prefixlen;
- zl.route.prefix.u.prefix4 = nhlfe.prefv4.prefix;
- zl.route.type = ZEBRA_ROUTE_OSPF;
- zl.route.instance = 0;
-
- zl.nexthop_num = 1;
- znh = &zl.nexthops[0];
- znh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
- znh->gate.ipv4 = nhlfe.nexthop;
- znh->ifindex = nhlfe.ifindex;
- znh->label_num = 1;
- znh->labels[0] = nhlfe.label_out;
-
- return zebra_send_mpls_labels(zclient, cmd, &zl);
-}
-
-/* Add new NHLFE entry for SID */
-static inline void add_sid_nhlfe(struct sr_nhlfe nhlfe)
+/* Add new NHLFE entry for Adjacency SID */
+static inline void add_adj_sid(struct sr_nhlfe nhlfe)
{
- if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0))
- ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, nhlfe);
+ if (nhlfe.label_in != 0)
+ ospf_zebra_send_adjacency_sid(ZEBRA_MPLS_LABELS_ADD, nhlfe);
}
-/* Remove NHLFE entry for SID */
-static inline void del_sid_nhlfe(struct sr_nhlfe nhlfe)
+/* Remove NHLFE entry for Adjacency SID */
+static inline void del_adj_sid(struct sr_nhlfe nhlfe)
{
- if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0))
- ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, nhlfe);
+ if (nhlfe.label_in != 0)
+ ospf_zebra_send_adjacency_sid(ZEBRA_MPLS_LABELS_DELETE, nhlfe);
}
-/* Update NHLFE entry for SID */
-static inline void update_sid_nhlfe(struct sr_nhlfe n1, struct sr_nhlfe n2)
+/* Update NHLFE entry for Adjacency SID */
+static inline void update_adj_sid(struct sr_nhlfe n1, struct sr_nhlfe n2)
{
-
- del_sid_nhlfe(n1);
- add_sid_nhlfe(n2);
+ del_adj_sid(n1);
+ add_adj_sid(n2);
}
/*
@@ -729,23 +661,10 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
sum += TLV_SIZE(sub_tlvh);
}
- IPV4_ADDR_COPY(&srl->nhlfe[0].prefv4.prefix, &link->link_data);
- srl->nhlfe[0].prefv4.prefixlen = IPV4_MAX_PREFIXLEN;
- srl->nhlfe[0].prefv4.family = AF_INET;
- apply_mask_ipv4(&srl->nhlfe[0].prefv4);
- IPV4_ADDR_COPY(&srl->nhlfe[1].prefv4.prefix, &link->link_data);
- srl->nhlfe[1].prefv4.prefixlen = IPV4_MAX_PREFIXLEN;
- srl->nhlfe[1].prefv4.family = AF_INET;
- apply_mask_ipv4(&srl->nhlfe[1].prefv4);
+ IPV4_ADDR_COPY(&srl->itf_addr, &link->link_data);
- if (IS_DEBUG_OSPF_SR) {
- zlog_debug(" |- Found primary Adj/Lan Sid %u for %s/%u",
- srl->sid[0], inet_ntoa(srl->nhlfe[0].prefv4.prefix),
- srl->nhlfe[0].prefv4.prefixlen);
- zlog_debug(" |- Found backup Adj/Lan Sid %u for %s/%u",
- srl->sid[1], inet_ntoa(srl->nhlfe[1].prefv4.prefix),
- srl->nhlfe[1].prefv4.prefixlen);
- }
+ osr_debug(" |- Found primary %u and backup %u Adj/Lan Sid for %pI4",
+ srl->sid[0], srl->sid[1], &srl->itf_addr);
return srl;
}
@@ -784,11 +703,10 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh)
srp->sid = GET_LABEL(ntohl(psid->value));
else
srp->sid = ntohl(psid->value);
- IPV4_ADDR_COPY(&srp->nhlfe.prefv4.prefix,
- &pref->address);
- srp->nhlfe.prefv4.prefixlen = pref->pref_length;
- srp->nhlfe.prefv4.family = AF_INET;
- apply_mask_ipv4(&srp->nhlfe.prefv4);
+ IPV4_ADDR_COPY(&srp->prefv4.prefix, &pref->address);
+ srp->prefv4.prefixlen = pref->pref_length;
+ srp->prefv4.family = AF_INET;
+ apply_mask_ipv4(&srp->prefv4);
break;
default:
break;
@@ -796,10 +714,9 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh)
sum += TLV_SIZE(sub_tlvh);
}
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Found SID %u for prefix %s/%u", srp->sid,
- inet_ntoa(srp->nhlfe.prefv4.prefix),
- srp->nhlfe.prefv4.prefixlen);
+ osr_debug(" |- Found SID %u for prefix %pFX", srp->sid,
+ (struct prefix *)&srp->prefv4);
+
return srp;
}
@@ -839,13 +756,12 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl,
if ((srn == NULL) || (srl == NULL))
return;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Process Extended Link Adj/Lan-SID");
+ osr_debug(" |- Process Extended Link Adj/Lan-SID");
- /* Process only Local Adj/Lan_Adj SID coming from LSA SELF */
- if (!CHECK_FLAG(srl->flags[0], EXT_SUBTLV_LINK_ADJ_SID_LFLG)
- || !CHECK_FLAG(srl->flags[1], EXT_SUBTLV_LINK_ADJ_SID_LFLG)
- || !CHECK_FLAG(lsa_flags, OSPF_LSA_SELF))
+ /* Skip Local Adj/Lan_Adj SID coming from neighbors */
+ if (!CHECK_FLAG(lsa_flags, OSPF_LSA_SELF)
+ && (CHECK_FLAG(srl->flags[0], EXT_SUBTLV_LINK_ADJ_SID_LFLG)
+ || CHECK_FLAG(srl->flags[1], EXT_SUBTLV_LINK_ADJ_SID_LFLG)))
return;
/* Search for existing Segment Link */
@@ -855,11 +771,9 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl,
break;
}
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- %s SR Link 8.0.0.%u for SR node %s",
- found ? "Update" : "Add",
- GET_OPAQUE_ID(srl->instance),
- inet_ntoa(srn->adv_router));
+ osr_debug(" |- %s SR Link 8.0.0.%u for SR node %pI4",
+ found ? "Update" : "Add", GET_OPAQUE_ID(srl->instance),
+ &srn->adv_router);
/* if not found, add new Segment Link and install NHLFE */
if (!found) {
@@ -869,14 +783,14 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl,
listnode_add(srn->ext_link, srl);
/* Try to set MPLS table */
if (compute_link_nhlfe(srl)) {
- add_sid_nhlfe(srl->nhlfe[0]);
- add_sid_nhlfe(srl->nhlfe[1]);
+ add_adj_sid(srl->nhlfe[0]);
+ add_adj_sid(srl->nhlfe[1]);
}
} else {
if (sr_link_cmp(lk, srl)) {
if (compute_link_nhlfe(srl)) {
- update_sid_nhlfe(lk->nhlfe[0], srl->nhlfe[0]);
- update_sid_nhlfe(lk->nhlfe[1], srl->nhlfe[1]);
+ update_adj_sid(lk->nhlfe[0], srl->nhlfe[0]);
+ update_adj_sid(lk->nhlfe[1], srl->nhlfe[1]);
/* Replace Segment List */
listnode_delete(srn->ext_link, lk);
XFREE(MTYPE_OSPF_SR_PARAMS, lk);
@@ -912,8 +826,7 @@ static void update_ext_prefix_sid(struct sr_node *srn, struct sr_prefix *srp)
if (srn == NULL || srp == NULL)
return;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Process Extended Prefix SID %u", srp->sid);
+ osr_debug(" |- Process Extended Prefix SID %u", srp->sid);
/* Process only Global Prefix SID */
if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_LFLG))
@@ -926,11 +839,9 @@ static void update_ext_prefix_sid(struct sr_node *srn, struct sr_prefix *srp)
break;
}
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- %s SR LSA ID 7.0.0.%u for SR node %s",
- found ? "Update" : "Add",
- GET_OPAQUE_ID(srp->instance),
- inet_ntoa(srn->adv_router));
+ osr_debug(" |- %s SR LSA ID 7.0.0.%u for SR node %pI4",
+ found ? "Update" : "Add", GET_OPAQUE_ID(srp->instance),
+ &srn->adv_router);
/* if not found, add new Segment Prefix and install NHLFE */
if (!found) {
@@ -940,11 +851,11 @@ static void update_ext_prefix_sid(struct sr_node *srn, struct sr_prefix *srp)
listnode_add(srn->ext_prefix, srp);
/* Try to set MPLS table */
if (compute_prefix_nhlfe(srp) == 1)
- add_sid_nhlfe(srp->nhlfe);
+ ospf_zebra_update_prefix_sid(srp);
} else {
if (sr_prefix_cmp(pref, srp)) {
if (compute_prefix_nhlfe(srp) == 1) {
- update_sid_nhlfe(pref->nhlfe, srp->nhlfe);
+ ospf_zebra_delete_prefix_sid(pref);
/* Replace Segment Prefix */
listnode_delete(srn->ext_prefix, pref);
XFREE(MTYPE_OSPF_SR_PARAMS, pref);
@@ -952,6 +863,7 @@ static void update_ext_prefix_sid(struct sr_node *srn, struct sr_prefix *srp)
IPV4_ADDR_COPY(&srp->adv_router,
&srn->adv_router);
listnode_add(srn->ext_prefix, srp);
+ ospf_zebra_update_prefix_sid(srp);
} else {
/* New NHLFE was not found.
* Just free the SR Prefix
@@ -976,7 +888,6 @@ static void update_in_nhlfe(struct hash_bucket *bucket, void *args)
struct listnode *node;
struct sr_node *srn = (struct sr_node *)bucket->data;
struct sr_prefix *srp;
- struct sr_nhlfe new;
/* Process Every Extended Prefix for this SR-Node */
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) {
@@ -989,13 +900,10 @@ 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 NHLFE */
- memcpy(&new, &srp->nhlfe, sizeof(struct sr_nhlfe));
- new.label_in = index2label(srp->sid, OspfSR.srgb);
- /* Update MPLS LFIB */
- update_sid_nhlfe(srp->nhlfe, new);
- /* Finally update Input Label */
- srp->nhlfe.label_in = new.label_in;
+ /* OK. Compute new input label ... */
+ srp->label_in = index2label(srp->sid, OspfSR.srgb);
+ /* ... and update MPLS LFIB */
+ ospf_zebra_update_prefix_sid(srp);
}
}
@@ -1005,21 +913,27 @@ static void update_in_nhlfe(struct hash_bucket *bucket, void *args)
*/
static void update_out_nhlfe(struct hash_bucket *bucket, void *args)
{
- struct listnode *node;
+ struct listnode *node, *pnode;
struct sr_node *srn = (struct sr_node *)bucket->data;
struct sr_node *srnext = (struct sr_node *)args;
struct sr_prefix *srp;
- struct sr_nhlfe new;
+ struct ospf_path *path;
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) {
- /* Process only SID Index for next hop without PHP */
- if ((srp->nexthop == NULL)
- && (!CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG)))
+ /* Process only SID Index with valid route */
+ if (srp->route == NULL)
continue;
- memcpy(&new, &srp->nhlfe, sizeof(struct sr_nhlfe));
- new.label_out = index2label(srp->sid, srnext->srgb);
- update_sid_nhlfe(srp->nhlfe, new);
- srp->nhlfe.label_out = new.label_out;
+
+ for (ALL_LIST_ELEMENTS_RO(srp->route->paths, pnode, path)) {
+ /* Process only SID Index for next hop without PHP */
+ if ((path->srni.nexthop == NULL)
+ && (!CHECK_FLAG(srp->flags,
+ EXT_SUBTLV_PREFIX_SID_NPFLG)))
+ continue;
+ path->srni.label_out =
+ index2label(srp->sid, srnext->srgb);
+ ospf_zebra_update_prefix_sid(srp);
+ }
}
}
@@ -1036,17 +950,15 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
struct sr_node *srn;
struct tlv_header *tlvh;
struct lsa_header *lsah = lsa->data;
- struct ri_sr_tlv_sid_label_range *ri_srgb;
- struct ri_sr_tlv_sr_algorithm *algo;
+ struct ri_sr_tlv_sid_label_range *ri_srgb = NULL;
+ struct ri_sr_tlv_sr_algorithm *algo = NULL;
struct sr_srgb srgb;
uint16_t length = 0, sum = 0;
+ uint8_t msd = 0;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(
- "SR (%s): Process Router "
- "Information LSA 4.0.0.%u from %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ osr_debug("SR (%s): Process Router Information LSA 4.0.0.%u from %pI4",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router);
/* Sanity check */
if (IS_LSA_SELF(lsa))
@@ -1058,26 +970,10 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
return;
}
- /* Get SR Node in hash table from Router ID */
- srn = hash_get(OspfSR.neighbors, (void *)&(lsah->adv_router),
- (void *)sr_node_new);
-
- /* Sanity check */
- if (srn == NULL) {
- flog_err(EC_OSPF_SR_NODE_CREATE,
- "SR (%s): Abort! can't create SR node in hash table",
- __func__);
- return;
- }
+ /* Search SR Node in hash table from Router ID */
+ srn = (struct sr_node *)hash_lookup(OspfSR.neighbors,
+ &lsah->adv_router);
- if ((srn->instance != 0) && (srn->instance != ntohl(lsah->id.s_addr))) {
- flog_err(EC_OSPF_SR_INVALID_LSA_ID,
- "SR (%s): Abort! Wrong "
- "LSA ID 4.0.0.%u for SR node %s/%u",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router), srn->instance);
- return;
- }
/* Collect Router Information Sub TLVs */
/* Initialize TLV browsing */
@@ -1090,23 +986,14 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
switch (ntohs(tlvh->type)) {
case RI_SR_TLV_SR_ALGORITHM:
algo = (struct ri_sr_tlv_sr_algorithm *)tlvh;
- int i;
-
- for (i = 0; i < ntohs(algo->header.length); i++)
- srn->algo[i] = algo->value[0];
- for (; i < ALGORITHM_COUNT; i++)
- srn->algo[i] = SR_ALGORITHM_UNSET;
sum += TLV_SIZE(tlvh);
break;
case RI_SR_TLV_SID_LABEL_RANGE:
ri_srgb = (struct ri_sr_tlv_sid_label_range *)tlvh;
- srgb.range_size = GET_RANGE_SIZE(ntohl(ri_srgb->size));
- srgb.lower_bound =
- GET_LABEL(ntohl(ri_srgb->lower.value));
sum += TLV_SIZE(tlvh);
break;
case RI_SR_TLV_NODE_MSD:
- srn->msd = ((struct ri_sr_tlv_node_msd *)(tlvh))->value;
+ msd = ((struct ri_sr_tlv_node_msd *)(tlvh))->value;
sum += TLV_SIZE(tlvh);
break;
default:
@@ -1115,38 +1002,82 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
}
}
- /* Check that we collect mandatory parameters */
- if (srn->algo[0] == SR_ALGORITHM_UNSET || srgb.range_size == 0
- || srgb.lower_bound == 0) {
- flog_err(EC_OSPF_SR_NODE_CREATE,
- "SR (%s): Missing mandatory parameters. Abort!",
- __func__);
- hash_release(OspfSR.neighbors, &(srn->adv_router));
- XFREE(MTYPE_OSPF_SR_PARAMS, srn);
+ /* Check if Segment Routing Capabilities has been found */
+ if (ri_srgb == NULL) {
+ /* Skip Router Information without SR capabilities
+ * advertise by a non SR Node */
+ if (srn == NULL) {
+ return;
+ } else {
+ /* Remove SR Node that advertise Router Information
+ * without SR capabilities. This could correspond to a
+ * Node stopping Segment Routing */
+ hash_release(OspfSR.neighbors, &(srn->adv_router));
+ sr_node_del(srn);
+ return;
+ }
+ }
+
+ /* Check that RI LSA belongs to the correct SR Node */
+ if ((srn != NULL) && (srn->instance != 0)
+ && (srn->instance != ntohl(lsah->id.s_addr))) {
+ flog_err(EC_OSPF_SR_INVALID_LSA_ID,
+ "SR (%s): Abort! Wrong "
+ "LSA ID 4.0.0.%u for SR node %pI4/%u",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router, srn->instance);
return;
}
+ /* OK. All things look good. Get SRGB */
+ srgb.range_size = GET_RANGE_SIZE(ntohl(ri_srgb->size));
+ srgb.lower_bound = GET_LABEL(ntohl(ri_srgb->lower.value));
+
/* Check if it is a new SR Node or not */
- if (srn->instance == 0) {
+ if (srn == NULL) {
+ /* Get a new SR Node in hash table from Router ID */
+ srn = (struct sr_node *)hash_get(OspfSR.neighbors,
+ &lsah->adv_router,
+ (void *)sr_node_new);
+ /* Sanity check */
+ if (srn == NULL) {
+ flog_err(
+ EC_OSPF_SR_NODE_CREATE,
+ "SR (%s): Abort! can't create SR node in hash table",
+ __func__);
+ return;
+ }
/* 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 */
+ if (algo != NULL) {
+ int i;
+ for (i = 0; i < ntohs(algo->header.length); i++)
+ srn->algo[i] = algo->value[0];
+ for (; i < ALGORITHM_COUNT; i++)
+ srn->algo[i] = SR_ALGORITHM_UNSET;
+ } else {
+ srn->algo[0] = SR_ALGORITHM_SPF;
+ }
+ /* set MSD */
+ srn->msd = msd;
+ return;
}
/* Check if SRGB has changed */
- if ((srn->srgb.range_size != srgb.range_size)
- || (srn->srgb.lower_bound != srgb.lower_bound)) {
- srn->srgb.range_size = srgb.range_size;
- srn->srgb.lower_bound = srgb.lower_bound;
- /* Update NHLFE if it is a neighbor SR node */
- if (srn->neighbor == OspfSR.self)
- hash_iterate(OspfSR.neighbors,
- (void (*)(struct hash_bucket *,
- void *))update_out_nhlfe,
- (void *)srn);
- }
+ if ((srn->srgb.range_size == srgb.range_size)
+ && (srn->srgb.lower_bound == srgb.lower_bound))
+ return;
+
+ /* Update SRGB ... */
+ srn->srgb.range_size = srgb.range_size;
+ srn->srgb.lower_bound = srgb.lower_bound;
+ /* ... and NHLFE if it is a neighbor SR node */
+ if (srn->neighbor == OspfSR.self)
+ hash_iterate(OspfSR.neighbors, update_out_nhlfe, srn);
}
/*
@@ -1158,10 +1089,8 @@ void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa)
struct sr_node *srn;
struct lsa_header *lsah = lsa->data;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Remove SR node %s from lsa_id 4.0.0.%u",
- __func__, inet_ntoa(lsah->adv_router),
- GET_OPAQUE_ID(ntohl(lsah->id.s_addr)));
+ osr_debug("SR (%s): Remove SR node %pI4 from lsa_id 4.0.0.%u", __func__,
+ &lsah->adv_router, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)));
/* Sanity check */
if (OspfSR.neighbors == NULL) {
@@ -1176,16 +1105,17 @@ void ospf_sr_ri_lsa_delete(struct ospf_lsa *lsa)
/* Sanity check */
if (srn == NULL) {
flog_err(EC_OSPF_SR_NODE_CREATE,
- "SR (%s): Abort! no entry in SRDB for SR Node %s",
- __func__, inet_ntoa(lsah->adv_router));
+ "SR (%s): Abort! no entry in SRDB for SR Node %pI4",
+ __func__, &lsah->adv_router);
return;
}
if ((srn->instance != 0) && (srn->instance != ntohl(lsah->id.s_addr))) {
- flog_err(EC_OSPF_SR_INVALID_LSA_ID,
- "SR (%s): Abort! Wrong LSA ID 4.0.0.%u for SR node %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ flog_err(
+ EC_OSPF_SR_INVALID_LSA_ID,
+ "SR (%s): Abort! Wrong LSA ID 4.0.0.%u for SR node %pI4",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router);
return;
}
@@ -1203,11 +1133,9 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa)
uint16_t length, sum;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(
- "SR (%s): Process Extended Link LSA 8.0.0.%u from %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ osr_debug("SR (%s): Process Extended Link LSA 8.0.0.%u from %pI4",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router);
/* Sanity check */
if (OspfSR.neighbors == NULL) {
@@ -1253,13 +1181,12 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa)
struct listnode *node;
struct sr_link *srl;
struct sr_node *srn;
- struct lsa_header *lsah = (struct lsa_header *)lsa->data;
+ struct lsa_header *lsah = lsa->data;
uint32_t instance = ntohl(lsah->id.s_addr);
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Remove Extended Link LSA 8.0.0.%u from %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ osr_debug("SR (%s): Remove Extended Link LSA 8.0.0.%u from %pI4",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router);
/* Sanity check */
if (OspfSR.neighbors == NULL) {
@@ -1278,8 +1205,8 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa)
*/
if (srn == NULL) {
flog_err(EC_OSPF_SR_INVALID_DB,
- "SR (%s): Stop! no entry in SRDB for SR Node %s",
- __func__, inet_ntoa(lsah->adv_router));
+ "SR (%s): Stop! no entry in SRDB for SR Node %pI4",
+ __func__, &lsah->adv_router);
return;
}
@@ -1288,18 +1215,143 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa)
if (srl->instance == instance)
break;
- /* Remove Segment Link if found */
+ /* Remove Segment Link if found. Note that for Neighbors, only Global
+ * Adj/Lan-Adj SID are stored in the SR-DB */
if ((srl != NULL) && (srl->instance == instance)) {
- del_sid_nhlfe(srl->nhlfe[0]);
- del_sid_nhlfe(srl->nhlfe[1]);
+ del_adj_sid(srl->nhlfe[0]);
+ del_adj_sid(srl->nhlfe[1]);
listnode_delete(srn->ext_link, srl);
XFREE(MTYPE_OSPF_SR_PARAMS, srl);
+ }
+}
+
+/* Add (LAN)Adjacency-SID from Extended Link Information */
+void ospf_sr_ext_itf_add(struct ext_itf *exti)
+{
+ struct sr_node *srn = OspfSR.self;
+ struct sr_link *srl;
+
+ osr_debug("SR (%s): Add Extended Link LSA 8.0.0.%u from self", __func__,
+ exti->instance);
+
+ /* Sanity check */
+ if (srn == NULL)
+ return;
+
+ /* Initialize new Segment Routing Link */
+ srl = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_link));
+ srl->srn = srn;
+ srl->adv_router = srn->adv_router;
+ srl->itf_addr = exti->link.link_data;
+ srl->instance =
+ SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_LINK_LSA, exti->instance);
+ switch (exti->stype) {
+ case ADJ_SID:
+ srl->type = ADJ_SID;
+ /* Primary information */
+ srl->flags[0] = exti->adj_sid[0].flags;
+ if (CHECK_FLAG(exti->adj_sid[0].flags,
+ EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ srl->sid[0] = GET_LABEL(ntohl(exti->adj_sid[0].value));
+ else
+ srl->sid[0] = ntohl(exti->adj_sid[0].value);
+ if (exti->rmt_itf_addr.header.type == 0)
+ srl->nhlfe[0].nexthop = exti->link.link_id;
+ else
+ srl->nhlfe[0].nexthop = exti->rmt_itf_addr.value;
+ /* Backup Information if set */
+ if (exti->adj_sid[1].header.type == 0)
+ break;
+ srl->flags[1] = exti->adj_sid[1].flags;
+ if (CHECK_FLAG(exti->adj_sid[1].flags,
+ EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ srl->sid[1] = GET_LABEL(ntohl(exti->adj_sid[1].value));
+ else
+ srl->sid[1] = ntohl(exti->adj_sid[1].value);
+ if (exti->rmt_itf_addr.header.type == 0)
+ srl->nhlfe[1].nexthop = exti->link.link_id;
+ else
+ srl->nhlfe[1].nexthop = exti->rmt_itf_addr.value;
+ break;
+ case LAN_ADJ_SID:
+ srl->type = LAN_ADJ_SID;
+ /* Primary information */
+ srl->flags[0] = exti->lan_sid[0].flags;
+ if (CHECK_FLAG(exti->lan_sid[0].flags,
+ EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ srl->sid[0] = GET_LABEL(ntohl(exti->lan_sid[0].value));
+ else
+ srl->sid[0] = ntohl(exti->lan_sid[0].value);
+ if (exti->rmt_itf_addr.header.type == 0)
+ srl->nhlfe[0].nexthop = exti->lan_sid[0].neighbor_id;
+ else
+ srl->nhlfe[0].nexthop = exti->rmt_itf_addr.value;
+ /* Backup Information if set */
+ if (exti->lan_sid[1].header.type == 0)
+ break;
+ srl->flags[1] = exti->lan_sid[1].flags;
+ if (CHECK_FLAG(exti->lan_sid[1].flags,
+ EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ srl->sid[1] = GET_LABEL(ntohl(exti->lan_sid[1].value));
+ else
+ srl->sid[1] = ntohl(exti->lan_sid[1].value);
+ if (exti->rmt_itf_addr.header.type == 0)
+ srl->nhlfe[1].nexthop = exti->lan_sid[1].neighbor_id;
+ else
+ srl->nhlfe[1].nexthop = exti->rmt_itf_addr.value;
+ break;
+ default:
+ /* Wrong SID Type. Abort! */
+ XFREE(MTYPE_OSPF_SR_PARAMS, srl);
+ return;
+ }
+
+ /* Segment Routing Link is ready, update it */
+ update_ext_link_sid(srn, srl, OSPF_LSA_SELF);
+}
+
+/* Delete Prefix or (LAN)Adjacency-SID from Extended Link Information */
+void ospf_sr_ext_itf_delete(struct ext_itf *exti)
+{
+ struct listnode *node;
+ struct sr_node *srn = OspfSR.self;
+ struct sr_prefix *srp = NULL;
+ struct sr_link *srl = NULL;
+ uint32_t instance;
+
+ osr_debug("SR (%s): Remove Extended LSA %u.0.0.%u from self",
+ __func__, exti->stype == PREF_SID ? 7 : 8, exti->instance);
+
+ /* Sanity check: SR-Node and Extended Prefix/Link list may have been
+ * removed earlier when stopping OSPF or OSPF-SR */
+ if (srn == NULL || srn->ext_prefix == NULL || srn->ext_link == NULL)
+ return;
+
+ if (exti->stype == PREF_SID) {
+ instance = SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_PREFIX_LSA,
+ exti->instance);
+ for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp))
+ if (srp->instance == instance)
+ break;
+
+ /* Uninstall Segment Prefix SID if found */
+ if ((srp != NULL) && (srp->instance == instance))
+ ospf_zebra_delete_prefix_sid(srp);
} else {
- flog_err(EC_OSPF_SR_INVALID_DB,
- "SR (%s): Didn't found corresponding SR Link 8.0.0.%u "
- "for SR Node %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ /* Search for corresponding Segment Link for self SR-Node */
+ instance = SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_LINK_LSA,
+ exti->instance);
+ for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl))
+ if (srl->instance == instance)
+ break;
+
+ /* Remove Segment Link if found */
+ if ((srl != NULL) && (srl->instance == instance)) {
+ del_adj_sid(srl->nhlfe[0]);
+ del_adj_sid(srl->nhlfe[1]);
+ listnode_delete(srn->ext_link, srl);
+ XFREE(MTYPE_OSPF_SR_PARAMS, srl);
+ }
}
}
@@ -1308,17 +1360,14 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa)
{
struct sr_node *srn;
struct tlv_header *tlvh;
- struct lsa_header *lsah = lsa->data;
+ struct lsa_header *lsah = (struct lsa_header *)lsa->data;
struct sr_prefix *srp;
uint16_t length, sum;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(
- "SR (%s): Process Extended Prefix LSA "
- "7.0.0.%u from %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ osr_debug("SR (%s): Process Extended Prefix LSA 7.0.0.%u from %pI4",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router);
/* Sanity check */
if (OspfSR.neighbors == NULL) {
@@ -1367,11 +1416,9 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa)
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
uint32_t instance = ntohl(lsah->id.s_addr);
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(
- "SR (%s): Remove Extended Prefix LSA 7.0.0.%u from %s",
- __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ osr_debug("SR (%s): Remove Extended Prefix LSA 7.0.0.%u from %pI4",
+ __func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
+ &lsah->adv_router);
/* Sanity check */
if (OspfSR.neighbors == NULL) {
@@ -1390,27 +1437,27 @@ void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa)
*/
if (srn == NULL) {
flog_err(EC_OSPF_SR_INVALID_DB,
- "SR (%s): Stop! no entry in SRDB for SR Node %s",
- __func__, inet_ntoa(lsah->adv_router));
+ "SR (%s): Stop! no entry in SRDB for SR Node %pI4",
+ __func__, &lsah->adv_router);
return;
}
- /* Search for corresponding Segment Link */
+ /* Search for corresponding Segment Prefix */
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp))
if (srp->instance == instance)
break;
- /* Remove Segment Link if found */
+ /* Remove Prefix if found */
if ((srp != NULL) && (srp->instance == instance)) {
- del_sid_nhlfe(srp->nhlfe);
- listnode_delete(srn->ext_link, srp);
+ ospf_zebra_delete_prefix_sid(srp);
+ listnode_delete(srn->ext_prefix, srp);
XFREE(MTYPE_OSPF_SR_PARAMS, srp);
} else {
flog_err(
EC_OSPF_SR_INVALID_DB,
- "SR (%s): Didn't found corresponding SR Prefix 7.0.0.%u for SR Node %s",
+ "SR (%s): Didn't found corresponding SR Prefix 7.0.0.%u for SR Node %pI4",
__func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
- inet_ntoa(lsah->adv_router));
+ &lsah->adv_router);
}
}
@@ -1428,14 +1475,14 @@ uint32_t get_ext_link_label_value(void)
/*
* Update Prefix SID. Call by ospf_ext_pref_ism_change to
- * complete initial CLI command at startutp.
+ * complete initial CLI command at startup.
*
* @param ifp - Loopback interface
* @param pref - Prefix address of this interface
*
* @return - void
*/
-void ospf_sr_update_prefix(struct interface *ifp, struct prefix *p)
+void ospf_sr_update_local_prefix(struct interface *ifp, struct prefix *p)
{
struct listnode *node;
struct sr_prefix *srp;
@@ -1450,29 +1497,31 @@ void ospf_sr_update_prefix(struct interface *ifp, struct prefix *p)
*/
for (ALL_LIST_ELEMENTS_RO(OspfSR.self->ext_prefix, node, srp)) {
if ((srp->nhlfe.ifindex == ifp->ifindex)
- || ((IPV4_ADDR_SAME(&srp->nhlfe.prefv4.prefix,
- &p->u.prefix4))
- && (srp->nhlfe.prefv4.prefixlen == p->prefixlen))) {
+ || ((IPV4_ADDR_SAME(&srp->prefv4.prefix, &p->u.prefix4))
+ && (srp->prefv4.prefixlen == p->prefixlen))) {
/* Update Interface & Prefix info */
srp->nhlfe.ifindex = ifp->ifindex;
- IPV4_ADDR_COPY(&srp->nhlfe.prefv4.prefix,
- &p->u.prefix4);
- srp->nhlfe.prefv4.prefixlen = p->prefixlen;
- srp->nhlfe.prefv4.family = p->family;
+ IPV4_ADDR_COPY(&srp->prefv4.prefix, &p->u.prefix4);
+ srp->prefv4.prefixlen = p->prefixlen;
+ srp->prefv4.family = p->family;
IPV4_ADDR_COPY(&srp->nhlfe.nexthop, &p->u.prefix4);
/* OK. Let's Schedule Extended Prefix LSA */
srp->instance = ospf_ext_schedule_prefix_index(
- ifp, srp->sid, &srp->nhlfe.prefv4, srp->flags);
+ ifp, srp->sid, &srp->prefv4, srp->flags);
+
+ osr_debug(
+ " |- Update Node SID %pFX - %u for self SR Node",
+ (struct prefix *)&srp->prefv4, srp->sid);
/* Install NHLFE if NO-PHP is requested */
if (CHECK_FLAG(srp->flags,
EXT_SUBTLV_PREFIX_SID_NPFLG)) {
- srp->nhlfe.label_in = index2label(
- srp->sid, OspfSR.self->srgb);
+ srp->label_in = index2label(srp->sid,
+ OspfSR.self->srgb);
srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL;
- add_sid_nhlfe(srp->nhlfe);
+ ospf_zebra_update_prefix_sid(srp);
}
}
}
@@ -1488,12 +1537,10 @@ static void ospf_sr_nhlfe_update(struct hash_bucket *bucket, void *args)
struct sr_node *srn = (struct sr_node *)bucket->data;
struct listnode *node;
struct sr_prefix *srp;
- struct sr_nhlfe old;
+ bool old;
int rc;
- if (IS_DEBUG_OSPF_SR)
- zlog_debug(" |- Update Prefix for SR Node %s",
- inet_ntoa(srn->adv_router));
+ osr_debug(" |- Update Prefix for SR Node %pI4", &srn->adv_router);
/* Skip Self SR Node */
if (srn == OspfSR.self)
@@ -1502,24 +1549,25 @@ static void ospf_sr_nhlfe_update(struct hash_bucket *bucket, void *args)
/* Update Extended Prefix */
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) {
- /* Backup current NHLFE */
- memcpy(&old, &srp->nhlfe, sizeof(struct sr_nhlfe));
+ /* Keep track of valid route */
+ old = srp->route != NULL;
/* Compute the new NHLFE */
rc = compute_prefix_nhlfe(srp);
/* Check computation result */
switch (rc) {
- /* next hop is not know, remove old NHLFE to avoid loop */
+ /* Routes are not know, remove old NHLFE if any to avoid loop */
case -1:
- del_sid_nhlfe(srp->nhlfe);
+ if (old)
+ ospf_zebra_delete_prefix_sid(srp);
break;
- /* next hop has not changed, skip it */
+ /* Routes exist but are not ready, skip it */
case 0:
break;
- /* there is a new next hop, update NHLFE */
+ /* There is at least one route, update NHLFE */
case 1:
- update_sid_nhlfe(old, srp->nhlfe);
+ ospf_zebra_update_prefix_sid(srp);
break;
default:
break;
@@ -1527,22 +1575,17 @@ static void ospf_sr_nhlfe_update(struct hash_bucket *bucket, void *args)
}
}
-static int ospf_sr_update_schedule(struct thread *t)
+void ospf_sr_update_task(struct ospf *ospf)
{
- struct ospf *ospf;
struct timeval start_time, stop_time;
- ospf = THREAD_ARG(t);
- ospf->t_sr_update = NULL;
-
- if (!OspfSR.update)
- return 0;
+ if (ospf == NULL)
+ return;
monotime(&start_time);
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Start SPF update", __func__);
+ osr_debug("SR (%s): Start SPF update", __func__);
hash_iterate(OspfSR.neighbors, (void (*)(struct hash_bucket *,
void *))ospf_sr_nhlfe_update,
@@ -1550,32 +1593,9 @@ static int ospf_sr_update_schedule(struct thread *t)
monotime(&stop_time);
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): SPF Processing Time(usecs): %lld",
- __func__,
- (stop_time.tv_sec - start_time.tv_sec) * 1000000LL
- + (stop_time.tv_usec - start_time.tv_usec));
-
- OspfSR.update = false;
- return 1;
-}
-
-#define OSPF_SR_UPDATE_INTERVAL 1
-
-void ospf_sr_update_timer_add(struct ospf *ospf)
-{
-
- if (ospf == NULL)
- return;
-
- /* Check if an update is not alreday engage */
- if (OspfSR.update)
- return;
-
- OspfSR.update = true;
-
- thread_add_timer(master, ospf_sr_update_schedule, ospf,
- OSPF_SR_UPDATE_INTERVAL, &ospf->t_sr_update);
+ osr_debug("SR (%s): SPF Processing Time(usecs): %lld", __func__,
+ (stop_time.tv_sec - start_time.tv_sec) * 1000000LL
+ + (stop_time.tv_usec - start_time.tv_usec));
}
/*
@@ -1620,8 +1640,8 @@ void ospf_sr_config_write_router(struct vty *vty)
vty_out(vty,
" segment-routing prefix %s/%u "
"index %u%s\n",
- inet_ntoa(srp->nhlfe.prefv4.prefix),
- srp->nhlfe.prefv4.prefixlen, srp->sid,
+ inet_ntoa(srp->prefv4.prefix),
+ srp->prefv4.prefixlen, srp->sid,
CHECK_FLAG(srp->flags,
EXT_SUBTLV_PREFIX_SID_NPFLG)
? " no-php-flag"
@@ -1650,22 +1670,19 @@ DEFUN(ospf_sr_enable,
return CMD_WARNING_CONFIG_FAILED;
}
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("SR: Segment Routing: OFF -> ON");
+ osr_debug("SR: Segment Routing: OFF -> ON");
/* Start Segment Routing */
OspfSR.enabled = true;
ospf_sr_start(ospf);
/* Set Router Information SR parameters */
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("SR: Activate SR for Router Information LSA");
+ osr_debug("SR: Activate SR for Router Information LSA");
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
/* Update Ext LSA */
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("SR: Activate SR for Extended Link/Prefix LSA");
+ osr_debug("SR: Activate SR for Extended Link/Prefix LSA");
ospf_ext_update_sr(true);
@@ -1683,8 +1700,7 @@ DEFUN (no_ospf_sr_enable,
if (!OspfSR.enabled)
return CMD_SUCCESS;
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("SR: Segment Routing: ON -> OFF");
+ osr_debug("SR: Segment Routing: ON -> OFF");
/* Start by Disabling Extended Link & Prefix LSA */
ospf_ext_update_sr(false);
@@ -1694,7 +1710,6 @@ DEFUN (no_ospf_sr_enable,
/* Finally, stop Segment Routing */
ospf_sr_stop();
- OspfSR.enabled = false;
return CMD_SUCCESS;
}
@@ -1913,22 +1928,20 @@ DEFUN (sr_prefix_sid,
/* Create new Extended Prefix to SRDB if not found */
new = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
- IPV4_ADDR_COPY(&new->nhlfe.prefv4.prefix, &p.u.prefix4);
- IPV4_ADDR_COPY(&new->nhlfe.nexthop, &p.u.prefix4);
- new->nhlfe.prefv4.prefixlen = p.prefixlen;
- new->nhlfe.prefv4.family = p.family;
+ IPV4_ADDR_COPY(&new->prefv4.prefix, &p.u.prefix4);
+ new->prefv4.prefixlen = p.prefixlen;
+ new->prefv4.family = p.family;
new->sid = index;
+ new->type = LOCAL_SID;
/* Set NO PHP flag if present and compute NHLFE */
if (argv_find(argv, argc, "no-php-flag", &idx)) {
SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG);
- new->nhlfe.label_in = index2label(new->sid, OspfSR.self->srgb);
+ new->label_in = index2label(new->sid, OspfSR.self->srgb);
new->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL;
}
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Add new index %u to Prefix %s/%u",
- __func__, index, inet_ntoa(new->nhlfe.prefv4.prefix),
- new->nhlfe.prefv4.prefixlen);
+ osr_debug("SR (%s): Add new index %u to Prefix %pFX", __func__, index,
+ (struct prefix *)&new->prefv4);
/* Get Interface and check if it is a Loopback */
ifp = if_lookup_prefix(&p, VRF_DEFAULT);
@@ -1941,9 +1954,9 @@ DEFUN (sr_prefix_sid,
*/
listnode_add(OspfSR.self->ext_prefix, new);
zlog_info(
- "Interface for prefix %s/%u not found. Deferred LSA "
+ "Interface for prefix %pFX not found. Deferred LSA "
"flooding",
- inet_ntoa(p.u.prefix4), p.prefixlen);
+ &p);
return CMD_SUCCESS;
}
@@ -1956,8 +1969,8 @@ DEFUN (sr_prefix_sid,
/* Search if this prefix already exist */
for (ALL_LIST_ELEMENTS_RO(OspfSR.self->ext_prefix, node, srp)) {
- if ((IPV4_ADDR_SAME(&srp->nhlfe.prefv4.prefix, &p.u.prefix4)
- && srp->nhlfe.prefv4.prefixlen == p.prefixlen))
+ if ((IPV4_ADDR_SAME(&srp->prefv4.prefix, &p.u.prefix4)
+ && srp->prefv4.prefixlen == p.prefixlen))
break;
else
srp = NULL;
@@ -1965,17 +1978,16 @@ DEFUN (sr_prefix_sid,
/* Update or Add this new SR Prefix */
if (srp) {
- update_sid_nhlfe(srp->nhlfe, new->nhlfe);
listnode_delete(OspfSR.self->ext_prefix, srp);
listnode_add(OspfSR.self->ext_prefix, new);
} else {
listnode_add(OspfSR.self->ext_prefix, new);
- add_sid_nhlfe(new->nhlfe);
}
+ ospf_zebra_update_prefix_sid(new);
/* Finally, update Extended Prefix LSA */
new->instance = ospf_ext_schedule_prefix_index(
- ifp, new->sid, &new->nhlfe.prefv4, new->flags);
+ ifp, new->sid, &new->prefv4, new->flags);
if (new->instance == 0) {
vty_out(vty, "Unable to set index %u for prefix %s/%u\n", index,
inet_ntoa(p.u.prefix4), p.prefixlen);
@@ -2017,8 +2029,8 @@ DEFUN (no_sr_prefix_sid,
/* check that the prefix is already set */
for (ALL_LIST_ELEMENTS_RO(OspfSR.self->ext_prefix, node, srp))
- if (IPV4_ADDR_SAME(&srp->nhlfe.prefv4.prefix, &p.u.prefix4)
- && (srp->nhlfe.prefv4.prefixlen == p.prefixlen)) {
+ if (IPV4_ADDR_SAME(&srp->prefv4.prefix, &p.u.prefix4)
+ && (srp->prefv4.prefixlen == p.prefixlen)) {
found = true;
break;
}
@@ -2043,14 +2055,12 @@ DEFUN (no_sr_prefix_sid,
return CMD_WARNING;
}
- if (IS_DEBUG_OSPF_SR)
- zlog_debug("SR (%s): Remove Prefix %s/%u with index %u",
- __func__, inet_ntoa(srp->nhlfe.prefv4.prefix),
- srp->nhlfe.prefv4.prefixlen, srp->sid);
+ osr_debug("SR (%s): Remove Prefix %pFX with index %u", __func__,
+ (struct prefix *)&srp->prefv4, srp->sid);
- /* Delete NHLFE is NO-PHP is set */
+ /* Delete NHLFE if NO-PHP is set */
if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG))
- del_sid_nhlfe(srp->nhlfe);
+ ospf_zebra_delete_prefix_sid(srp);
/* OK, all is clean, remove SRP from SRDB */
listnode_delete(OspfSR.self->ext_prefix, srp);
@@ -2060,6 +2070,116 @@ DEFUN (no_sr_prefix_sid,
}
+static char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
+ mpls_label_t label_out)
+{
+ if (size < 24)
+ return NULL;
+
+ switch (label_out) {
+ case MPLS_LABEL_IMPLICIT_NULL:
+ snprintf(buf, size, "Pop(%u)", label_in);
+ break;
+ case MPLS_LABEL_IPV4_EXPLICIT_NULL:
+ snprintf(buf, size, "Swap(%u, null)", label_in);
+ break;
+ case MPLS_INVALID_LABEL:
+ snprintf(buf, size, "no-op.");
+ break;
+ default:
+ snprintf(buf, size, "Swap(%u, %u)", label_in, label_out);
+ break;
+ }
+ return buf;
+}
+
+static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json,
+ struct sr_prefix *srp)
+{
+
+ struct listnode *node;
+ struct ospf_path *path;
+ struct interface *itf;
+ json_object *json_route = NULL, *json_obj;
+ char pref[19];
+ char sid[22];
+ char op[32];
+ int indent = 0;
+
+ snprintfrr(pref, 19, "%pFX", (struct prefix *)&srp->prefv4);
+ snprintf(sid, 22, "SR Pfx (idx %u)", srp->sid);
+ if (json) {
+ json_object_string_add(json, "prefix", pref);
+ json_object_int_add(json, "sid", srp->sid);
+ json_object_int_add(json, "inputLabel", srp->label_in);
+ } else {
+ sbuf_push(sbuf, 0, "%18s %21s ", pref, sid);
+ }
+
+ /* Check if it is a Local Node SID */
+ if (srp->type == LOCAL_SID) {
+ itf = if_lookup_by_index(srp->nhlfe.ifindex, VRF_DEFAULT);
+ if (json) {
+ if (!json_route) {
+ json_route = json_object_new_array();
+ json_object_object_add(json, "prefixRoute",
+ json_route);
+ }
+ json_obj = json_object_new_object();
+ json_object_int_add(json_obj, "outputLabel",
+ srp->nhlfe.label_out);
+ json_object_string_add(json_obj, "interface",
+ itf ? itf->name : "-");
+ json_object_string_add(json_obj, "nexthop",
+ inet_ntoa(srp->nhlfe.nexthop));
+ json_object_array_add(json_route, json_obj);
+ } else {
+ sbuf_push(sbuf, 0, "%20s %9s %15s\n",
+ sr_op2str(op, 32, srp->label_in,
+ srp->nhlfe.label_out),
+ itf ? itf->name : "-",
+ inet_ntoa(srp->nhlfe.nexthop));
+ }
+ return;
+ }
+
+ /* Check if we have a valid path for this prefix */
+ if (srp->route == NULL) {
+ if (!json) {
+ sbuf_push(sbuf, 0, "\n");
+ }
+ return;
+ }
+
+ /* Process list of OSPF paths */
+ for (ALL_LIST_ELEMENTS_RO(srp->route->paths, node, path)) {
+ itf = if_lookup_by_index(path->ifindex, VRF_DEFAULT);
+ if (json) {
+ if (!json_route) {
+ json_route = json_object_new_array();
+ json_object_object_add(json, "prefixRoute",
+ json_route);
+ }
+ json_obj = json_object_new_object();
+ json_object_int_add(json_obj, "outputLabel",
+ path->srni.label_out);
+ json_object_string_add(json_obj, "interface",
+ itf ? itf->name : "-");
+ json_object_string_add(json_obj, "nexthop",
+ inet_ntoa(path->nexthop));
+ json_object_array_add(json_route, json_obj);
+ } else {
+ sbuf_push(sbuf, indent, "%20s %9s %15s\n",
+ sr_op2str(op, 32, srp->label_in,
+ path->srni.label_out),
+ itf ? itf->name : "-",
+ inet_ntoa(path->nexthop));
+ /* Offset to align information for ECMP */
+ indent = 43;
+ }
+ }
+}
+
static void show_sr_node(struct vty *vty, struct json_object *json,
struct sr_node *srn)
{
@@ -2068,9 +2188,10 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
struct sr_link *srl;
struct sr_prefix *srp;
struct interface *itf;
+ struct sbuf sbuf;
char pref[19];
char sid[22];
- char label[8];
+ char op[32];
json_object *json_node = NULL, *json_algo, *json_obj;
json_object *json_prefix = NULL, *json_link = NULL;
@@ -2078,6 +2199,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
if (srn == NULL)
return;
+ sbuf_init(&sbuf, NULL, 0);
+
if (json) {
json_node = json_object_new_object();
json_object_string_add(json_node, "routerID",
@@ -2104,41 +2227,31 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
if (srn->msd != 0)
json_object_int_add(json_node, "nodeMsd", srn->msd);
} else {
- vty_out(vty, "SR-Node: %s", inet_ntoa(srn->adv_router));
- vty_out(vty, "\tSRGB (Size/Label): %u/%u", srn->srgb.range_size,
- srn->srgb.lower_bound);
- vty_out(vty, "\tAlgorithm(s): %s",
- srn->algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF");
+ 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",
+ srn->algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF");
for (int i = 1; i < ALGORITHM_COUNT; i++) {
if (srn->algo[i] == SR_ALGORITHM_UNSET)
continue;
- vty_out(vty, "/%s",
- srn->algo[i] == SR_ALGORITHM_SPF ? "SPF"
- : "S-SPF");
+ sbuf_push(&sbuf, 0, "/%s",
+ srn->algo[i] == SR_ALGORITHM_SPF ? "SPF"
+ : "S-SPF");
}
if (srn->msd != 0)
- vty_out(vty, "\tMSD: %u", srn->msd);
+ sbuf_push(&sbuf, 0, "\tMSD: %u", srn->msd);
}
if (!json) {
- vty_out(vty,
- "\n\n Prefix or Link Label In Label Out "
- "Node or Adj. SID Interface Nexthop\n");
- vty_out(vty,
- "------------------ -------- --------- "
- "--------------------- --------- ---------------\n");
+ sbuf_push(&sbuf, 0,
+ "\n\n Prefix or Link Node or Adj. SID "
+ " Label Operation Interface Nexthop\n");
+ sbuf_push(&sbuf, 0,
+ "------------------ --------------------- "
+ "-------------------- --------- ---------------\n");
}
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) {
- snprintf(pref, sizeof(pref), "%s/%u",
- inet_ntoa(srp->nhlfe.prefv4.prefix),
- srp->nhlfe.prefv4.prefixlen);
- snprintf(sid, sizeof(sid), "SR Pfx (idx %u)", srp->sid);
- if (srp->nhlfe.label_out == MPLS_LABEL_IMPLICIT_NULL)
- snprintf(label, sizeof(label), "pop");
- else
- snprintf(label, sizeof(label), "%u",
- srp->nhlfe.label_out);
- itf = if_lookup_by_index(srp->nhlfe.ifindex, VRF_DEFAULT);
if (json) {
if (!json_prefix) {
json_prefix = json_object_new_array();
@@ -2147,34 +2260,16 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
json_prefix);
}
json_obj = json_object_new_object();
- json_object_string_add(json_obj, "prefix", pref);
- json_object_int_add(json_obj, "sid", srp->sid);
- json_object_int_add(json_obj, "inputLabel",
- srp->nhlfe.label_in);
- json_object_string_add(json_obj, "outputLabel", label);
- json_object_string_add(json_obj, "interface",
- itf ? itf->name : "-");
- json_object_string_add(json_obj, "nexthop",
- inet_ntoa(srp->nhlfe.nexthop));
+ show_sr_prefix(NULL, json_obj, srp);
json_object_array_add(json_prefix, json_obj);
} else {
- vty_out(vty, "%18s %8u %9s %21s %9s %15s\n", pref,
- srp->nhlfe.label_in, label, sid,
- itf ? itf->name : "-",
- inet_ntoa(srp->nhlfe.nexthop));
+ show_sr_prefix(&sbuf, NULL, srp);
}
}
for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) {
- snprintf(pref, sizeof(pref), "%s/%u",
- inet_ntoa(srl->nhlfe[0].prefv4.prefix),
- srl->nhlfe[0].prefv4.prefixlen);
- snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", srl->sid[0]);
- if (srl->nhlfe[0].label_out == MPLS_LABEL_IMPLICIT_NULL)
- snprintf(label, sizeof(label), "pop");
- else
- snprintf(label, sizeof(label), "%u",
- srl->nhlfe[0].label_out);
+ snprintfrr(pref, 19, "%pI4/32", &srl->itf_addr);
+ snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[0]);
itf = if_lookup_by_index(srl->nhlfe[0].ifindex, VRF_DEFAULT);
if (json) {
if (!json_link) {
@@ -2188,7 +2283,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
json_object_int_add(json_obj, "sid", srl->sid[0]);
json_object_int_add(json_obj, "inputLabel",
srl->nhlfe[0].label_in);
- json_object_string_add(json_obj, "outputLabel", label);
+ json_object_int_add(json_obj, "outputLabel",
+ srl->nhlfe[0].label_out);
json_object_string_add(json_obj, "interface",
itf ? itf->name : "-");
json_object_string_add(
@@ -2197,18 +2293,13 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
json_object_array_add(json_link, json_obj);
/* Backup Link */
json_obj = json_object_new_object();
- snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)",
- srl->sid[1]);
- if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL)
- snprintf(label, sizeof(label), "pop");
- else
- snprintf(label, sizeof(label), "%u",
- srl->nhlfe[0].label_out);
+ snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]);
json_object_string_add(json_obj, "prefix", pref);
json_object_int_add(json_obj, "sid", srl->sid[1]);
json_object_int_add(json_obj, "inputLabel",
srl->nhlfe[1].label_in);
- json_object_string_add(json_obj, "outputLabel", label);
+ json_object_int_add(json_obj, "outputLabel",
+ srl->nhlfe[1].label_out);
json_object_string_add(json_obj, "interface",
itf ? itf->name : "-");
json_object_string_add(
@@ -2216,27 +2307,27 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
inet_ntoa(srl->nhlfe[1].nexthop));
json_object_array_add(json_link, json_obj);
} else {
- vty_out(vty, "%18s %8u %9s %21s %9s %15s\n", pref,
- srl->nhlfe[0].label_in, label, sid,
- itf ? itf->name : "-",
- inet_ntoa(srl->nhlfe[0].nexthop));
- snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)",
- srl->sid[1]);
- if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL)
- snprintf(label, sizeof(label), "pop");
- else
- snprintf(label, sizeof(label), "%u",
- srl->nhlfe[1].label_out);
- vty_out(vty, "%18s %8u %9s %21s %9s %15s\n", pref,
- srl->nhlfe[1].label_in, label, sid,
- itf ? itf->name : "-",
- inet_ntoa(srl->nhlfe[1].nexthop));
+ sbuf_push(&sbuf, 0, "%18s %21s %20s %9s %15s\n",
+ pref, sid,
+ sr_op2str(op, 32, srl->nhlfe[0].label_in,
+ srl->nhlfe[0].label_out),
+ itf ? itf->name : "-",
+ inet_ntoa(srl->nhlfe[0].nexthop));
+ snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]);
+ sbuf_push(&sbuf, 0, "%18s %21s %20s %9s %15s\n",
+ pref, sid,
+ sr_op2str(op, 32, srl->nhlfe[1].label_in,
+ srl->nhlfe[1].label_out),
+ itf ? itf->name : "-",
+ inet_ntoa(srl->nhlfe[1].nexthop));
}
}
if (json)
json_object_array_add(json, json_node);
else
- vty_out(vty, "\n");
+ vty_out(vty, "%s\n", sbuf_buf(&sbuf));
+
+ sbuf_free(&sbuf);
}
static void show_vty_srdb(struct hash_bucket *bucket, void *args)