]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: fix do not export VPN prefix when no SID available on the VRF
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 20 Mar 2025 15:11:59 +0000 (16:11 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 24 Mar 2025 08:17:01 +0000 (09:17 +0100)
When detaching the locator from the main BGP instance, the used SIDs
and locators are removed from the srv6 per-afi or per-vrf contects.
Under those conditions, it is not possible to attempt to export new
VPN updates. Do invalidate the nexthop for leaking.

Restrict the control for exported VPN prefixes and not for unicast
imported prefixes.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h

index d1d4c5af68c180ec101ed93a13d2a7dc3c0b7f9f..ff64f8361d5279e3958e4f1577fd1d07bf3bbfdf 100644 (file)
@@ -1112,11 +1112,11 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
         * If you are using SRv6 VPN instead of MPLS, it need to check
         * the SID allocation. If the sid is not allocated, the rib
         * will be invalid.
+        * If the SID per VRF is not available, also consider the rib as
+        * invalid.
         */
-       if (to_bgp->srv6_enabled &&
-           (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) {
-               nh_valid = false;
-       }
+       if (to_bgp->srv6_enabled && nh_valid)
+               nh_valid = is_pi_srv6_valid(bpi, bgp_nexthop, afi, safi);
 
        if (debug)
                zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__, p,
@@ -2337,8 +2337,8 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,     /* to */
                        break;
        }
 
-       if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi,
-                                            path_vpn, bpi, src_vrf, p, debug))
+       if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, path_vpn, bpi,
+                                            src_vrf, p, debug))
                SET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);
        else
                UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);
index 56dd33f9b1641cf26bcf8378cf63fbe13975fc6b..75c0264987ff0a5c270f4a41843ca76e513f169a 100644 (file)
@@ -342,6 +342,37 @@ static inline bool is_pi_family_vpn(struct bgp_path_info *pi)
                is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN));
 }
 
+/*
+ * If you are using SRv6 VPN instead of MPLS, it need to check
+ * the SID allocation. If the sid is not allocated, the rib
+ * will be invalid.
+ * If the SID per VRF is not available, also consider the rib as
+ * invalid.
+ */
+static inline bool is_pi_srv6_valid(struct bgp_path_info *pi, struct bgp *bgp_nexthop, afi_t afi,
+                                   safi_t safi)
+{
+       if (!pi->attr->srv6_l3vpn && !pi->attr->srv6_vpn)
+               return false;
+
+       /* imported paths from VPN: srv6 enabled and nht reachability
+        * are enough to know if that path is valid
+        */
+       if (safi == SAFI_UNICAST)
+               return true;
+
+       if (bgp_nexthop->vpn_policy[afi].tovpn_sid == NULL && bgp_nexthop->tovpn_sid == NULL)
+               return false;
+
+       if (bgp_nexthop->tovpn_sid_index == 0 &&
+           !CHECK_FLAG(bgp_nexthop->vrf_flags, BGP_VRF_TOVPN_SID_AUTO) &&
+           bgp_nexthop->vpn_policy[afi].tovpn_sid_index == 0 &&
+           !CHECK_FLAG(bgp_nexthop->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_AUTO))
+               return false;
+
+       return true;
+}
+
 extern void vpn_policy_routemap_event(const char *rmap_name);
 
 extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);