From 914931ed367a047577c5b084aa4bc025e0eefd4a Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 20 Mar 2025 16:11:59 +0100 Subject: [PATCH] bgpd: fix do not export VPN prefix when no SID available on the VRF 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 --- bgpd/bgp_mplsvpn.c | 12 ++++++------ bgpd/bgp_mplsvpn.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index d1d4c5af68..ff64f8361d 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -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); diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 56dd33f9b1..75c0264987 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -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); -- 2.39.5