Skip to content

Commit d56c0d2

Browse files
committed
isisd: Unpack SRv6 (LAN) End.X SID Sub-TLV
Extend the Extended IS Reachability TLV unpack function to unpack the SRv6 End.X SID Sub-TLV and SRv6 LAN End.X SID Sub-TLV, if present. Signed-off-by: Carmine Scarpitta <[email protected]>
1 parent 8b6a73c commit d56c0d2

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

isisd/isis_tlvs.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ static void isis_format_subsubtlvs(struct isis_subsubtlvs *subsubtlvs,
120120
int indent);
121121
static int isis_pack_subsubtlvs(struct isis_subsubtlvs *subsubtlvs,
122122
struct stream *s);
123+
static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len,
124+
struct stream *stream, struct sbuf *log, void *dest,
125+
int indent, bool *unpacked_known_tlvs);
126+
static void isis_free_subsubtlvs(struct isis_subsubtlvs *subsubtlvs);
123127

124128
/* For tests/isisd, TLV text requires ipv4-unicast instead of standard */
125129
static const char *isis_mtid2str_fake(uint16_t mtid)
@@ -1656,6 +1660,7 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
16561660
uint8_t sum = 0;
16571661
uint8_t subtlv_type;
16581662
uint8_t subtlv_len;
1663+
uint8_t subsubtlv_len;
16591664
size_t nb_groups;
16601665
uint32_t val;
16611666

@@ -1994,6 +1999,92 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
19941999
SET_SUBTLV(exts, EXT_LAN_ADJ_SID);
19952000
}
19962001
break;
2002+
/* SRv6 End.X SID as per RFC9352 section #8.1 */
2003+
case ISIS_SUBTLV_SRV6_ENDX_SID:
2004+
if (subtlv_len < ISIS_SUBTLV_SRV6_ENDX_SID_SIZE) {
2005+
TLV_SIZE_MISMATCH(log, indent,
2006+
"SRv6 End.X SID");
2007+
stream_forward_getp(s, subtlv_len);
2008+
} else {
2009+
struct isis_srv6_endx_sid_subtlv *adj;
2010+
2011+
adj = XCALLOC(
2012+
MTYPE_ISIS_SUBTLV,
2013+
sizeof(struct
2014+
isis_srv6_endx_sid_subtlv));
2015+
adj->flags = stream_getc(s);
2016+
adj->algorithm = stream_getc(s);
2017+
adj->weight = stream_getc(s);
2018+
adj->behavior = stream_getw(s);
2019+
stream_get(&adj->sid, s, IPV6_MAX_BYTELEN);
2020+
subsubtlv_len = stream_getc(s);
2021+
2022+
adj->subsubtlvs = isis_alloc_subsubtlvs(
2023+
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID);
2024+
2025+
bool unpacked_known_tlvs = false;
2026+
if (unpack_tlvs(
2027+
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID,
2028+
subsubtlv_len, s, log,
2029+
adj->subsubtlvs, indent + 4,
2030+
&unpacked_known_tlvs)) {
2031+
XFREE(MTYPE_ISIS_SUBTLV, adj);
2032+
break;
2033+
}
2034+
if (!unpacked_known_tlvs) {
2035+
isis_free_subsubtlvs(adj->subsubtlvs);
2036+
adj->subsubtlvs = NULL;
2037+
}
2038+
2039+
append_item(&exts->srv6_endx_sid,
2040+
(struct isis_item *)adj);
2041+
SET_SUBTLV(exts, EXT_SRV6_ENDX_SID);
2042+
}
2043+
break;
2044+
/* SRv6 LAN End.X SID as per RFC9352 section #8.2 */
2045+
case ISIS_SUBTLV_SRV6_LAN_ENDX_SID:
2046+
if (subtlv_len < ISIS_SUBTLV_SRV6_LAN_ENDX_SID_SIZE) {
2047+
TLV_SIZE_MISMATCH(log, indent,
2048+
"SRv6 LAN End.X SID");
2049+
stream_forward_getp(s, subtlv_len);
2050+
} else {
2051+
struct isis_srv6_lan_endx_sid_subtlv *lan;
2052+
2053+
lan = XCALLOC(
2054+
MTYPE_ISIS_SUBTLV,
2055+
sizeof(struct
2056+
isis_srv6_lan_endx_sid_subtlv));
2057+
stream_get(&(lan->neighbor_id), s,
2058+
ISIS_SYS_ID_LEN);
2059+
lan->flags = stream_getc(s);
2060+
lan->algorithm = stream_getc(s);
2061+
lan->weight = stream_getc(s);
2062+
lan->behavior = stream_getw(s);
2063+
stream_get(&lan->sid, s, IPV6_MAX_BYTELEN);
2064+
subsubtlv_len = stream_getc(s);
2065+
2066+
lan->subsubtlvs = isis_alloc_subsubtlvs(
2067+
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID);
2068+
2069+
bool unpacked_known_tlvs = false;
2070+
if (unpack_tlvs(
2071+
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID,
2072+
subsubtlv_len, s, log,
2073+
lan->subsubtlvs, indent + 4,
2074+
&unpacked_known_tlvs)) {
2075+
XFREE(MTYPE_ISIS_SUBTLV, lan);
2076+
break;
2077+
}
2078+
if (!unpacked_known_tlvs) {
2079+
isis_free_subsubtlvs(lan->subsubtlvs);
2080+
lan->subsubtlvs = NULL;
2081+
}
2082+
2083+
append_item(&exts->srv6_lan_endx_sid,
2084+
(struct isis_item *)lan);
2085+
SET_SUBTLV(exts, EXT_SRV6_LAN_ENDX_SID);
2086+
}
2087+
break;
19972088
case ISIS_SUBTLV_ASLA:
19982089
if (unpack_item_ext_subtlv_asla(mtid, subtlv_len, s,
19992090
log, indent,
@@ -7147,6 +7238,12 @@ static const struct tlv_ops *const tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
71477238
},
71487239
[ISIS_CONTEXT_SUBSUBTLV_SRV6_END_SID] = {
71497240
[ISIS_SUBSUBTLV_SRV6_SID_STRUCTURE] = &subsubtlv_srv6_sid_structure_ops,
7241+
},
7242+
[ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID] = {
7243+
[ISIS_SUBSUBTLV_SRV6_SID_STRUCTURE] = &subsubtlv_srv6_sid_structure_ops,
7244+
},
7245+
[ISIS_CONTEXT_SUBSUBTLV_SRV6_LAN_ENDX_SID] = {
7246+
[ISIS_SUBSUBTLV_SRV6_SID_STRUCTURE] = &subsubtlv_srv6_sid_structure_ops,
71507247
}
71517248
};
71527249

isisd/isis_tlvs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ enum isis_tlv_context {
423423
ISIS_CONTEXT_SUBTLV_IPV6_REACH,
424424
ISIS_CONTEXT_SUBTLV_SRV6_LOCATOR,
425425
ISIS_CONTEXT_SUBSUBTLV_SRV6_END_SID,
426+
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID,
427+
ISIS_CONTEXT_SUBSUBTLV_SRV6_LAN_ENDX_SID,
426428
ISIS_CONTEXT_MAX,
427429
};
428430

0 commit comments

Comments
 (0)