]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: fix accept-own routes received by a route reflector
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 1 Jun 2023 07:48:58 +0000 (09:48 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 16 Jun 2023 08:55:17 +0000 (10:55 +0200)
When using the bgp-accept-own community, with the
'attribute-unchanged next-hop' command, the advertised
mpls vpn updates that are reflected by a route reflector
are received, but are not selected.

Once the accept-own community is detected, a new bgp_path
is created, in addition of the original one; then the
next-hop of the NLRI is checked, but fails for two reasons:
- the next-hop tracking returns the real IP reachability
status for prefixes that have the BGP_ROUTE_IMPORTED subtype.
This is what happens with bgp updates with the accept-own
community.
- as the next-hop was unchanged and was the peer IP in the VRF.
Consequently, the new bgp_path is considered inactive in the
default VRF, and is not selected.

The incoming bgp updates with the accept-own community should
not be checked against the next-hop tracking. As the bgp_path
subtype has been changed to BGP_ROUTE_IMPORTED, let us check
the bgp subtype before calling the 'bgp_find_or_add_nexthop()'
function in the 'bgp_update()' call.

Fixes: 46dbf9d0c0b9 bgpd: ("Implement ACCEPT_OWN extended community")
Fixes: 376797711f4d - bgpd: track mpls vpn nexthops
Fixes: e6110f755718 bgpd: ("fix use nexthop tracking for exported vpn paths")
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_route.c

index c2e554cddbceb77dcfdf6e59370372bd826a1b56..b267f0d6bd842ae8dbd5196295e17f85bf254f1d 100644 (file)
@@ -4744,7 +4744,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                 * labeled-unicast.. */
                if (((afi == AFI_IP || afi == AFI_IP6) &&
                     (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST ||
-                     safi == SAFI_MPLS_VPN)) ||
+                     (safi == SAFI_MPLS_VPN &&
+                      pi->sub_type != BGP_ROUTE_IMPORTED))) ||
                    (safi == SAFI_EVPN &&
                     bgp_evpn_is_prefix_nht_supported(p))) {
                        if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
@@ -4784,6 +4785,13 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                                                         BGP_PATH_VALID);
                        }
                } else {
+                       /* case mpls-vpn routes with accept-own community
+                        * (which have the BGP_ROUTE_IMPORTED subtype)
+                        * case other afi/safi not supporting nexthop tracking
+                        */
+                       if (accept_own)
+                               bgp_path_info_set_flag(dest, pi,
+                                                      BGP_PATH_ACCEPT_OWN);
                        bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
                }
 
@@ -4915,7 +4923,8 @@ 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_MPLS_VPN)) ||
+             (safi == SAFI_MPLS_VPN &&
+              new->sub_type != BGP_ROUTE_IMPORTED))) ||
            (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
                if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
                    && peer->ttl == BGP_DEFAULT_TTL
@@ -4944,6 +4953,12 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                        bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
                }
        } else {
+               /* case mpls-vpn routes with accept-own community
+                * (which have the BGP_ROUTE_IMPORTED subtype)
+                * case other afi/safi not supporting nexthop tracking
+                */
+               if (accept_own)
+                       bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
                bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
        }