mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 07:48:38 +00:00
bgpd: Parse EVPN RT-5 NLRI and store gateway IP for EVPN route
While installing this route in the EVPN table, make sure all the conditions mentioned in the draft https://tools.ietf.org/html/draft-ietf-bess-evpn-prefix-advertisement-11 are met. Draft mentions following conditions: - ESI and gateway IP cannot be both nonzero at the same time. - ESI, gateway IP, RMAC and VNI label all cannot be 0 at the same time. If the received EVPN RT-5 route does not meet these conditions, the route is treated as withdraw. Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
This commit is contained in:
parent
8304dabfab
commit
66ff60895a
@ -315,3 +315,4 @@ extern bool is_zero_gw_ip(const union gw_addr *gw_ip, const afi_t afi)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3972,7 +3972,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
mpls_label_t label; /* holds the VNI as in the packet */
|
||||
int ret;
|
||||
afi_t gw_afi;
|
||||
bool is_valid_update = false;
|
||||
bool is_valid_update = true;
|
||||
|
||||
/* Type-5 route should be 34 or 58 bytes:
|
||||
* RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
|
||||
@ -4001,9 +4001,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
/* Additional information outside of prefix - ESI and GW IP */
|
||||
memset(&evpn, 0, sizeof(evpn));
|
||||
|
||||
/* Fetch ESI */
|
||||
/* Fetch ESI overlay index */
|
||||
if (attr)
|
||||
memcpy(&attr->esi, pfx, sizeof(esi_t));
|
||||
memcpy(&evpn.eth_s_id, pfx, sizeof(esi_t));
|
||||
pfx += ESI_BYTES;
|
||||
|
||||
/* Fetch Ethernet Tag. */
|
||||
@ -4052,25 +4052,53 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||
* field
|
||||
*/
|
||||
|
||||
/*
|
||||
* An update containing a non-zero gateway IP and a non-zero ESI
|
||||
* at the same time is should be treated as withdraw
|
||||
*/
|
||||
if (bgp_evpn_is_esi_valid(&evpn.eth_s_id)
|
||||
&& !is_zero_gw_ip(&evpn.gw_ip, gw_afi)) {
|
||||
flog_err(EC_BGP_EVPN_ROUTE_INVALID,
|
||||
"%s - Rx EVPN Type-5 ESI and gateway-IP both non-zero.",
|
||||
peer->host);
|
||||
is_valid_update = false;
|
||||
} else if (bgp_evpn_is_esi_valid(&evpn.eth_s_id))
|
||||
evpn.type = OVERLAY_INDEX_ESI;
|
||||
else if (!is_zero_gw_ip(&evpn.gw_ip, gw_afi))
|
||||
evpn.type = OVERLAY_INDEX_GATEWAY_IP;
|
||||
if (attr) {
|
||||
is_valid_update = true;
|
||||
if (is_zero_mac(&attr->rmac) &&
|
||||
is_zero_gw_ip(&evpn.gw_ip, gw_afi))
|
||||
if (is_zero_mac(&attr->rmac)
|
||||
&& !bgp_evpn_is_esi_valid(&evpn.eth_s_id)
|
||||
&& is_zero_gw_ip(&evpn.gw_ip, gw_afi) && label == 0) {
|
||||
flog_err(EC_BGP_EVPN_ROUTE_INVALID,
|
||||
"%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero",
|
||||
peer->host);
|
||||
is_valid_update = false;
|
||||
}
|
||||
|
||||
if (is_mcast_mac(&attr->rmac) || is_bcast_mac(&attr->rmac))
|
||||
is_valid_update = false;
|
||||
}
|
||||
|
||||
/* Process the route. */
|
||||
if (is_valid_update)
|
||||
if (attr && is_valid_update)
|
||||
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||
&prd, &label, 1, 0, &evpn);
|
||||
else
|
||||
else {
|
||||
if (!is_valid_update) {
|
||||
char attr_str[BUFSIZ] = {0};
|
||||
|
||||
bgp_dump_attr(attr, attr_str, BUFSIZ);
|
||||
zlog_warn(
|
||||
"Invalid update from peer %s vrf %u prefix %pFX attr %s - treat as withdraw",
|
||||
peer->hostname, peer->bgp->vrf_id, &p,
|
||||
attr_str);
|
||||
}
|
||||
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||
&prd, &label, 1, &evpn);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -3442,23 +3442,6 @@ struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
|
||||
return new;
|
||||
}
|
||||
|
||||
static void overlay_index_update(struct attr *attr,
|
||||
union gw_addr *gw_ip)
|
||||
{
|
||||
if (!attr)
|
||||
return;
|
||||
if (gw_ip == NULL) {
|
||||
struct bgp_route_evpn eo;
|
||||
|
||||
memset(&eo, 0, sizeof(eo));
|
||||
bgp_attr_set_evpn_overlay(attr, &eo);
|
||||
} else {
|
||||
struct bgp_route_evpn eo = {.gw_ip = *gw_ip};
|
||||
|
||||
bgp_attr_set_evpn_overlay(attr, &eo);
|
||||
}
|
||||
}
|
||||
|
||||
static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
|
||||
union gw_addr *gw_ip)
|
||||
{
|
||||
@ -3641,6 +3624,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
||||
if (has_valid_label)
|
||||
assert(label != NULL);
|
||||
|
||||
/* Update overlay index of the attribute */
|
||||
if (afi == AFI_L2VPN && evpn)
|
||||
memcpy(&attr->evpn_overlay, evpn,
|
||||
sizeof(struct bgp_route_evpn));
|
||||
|
||||
/* When peer's soft reconfiguration enabled. Record input packet in
|
||||
Adj-RIBs-In. */
|
||||
if (!soft_reconfig
|
||||
@ -3816,12 +3804,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
||||
goto filtered;
|
||||
}
|
||||
|
||||
/* Update Overlay Index */
|
||||
if (afi == AFI_L2VPN) {
|
||||
overlay_index_update(&new_attr,
|
||||
evpn == NULL ? NULL : &evpn->gw_ip);
|
||||
}
|
||||
|
||||
/* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
|
||||
* condition :
|
||||
* Suppress fib is enabled
|
||||
@ -3856,10 +3838,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
||||
&& (!has_valid_label
|
||||
|| memcmp(&(bgp_path_info_extra_get(pi))->label, label,
|
||||
num_labels * sizeof(mpls_label_t))
|
||||
== 0)
|
||||
&& (overlay_index_equal(
|
||||
afi, pi,
|
||||
evpn == NULL ? NULL : &evpn->gw_ip))) {
|
||||
== 0)) {
|
||||
if (get_active_bdc_from_pi(pi, afi, safi)
|
||||
&& peer->sort == BGP_PEER_EBGP
|
||||
&& CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
|
||||
@ -3867,7 +3846,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, NULL, pfx_buf,
|
||||
addpath_id, evpn, pfx_buf,
|
||||
sizeof(pfx_buf));
|
||||
zlog_debug("%s rcvd %s", peer->host,
|
||||
pfx_buf);
|
||||
@ -3893,7 +3872,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, NULL, pfx_buf,
|
||||
addpath_id, evpn, pfx_buf,
|
||||
sizeof(pfx_buf));
|
||||
zlog_debug(
|
||||
"%s rcvd %s...duplicate ignored",
|
||||
@ -3920,7 +3899,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, NULL,
|
||||
addpath_id ? 1 : 0, addpath_id, evpn,
|
||||
pfx_buf, sizeof(pfx_buf));
|
||||
zlog_debug(
|
||||
"%s rcvd %s, flapped quicker than processing",
|
||||
@ -3934,7 +3913,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, NULL, pfx_buf,
|
||||
addpath_id, evpn, pfx_buf,
|
||||
sizeof(pfx_buf));
|
||||
zlog_debug("%s rcvd %s", peer->host, pfx_buf);
|
||||
}
|
||||
@ -4207,7 +4186,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, NULL,
|
||||
addpath_id ? 1 : 0, addpath_id, evpn,
|
||||
pfx_buf, sizeof(pfx_buf));
|
||||
zlog_debug("%s rcvd %s", peer->host, pfx_buf);
|
||||
}
|
||||
@ -4239,11 +4218,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
||||
}
|
||||
}
|
||||
|
||||
/* Update Overlay Index */
|
||||
if (afi == AFI_L2VPN) {
|
||||
overlay_index_update(new->attr,
|
||||
evpn == NULL ? NULL : &evpn->gw_ip);
|
||||
}
|
||||
/* Nexthop reachability check. */
|
||||
if (((afi == AFI_IP || afi == AFI_IP6)
|
||||
&& (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
|
||||
@ -4353,7 +4327,7 @@ filtered:
|
||||
}
|
||||
|
||||
bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
|
||||
addpath_id ? 1 : 0, addpath_id, NULL,
|
||||
addpath_id ? 1 : 0, addpath_id, evpn,
|
||||
pfx_buf, sizeof(pfx_buf));
|
||||
zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
|
||||
peer->host, pfx_buf, reason);
|
||||
|
Loading…
Reference in New Issue
Block a user