@@ -120,6 +120,10 @@ static void isis_format_subsubtlvs(struct isis_subsubtlvs *subsubtlvs,
120
120
int indent );
121
121
static int isis_pack_subsubtlvs (struct isis_subsubtlvs * subsubtlvs ,
122
122
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 );
123
127
124
128
/* For tests/isisd, TLV text requires ipv4-unicast instead of standard */
125
129
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,
1656
1660
uint8_t sum = 0 ;
1657
1661
uint8_t subtlv_type ;
1658
1662
uint8_t subtlv_len ;
1663
+ uint8_t subsubtlv_len ;
1659
1664
size_t nb_groups ;
1660
1665
uint32_t val ;
1661
1666
@@ -1994,6 +1999,92 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s,
1994
1999
SET_SUBTLV (exts , EXT_LAN_ADJ_SID );
1995
2000
}
1996
2001
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 ;
1997
2088
case ISIS_SUBTLV_ASLA :
1998
2089
if (unpack_item_ext_subtlv_asla (mtid , subtlv_len , s ,
1999
2090
log , indent ,
@@ -7147,6 +7238,12 @@ static const struct tlv_ops *const tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
7147
7238
},
7148
7239
[ISIS_CONTEXT_SUBSUBTLV_SRV6_END_SID ] = {
7149
7240
[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 ,
7150
7247
}
7151
7248
};
7152
7249
0 commit comments