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)