From 6c995628c1d175d255c2a02f108813090da4c4e2 Mon Sep 17 00:00:00 2001 From: Ameya Dharkar Date: Sun, 10 Jan 2021 18:32:34 -0800 Subject: [PATCH] bgpd: Generate and advertise gateway IP overlay index with EVPN RT-5 Gateway IP overlay index is generated for EVPN RT-5 when following CLI is configured. router bgp 100 vrf vrf-blue address-family l2vpn evpn advertise ipv4 unicast gateway-ip advertise ipv6 unicast gateway-ip BGP nexthop of the VRF IP/IPv6 route is set as the gateway IP of the corresponding EVPN RT-5 Signed-off-by: Ameya Dharkar --- bgpd/bgp_debug.c | 26 ++++++++++++++++++++++++-- bgpd/bgp_debug.h | 13 +++++++------ bgpd/bgp_evpn.c | 29 +++++++++++++++++++++++++---- bgpd/bgp_mac.c | 4 ++-- bgpd/bgp_route.c | 30 +++++++++++++++--------------- bgpd/bgp_updgrp_packet.c | 3 ++- 6 files changed, 75 insertions(+), 30 deletions(-) diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 8f286e66df..856afb05f8 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -2680,10 +2680,14 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, union prefixconstptr pu, mpls_label_t *label, uint32_t num_labels, int addpath_valid, uint32_t addpath_id, + struct bgp_route_evpn *overlay_index, char *str, int size) { char rd_buf[RD_ADDRSTRLEN]; char tag_buf[30]; + char overlay_index_buf[INET6_ADDRSTRLEN + 14]; + const struct prefix_evpn *evp; + /* ' with addpath ID ' 17 * max strlen of uint32 + 10 * +/- (just in case) + 1 @@ -2701,6 +2705,23 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, snprintf(pathid_buf, sizeof(pathid_buf), " with addpath ID %u", addpath_id); + overlay_index_buf[0] = '\0'; + if (overlay_index && overlay_index->type == OVERLAY_INDEX_GATEWAY_IP) { + char obuf[INET6_ADDRSTRLEN]; + + obuf[0] = '\0'; + evp = pu.evp; + if (is_evpn_prefix_ipaddr_v4(evp)) + inet_ntop(AF_INET, &overlay_index->gw_ip, obuf, + sizeof(obuf)); + else if (is_evpn_prefix_ipaddr_v6(evp)) + inet_ntop(AF_INET6, &overlay_index->gw_ip, obuf, + sizeof(obuf)); + + snprintf(overlay_index_buf, sizeof(overlay_index_buf), + " gateway IP %s", obuf); + } + tag_buf[0] = '\0'; if (bgp_labeled_safi(safi) && num_labels) { @@ -2720,9 +2741,10 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, } if (prd) - snprintfrr(str, size, "RD %s %pFX%s%s %s %s", + snprintfrr(str, size, "RD %s %pFX%s%s%s %s %s", prefix_rd2str(prd, rd_buf, sizeof(rd_buf)), pu.p, - tag_buf, pathid_buf, afi2str(afi), safi2str(safi)); + overlay_index_buf, tag_buf, pathid_buf, afi2str(afi), + safi2str(safi)); else if (safi == SAFI_FLOWSPEC) { char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; const struct prefix_fs *fs = pu.fs; diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index fa8da1c345..d847fb84e7 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -37,7 +37,8 @@ #define DUMP_DETAIL 32 /* RD + Prefix + Path-Id */ -#define BGP_PRD_PATH_STRLEN (PREFIX_STRLEN + RD_ADDRSTRLEN + 20) +#define BGP_PRD_PATH_STRLEN \ + (PREFIX_STRLEN + RD_ADDRSTRLEN + INET6_ADDRSTRLEN + 34) extern int dump_open; extern int dump_update; @@ -179,11 +180,11 @@ extern bool bgp_debug_update(struct peer *peer, const struct prefix *p, extern bool bgp_debug_bestpath(struct bgp_dest *dest); extern bool bgp_debug_zebra(const struct prefix *p); -extern const char * -bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, const struct prefix_rd *prd, - union prefixconstptr pu, mpls_label_t *label, - uint32_t num_labels, int addpath_valid, - uint32_t addpath_id, char *str, int size); +extern const char *bgp_debug_rdpfxpath2str( + afi_t afi, safi_t safi, const struct prefix_rd *prd, + union prefixconstptr pu, mpls_label_t *label, uint32_t num_labels, + int addpath_valid, uint32_t addpath_id, + struct bgp_route_evpn *overlay_index, char *str, int size); const char *bgp_notify_admin_message(char *buf, size_t bufsz, uint8_t *data, size_t datalen); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index d8e57419ee..b29825afc5 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1261,7 +1261,8 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, /* update evpn type-5 route entry */ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, - struct attr *src_attr) + struct attr *src_attr, afi_t src_afi, + safi_t src_safi) { afi_t afi = AFI_L2VPN; safi_t safi = SAFI_EVPN; @@ -1315,6 +1316,26 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; + if (src_afi == AFI_IP6 && + CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], + BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP)) { + if (src_attr && + !IN6_IS_ADDR_UNSPECIFIED(&src_attr->mp_nexthop_global)) { + attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; + memcpy(&attr.evpn_overlay.gw_ip.ipv6, + &src_attr->mp_nexthop_global, + sizeof(struct in6_addr)); + } + } else if (src_afi == AFI_IP && + CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], + BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) { + if (src_attr && src_attr->nexthop.s_addr != 0) { + attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; + memcpy(&attr.evpn_overlay.gw_ip.ipv4, + &src_attr->nexthop, sizeof(struct in_addr)); + } + } + /* Setup RT and encap extended community */ build_evpn_type5_route_extcomm(bgp_vrf, &attr); @@ -4078,7 +4099,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */ stream_putc(s, 8 + 10 + 4 + 1 + len + 3); stream_put(s, prd->val, 8); - if (attr) + if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_ESI) stream_put(s, &attr->esi, sizeof(esi_t)); else stream_put(s, 0, sizeof(esi_t)); @@ -4088,7 +4109,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, stream_put_ipv4(s, p_evpn_p->prefix_addr.ip.ipaddr_v4.s_addr); else stream_put(s, &p_evpn_p->prefix_addr.ip.ipaddr_v6, 16); - if (attr) { + if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) { const struct bgp_route_evpn *evpn_overlay = bgp_attr_get_evpn_overlay(attr); @@ -4301,7 +4322,7 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, const struct prefix *p, struct prefix_evpn evp; build_type5_prefix_from_ip_prefix(&evp, p); - ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr); + ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr, afi, safi); if (ret) flog_err(EC_BGP_EVPN_ROUTE_CREATE, "%u: Failed to create type-5 route for prefix %pFX", diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 3d7bc08ac5..02b7e64869 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -200,8 +200,8 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, AFI_L2VPN, SAFI_EVPN, &prd, p, label_pnt, num_labels, pi->addpath_rx_id ? 1 : 0, - pi->addpath_rx_id, pfx_buf, - sizeof(pfx_buf)); + pi->addpath_rx_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug( "%s skip update of %s marked as removed", peer->host, pfx_buf); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8438621f68..c539bccb62 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3867,7 +3867,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, - addpath_id, pfx_buf, + addpath_id, NULL, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); @@ -3893,7 +3893,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, - addpath_id, pfx_buf, + addpath_id, NULL, pfx_buf, sizeof(pfx_buf)); zlog_debug( "%s rcvd %s...duplicate ignored", @@ -3920,8 +3920,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, pfx_buf, - sizeof(pfx_buf)); + addpath_id ? 1 : 0, addpath_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug( "%s rcvd %s, flapped quicker than processing", peer->host, pfx_buf); @@ -3934,7 +3934,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, - addpath_id, pfx_buf, + addpath_id, NULL, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -4207,8 +4207,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, pfx_buf, - sizeof(pfx_buf)); + addpath_id ? 1 : 0, addpath_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -4353,8 +4353,8 @@ filtered: } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, pfx_buf, - sizeof(pfx_buf)); + addpath_id ? 1 : 0, addpath_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s", peer->host, pfx_buf, reason); } @@ -4438,8 +4438,8 @@ int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, pfx_buf, - sizeof(pfx_buf)); + addpath_id ? 1 : 0, addpath_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug( "%s withdrawing route %s not in adj-in", peer->host, pfx_buf); @@ -4458,8 +4458,8 @@ int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, pfx_buf, - sizeof(pfx_buf)); + addpath_id ? 1 : 0, addpath_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host, pfx_buf); } @@ -4479,8 +4479,8 @@ int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } else if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, pfx_buf, - sizeof(pfx_buf)); + addpath_id ? 1 : 0, addpath_id, NULL, + pfx_buf, sizeof(pfx_buf)); zlog_debug("%s Can't find the route %s", peer->host, pfx_buf); } diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 6418decd16..038ef4f798 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -862,6 +862,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) bgp_debug_rdpfxpath2str(afi, safi, prd, dest_p, label_pnt, num_labels, addpath_encode, addpath_tx_id, + &adv->baa->attr->evpn_overlay, pfx_buf, sizeof(pfx_buf)); zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s", subgrp->update_group->id, subgrp->id, @@ -1031,7 +1032,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp) bgp_debug_rdpfxpath2str(afi, safi, prd, dest_p, NULL, 0, addpath_encode, addpath_tx_id, - pfx_buf, sizeof(pfx_buf)); + NULL, pfx_buf, sizeof(pfx_buf)); zlog_debug("u%" PRIu64 ":s%" PRIu64" send UPDATE %s -- unreachable", subgrp->update_group->id, subgrp->id, pfx_buf); -- 2.39.5