]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: update isis_tlvs_add_*_reach() with multi algorithm
authorHiroki Shirokura <hiroki.shirokura@linecorp.com>
Sat, 11 Dec 2021 06:22:42 +0000 (06:22 +0000)
committerLouis Scalbert <louis.scalbert@6wind.com>
Tue, 18 Apr 2023 08:11:52 +0000 (10:11 +0200)
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>
isisd/isis_lsp.c
isisd/isis_tlvs.c
isisd/isis_tlvs.h
tests/isisd/test_common.c

index 9e5c200cce24aae24455b11874de9da3f4cf3b25..1dbca8ac783b5b3163ed9f8b60d30ff63556ec3a 100644 (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);
                        }
                }
 
index fb4b9be7e45ba4592ce911574c0ce399a62c20eb..114c627c14436aa4dbdb391063cf6041d84351ad 100644 (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;
index 2e26c13eb7d1c46f9229b1ea62a5ce1a7428df5e..cd6089c4a3b739ed1180d3bded294f1f5cf22e00 100644 (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,
index d0288f600def91839761003c2d2f17e3c14dbe98..5c1debca8d7b4a7ca6c9ce5460f052eaf4440258 100644 (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;