From cd0e9bfbc43e5cd30c90a4ea16e1e810f94a7477 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 21 Apr 2023 14:28:28 +0200 Subject: [PATCH] bgpd: track mpls vpn nexthops There is no nexthop reachability information for received MPLS VPN prefixes. This information is necessary when BGP also acts as LSR device, and is needed to create an MPLS entry between two BGP speakers: the next-hop to pick-up in the MPLS entry has to be connected. The nexthop reachability information is available for other non MPLS VPN prefixes, and is handled by the bgp nexthop cache (bnc) contexts. Extend the usage of the BNC contexts for L3VPN prefixes. Note that the MPLS VPN routes had to be redistributed as before, to avoid breaking existing deployments that use FRR as route reflectors. Because of this, the nexthop reachability status has been maintained to OK for MPLS VPN prefixes. Note also that the label allocation per nexthop tracking was wrongly using the MPLS VPN safi to get a valid BNC context, when choosing which label to return in the 'vpn_leak_from_vrf_get_per_nexthop_label()' function. Fix this by using SAFI_UNICAST instead. Fixes: 577be36a41be ("bgpd: add support for l3vpn per-nexthop label") Link: https://github.com/FRRouting/frr/pull/13380 Signed-off-by: Philippe Guibert --- bgpd/bgp_nht.c | 6 ++++++ bgpd/bgp_route.c | 39 +++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index d7b1429881..df59e31d4a 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -467,6 +467,9 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, pi->sub_type == BGP_ROUTE_IMPORTED && pi->extra && pi->extra->num_labels && !bnc->is_evpn_gwip_nexthop) return bgp_isvalid_nexthop_for_mpls(bnc, pi); + else if (safi == SAFI_MPLS_VPN) + /* avoid not redistributing mpls vpn routes */ + return 1; else return (bgp_isvalid_nexthop(bnc)); } @@ -1190,6 +1193,9 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc) bnc_is_valid_nexthop = bgp_isvalid_nexthop_for_mpls(bnc, path) ? true : false; + } else if (safi == SAFI_MPLS_VPN) { + /* avoid not redistributing mpls vpn routes */ + bnc_is_valid_nexthop = true; } else { if (bgp_update_martian_nexthop( bnc->bgp, afi, safi, path->type, diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7737738d28..c4c08cf10c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4621,10 +4621,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Nexthop reachability check - for unicast and * labeled-unicast.. */ - if (((afi == AFI_IP || afi == AFI_IP6) - && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) - || (safi == SAFI_EVPN && - bgp_evpn_is_prefix_nht_supported(p))) { + if (((afi == AFI_IP || afi == AFI_IP6) && + (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || + safi == SAFI_MPLS_VPN)) || + (safi == SAFI_EVPN && + bgp_evpn_is_prefix_nht_supported(p))) { if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL && !CHECK_FLAG(peer->flags, @@ -4645,10 +4646,14 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, safi, pi, NULL, connected, bgp_nht_param_prefix) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { + if (accept_own) + bgp_path_info_set_flag( + dest, pi, BGP_PATH_ACCEPT_OWN); + bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); - else { + } else { if (BGP_DEBUG(nht, NHT)) { zlog_debug("%s(%pI4): NH unresolved", __func__, @@ -4658,10 +4663,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, BGP_PATH_VALID); } } else { - if (accept_own) - bgp_path_info_set_flag(dest, pi, - BGP_PATH_ACCEPT_OWN); - bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); } @@ -4791,9 +4792,10 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } /* Nexthop reachability check. */ - if (((afi == AFI_IP || afi == AFI_IP6) - && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) - || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) { + if (((afi == AFI_IP || afi == AFI_IP6) && + (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || + safi == SAFI_MPLS_VPN)) || + (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) { if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL && !CHECK_FLAG(peer->flags, @@ -4808,18 +4810,19 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL, connected, bgp_nht_param_prefix) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { + if (accept_own) + bgp_path_info_set_flag(dest, new, + BGP_PATH_ACCEPT_OWN); + bgp_path_info_set_flag(dest, new, BGP_PATH_VALID); - else { + } else { if (BGP_DEBUG(nht, NHT)) zlog_debug("%s(%pI4): NH unresolved", __func__, &attr_new->nexthop); bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID); } } else { - if (accept_own) - bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN); - bgp_path_info_set_flag(dest, new, BGP_PATH_VALID); }