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, isis_tlvs_add_oldstyle_ip_reach(lsp->tlvs, ipv4,
metric); metric);
if (area->newmetric) { if (area->newmetric) {
struct sr_prefix_cfg *pcfg = NULL; struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {
NULL};
if (area->srdb.enabled) if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find( for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
area, ipv4, SR_ALGORITHM_SPF); pcfgs[i] = isis_sr_cfg_prefix_find(
area, ipv4, i);
isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4, metric, 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; metric = MAX_WIDE_PATH_METRIC;
if (!src_p || !src_p->prefixlen) { 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) if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find( for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
area, p, SR_ALGORITHM_SPF); pcfgs[i] = isis_sr_cfg_prefix_find(
area, p, i);
isis_tlvs_add_ipv6_reach(lsp->tlvs, isis_tlvs_add_ipv6_reach(lsp->tlvs,
isis_area_ipv6_topology(area), isis_area_ipv6_topology(area),
p, metric, true, pcfg); p, metric, true, pcfgs);
} else if (isis_area_ipv6_dstsrc_enabled(area)) { } else if (isis_area_ipv6_dstsrc_enabled(area)) {
isis_tlvs_add_ipv6_dstsrc_reach(lsp->tlvs, isis_tlvs_add_ipv6_dstsrc_reach(lsp->tlvs,
ISIS_MT_IPV6_DSTSRC, ISIS_MT_IPV6_DSTSRC,
@ -1199,20 +1203,27 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
} }
if (area->newmetric) { if (area->newmetric) {
struct sr_prefix_cfg *pcfg = NULL; struct sr_prefix_cfg
*pcfgs[SR_ALGORITHM_COUNT] = {
NULL};
lsp_debug( lsp_debug(
"ISIS (%s): Adding te-style IP reachability for %pFX", "ISIS (%s): Adding te-style IP reachability for %pFX",
area->area_tag, ipv4); area->area_tag, ipv4);
if (area->srdb.enabled) if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find( for (int i = 0;
area, ipv4, i < SR_ALGORITHM_COUNT;
SR_ALGORITHM_SPF); i++)
pcfgs[i] =
isis_sr_cfg_prefix_find(
area,
ipv4,
i);
isis_tlvs_add_extended_ip_reach( isis_tlvs_add_extended_ip_reach(
lsp->tlvs, ipv4, metric, false, 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, for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link,
ipnode, ipv6)) { ipnode, ipv6)) {
struct sr_prefix_cfg *pcfg = NULL; struct sr_prefix_cfg
*pcfgs[SR_ALGORITHM_COUNT] = {NULL};
lsp_debug( lsp_debug(
"ISIS (%s): Adding IPv6 reachability for %pFX", "ISIS (%s): Adding IPv6 reachability for %pFX",
area->area_tag, ipv6); area->area_tag, ipv6);
if (area->srdb.enabled) if (area->srdb.enabled)
pcfg = isis_sr_cfg_prefix_find(area, for (int i = 0; i < SR_ALGORITHM_COUNT;
ipv6, 0); i++)
pcfgs[i] =
isis_sr_cfg_prefix_find(
area, ipv6, i);
isis_tlvs_add_ipv6_reach( isis_tlvs_add_ipv6_reach(
lsp->tlvs, lsp->tlvs,
isis_area_ipv6_topology(area), ipv6, 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, void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs,
struct prefix_ipv4 *dest, uint32_t metric, 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)); struct isis_extended_ip_reach *r = XCALLOC(MTYPE_ISIS_TLV, sizeof(*r));
r->metric = metric; r->metric = metric;
memcpy(&r->prefix, dest, sizeof(*dest)); memcpy(&r->prefix, dest, sizeof(*dest));
apply_mask_ipv4(&r->prefix); 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); 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); append_item(&tlvs->extended_ip_reach, (struct isis_item *)r);
} }
void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid, void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest, uint32_t metric, 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)); struct isis_ipv6_reach *r = XCALLOC(MTYPE_ISIS_TLV, sizeof(*r));
r->metric = metric; r->metric = metric;
memcpy(&r->prefix, dest, sizeof(*dest)); memcpy(&r->prefix, dest, sizeof(*dest));
apply_mask_ipv6(&r->prefix); apply_mask_ipv6(&r->prefix);
if (pcfg) { if (pcfgs) {
struct isis_prefix_sid *psid =
XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid));
isis_sr_prefix_cfg2subtlv(pcfg, external, psid);
r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH); 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; 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); struct prefix_ipv4 *dest, uint8_t metric);
void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs, void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs,
struct prefix_ipv4 *dest, uint32_t metric, 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, void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest, uint32_t metric, 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, void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest, struct prefix_ipv6 *dest,
struct prefix_ipv6 *src, struct prefix_ipv6 *src,

View File

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