isisd: add isis flex-algo lsp advertisement

Deal with the packing and unpacking of following Flex-Algo
Sub-Sub-TLVs:

- Router Capability (already defined TLV 242)
	- List of the Flex-Algo Definitions (Sub-TLV 26)
		- Exclude admin group (Sub-Sub-TLV 1)
                - Include-any admin group (Sub-Sub-TLV 2)
                - Include-all admin group (Sub-Sub-TLV 3)
                - Flags (for prefix-metric) (Sub-Sub-TLV 4)

This commit splits data into multiple router capability TLVs if needed
because a TLV cannot contains more than 255 bytes.

Note that the list of SR Algorithm (Sub-TLV 19) within Router Capability
(TLV 242) is already set in a previous commit.

Signed-off-by: Hiroki Shirokura <hiroki.shirokura@linecorp.com>
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Hiroki Shirokura 2022-01-04 01:31:45 +00:00 committed by Louis Scalbert
parent 5749ac83a8
commit 78774bbcd5
4 changed files with 526 additions and 70 deletions

View File

@ -46,6 +46,7 @@
#include "isisd/fabricd.h"
#include "isisd/isis_tx_queue.h"
#include "isisd/isis_nb.h"
#include "isisd/isis_flex_algo.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_LSP, "ISIS LSP");
@ -898,9 +899,15 @@ static void lsp_build_internal_reach_ipv4(struct isis_lsp *lsp,
area->area_tag, ipv4);
if (area->srdb.enabled)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
#ifndef FABRICD
if (flex_algo_id_valid(i) &&
!isis_flex_algo_elected_supported(i, area))
continue;
#endif /* ifndef FABRICD */
pcfgs[i] =
isis_sr_cfg_prefix_find(area, ipv4, i);
}
isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4, metric, false,
pcfgs);
@ -918,8 +925,14 @@ static void lsp_build_internal_reach_ipv6(struct isis_lsp *lsp,
area->area_tag, ipv6);
if (area->srdb.enabled)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
#ifndef FABRICD
if (flex_algo_id_valid(i) &&
!isis_flex_algo_elected_supported(i, area))
continue;
#endif /* ifndef FABRICD */
pcfgs[i] = isis_sr_cfg_prefix_find(area, ipv6, i);
}
isis_tlvs_add_ipv6_reach(lsp->tlvs, isis_area_ipv6_topology(area), ipv6,
metric, false, pcfgs);
@ -955,9 +968,16 @@ static void lsp_build_ext_reach_ipv4(struct isis_lsp *lsp,
NULL};
if (area->srdb.enabled)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
#ifndef FABRICD
if (flex_algo_id_valid(i) &&
!isis_flex_algo_elected_supported(
i, area))
continue;
#endif /* ifndef FABRICD */
pcfgs[i] = isis_sr_cfg_prefix_find(
area, ipv4, i);
}
isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4, metric,
true, pcfgs);
@ -992,9 +1012,16 @@ static void lsp_build_ext_reach_ipv6(struct isis_lsp *lsp,
NULL};
if (area->srdb.enabled)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
#ifndef FABRICD
if (flex_algo_id_valid(i) &&
!isis_flex_algo_elected_supported(
i, area))
continue;
#endif /* ifndef FABRICD */
pcfgs[i] = isis_sr_cfg_prefix_find(
area, p, i);
}
isis_tlvs_add_ipv6_reach(lsp->tlvs,
isis_area_ipv6_topology(area),
@ -1115,13 +1142,30 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
/* Add Router Capability TLV. */
if (area->isis->router_id != 0) {
struct isis_router_cap cap = {};
struct isis_router_cap *rcap;
#ifndef FABRICD
struct isis_router_cap_fad *rcap_fad;
struct listnode *node;
struct flex_algo *fa;
#endif /* ifndef FABRICD */
/* init SR algo list content to the default value */
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
cap.algo[i] = SR_ALGORITHM_UNSET;
rcap = isis_tlvs_init_router_capability(lsp->tlvs);
cap.router_id.s_addr = area->isis->router_id;
rcap->router_id.s_addr = area->isis->router_id;
#ifndef FABRICD
/* Set flex-algo definitions */
for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos, node,
fa)) {
if (!fa->advertise_definition)
continue;
lsp_debug("ISIS (%s): Flex-Algo Definition %u",
area->area_tag, fa->algorithm);
isis_tlvs_set_router_capability_fad(lsp->tlvs, fa,
fa->algorithm,
area->isis->sysid);
}
#endif /* ifndef FABRICD */
/* Add SR Sub-TLVs if SR is enabled. */
if (area->srdb.enabled) {
@ -1131,26 +1175,38 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
/* SRGB first */
range_size = srdb->config.srgb_upper_bound
- srdb->config.srgb_lower_bound + 1;
cap.srgb.flags = ISIS_SUBTLV_SRGB_FLAG_I
| ISIS_SUBTLV_SRGB_FLAG_V;
cap.srgb.range_size = range_size;
cap.srgb.lower_bound = srdb->config.srgb_lower_bound;
rcap->srgb.flags = ISIS_SUBTLV_SRGB_FLAG_I |
ISIS_SUBTLV_SRGB_FLAG_V;
rcap->srgb.range_size = range_size;
rcap->srgb.lower_bound = srdb->config.srgb_lower_bound;
/* Then Algorithm */
cap.algo[0] = SR_ALGORITHM_SPF;
cap.algo[1] = SR_ALGORITHM_UNSET;
rcap->algo[0] = SR_ALGORITHM_SPF;
rcap->algo[1] = SR_ALGORITHM_UNSET;
#ifndef FABRICD
for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos,
node, fa)) {
if (fa->advertise_definition)
rcap_fad = rcap->fads[fa->algorithm];
else
rcap_fad = NULL;
if (!isis_flex_algo_elected_supported_local_fad(
fa->algorithm, area, &rcap_fad))
continue;
lsp_debug("ISIS (%s): SR Algorithm %u",
area->area_tag, fa->algorithm);
rcap->algo[fa->algorithm] = fa->algorithm;
}
#endif /* ifndef FABRICD */
/* SRLB */
cap.srlb.flags = 0;
rcap->srlb.flags = 0;
range_size = srdb->config.srlb_upper_bound
- srdb->config.srlb_lower_bound + 1;
cap.srlb.range_size = range_size;
cap.srlb.lower_bound = srdb->config.srlb_lower_bound;
rcap->srlb.range_size = range_size;
rcap->srlb.lower_bound = srdb->config.srlb_lower_bound;
/* And finally MSD */
cap.msd = srdb->config.msd;
rcap->msd = srdb->config.msd;
}
isis_tlvs_set_router_capability(lsp->tlvs, &cap);
lsp_debug("ISIS (%s): Adding Router Capabilities information",
area->area_tag);
}
/* IPv4 address and TE router ID TLVs.

View File

@ -29,6 +29,7 @@
#include "isisd/isis_lsp.h"
#include "isisd/isis_te.h"
#include "isisd/isis_sr.h"
#include "isisd/isis_flex_algo.h"
#define TLV_SIZE_MISMATCH(log, indent, target) \
sbuf_push(log, indent, \
@ -36,6 +37,7 @@
DEFINE_MTYPE_STATIC(ISISD, ISIS_TLV, "ISIS TLVs");
DEFINE_MTYPE(ISISD, ISIS_SUBTLV, "ISIS Sub-TLVs");
DEFINE_MTYPE_STATIC(ISISD, ISIS_SUBSUBTLV, "ISIS Sub-Sub-TLVs");
DEFINE_MTYPE_STATIC(ISISD, ISIS_MT_ITEM_LIST, "ISIS MT Item Lists");
typedef int (*unpack_tlv_func)(enum isis_tlv_context context, uint8_t tlv_type,
@ -381,7 +383,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
exts->adm_group);
json_object_string_add(json, "adm-group", aux_buf);
} else {
sbuf_push(buf, indent, "Administrative Group: 0x%x\n",
sbuf_push(buf, indent, "Admin Group: 0x%08x\n",
exts->adm_group);
sbuf_push(buf, indent + 2, "Bit positions: %s\n",
admin_group_standard_print(
@ -3912,6 +3914,39 @@ static struct isis_router_cap *copy_tlv_router_cap(
memcpy(rv, router_cap, sizeof(*rv));
#ifndef FABRICD
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
struct isis_router_cap_fad *sc_fad;
struct isis_router_cap_fad *rv_fad;
sc_fad = router_cap->fads[i];
if (!sc_fad)
continue;
rv_fad = XMALLOC(MTYPE_ISIS_TLV,
sizeof(struct isis_router_cap_fad));
*rv_fad = *sc_fad;
rv_fad->fad.admin_group_exclude_any.bitmap.data = NULL;
rv_fad->fad.admin_group_include_any.bitmap.data = NULL;
rv_fad->fad.admin_group_include_all.bitmap.data = NULL;
assert(bf_is_inited(
sc_fad->fad.admin_group_exclude_any.bitmap));
assert(bf_is_inited(
sc_fad->fad.admin_group_include_any.bitmap));
assert(bf_is_inited(
sc_fad->fad.admin_group_include_all.bitmap));
admin_group_copy(&rv_fad->fad.admin_group_exclude_any,
&sc_fad->fad.admin_group_exclude_any);
admin_group_copy(&rv_fad->fad.admin_group_include_any,
&sc_fad->fad.admin_group_include_any);
admin_group_copy(&rv_fad->fad.admin_group_include_all,
&sc_fad->fad.admin_group_include_all);
rv->fads[i] = rv_fad;
}
#endif /* ifndef FABRICD */
return rv;
}
@ -4031,37 +4066,178 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap,
if (router_cap->msd != 0)
sbuf_push(buf, indent, " Node Maximum SID Depth: %u\n",
router_cap->msd);
#ifndef FABRICD
/* Flex-Algo */
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
char admin_group_buf[ADMIN_GROUP_PRINT_MAX_SIZE];
int indent2;
struct admin_group *admin_group;
struct isis_router_cap_fad *fad;
fad = router_cap->fads[i];
if (!fad)
continue;
sbuf_push(buf, indent, " Flex-Algo Definition: %d\n",
fad->fad.algorithm);
sbuf_push(buf, indent, " Metric-Type: %d\n",
fad->fad.metric_type);
sbuf_push(buf, indent, " Calc-Type: %d\n",
fad->fad.calc_type);
sbuf_push(buf, indent, " Priority: %d\n", fad->fad.priority);
indent2 = indent + strlen(" Exclude-Any: ");
admin_group = &fad->fad.admin_group_exclude_any;
sbuf_push(buf, indent, " Exclude-Any: ");
sbuf_push(buf, 0, "%s\n",
admin_group_string(admin_group_buf,
ADMIN_GROUP_PRINT_MAX_SIZE,
indent2, admin_group));
indent2 = indent + strlen(" Include-Any: ");
admin_group = &fad->fad.admin_group_include_any;
sbuf_push(buf, indent, " Include-Any: ");
sbuf_push(buf, 0, "%s\n",
admin_group_string(admin_group_buf,
ADMIN_GROUP_PRINT_MAX_SIZE,
indent2, admin_group));
indent2 = indent + strlen(" Include-All: ");
admin_group = &fad->fad.admin_group_include_all;
sbuf_push(buf, indent, " Include-All: ");
sbuf_push(buf, 0, "%s\n",
admin_group_string(admin_group_buf,
ADMIN_GROUP_PRINT_MAX_SIZE,
indent2, admin_group));
sbuf_push(buf, indent, " M-Flag: %c\n",
CHECK_FLAG(fad->fad.flags, FAD_FLAG_M) ? '1' : '0');
if (fad->fad.flags != 0 && fad->fad.flags != FAD_FLAG_M)
sbuf_push(buf, indent, " Flags: 0x%x\n",
fad->fad.flags);
if (fad->fad.exclude_srlg)
sbuf_push(buf, indent, " Exclude SRLG: Enabled\n");
if (fad->fad.unsupported_subtlv)
sbuf_push(buf, indent,
" Got an unsupported sub-TLV: Yes\n");
}
#endif /* ifndef FABRICD */
}
static void free_tlv_router_cap(struct isis_router_cap *router_cap)
{
if (!router_cap)
return;
#ifndef FABRICD
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
struct isis_router_cap_fad *fad;
fad = router_cap->fads[i];
if (!fad)
continue;
admin_group_term(&fad->fad.admin_group_exclude_any);
admin_group_term(&fad->fad.admin_group_include_any);
admin_group_term(&fad->fad.admin_group_include_all);
XFREE(MTYPE_ISIS_TLV, fad);
}
#endif /* ifndef FABRICD */
XFREE(MTYPE_ISIS_TLV, router_cap);
}
#ifndef FABRICD
static size_t
isis_router_cap_fad_sub_tlv_len(const struct isis_router_cap_fad *fad)
{
size_t sz = ISIS_SUBTLV_FAD_MIN_SIZE;
uint32_t admin_group_length;
admin_group_length =
admin_group_nb_words(&fad->fad.admin_group_exclude_any);
if (admin_group_length)
sz += sizeof(uint32_t) * admin_group_length + 2;
admin_group_length =
admin_group_nb_words(&fad->fad.admin_group_include_any);
if (admin_group_length)
sz += sizeof(uint32_t) * admin_group_length + 2;
admin_group_length =
admin_group_nb_words(&fad->fad.admin_group_include_all);
if (admin_group_length)
sz += sizeof(uint32_t) * admin_group_length + 2;
if (fad->fad.flags != 0)
sz += ISIS_SUBTLV_FAD_SUBSUBTLV_FLAGS_SIZE + 2;
/* TODO: add exclude SRLG sub-sub-TLV length when supported */
return sz;
}
#endif /* ifndef FABRICD */
static size_t isis_router_cap_tlv_size(const struct isis_router_cap *router_cap)
{
size_t sz = 2 + ISIS_ROUTER_CAP_SIZE;
#ifndef FABRICD
size_t fad_sz;
#endif /* ifndef FABRICD */
int nb_algo;
if ((router_cap->srgb.range_size != 0) &&
(router_cap->srgb.lower_bound != 0)) {
sz += 2 + ISIS_SUBTLV_SID_LABEL_RANGE_SIZE;
sz += 2 + ISIS_SUBTLV_SID_LABEL_SIZE;
nb_algo = isis_tlvs_sr_algo_count(router_cap);
if (nb_algo != 0)
sz += 2 + nb_algo;
if ((router_cap->srlb.range_size != 0) &&
(router_cap->srlb.lower_bound != 0)) {
sz += 2 + ISIS_SUBTLV_SID_LABEL_RANGE_SIZE;
sz += 2 + ISIS_SUBTLV_SID_LABEL_SIZE;
}
if (router_cap->msd != 0)
sz += 2 + ISIS_SUBTLV_NODE_MSD_SIZE;
}
#ifndef FABRICD
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
if (!router_cap->fads[i])
continue;
fad_sz = 2 +
isis_router_cap_fad_sub_tlv_len(router_cap->fads[i]);
if (((sz + fad_sz) % 256) < (sz % 256))
sz += 2 + ISIS_ROUTER_CAP_SIZE + fad_sz;
else
sz += fad_sz;
}
#endif /* ifndef FABRICD */
return sz;
}
static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
struct stream *s)
{
size_t tlv_len = ISIS_ROUTER_CAP_SIZE;
size_t len_pos;
size_t tlv_len, len_pos;
uint8_t nb_algo;
if (!router_cap)
return 0;
/* Compute Maximum TLV size */
tlv_len += ISIS_SUBTLV_SID_LABEL_RANGE_SIZE
+ ISIS_SUBTLV_HDR_SIZE
+ ISIS_SUBTLV_ALGORITHM_SIZE
+ ISIS_SUBTLV_NODE_MSD_SIZE;
if (STREAM_WRITEABLE(s) < (unsigned int)(2 + tlv_len))
if (STREAM_WRITEABLE(s) < isis_router_cap_tlv_size(router_cap))
return 1;
/* Add Router Capability TLV 242 with Router ID and Flags */
stream_putc(s, ISIS_TLV_ROUTER_CAPABILITY);
/* Real length will be adjusted later */
len_pos = stream_get_endp(s);
stream_putc(s, tlv_len);
stream_putc(s, 0); /* Real length will be adjusted later */
stream_put_ipv4(s, router_cap->router_id.s_addr);
stream_putc(s, router_cap->flags);
@ -4108,6 +4284,80 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
}
}
#ifndef FABRICD
/* Flex Algo Definitions */
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
struct isis_router_cap_fad *fad;
size_t subtlv_len;
struct admin_group *ag;
uint32_t admin_group_length;
fad = router_cap->fads[i];
if (!fad)
continue;
subtlv_len = isis_router_cap_fad_sub_tlv_len(fad);
if ((stream_get_endp(s) - len_pos - 1) > 250) {
/* Adjust TLV length which depends on subTLVs presence
*/
tlv_len = stream_get_endp(s) - len_pos - 1;
stream_putc_at(s, len_pos, tlv_len);
/* Add Router Capability TLV 242 with Router ID and
* Flags
*/
stream_putc(s, ISIS_TLV_ROUTER_CAPABILITY);
/* Real length will be adjusted later */
len_pos = stream_get_endp(s);
stream_putc(s, 0);
stream_put_ipv4(s, router_cap->router_id.s_addr);
stream_putc(s, router_cap->flags);
}
stream_putc(s, ISIS_SUBTLV_FAD);
stream_putc(s, subtlv_len); /* length will be filled later */
stream_putc(s, fad->fad.algorithm);
stream_putc(s, fad->fad.metric_type);
stream_putc(s, fad->fad.calc_type);
stream_putc(s, fad->fad.priority);
ag = &fad->fad.admin_group_exclude_any;
admin_group_length = admin_group_nb_words(ag);
if (admin_group_length) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_EXCAG);
stream_putc(s, sizeof(uint32_t) * admin_group_length);
for (size_t i = 0; i < admin_group_length; i++)
stream_putl(s, admin_group_get_offset(ag, i));
}
ag = &fad->fad.admin_group_include_any;
admin_group_length = admin_group_nb_words(ag);
if (admin_group_length) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_INCANYAG);
stream_putc(s, sizeof(uint32_t) * admin_group_length);
for (size_t i = 0; i < admin_group_length; i++)
stream_putl(s, admin_group_get_offset(ag, i));
}
ag = &fad->fad.admin_group_include_all;
admin_group_length = admin_group_nb_words(ag);
if (admin_group_length) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_INCALLAG);
stream_putc(s, sizeof(uint32_t) * admin_group_length);
for (size_t i = 0; i < admin_group_length; i++)
stream_putl(s, admin_group_get_offset(ag, i));
}
if (fad->fad.flags != 0) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_FLAGS);
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_FLAGS_SIZE);
stream_putc(s, fad->fad.flags);
}
}
#endif /* ifndef FABRICD */
/* Adjust TLV length which depends on subTLVs presence */
tlv_len = stream_get_endp(s) - len_pos - 1;
stream_putc_at(s, len_pos, tlv_len);
@ -4134,17 +4384,15 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
return 0;
}
if (tlvs->router_cap) {
sbuf_push(log, indent,
"WARNING: Router Capability TLV present multiple times.\n");
stream_forward_getp(s, tlv_len);
return 0;
}
if (tlvs->router_cap)
/* Multiple Router Capability found */
rcap = tlvs->router_cap;
else {
/* Allocate router cap structure and initialize SR Algorithms */
rcap = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct isis_router_cap));
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
rcap->algo[i] = SR_ALGORITHM_UNSET;
}
/* Get Router ID and Flags */
rcap->router_id.s_addr = stream_get_ipv4(s);
@ -4153,6 +4401,10 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
/* Parse remaining part of the TLV if present */
subtlv_len = tlv_len - ISIS_ROUTER_CAP_SIZE;
while (subtlv_len > 2) {
#ifndef FABRICD
struct isis_router_cap_fad *fad;
uint8_t subsubtlvs_len;
#endif /* ifndef FABRICD */
uint8_t msd_type;
type = stream_getc(s);
@ -4306,6 +4558,80 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
if (length > MSD_TLV_SIZE)
stream_forward_getp(s, length - MSD_TLV_SIZE);
break;
#ifndef FABRICD
case ISIS_SUBTLV_FAD:
fad = XCALLOC(MTYPE_ISIS_TLV,
sizeof(struct isis_router_cap_fad));
fad->fad.algorithm = stream_getc(s);
fad->fad.metric_type = stream_getc(s);
fad->fad.calc_type = stream_getc(s);
fad->fad.priority = stream_getc(s);
rcap->fads[fad->fad.algorithm] = fad;
admin_group_init(&fad->fad.admin_group_exclude_any);
admin_group_init(&fad->fad.admin_group_include_any);
admin_group_init(&fad->fad.admin_group_include_all);
subsubtlvs_len = length - 4;
while (subsubtlvs_len > 2) {
struct admin_group *ag;
uint8_t subsubtlv_type;
uint8_t subsubtlv_len;
uint32_t v;
int n_ag, i;
subsubtlv_type = stream_getc(s);
subsubtlv_len = stream_getc(s);
switch (subsubtlv_type) {
case ISIS_SUBTLV_FAD_SUBSUBTLV_EXCAG:
ag = &fad->fad.admin_group_exclude_any;
n_ag = subsubtlv_len / sizeof(uint32_t);
for (i = 0; i < n_ag; i++) {
v = stream_getl(s);
admin_group_bulk_set(ag, v, i);
}
break;
case ISIS_SUBTLV_FAD_SUBSUBTLV_INCANYAG:
ag = &fad->fad.admin_group_include_any;
n_ag = subsubtlv_len / sizeof(uint32_t);
for (i = 0; i < n_ag; i++) {
v = stream_getl(s);
admin_group_bulk_set(ag, v, i);
}
break;
case ISIS_SUBTLV_FAD_SUBSUBTLV_INCALLAG:
ag = &fad->fad.admin_group_include_all;
n_ag = subsubtlv_len / sizeof(uint32_t);
for (i = 0; i < n_ag; i++) {
v = stream_getl(s);
admin_group_bulk_set(ag, v, i);
}
break;
case ISIS_SUBTLV_FAD_SUBSUBTLV_FLAGS:
if (subsubtlv_len == 0)
break;
fad->fad.flags = stream_getc(s);
for (i = subsubtlv_len - 1; i > 0; --i)
stream_getc(s);
break;
case ISIS_SUBTLV_FAD_SUBSUBTLV_ESRLG:
fad->fad.exclude_srlg = true;
stream_forward_getp(s, subsubtlv_len);
break;
default:
sbuf_push(
log, indent,
"Received an unsupported Flex-Algo sub-TLV type %u\n",
subsubtlv_type);
fad->fad.unsupported_subtlv = true;
stream_forward_getp(s, subsubtlv_len);
break;
}
subsubtlvs_len -= 2 + subsubtlv_len;
}
break;
#endif /* ifndef FABRICD */
default:
stream_forward_getp(s, length);
break;
@ -6253,18 +6579,53 @@ void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs,
tlvs->hostname = XSTRDUP(MTYPE_ISIS_TLV, hostname);
}
/* Set Router Capability TLV parameters */
void isis_tlvs_set_router_capability(struct isis_tlvs *tlvs,
const struct isis_router_cap *cap)
/* Init Router Capability TLV parameters */
struct isis_router_cap *isis_tlvs_init_router_capability(struct isis_tlvs *tlvs)
{
XFREE(MTYPE_ISIS_TLV, tlvs->router_cap);
if (!cap)
return;
tlvs->router_cap = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->router_cap));
*tlvs->router_cap = *cap;
/* init SR algo list content to the default value */
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
tlvs->router_cap->algo[i] = SR_ALGORITHM_UNSET;
return tlvs->router_cap;
}
#ifndef FABRICD
void isis_tlvs_set_router_capability_fad(struct isis_tlvs *tlvs,
struct flex_algo *fa, int algorithm,
uint8_t *sysid)
{
struct isis_router_cap_fad *rcap_fad;
assert(tlvs->router_cap);
rcap_fad = tlvs->router_cap->fads[algorithm];
if (!rcap_fad)
rcap_fad = XCALLOC(MTYPE_ISIS_TLV,
sizeof(struct isis_router_cap_fad));
memset(rcap_fad->sysid, 0, ISIS_SYS_ID_LEN + 2);
memcpy(rcap_fad->sysid, sysid, ISIS_SYS_ID_LEN);
memcpy(&rcap_fad->fad, fa, sizeof(struct flex_algo));
rcap_fad->fad.admin_group_exclude_any.bitmap.data = NULL;
rcap_fad->fad.admin_group_include_any.bitmap.data = NULL;
rcap_fad->fad.admin_group_include_all.bitmap.data = NULL;
admin_group_copy(&rcap_fad->fad.admin_group_exclude_any,
&fa->admin_group_exclude_any);
admin_group_copy(&rcap_fad->fad.admin_group_include_any,
&fa->admin_group_include_any);
admin_group_copy(&rcap_fad->fad.admin_group_include_all,
&fa->admin_group_include_all);
tlvs->router_cap->fads[algorithm] = rcap_fad;
}
#endif /* ifndef FABRICD */
int isis_tlvs_sr_algo_count(const struct isis_router_cap *cap)
{
int count = 0;

View File

@ -13,6 +13,8 @@
#include "openbsd-tree.h"
#include "prefix.h"
#include "flex_algo.h"
#include "affinitymap.h"
DECLARE_MTYPE(ISIS_SUBTLV);
@ -400,10 +402,22 @@ enum isis_tlv_type {
ISIS_SUBTLV_AVA_BW = 38,
ISIS_SUBTLV_USE_BW = 39,
/* RFC 7308 */
ISIS_SUBTLV_EXT_ADMIN_GRP = 14,
/* RFC 8919 */
ISIS_SUBTLV_ASLA = 16,
/* draft-ietf-lsr-isis-srv6-extensions */
ISIS_SUBTLV_SID_END = 5,
ISIS_SUBTLV_SID_END_X = 43,
ISIS_SUBTLV_MAX = 40,
/* draft-ietf-lsr-isis-srv6-extensions */
ISIS_SUBSUBTLV_SID_STRUCTURE = 1,
ISIS_SUBSUBTLV_MAX = 256,
};
/* subTLVs size for TE and SR */
@ -431,15 +445,31 @@ enum ext_subtlv_size {
/* RFC 7810 */
ISIS_SUBTLV_MM_DELAY_SIZE = 8,
/* RFC9350 - Flex-Algorithm */
ISIS_SUBTLV_FAD = 26,
ISIS_SUBTLV_FAD_MIN_SIZE = 4,
ISIS_SUBTLV_HDR_SIZE = 2,
ISIS_SUBTLV_DEF_SIZE = 4,
/* RFC 7308 */
ISIS_SUBTLV_EXT_ADMIN_GRP = 14,
ISIS_SUBTLV_MAX_SIZE = 180,
/* draft-ietf-lsr-isis-srv6-extensions */
ISIS_SUBSUBTLV_SID_STRUCTURE_SIZE = 4,
ISIS_SUBSUBTLV_HDR_SIZE = 2,
ISIS_SUBSUBTLV_MAX_SIZE = 180,
ISIS_SUBTLV_MAX_SIZE = 180,
/* RFC9350 - Flex-Algorithm */
ISIS_SUBTLV_FAD_SUBSUBTLV_FLAGS_SIZE = 1,
};
enum ext_subsubtlv_types {
ISIS_SUBTLV_FAD_SUBSUBTLV_EXCAG = 1,
ISIS_SUBTLV_FAD_SUBSUBTLV_INCANYAG = 2,
ISIS_SUBTLV_FAD_SUBSUBTLV_INCALLAG = 3,
ISIS_SUBTLV_FAD_SUBSUBTLV_FLAGS = 4,
ISIS_SUBTLV_FAD_SUBSUBTLV_ESRLG = 5,
};
/* Macros to manage the optional presence of EXT subTLVs */
@ -625,8 +655,16 @@ void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
struct isis_lsp **last_lsp);
void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs,
const char *hostname);
void isis_tlvs_set_router_capability(struct isis_tlvs *tlvs,
const struct isis_router_cap *cap);
struct isis_router_cap *
isis_tlvs_init_router_capability(struct isis_tlvs *tlvs);
struct isis_area;
struct isis_flex_algo;
void isis_tlvs_set_router_capability_fad(struct isis_tlvs *tlvs,
struct flex_algo *fa, int algorithm,
uint8_t *sysid);
struct isis_area;
int isis_tlvs_sr_algo_count(const struct isis_router_cap *cap);

View File

@ -163,31 +163,32 @@ static void lsp_add_reach(struct isis_lsp *lsp,
static void lsp_add_router_capability(struct isis_lsp *lsp,
const struct isis_test_node *tnode)
{
struct isis_router_cap cap = {};
struct isis_router_cap *cap;
if (!tnode->router_id)
return;
if (inet_pton(AF_INET, tnode->router_id, &cap.router_id) != 1) {
cap = isis_tlvs_init_router_capability(lsp->tlvs);
if (inet_pton(AF_INET, tnode->router_id, &cap->router_id) != 1) {
zlog_debug("%s: invalid router-id: %s", __func__,
tnode->router_id);
return;
}
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
cap.srgb.flags =
cap->srgb.flags =
ISIS_SUBTLV_SRGB_FLAG_I | ISIS_SUBTLV_SRGB_FLAG_V;
cap.srgb.lower_bound = tnode->srgb.lower_bound
cap->srgb.lower_bound = tnode->srgb.lower_bound
? tnode->srgb.lower_bound
: SRGB_DFTL_LOWER_BOUND;
cap.srgb.range_size = tnode->srgb.range_size
cap->srgb.range_size = tnode->srgb.range_size
? tnode->srgb.range_size
: SRGB_DFTL_RANGE_SIZE;
cap.algo[0] = SR_ALGORITHM_SPF;
cap.algo[1] = SR_ALGORITHM_UNSET;
cap->algo[0] = SR_ALGORITHM_SPF;
cap->algo[1] = SR_ALGORITHM_UNSET;
}
isis_tlvs_set_router_capability(lsp->tlvs, &cap);
}
static void lsp_add_mt_router_info(struct isis_lsp *lsp,