From 0de7b43308e13b810202885d94ce2e8aa9734c31 Mon Sep 17 00:00:00 2001 From: Hiroki Shirokura Date: Sat, 11 Dec 2021 06:22:42 +0000 Subject: [PATCH] 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 Signed-off-by: Louis Scalbert --- isisd/isis_lsp.c | 49 +++++++++++++++++++++++++-------------- isisd/isis_tlvs.c | 43 +++++++++++++++++++++++----------- isisd/isis_tlvs.h | 5 ++-- tests/isisd/test_common.c | 4 ++-- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 9e5c200cce..1dbca8ac78 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -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); } } diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index fb4b9be7e4..114c627c14 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -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; diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 2e26c13eb7..cd6089c4a3 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -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, diff --git a/tests/isisd/test_common.c b/tests/isisd/test_common.c index d0288f600d..5c1debca8d 100644 --- a/tests/isisd/test_common.c +++ b/tests/isisd/test_common.c @@ -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;