From 7b55ca7f1c22c70bd6fd1f7d5ebdcdde62bd9f19 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 14 Mar 2025 21:09:29 +0100 Subject: [PATCH] bgpd: fix do not use srv6 SID for NHT when SID is ours The resulting VPN prefix of a BGP route from a L3VPN in an srv6 setup is not advertised to remote devices. > r1# show bgp ipv6 vpn > BGP table version is 2, local router ID is 1.1.1.1, vrf id 0 > Default local pref 100, local AS 65500 > Status codes: s suppressed, d damped, h history, u unsorted, * valid, > best, = multipath, > i internal, r RIB-failure, S Stale, R Removed > Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self > Origin codes: i - IGP, e - EGP, ? - incomplete > RPKI validation codes: V valid, I invalid, N Not found > > Network Next Hop Metric LocPrf Weight Path > Route Distinguisher: 1:10 > 2011:1::/64 2001:1::2@6< 0 100 0 i > UN=2001:1::2 EC{99:99} label=4096 sid=2001:db8:1:1:: sid_structure=[40,24,8,0] type=bgp, subtype=5 What happens is that the SID of this BGP update is used as nexthop. Consequently, the prefix is not valid because of nexthop unreachable. obviously the locator prefix is not reachable in that L3VRF, and the real nexthop 2001:1::2 should be used. > r1# show bgp vrf vrf10 nexthop detail > Current BGP nexthop cache: > 2001:db8:1:1:100:: invalid, #paths 1 > Last update: Fri Mar 14 21:18:59 2025 > Paths: > 2/3 2011:1::/64 RD 1:10 VRF default flags 0x4000 Fix this by considering the SID of a given BGP update, only if the SID is not ours. Signed-off-by: Philippe Guibert --- bgpd/bgp_nht.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 268d804699..76ac6a5e96 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -38,7 +38,8 @@ extern struct zclient *zclient; static void register_zebra_rnh(struct bgp_nexthop_cache *bnc); static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc); -static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p); +static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p, + struct bgp *bgp_nexthop); static void bgp_nht_ifp_initial(struct event *thread); DEFINE_HOOK(bgp_nht_path_update, (struct bgp *bgp, struct bgp_path_info *pi, bool valid), @@ -330,7 +331,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, /* This will return true if the global IPv6 NH is a link local * addr */ - if (!make_prefix(afi, pi, &p)) + if (!make_prefix(afi, pi, &p, bgp_nexthop)) return 1; /* @@ -988,7 +989,7 @@ void bgp_cleanup_nexthops(struct bgp *bgp) * make_prefix - make a prefix structure from the path (essentially * path's node. */ -static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) +static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p, struct bgp *bgp_nexthop) { int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP) @@ -1000,6 +1001,9 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) struct in_addr ipv4; struct peer *peer = pi->peer; struct attr *attr = pi->attr; + bool local_sid = false; + struct bgp *bgp = bgp_get_default(); + struct prefix_ipv6 tmp_prefix; if (p_orig->family == AF_FLOWSPEC) { if (!peer) @@ -1029,7 +1033,20 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) break; case AFI_IP6: p->family = AF_INET6; - if (attr->srv6_l3vpn) { + if (bgp && bgp->srv6_locator && bgp->srv6_enabled && attr->srv6_l3vpn) { + tmp_prefix.family = AF_INET6; + tmp_prefix.prefixlen = IPV6_MAX_BITLEN; + tmp_prefix.prefix = attr->srv6_l3vpn->sid; + if (bgp_nexthop->vpn_policy[afi].tovpn_sid_locator && + bgp_nexthop->vpn_policy[afi].tovpn_sid) + local_sid = prefix_match(&bgp_nexthop->vpn_policy[afi] + .tovpn_sid_locator->prefix, + &tmp_prefix); + else if (bgp_nexthop->tovpn_sid_locator && bgp_nexthop->tovpn_sid) + local_sid = prefix_match(&bgp_nexthop->tovpn_sid_locator->prefix, + &tmp_prefix); + } + if (local_sid == false && attr->srv6_l3vpn) { p->prefixlen = IPV6_MAX_BITLEN; if (attr->srv6_l3vpn->transposition_len != 0 && BGP_PATH_INFO_NUM_LABELS(pi)) { -- 2.39.5