]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: Extend SPF algo to process SRv6 locator
authorCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Wed, 22 Feb 2023 09:27:15 +0000 (10:27 +0100)
committerCarmine Scarpitta <carmine.scarpitta@uniroma2.it>
Mon, 11 Sep 2023 15:35:09 +0000 (17:35 +0200)
Extend SPF algorithm to process SRv6 locator.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
isisd/isis_spf.c

index e114467e07ccdd9a36c5b8bdd3bb4f5d28e49717..a2230cd00995fd8a073f713e3d7eee9389b4524b 100644 (file)
@@ -837,6 +837,7 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
        struct isis_mt_router_info *mt_router_info = NULL;
        struct prefix_pair ip_info;
        bool has_valid_psid;
+       bool loc_is_in_ipv6_reach = false;
 
        if (isis_lfa_excise_node_check(spftree, lsp->hdr.lsp_id)) {
                if (IS_DEBUG_LFA)
@@ -1128,6 +1129,50 @@ lspfragloop:
                                process_N(spftree, vtype, &ip_info, dist,
                                          depth + 1, NULL, parent);
                }
+
+               /* Process SRv6 Locator TLVs */
+
+               struct isis_item_list *srv6_locators = isis_lookup_mt_items(
+                       &lsp->tlvs->srv6_locator, spftree->mtid);
+
+               struct isis_srv6_locator_tlv *loc;
+               for (loc = srv6_locators ? (struct isis_srv6_locator_tlv *)
+                                                  srv6_locators->head
+                                        : NULL;
+                    loc; loc = loc->next) {
+
+                       if (loc->algorithm != SR_ALGORITHM_SPF)
+                               continue;
+
+                       dist = cost + loc->metric;
+                       vtype = VTYPE_IP6REACH_INTERNAL;
+                       memset(&ip_info, 0, sizeof(ip_info));
+                       ip_info.dest.family = AF_INET6;
+                       ip_info.dest.u.prefix6 = loc->prefix.prefix;
+                       ip_info.dest.prefixlen = loc->prefix.prefixlen;
+
+                       /* An SRv6 Locator can be received in both a Prefix
+                       Reachability TLV and an SRv6 Locator TLV (as per RFC
+                       9352 section #5). We go through the Prefix Reachability
+                       TLVs and check if the SRv6 Locator is present in some of
+                       them. If we find the SRv6 Locator in some Prefix
+                       Reachbility TLV then it means that we have already
+                       processed it before and we can skip it. */
+                       for (r = ipv6_reachs ? (struct isis_ipv6_reach *)
+                                                      ipv6_reachs->head
+                                            : NULL;
+                            r; r = r->next) {
+                               if (prefix_same((struct prefix *)&r->prefix,
+                                               (struct prefix *)&loc->prefix))
+                                       loc_is_in_ipv6_reach = true;
+                       }
+
+                       /* SRv6 locator not present in Prefix Reachability TLV,
+                        * let's process it */
+                       if (!loc_is_in_ipv6_reach)
+                               process_N(spftree, vtype, &ip_info, dist,
+                                         depth + 1, NULL, parent);
+               }
        }
 
 end: