mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-28 16:06:20 +00:00
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 <carmine.scarpitta@uniroma2.it>
This commit is contained in:
parent
8b6a73c306
commit
d56c0d23b0
@ -120,6 +120,10 @@ static void isis_format_subsubtlvs(struct isis_subsubtlvs *subsubtlvs,
|
||||
int indent);
|
||||
static int isis_pack_subsubtlvs(struct isis_subsubtlvs *subsubtlvs,
|
||||
struct stream *s);
|
||||
static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len,
|
||||
struct stream *stream, struct sbuf *log, void *dest,
|
||||
int indent, bool *unpacked_known_tlvs);
|
||||
static void isis_free_subsubtlvs(struct isis_subsubtlvs *subsubtlvs);
|
||||
|
||||
/* For tests/isisd, TLV text requires ipv4-unicast instead of standard */
|
||||
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,
|
||||
uint8_t sum = 0;
|
||||
uint8_t subtlv_type;
|
||||
uint8_t subtlv_len;
|
||||
uint8_t subsubtlv_len;
|
||||
size_t nb_groups;
|
||||
uint32_t val;
|
||||
|
||||
@ -1994,6 +1999,92 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
|
||||
SET_SUBTLV(exts, EXT_LAN_ADJ_SID);
|
||||
}
|
||||
break;
|
||||
/* SRv6 End.X SID as per RFC9352 section #8.1 */
|
||||
case ISIS_SUBTLV_SRV6_ENDX_SID:
|
||||
if (subtlv_len < ISIS_SUBTLV_SRV6_ENDX_SID_SIZE) {
|
||||
TLV_SIZE_MISMATCH(log, indent,
|
||||
"SRv6 End.X SID");
|
||||
stream_forward_getp(s, subtlv_len);
|
||||
} else {
|
||||
struct isis_srv6_endx_sid_subtlv *adj;
|
||||
|
||||
adj = XCALLOC(
|
||||
MTYPE_ISIS_SUBTLV,
|
||||
sizeof(struct
|
||||
isis_srv6_endx_sid_subtlv));
|
||||
adj->flags = stream_getc(s);
|
||||
adj->algorithm = stream_getc(s);
|
||||
adj->weight = stream_getc(s);
|
||||
adj->behavior = stream_getw(s);
|
||||
stream_get(&adj->sid, s, IPV6_MAX_BYTELEN);
|
||||
subsubtlv_len = stream_getc(s);
|
||||
|
||||
adj->subsubtlvs = isis_alloc_subsubtlvs(
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID);
|
||||
|
||||
bool unpacked_known_tlvs = false;
|
||||
if (unpack_tlvs(
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID,
|
||||
subsubtlv_len, s, log,
|
||||
adj->subsubtlvs, indent + 4,
|
||||
&unpacked_known_tlvs)) {
|
||||
XFREE(MTYPE_ISIS_SUBTLV, adj);
|
||||
break;
|
||||
}
|
||||
if (!unpacked_known_tlvs) {
|
||||
isis_free_subsubtlvs(adj->subsubtlvs);
|
||||
adj->subsubtlvs = NULL;
|
||||
}
|
||||
|
||||
append_item(&exts->srv6_endx_sid,
|
||||
(struct isis_item *)adj);
|
||||
SET_SUBTLV(exts, EXT_SRV6_ENDX_SID);
|
||||
}
|
||||
break;
|
||||
/* SRv6 LAN End.X SID as per RFC9352 section #8.2 */
|
||||
case ISIS_SUBTLV_SRV6_LAN_ENDX_SID:
|
||||
if (subtlv_len < ISIS_SUBTLV_SRV6_LAN_ENDX_SID_SIZE) {
|
||||
TLV_SIZE_MISMATCH(log, indent,
|
||||
"SRv6 LAN End.X SID");
|
||||
stream_forward_getp(s, subtlv_len);
|
||||
} else {
|
||||
struct isis_srv6_lan_endx_sid_subtlv *lan;
|
||||
|
||||
lan = XCALLOC(
|
||||
MTYPE_ISIS_SUBTLV,
|
||||
sizeof(struct
|
||||
isis_srv6_lan_endx_sid_subtlv));
|
||||
stream_get(&(lan->neighbor_id), s,
|
||||
ISIS_SYS_ID_LEN);
|
||||
lan->flags = stream_getc(s);
|
||||
lan->algorithm = stream_getc(s);
|
||||
lan->weight = stream_getc(s);
|
||||
lan->behavior = stream_getw(s);
|
||||
stream_get(&lan->sid, s, IPV6_MAX_BYTELEN);
|
||||
subsubtlv_len = stream_getc(s);
|
||||
|
||||
lan->subsubtlvs = isis_alloc_subsubtlvs(
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID);
|
||||
|
||||
bool unpacked_known_tlvs = false;
|
||||
if (unpack_tlvs(
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID,
|
||||
subsubtlv_len, s, log,
|
||||
lan->subsubtlvs, indent + 4,
|
||||
&unpacked_known_tlvs)) {
|
||||
XFREE(MTYPE_ISIS_SUBTLV, lan);
|
||||
break;
|
||||
}
|
||||
if (!unpacked_known_tlvs) {
|
||||
isis_free_subsubtlvs(lan->subsubtlvs);
|
||||
lan->subsubtlvs = NULL;
|
||||
}
|
||||
|
||||
append_item(&exts->srv6_lan_endx_sid,
|
||||
(struct isis_item *)lan);
|
||||
SET_SUBTLV(exts, EXT_SRV6_LAN_ENDX_SID);
|
||||
}
|
||||
break;
|
||||
case ISIS_SUBTLV_ASLA:
|
||||
if (unpack_item_ext_subtlv_asla(mtid, subtlv_len, s,
|
||||
log, indent,
|
||||
@ -7147,6 +7238,12 @@ static const struct tlv_ops *const tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
|
||||
},
|
||||
[ISIS_CONTEXT_SUBSUBTLV_SRV6_END_SID] = {
|
||||
[ISIS_SUBSUBTLV_SRV6_SID_STRUCTURE] = &subsubtlv_srv6_sid_structure_ops,
|
||||
},
|
||||
[ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID] = {
|
||||
[ISIS_SUBSUBTLV_SRV6_SID_STRUCTURE] = &subsubtlv_srv6_sid_structure_ops,
|
||||
},
|
||||
[ISIS_CONTEXT_SUBSUBTLV_SRV6_LAN_ENDX_SID] = {
|
||||
[ISIS_SUBSUBTLV_SRV6_SID_STRUCTURE] = &subsubtlv_srv6_sid_structure_ops,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -423,6 +423,8 @@ enum isis_tlv_context {
|
||||
ISIS_CONTEXT_SUBTLV_IPV6_REACH,
|
||||
ISIS_CONTEXT_SUBTLV_SRV6_LOCATOR,
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_END_SID,
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_ENDX_SID,
|
||||
ISIS_CONTEXT_SUBSUBTLV_SRV6_LAN_ENDX_SID,
|
||||
ISIS_CONTEXT_MAX,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user