]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: track mpls vpn nexthops
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 21 Apr 2023 12:28:28 +0000 (14:28 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 16 Jun 2023 08:54:58 +0000 (10:54 +0200)
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 <philippe.guibert@6wind.com>
bgpd/bgp_nht.c
bgpd/bgp_route.c

index d7b14298815906f13374302195d5a60791083f8c..df59e31d4afce9495ac2b09cce97e3ae39fd2a5e 100644 (file)
@@ -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,
index 7737738d28215e00f8ab286ae4fb8db19bcb2864..c4c08cf10c2b2376d8ad334dee0363d631c4f4e0 100644 (file)
@@ -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);
        }