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)
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: