From e7948f8ce607fca184a5c86591c29e31604454ae Mon Sep 17 00:00:00 2001 From: Hiroki Shirokura Date: Sat, 18 Dec 2021 09:03:01 +0000 Subject: [PATCH] isisd: update SR_ALGORITHM_COUNT to 256 Before this commit, SR_ALGORITHM_COUNT was set to 2, and each was hardcoded with router capability tlv. When Flex-Algo is supported, SR-Algorithm may be variably supported up to 256. Signed-off-by: Hiroki Shirokura Signed-off-by: Louis Scalbert --- isisd/isis_lsp.c | 8 ++++---- isisd/isis_sr.c | 23 +++++++++++++++-------- isisd/isis_tlvs.c | 35 +++++++++++++++++++++++++---------- isisd/isis_tlvs.h | 3 +++ 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index dc43822847..9e5c200cce 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -1066,6 +1066,10 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) if (area->isis->router_id != 0) { struct isis_router_cap cap = {}; + /* init SR algo list content to the default value */ + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) + cap.algo[i] = SR_ALGORITHM_UNSET; + cap.router_id.s_addr = area->isis->router_id; /* Add SR Sub-TLVs if SR is enabled. */ @@ -1091,10 +1095,6 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) cap.srlb.lower_bound = srdb->config.srlb_lower_bound; /* And finally MSD */ cap.msd = srdb->config.msd; - } else { - /* Disable SR Algorithm */ - cap.algo[0] = SR_ALGORITHM_UNSET; - cap.algo[1] = SR_ALGORITHM_UNSET; } isis_tlvs_set_router_capability(lsp->tlvs, &cap); diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index b809c1c3a5..87b6f08670 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -931,10 +931,12 @@ static int sr_adj_ip_disabled(struct isis_adjacency *adj, int family, */ static int sr_if_new_hook(struct interface *ifp) { + struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {NULL}; struct isis_circuit *circuit; struct isis_area *area; struct connected *connected; struct listnode *node; + bool need_lsp_regenerate = false; /* Get corresponding circuit */ circuit = circuit_scan_by_ifp(ifp); @@ -951,19 +953,24 @@ static int sr_if_new_hook(struct interface *ifp) * configuration before receiving interface information from zebra. */ FOR_ALL_INTERFACES_ADDRESSES (ifp, connected, node) { - struct sr_prefix_cfg *pcfg; - pcfg = isis_sr_cfg_prefix_find(area, connected->address, - SR_ALGORITHM_SPF); - if (!pcfg) - continue; + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) { + pcfgs[i] = isis_sr_cfg_prefix_find( + area, connected->address, i); + + if (!pcfgs[i]) + continue; - if (sr_prefix_is_node_sid(ifp, &pcfg->prefix)) { - pcfg->node_sid = true; - lsp_regenerate_schedule(area, area->is_type, 0); + if (sr_prefix_is_node_sid(ifp, &pcfgs[i]->prefix)) { + pcfgs[i]->node_sid = true; + need_lsp_regenerate = true; + } } } + if (need_lsp_regenerate) + lsp_regenerate_schedule(area, area->is_type, 0); + return 0; } diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 15f927969d..fb4b9be7e4 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -3572,7 +3572,7 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, { size_t tlv_len = ISIS_ROUTER_CAP_SIZE; size_t len_pos; - uint16_t nb_algo; + uint8_t nb_algo; if (!router_cap) return 0; @@ -3606,14 +3606,13 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, stream_put3(s, router_cap->srgb.lower_bound); /* Then SR Algorithm if set as per RFC8667 section #3.2 */ - for (nb_algo = 0; nb_algo < SR_ALGORITHM_COUNT; nb_algo++) - if (router_cap->algo[nb_algo] == SR_ALGORITHM_UNSET) - break; + nb_algo = isis_tlvs_sr_algo_count(router_cap); if (nb_algo > 0) { stream_putc(s, ISIS_SUBTLV_ALGORITHM); stream_putc(s, nb_algo); - for (int i = 0; i < nb_algo; i++) - stream_putc(s, router_cap->algo[i]); + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) + if (router_cap->algo[i] != SR_ALGORITHM_UNSET) + stream_putc(s, router_cap->algo[i]); } /* Local Block if defined as per RFC8667 section #3.3 */ @@ -3755,10 +3754,16 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, case ISIS_SUBTLV_ALGORITHM: if (length == 0) break; - /* Only 2 algorithms are supported: SPF & Strict SPF */ - stream_get(&rcap->algo, s, length > 2 ? 2 : length); - if (length > 2) - stream_forward_getp(s, length - 2); + + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) + rcap->algo[i] = SR_ALGORITHM_UNSET; + + for (int i = 0; i < length; i++) { + uint8_t algo; + + algo = stream_getc(s); + rcap->algo[algo] = algo; + } break; case ISIS_SUBTLV_SRLB: /* Check that SRLB is correctly formated */ @@ -5789,6 +5794,16 @@ void isis_tlvs_set_router_capability(struct isis_tlvs *tlvs, *tlvs->router_cap = *cap; } +int isis_tlvs_sr_algo_count(const struct isis_router_cap *cap) +{ + int count = 0; + + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) + if (cap->algo[i] != SR_ALGORITHM_UNSET) + count++; + return count; +} + void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs, const struct in_addr *id) { diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 454288c45e..2e26c13eb7 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -560,6 +560,9 @@ 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); + +int isis_tlvs_sr_algo_count(const struct isis_router_cap *cap); + void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs, const struct in_addr *id); void isis_tlvs_set_te_router_id_ipv6(struct isis_tlvs *tlvs, -- 2.39.5