From ace295a90d6df40c4683dc82ad4004a8b2f0b002 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Thu, 1 Mar 2018 01:47:28 -0800 Subject: [PATCH] bgpd: enable neighbor-nexthop-self for l2vpn evpn address family 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 --- bgpd/bgp_route.c | 2 ++ bgpd/bgp_updgrp_packet.c | 3 +-- bgpd/bgp_vty.c | 2 ++ bgpd/bgpd.c | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 19af159be0..401a7e8549 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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, diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 8ba7902a5f..cabd5b5cbd 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -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 */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e1b050bf59..f9c4a26dc6 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a331fad5d4..c6ad57f84a 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -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) -- 2.39.5