summaryrefslogtreecommitdiff
path: root/isisd
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2024-07-26 14:45:01 -0400
committerGitHub <noreply@github.com>2024-07-26 14:45:01 -0400
commit7f10381374f451b6550ae8c456f27101381c19f8 (patch)
tree51b35f88a861a280683c6753c775b3e2b5d83946 /isisd
parent1f5a663cb51b909ef79b329a140bb24089187827 (diff)
parent4e76df05476e728d3bdd53821c0f20e4139db1f8 (diff)
Merge pull request #15797 from pguibert6WIND/isis_srv6_ls_subnet
isis, lib: add isis srv6 end sid to ls_prefix
Diffstat (limited to 'isisd')
-rw-r--r--isisd/isis_lsp.c50
-rw-r--r--isisd/isis_lsp.h2
-rw-r--r--isisd/isis_te.c45
-rw-r--r--isisd/isis_te.h1
4 files changed, 96 insertions, 2 deletions
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index bda7ed89a4..391d42fba1 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -2341,6 +2341,56 @@ static int lsp_handle_adj_state_change(struct isis_adjacency *adj)
}
/*
+ * Iterate over all SRv6 locator TLVs
+ */
+int isis_lsp_iterate_srv6_locator(struct isis_lsp *lsp, uint16_t mtid,
+ lsp_ip_reach_iter_cb cb, void *arg)
+{
+ bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
+ struct isis_lsp *frag;
+ struct listnode *node;
+
+ if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0)
+ return LSP_ITER_CONTINUE;
+
+ /* Parse LSP */
+ if (lsp->tlvs) {
+ if (!pseudo_lsp) {
+ struct isis_item_list *srv6_locator_reachs;
+ struct isis_srv6_locator_tlv *r;
+
+ srv6_locator_reachs =
+ isis_lookup_mt_items(&lsp->tlvs->srv6_locator,
+ mtid);
+
+ for (r = srv6_locator_reachs
+ ? (struct isis_srv6_locator_tlv *)
+ srv6_locator_reachs->head
+ : NULL;
+ r; r = r->next) {
+ if ((*cb)((struct prefix *)&r->prefix,
+ r->metric, false /* ignore */,
+ r->subtlvs, arg) == LSP_ITER_STOP)
+ return LSP_ITER_STOP;
+ }
+ }
+ }
+
+ /* Parse LSP fragments if it is not a fragment itself */
+ if (!LSP_FRAGMENT(lsp->hdr.lsp_id))
+ for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
+ if (!frag->tlvs)
+ continue;
+
+ if (isis_lsp_iterate_srv6_locator(frag, mtid, cb,
+ arg) == LSP_ITER_STOP)
+ return LSP_ITER_STOP;
+ }
+
+ return LSP_ITER_CONTINUE;
+}
+
+/*
* Iterate over all IP reachability TLVs in a LSP (all fragments) of the given
* address-family and MT-ID.
*/
diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h
index 3839a9504c..15db88b02f 100644
--- a/isisd/isis_lsp.h
+++ b/isisd/isis_lsp.h
@@ -143,6 +143,8 @@ int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid,
lsp_ip_reach_iter_cb cb, void *arg);
int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid,
lsp_is_reach_iter_cb cb, void *arg);
+int isis_lsp_iterate_srv6_locator(struct isis_lsp *lsp, uint16_t mtid,
+ lsp_ip_reach_iter_cb cb, void *arg);
#define lsp_flood(lsp, circuit) \
_lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__)
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index fead826fcd..b6321dbac3 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -1258,8 +1258,11 @@ static int lsp_to_subnet_cb(const struct prefix *prefix, uint32_t metric,
if (!args || !prefix)
return LSP_ITER_CONTINUE;
- te_debug(" |- Process Extended %s Reachability %pFX",
- prefix->family == AF_INET ? "IP" : "IPv6", prefix);
+ if (args->srv6_locator)
+ te_debug(" |- Process SRv6 Locator %pFX", prefix);
+ else
+ te_debug(" |- Process Extended %s Reachability %pFX",
+ prefix->family == AF_INET ? "IP" : "IPv6", prefix);
vertex = args->vertex;
@@ -1386,6 +1389,38 @@ static int lsp_to_subnet_cb(const struct prefix *prefix, uint32_t metric,
}
}
+ /* Update SRv6 SID and locator if any */
+ if (subtlvs && subtlvs->srv6_end_sids.count != 0) {
+ struct isis_srv6_end_sid_subtlv *psid;
+ struct ls_srv6_sid sr = {};
+
+ psid = (struct isis_srv6_end_sid_subtlv *)
+ subtlvs->srv6_end_sids.head;
+ sr.behavior = psid->behavior;
+ sr.flags = psid->flags;
+ memcpy(&sr.sid, &psid->sid, sizeof(struct in6_addr));
+
+ if (!CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6) ||
+ memcmp(&ls_pref->srv6, &sr, sizeof(struct ls_srv6_sid))) {
+ memcpy(&ls_pref->srv6, &sr, sizeof(struct ls_srv6_sid));
+ SET_FLAG(ls_pref->flags, LS_PREF_SRV6);
+ if (subnet->status != NEW)
+ subnet->status = UPDATE;
+ } else {
+ if (subnet->status == ORPHAN)
+ subnet->status = SYNC;
+ }
+ } else {
+ if (CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6)) {
+ UNSET_FLAG(ls_pref->flags, LS_PREF_SRV6);
+ if (subnet->status != NEW)
+ subnet->status = UPDATE;
+ } else {
+ if (subnet->status == ORPHAN)
+ subnet->status = SYNC;
+ }
+ }
+
/* Update status and Export Link State Edge if needed */
if (subnet->status != SYNC) {
if (args->export)
@@ -1454,12 +1489,18 @@ static void isis_te_parse_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp)
&args);
/* Process all Extended IP (v4 & v6) in LSP (all fragments) */
+ args.srv6_locator = false;
isis_lsp_iterate_ip_reach(lsp, AF_INET, ISIS_MT_IPV4_UNICAST,
lsp_to_subnet_cb, &args);
isis_lsp_iterate_ip_reach(lsp, AF_INET6, ISIS_MT_IPV6_UNICAST,
lsp_to_subnet_cb, &args);
isis_lsp_iterate_ip_reach(lsp, AF_INET6, ISIS_MT_IPV4_UNICAST,
lsp_to_subnet_cb, &args);
+ args.srv6_locator = true;
+ isis_lsp_iterate_srv6_locator(lsp, ISIS_MT_STANDARD, lsp_to_subnet_cb,
+ &args);
+ isis_lsp_iterate_srv6_locator(lsp, ISIS_MT_IPV6_UNICAST,
+ lsp_to_subnet_cb, &args);
/* Clean remaining Orphan Edges or Subnets */
if (IS_EXPORT_TE(mta))
diff --git a/isisd/isis_te.h b/isisd/isis_te.h
index 326e50479d..697f03b612 100644
--- a/isisd/isis_te.h
+++ b/isisd/isis_te.h
@@ -103,6 +103,7 @@ struct isis_te_args {
struct ls_ted *ted;
struct ls_vertex *vertex;
bool export;
+ bool srv6_locator;
};
enum lsp_event { LSP_UNKNOWN, LSP_ADD, LSP_UPD, LSP_DEL, LSP_INC, LSP_TICK };