]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: enable neighbor-nexthop-self for l2vpn evpn address family
authorMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Thu, 1 Mar 2018 09:47:28 +0000 (01:47 -0800)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 May 2018 23:24:15 +0000 (19:24 -0400)
In the FRR implementation of EVPN,
eBGP leaf-spine peering for EVPN is fully supported by allowing
the next hop to be propagated and not rewritten at each hop.
There are other changes also related to route import to facilitate this.
However, propagating the next hop is not correct in some cases.
Specifically, if the DC is comprised of multiple PODs
with distinct intra-POD and inter-POD VxLAN tunnels,
EVPN routes received from an adjacent POD by a border/exit leaf
must be propagated into the local POD with the next hop rewritten (to self).

Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_route.c
bgpd/bgp_updgrp_packet.c
bgpd/bgp_vty.c
bgpd/bgpd.c

index 19af159be0477d005dbbf0d05d234b9b88a8047d..401a7e854998d2d5f3de595447b77221058b3fcf 100644 (file)
@@ -1336,6 +1336,8 @@ static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
        }
        if (family == AF_INET6)
                memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
+       if (family == AF_EVPN)
+               memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
 }
 
 int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
index 8ba7902a5f688557c7bae5572a3ffaeb84587370..cabd5b5cbd795027ae9a4797a2b2e17abce90d4f 100644 (file)
@@ -467,13 +467,12 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
                                nh_modified = 1;
                        } else if (
                                peer->sort == BGP_PEER_EBGP
-                               && paf->safi != SAFI_EVPN
                                && (bgp_multiaccess_check_v4(v4nh, peer) == 0)
                                && !CHECK_FLAG(
                                           vec->flags,
                                           BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
                                && !peer_af_flag_check(
-                                          peer, nhafi, paf->safi,
+                                          peer, paf->afi, paf->safi,
                                           PEER_FLAG_NEXTHOP_UNCHANGED)) {
                                /* NOTE: not handling case where NH has new AFI
                                 */
index e1b050bf59cb2a563c05b18fb5b48ef9c8ca69be..f9c4a26dc6e5ac5fdcaa5f503089266b69b02258 100644 (file)
@@ -12575,6 +12575,8 @@ void bgp_vty_init(void)
        install_element(BGP_VPNV4_NODE, &no_neighbor_nexthop_self_cmd);
        install_element(BGP_VPNV6_NODE, &neighbor_nexthop_self_cmd);
        install_element(BGP_VPNV6_NODE, &no_neighbor_nexthop_self_cmd);
+       install_element(BGP_EVPN_NODE, &neighbor_nexthop_self_cmd);
+       install_element(BGP_EVPN_NODE, &no_neighbor_nexthop_self_cmd);
 
        /* "neighbor next-hop-self force" commands. */
        install_element(BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd);
index a331fad5d4a242397050bf1438a2c3df959745d8..c6ad57f84a9e6c71d978866089082d610a7b8754 100644 (file)
@@ -711,6 +711,10 @@ struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi)
        af->afid = afid;
        af->peer = peer;
 
+       /* for l2vpn/evpn the default behaviour is nexthop-unchanged */
+       if (afi == AFI_L2VPN && safi == SAFI_EVPN)
+               peer_af_flag_set(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED);
+
        return af;
 }
 
@@ -1928,6 +1932,10 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
                }
        }
 
+       /* for l2vpn/evpn the default behaviour is nexthop-unchanged */
+       if (afi == AFI_L2VPN && safi == SAFI_EVPN)
+               peer_af_flag_set(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED);
+
        return 0;
 }
 
@@ -4072,6 +4080,32 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
                        return 0;
        }
 
+       /*
+        * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
+        * if we are setting/unsetting flags which conflict with this flag
+        * handle accordingly
+        */
+       if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
+               if (set) {
+
+                       /* if we are setting NEXTHOP_SELF, we need to unset the
+                        * NEXTHOP_UNCHANGED flag */
+                       if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
+                           CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
+                               UNSET_FLAG(peer->af_flags[afi][safi],
+                                          PEER_FLAG_NEXTHOP_UNCHANGED);
+               } else {
+
+                       /* if we are unsetting NEXTHOP_SELF, we need to set the
+                        * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
+                        */
+                       if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
+                           CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
+                               SET_FLAG(peer->af_flags[afi][safi],
+                                        PEER_FLAG_NEXTHOP_UNCHANGED);
+               }
+       }
+
        if (set)
                SET_FLAG(peer->af_flags[afi][safi], flag);
        else
@@ -7109,7 +7143,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
 
        /* atribute-unchanged. */
        if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED)
-           || peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED)
+           || (safi != SAFI_EVPN &&
+               peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED))
            || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
 
                if (!peer_group_active(peer)