Skip to content

Commit

Permalink
isisd, lib: add link state support for srv6 adjacencies
Browse files Browse the repository at this point in the history
Add support for endx_lan and endx adjacency.

Signed-off-by: Philippe Guibert <[email protected]>
  • Loading branch information
pguibert6WIND committed Apr 3, 2024
1 parent 27cc9ae commit a9f49ef
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 5 deletions.
48 changes: 47 additions & 1 deletion isisd/isis_te.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,10 @@ void isis_link_params_update(struct isis_circuit *circuit,
ext->status = EXT_ADJ_SID;
else if (IS_SUBTLV(ext, EXT_LAN_ADJ_SID))
ext->status = EXT_LAN_ADJ_SID;
else if (IS_SUBTLV(ext, EXT_SRV6_LAN_ENDX_SID))
ext->status = EXT_SRV6_LAN_ENDX_SID;
else if (IS_SUBTLV(ext, EXT_SRV6_ENDX_SID))
ext->status = EXT_SRV6_ENDX_SID;
else
ext->status = 0;
}
Expand Down Expand Up @@ -1048,7 +1052,49 @@ static struct ls_attributes *get_attributes(struct ls_node_id adv,
}
}
}

if (CHECK_FLAG(tlvs->status, EXT_SRV6_ENDX_SID)) {
struct isis_srv6_endx_sid_subtlv *endx =
(struct isis_srv6_endx_sid_subtlv *)
tlvs->srv6_endx_sid.head;
int i;
for (; endx; endx = endx->next) {
if (endx->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG) {
i = 1;
SET_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SRV6SID);
} else {
i = 0;
SET_FLAG(attr->flags, LS_ATTR_ADJ_SRV6SID);
}
attr->adj_srv6_sid[i].flags = endx->flags;
attr->adj_srv6_sid[i].weight = endx->weight;
memcpy(&attr->adj_srv6_sid[i].sid, &endx->sid,
sizeof(struct in6_addr));
attr->adj_srv6_sid[i].endpoint_behavior = endx->behavior;
}
}
if (CHECK_FLAG(tlvs->status, EXT_SRV6_LAN_ENDX_SID)) {
struct isis_srv6_lan_endx_sid_subtlv *lendx =
(struct isis_srv6_lan_endx_sid_subtlv *)
tlvs->srv6_lan_endx_sid.head;
int i;
for (; lendx; lendx = lendx->next) {
if (lendx->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG) {
i = 1;
SET_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SRV6SID);
} else {
i = 0;
SET_FLAG(attr->flags, LS_ATTR_ADJ_SRV6SID);
}
memcpy(&attr->adj_srv6_sid[i].neighbor.sysid,
&lendx->neighbor_id, ISIS_SYS_ID_LEN);
attr->adj_srv6_sid[i].flags = lendx->flags;
attr->adj_srv6_sid[i].weight = lendx->weight;
memcpy(&attr->adj_srv6_sid[i].sid, &lendx->sid,
sizeof(struct in6_addr));
attr->adj_srv6_sid[i].endpoint_behavior =
lendx->behavior;
}
}
return attr;
}

Expand Down
7 changes: 4 additions & 3 deletions isisd/isis_te.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ typedef enum _status_t { disable, enable, learn } status_t;
/* Mode for Inter-AS LSP */ /* TODO: Check how if LSP is flooded in RFC5316 */
typedef enum _interas_mode_t { off, region, as, emulate } interas_mode_t;

#define IS_EXT_TE(e) (e && e->status != 0 \
&& e->status != EXT_ADJ_SID \
&& e->status != EXT_LAN_ADJ_SID)
#define IS_EXT_TE(e) \
(e && e->status != 0 && e->status != EXT_ADJ_SID && \
e->status != EXT_LAN_ADJ_SID && e->status != EXT_SRV6_ENDX_SID && \
e->status != EXT_SRV6_LAN_ENDX_SID)
#define IS_MPLS_TE(a) (a && a->status == enable)
#define IS_EXPORT_TE(a) (a->export)

Expand Down
118 changes: 117 additions & 1 deletion lib/link_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,23 @@ int ls_attributes_same(struct ls_attributes *l1, struct ls_attributes *l2)
&l2->adj_sid[i].neighbor.addr)))
return 0;
}
for (int i = 0; i < ADJ_SRV6_MAX; i++) {
if (!CHECK_FLAG(l1->flags, (LS_ATTR_ADJ_SRV6SID << i)))
continue;
if (memcmp(&l1->adj_srv6_sid[i].sid, &l2->adj_srv6_sid[i].sid,
sizeof(struct in6_addr)) ||
(l1->adj_srv6_sid[i].flags != l2->adj_srv6_sid[i].flags) ||
(l1->adj_srv6_sid[i].weight != l2->adj_srv6_sid[i].weight) ||
(l1->adj_srv6_sid[i].endpoint_behavior !=
l2->adj_srv6_sid[i].endpoint_behavior))
return 0;
if (((l1->adv.origin == ISIS_L1) ||
(l1->adv.origin == ISIS_L2)) &&
(memcmp(&l1->adj_srv6_sid[i].neighbor.sysid,
&l2->adj_srv6_sid[i].neighbor.sysid,
ISO_SYS_ID_LEN) != 0))
return 0;
}
if (CHECK_FLAG(l1->flags, LS_ATTR_SRLG)
&& ((l1->srlg_len != l2->srlg_len)
|| memcmp(l1->srlgs, l2->srlgs,
Expand Down Expand Up @@ -1298,6 +1315,26 @@ static struct ls_attributes *ls_parse_attributes(struct stream *s)
STREAM_GET(attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid, s,
ISO_SYS_ID_LEN);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SRV6SID)) {
STREAM_GET(&attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].sid, s,
sizeof(struct in6_addr));
STREAM_GETC(s, attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].flags);
STREAM_GETC(s, attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].weight);
STREAM_GETW(s, attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6]
.endpoint_behavior);
STREAM_GET(attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].neighbor.sysid,
s, ISO_SYS_ID_LEN);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SRV6SID)) {
STREAM_GET(&attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].sid, s,
sizeof(struct in6_addr));
STREAM_GETC(s, attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].flags);
STREAM_GETC(s, attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].weight);
STREAM_GETW(s, attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6]
.endpoint_behavior);
STREAM_GET(attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].neighbor.sysid,
s, ISO_SYS_ID_LEN);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
STREAM_GETC(s, len);
attr->srlgs = XCALLOC(MTYPE_LS_DB, len*sizeof(uint32_t));
Expand Down Expand Up @@ -1532,6 +1569,28 @@ static int ls_format_attributes(struct stream *s, struct ls_attributes *attr)
stream_put(s, attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid,
ISO_SYS_ID_LEN);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SRV6SID)) {
stream_put(s, &attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].sid,
sizeof(struct in6_addr));
stream_putc(s, attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].flags);
stream_putc(s, attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].weight);
stream_putw(s, attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6]
.endpoint_behavior);
stream_put(s,
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].neighbor.sysid,
ISO_SYS_ID_LEN);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SRV6SID)) {
stream_put(s, &attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].sid,
sizeof(struct in6_addr));
stream_putc(s, attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].flags);
stream_putc(s, attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].weight);
stream_putw(s, attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6]
.endpoint_behavior);
stream_put(s,
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].neighbor.sysid,
ISO_SYS_ID_LEN);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
stream_putc(s, attr->srlg_len);
for (len = 0; len < attr->srlg_len; len++)
Expand Down Expand Up @@ -2351,6 +2410,24 @@ static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty,
attr->adj_sid[ADJ_BCK_IPV6].flags,
attr->adj_sid[ADJ_BCK_IPV6].weight);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SRV6SID)) {
sbuf_push(&sbuf, 4, "IPv6 Adjacency-SRV6-SID: %pI6",
&attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].sid);
sbuf_push(&sbuf, 0,
"\tFlags: 0x%x\tWeight: 0x%x\tbehavior: 0x%x\n",
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].flags,
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].weight,
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].endpoint_behavior);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SRV6SID)) {
sbuf_push(&sbuf, 4, "IPv6 Bck. Adjacency-SRV6-SID: %pI6",
&attr->adj_sid[ADJ_SRV6_BCK_IPV6].sid);
sbuf_push(&sbuf, 0,
"\tFlags: 0x%x\tWeight: 0x%x\tbehavior: 0x%x\n",
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].flags,
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].weight,
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].endpoint_behavior);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
sbuf_push(&sbuf, 4, "SRLGs: %d", attr->srlg_len);
for (int i = 1; i < attr->srlg_len; i++) {
Expand All @@ -2372,7 +2449,7 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
struct ls_attributes *attr;
struct json_object *jte, *jbw, *jobj, *jsr = NULL, *jsrlg, *js_ext_ag,
*js_ext_ag_arr_word,
*js_ext_ag_arr_bit;
*js_ext_ag_arr_bit, *jsrv6 = NULL;
char buf[INET6_BUFSIZ];
char buf_ag[strlen("0xffffffff") + 1];
uint32_t bitmap;
Expand Down Expand Up @@ -2557,6 +2634,45 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
attr->adj_sid[ADJ_BCK_IPV6].weight);
json_object_array_add(jsr, jobj);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SRV6SID)) {
jsrv6 = json_object_new_array();
json_object_object_add(json, "segment-routing-ipv6", jsrv6);
jobj = json_object_new_object();
snprintfrr(buf, INET6_BUFSIZ, "%pI6",
&attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].sid);
json_object_string_add(jobj, "adj-sid", buf);
snprintfrr(buf, 6, "0x%x",
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].flags);
json_object_string_add(jobj, "flags", buf);
json_object_int_add(jobj, "weight",
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6].weight);
snprintfrr(buf, 6, "0x%x",
attr->adj_srv6_sid[ADJ_SRV6_PRI_IPV6]
.endpoint_behavior);
json_object_string_add(jobj, "endpoint-behavior", buf);
json_object_array_add(jsr, jobj);
}
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SRV6SID)) {
if (!jsrv6) {
jsrv6 = json_object_new_array();
json_object_object_add(json, "segment-routing-ipv6",
jsrv6);
}
jobj = json_object_new_object();
snprintfrr(buf, INET6_BUFSIZ, "%pI6",
&attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].sid);
json_object_string_add(jobj, "adj-sid", buf);
snprintfrr(buf, 6, "0x%x",
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].flags);
json_object_string_add(jobj, "flags", buf);
json_object_int_add(jobj, "weight",
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6].weight);
snprintfrr(buf, 6, "0x%x",
attr->adj_srv6_sid[ADJ_SRV6_BCK_IPV6]
.endpoint_behavior);
json_object_string_add(jobj, "endpoint-behavior", buf);
json_object_array_add(jsr, jobj);
}
}

void ls_show_edge(struct ls_edge *edge, struct vty *vty,
Expand Down
14 changes: 14 additions & 0 deletions lib/link_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ struct ls_node {
#define LS_ATTR_BCK_ADJ_SID6 0x08000000
#define LS_ATTR_SRLG 0x10000000
#define LS_ATTR_EXT_ADM_GRP 0x20000000
#define LS_ATTR_ADJ_SRV6SID 0x40000000
#define LS_ATTR_BCK_ADJ_SRV6SID 0x80000000

/* Link State Attributes */
struct ls_attributes {
Expand Down Expand Up @@ -209,6 +211,18 @@ struct ls_attributes {
uint8_t sysid[ISO_SYS_ID_LEN]; /* or Sys-ID for ISIS */
} neighbor;
} adj_sid[4]; /* IPv4/IPv6 & Primary/Backup (LAN)-Adj. SID */
#define ADJ_SRV6_PRI_IPV6 0
#define ADJ_SRV6_BCK_IPV6 1
#define ADJ_SRV6_MAX 2
struct ls_srv6_adjacency { /* Adjacency SID for IS-IS */
struct in6_addr sid; /* SID as IPv6 address */
uint8_t flags; /* Flags */
uint8_t weight; /* Administrative weight */
uint16_t endpoint_behavior; /* Endpoint Behavior */
union {
uint8_t sysid[ISO_SYS_ID_LEN]; /* Sys-ID for ISIS */
} neighbor;
} adj_srv6_sid[2];
uint32_t *srlgs; /* List of Shared Risk Link Group */
uint8_t srlg_len; /* number of SRLG in the list */
};
Expand Down

0 comments on commit a9f49ef

Please sign in to comment.