isisd: update isis_tlvs_add_*_reach() with multi algorithm

isis_tlvs_add_extended_ip_reach adds IS-IS Extended
IP reachability to the LSP. In this case, if the
pcfg argument is not NULL, you can add IGP
Prefix-SID as its sub tlv.

Before this commit, only one Prefix-SID can be added.
After this commit, the argument is not a single
pointer but an array of pointers, and multiple
Prefix-SIDs can be added.

This feature is necessary because Flex-Algo
requires multiple Prefix-SIDs for each Algorithm.

Signed-off-by: Hiroki Shirokura <hiroki.shirokura@linecorp.com>
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Hiroki Shirokura 2021-12-11 06:22:42 +00:00 committed by Louis Scalbert
parent e7948f8ce6
commit 0de7b43308
4 changed files with 67 additions and 34 deletions

View File

@ -904,14 +904,16 @@ static void lsp_build_ext_reach_ipv4(struct isis_lsp *lsp,
isis_tlvs_add_oldstyle_ip_reach(lsp->tlvs, ipv4,
metric);
if (area->newmetric) {
struct sr_prefix_cfg *pcfg = NULL;
struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {
NULL};
if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find(
area, ipv4, SR_ALGORITHM_SPF);
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
pcfgs[i] = isis_sr_cfg_prefix_find(
area, ipv4, i);
isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4, metric,
true, pcfg);
true, pcfgs);
}
}
}
@ -939,15 +941,17 @@ static void lsp_build_ext_reach_ipv6(struct isis_lsp *lsp,
metric = MAX_WIDE_PATH_METRIC;
if (!src_p || !src_p->prefixlen) {
struct sr_prefix_cfg *pcfg = NULL;
struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {
NULL};
if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find(
area, p, SR_ALGORITHM_SPF);
for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
pcfgs[i] = isis_sr_cfg_prefix_find(
area, p, i);
isis_tlvs_add_ipv6_reach(lsp->tlvs,
isis_area_ipv6_topology(area),
p, metric, true, pcfg);
p, metric, true, pcfgs);
} else if (isis_area_ipv6_dstsrc_enabled(area)) {
isis_tlvs_add_ipv6_dstsrc_reach(lsp->tlvs,
ISIS_MT_IPV6_DSTSRC,
@ -1199,20 +1203,27 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
}
if (area->newmetric) {
struct sr_prefix_cfg *pcfg = NULL;
struct sr_prefix_cfg
*pcfgs[SR_ALGORITHM_COUNT] = {
NULL};
lsp_debug(
"ISIS (%s): Adding te-style IP reachability for %pFX",
area->area_tag, ipv4);
if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find(
area, ipv4,
SR_ALGORITHM_SPF);
for (int i = 0;
i < SR_ALGORITHM_COUNT;
i++)
pcfgs[i] =
isis_sr_cfg_prefix_find(
area,
ipv4,
i);
isis_tlvs_add_extended_ip_reach(
lsp->tlvs, ipv4, metric, false,
pcfg);
pcfgs);
}
}
}
@ -1223,20 +1234,24 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link,
ipnode, ipv6)) {
struct sr_prefix_cfg *pcfg = NULL;
struct sr_prefix_cfg
*pcfgs[SR_ALGORITHM_COUNT] = {NULL};
lsp_debug(
"ISIS (%s): Adding IPv6 reachability for %pFX",
area->area_tag, ipv6);
if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find(area,
ipv6, 0);
for (int i = 0; i < SR_ALGORITHM_COUNT;
i++)
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, pcfg);
metric, false, pcfgs);
}
}

View File

@ -5873,40 +5873,57 @@ void isis_tlvs_del_lan_adj_sid(struct isis_ext_subtlvs *exts,
void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs,
struct prefix_ipv4 *dest, uint32_t metric,
bool external, struct sr_prefix_cfg *pcfg)
bool external,
struct sr_prefix_cfg **pcfgs)
{
struct isis_extended_ip_reach *r = XCALLOC(MTYPE_ISIS_TLV, sizeof(*r));
r->metric = metric;
memcpy(&r->prefix, dest, sizeof(*dest));
apply_mask_ipv4(&r->prefix);
if (pcfg) {
struct isis_prefix_sid *psid =
XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid));
isis_sr_prefix_cfg2subtlv(pcfg, external, psid);
if (pcfgs) {
r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH);
append_item(&r->subtlvs->prefix_sids, (struct isis_item *)psid);
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
struct isis_prefix_sid *psid;
struct sr_prefix_cfg *pcfg = pcfgs[i];
if (!pcfg)
continue;
psid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid));
isis_sr_prefix_cfg2subtlv(pcfg, external, psid);
append_item(&r->subtlvs->prefix_sids,
(struct isis_item *)psid);
}
}
append_item(&tlvs->extended_ip_reach, (struct isis_item *)r);
}
void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest, uint32_t metric,
bool external, struct sr_prefix_cfg *pcfg)
bool external, struct sr_prefix_cfg **pcfgs)
{
struct isis_ipv6_reach *r = XCALLOC(MTYPE_ISIS_TLV, sizeof(*r));
r->metric = metric;
memcpy(&r->prefix, dest, sizeof(*dest));
apply_mask_ipv6(&r->prefix);
if (pcfg) {
struct isis_prefix_sid *psid =
XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid));
isis_sr_prefix_cfg2subtlv(pcfg, external, psid);
if (pcfgs) {
r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH);
append_item(&r->subtlvs->prefix_sids, (struct isis_item *)psid);
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
struct isis_prefix_sid *psid;
struct sr_prefix_cfg *pcfg = pcfgs[i];
if (!pcfg)
continue;
psid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid));
isis_sr_prefix_cfg2subtlv(pcfg, external, psid);
append_item(&r->subtlvs->prefix_sids,
(struct isis_item *)psid);
}
}
struct isis_item_list *l;

View File

@ -571,10 +571,11 @@ void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs,
struct prefix_ipv4 *dest, uint8_t metric);
void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs,
struct prefix_ipv4 *dest, uint32_t metric,
bool external, struct sr_prefix_cfg *pcfg);
bool external,
struct sr_prefix_cfg **pcfgs);
void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest, uint32_t metric,
bool external, struct sr_prefix_cfg *pcfg);
bool external, struct sr_prefix_cfg **pcfgs);
void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest,
struct prefix_ipv6 *src,

View File

@ -98,7 +98,7 @@ static void lsp_add_ip_reach(struct isis_lsp *lsp,
{
struct prefix prefix;
struct sr_prefix_cfg pcfg = {};
struct sr_prefix_cfg *pcfg_p = NULL;
struct sr_prefix_cfg *pcfg_p[SR_ALGORITHM_COUNT] = {NULL};
if (str2prefix(prefix_str, &prefix) != 1) {
zlog_debug("%s: invalid network: %s", __func__, prefix_str);
@ -106,7 +106,7 @@ static void lsp_add_ip_reach(struct isis_lsp *lsp,
}
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
pcfg_p = &pcfg;
pcfg_p[SR_ALGORITHM_SPF] = &pcfg;
pcfg.sid = *next_sid_index;
*next_sid_index = *next_sid_index + 1;