Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isis, lib: add isis srv6 end sid to ls_prefix #15797

Merged
merged 1 commit into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions isisd/isis_lsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,56 @@ static int lsp_handle_adj_state_change(struct isis_adjacency *adj)
return 0;
}

/*
* 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.
Expand Down
2 changes: 2 additions & 0 deletions isisd/isis_lsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down
45 changes: 43 additions & 2 deletions isisd/isis_te.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions isisd/isis_te.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
36 changes: 35 additions & 1 deletion lib/link_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,13 @@ int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2)
|| (p1->sr.sid_flag != p2->sr.sid_flag))
return 0;
}
if (CHECK_FLAG(p1->flags, LS_PREF_SRV6)) {
if (memcmp(&p1->srv6.sid, &p2->srv6.sid,
sizeof(struct in6_addr)) ||
(p1->srv6.flags != p2->srv6.flags) ||
(p1->srv6.behavior != p2->srv6.behavior))
return 0;
}

/* OK, p1 & p2 are equal */
return 1;
Expand Down Expand Up @@ -1388,6 +1395,11 @@ static struct ls_prefix *ls_parse_prefix(struct stream *s)
STREAM_GETC(s, ls_pref->sr.sid_flag);
STREAM_GETC(s, ls_pref->sr.algo);
}
if (CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6)) {
STREAM_GET(&ls_pref->srv6.sid, s, sizeof(struct in6_addr));
STREAM_GETW(s, ls_pref->srv6.behavior);
STREAM_GETC(s, ls_pref->srv6.flags);
}

return ls_pref;

Expand Down Expand Up @@ -1632,6 +1644,11 @@ static int ls_format_prefix(struct stream *s, struct ls_prefix *ls_pref)
stream_putc(s, ls_pref->sr.sid_flag);
stream_putc(s, ls_pref->sr.algo);
}
if (CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6)) {
stream_put(s, &ls_pref->srv6.sid, sizeof(struct in6_addr));
stream_putw(s, ls_pref->srv6.behavior);
stream_putc(s, ls_pref->srv6.flags);
}

return 0;
}
Expand Down Expand Up @@ -2748,6 +2765,13 @@ static void ls_show_subnet_vty(struct ls_subnet *subnet, struct vty *vty,
sbuf_push(&sbuf, 4, "SID: %d\tAlgorithm: %d\tFlags: 0x%x\n",
pref->sr.sid, pref->sr.algo, pref->sr.sid_flag);

if (CHECK_FLAG(pref->flags, LS_PREF_SRV6))
sbuf_push(&sbuf, 4,
"SIDv6: %pI6\tEndpoint behavior: %s\tFlags: 0x%x\n",
&pref->srv6.sid,
seg6local_action2str(pref->srv6.behavior),
pref->srv6.flags);

end:
vty_out(vty, "%s\n", sbuf_buf(&sbuf));
sbuf_free(&sbuf);
Expand All @@ -2757,7 +2781,7 @@ static void ls_show_subnet_json(struct ls_subnet *subnet,
struct json_object *json)
{
struct ls_prefix *pref;
json_object *jsr;
json_object *jsr, *jsrv6;
char buf[INET6_BUFSIZ];

pref = subnet->ls_pref;
Expand Down Expand Up @@ -2787,6 +2811,16 @@ static void ls_show_subnet_json(struct ls_subnet *subnet,
snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->sr.sid_flag);
json_object_string_add(jsr, "flags", buf);
}
if (CHECK_FLAG(pref->flags, LS_PREF_SRV6)) {
jsrv6 = json_object_new_object();
json_object_object_add(json, "segment-routing-ipv6", jsrv6);
snprintfrr(buf, INET6_BUFSIZ, "%pI6", &pref->srv6.sid);
json_object_string_add(jsrv6, "sid", buf);
json_object_string_add(jsrv6, "behavior",
seg6local_action2str(pref->srv6.behavior));
snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->srv6.flags);
json_object_string_add(jsrv6, "flags", buf);
}
}

void ls_show_subnet(struct ls_subnet *subnet, struct vty *vty,
Expand Down
6 changes: 6 additions & 0 deletions lib/link_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ struct ls_attributes {
#define LS_PREF_EXTENDED_TAG 0x04
#define LS_PREF_METRIC 0x08
#define LS_PREF_SR 0x10
#define LS_PREF_SRV6 0x20

/* Link State Prefix */
struct ls_prefix {
Expand All @@ -258,6 +259,11 @@ struct ls_prefix {
uint8_t sid_flag; /* Segment Routing Flags */
uint8_t algo; /* Algorithm for Segment Routing */
} sr;
struct ls_srv6_sid {
struct in6_addr sid; /* Segment Routing ID */
uint16_t behavior; /* Endpoint behavior bound to the SID */
uint8_t flags; /* Flags */
} srv6;
};

/**
Expand Down
Loading