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 <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2025-03-20 16:11:59 +01:00
parent 7b55ca7f1c
commit 914931ed36
2 changed files with 37 additions and 6 deletions

View 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 * If you are using SRv6 VPN instead of MPLS, it need to check
* the SID allocation. If the sid is not allocated, the rib * the SID allocation. If the sid is not allocated, the rib
* will be invalid. * will be invalid.
* If the SID per VRF is not available, also consider the rib as
* invalid.
*/ */
if (to_bgp->srv6_enabled && if (to_bgp->srv6_enabled && nh_valid)
(!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) { nh_valid = is_pi_srv6_valid(bpi, bgp_nexthop, afi, safi);
nh_valid = false;
}
if (debug) if (debug)
zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__, p, 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; break;
} }
if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, path_vpn, bpi,
path_vpn, bpi, src_vrf, p, debug)) src_vrf, p, debug))
SET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID); SET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);
else else
UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID); UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);

View 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)); 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 void vpn_policy_routemap_event(const char *rmap_name);
extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);