bgpd: add config knobs to disable rx and tx of ead-per-evi routes

Some vendors only advertise EAD-per-ES routes i.e. they do not
advertise EAD-per-EVI routes. To interop with these vendors we need
to relax the dependancy on EAD-per-EVI routes to activate a remote ES-PE.

Sample config -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
router bgp 5553
 address-family l2vpn evpn
  disable-ead-evi-rx
>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Ticket: CM-31177

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
Anuradha Karuppiah 2020-08-25 18:31:29 -07:00 committed by Anuradha Karuppiah
parent 9c47491551
commit fe8293c326
4 changed files with 79 additions and 7 deletions

View File

@ -990,6 +990,10 @@ static void bgp_evpn_local_type1_evi_route_add(struct bgp *bgp,
struct prefix_evpn p; struct prefix_evpn p;
struct bgp_evpn_es_evi *es_evi; struct bgp_evpn_es_evi *es_evi;
/* EAD-per-EVI routes have been suppressed */
if (!bgp_mh_info->ead_evi_tx)
return;
if (CHECK_FLAG(es->flags, BGP_EVPNES_ADV_EVI)) if (CHECK_FLAG(es->flags, BGP_EVPNES_ADV_EVI))
/* EAD-EVI route add for this ES is already done */ /* EAD-EVI route add for this ES is already done */
return; return;
@ -2717,14 +2721,20 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
{ {
bool old_active; bool old_active;
bool new_active; bool new_active;
uint32_t ead_activity_flags;
old_active = !!CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE); old_active = !!CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
if (bgp_mh_info->ead_evi_rx)
/* Both EAD-per-ES and EAD-per-EVI routes must be rxed from a PE /* Both EAD-per-ES and EAD-per-EVI routes must be rxed from a PE
* before it can be activated. * before it can be activated.
*/ */
if ((evi_vtep->flags & BGP_EVPN_EVI_VTEP_EAD) == ead_activity_flags = BGP_EVPN_EVI_VTEP_EAD;
BGP_EVPN_EVI_VTEP_EAD) else
/* EAD-per-ES is sufficent to activate the PE */
ead_activity_flags = BGP_EVPN_EVI_VTEP_EAD_PER_ES;
if ((evi_vtep->flags & ead_activity_flags) == ead_activity_flags)
SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE); SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
else else
UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE); UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
@ -3075,9 +3085,9 @@ int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni)
bgp_evpn_es_evi_local_info_set(es_evi); bgp_evpn_es_evi_local_info_set(es_evi);
/* generate an EAD-EVI for this new VNI */ /* generate an EAD-EVI for this new VNI */
build_evpn_type1_prefix(&p, BGP_EVPN_AD_EVI_ETH_TAG,
&es->esi, es->originator_ip);
if (CHECK_FLAG(es->flags, BGP_EVPNES_ADV_EVI)) { if (CHECK_FLAG(es->flags, BGP_EVPNES_ADV_EVI)) {
build_evpn_type1_prefix(&p, BGP_EVPN_AD_EVI_ETH_TAG, &es->esi,
es->originator_ip);
if (bgp_evpn_type1_route_update(bgp, es, vpn, &p)) if (bgp_evpn_type1_route_update(bgp, es, vpn, &p))
flog_err(EC_BGP_EVPN_ROUTE_CREATE, flog_err(EC_BGP_EVPN_ROUTE_CREATE,
"%u: EAD-EVI route creation failure for ESI %s VNI %u", "%u: EAD-EVI route creation failure for ESI %s VNI %u",
@ -3700,6 +3710,9 @@ void bgp_evpn_mh_init(void)
bgp_mh_info->pend_es_list = list_new(); bgp_mh_info->pend_es_list = list_new();
listset_app_node_mem(bgp_mh_info->pend_es_list); listset_app_node_mem(bgp_mh_info->pend_es_list);
bgp_mh_info->ead_evi_rx = BGP_EVPN_MH_EAD_EVI_RX_DEF;
bgp_mh_info->ead_evi_tx = BGP_EVPN_MH_EAD_EVI_TX_DEF;
/* config knobs - XXX add cli to control it */ /* config knobs - XXX add cli to control it */
bgp_mh_info->ead_evi_adv_for_down_links = true; bgp_mh_info->ead_evi_adv_for_down_links = true;
bgp_mh_info->consistency_checking = true; bgp_mh_info->consistency_checking = true;

View File

@ -261,6 +261,15 @@ struct bgp_evpn_mh_info {
/* Use L3 NHGs for host routes in symmetric IRB */ /* Use L3 NHGs for host routes in symmetric IRB */
bool install_l3nhg; bool install_l3nhg;
bool host_routes_use_l3nhg; bool host_routes_use_l3nhg;
/* Some vendors are not generating the EAD-per-EVI route. This knob
* can be turned off to activate a remote ES-PE when the EAD-per-ES
* route is rxed i.e. not wait on the EAD-per-EVI route
*/
bool ead_evi_rx;
#define BGP_EVPN_MH_EAD_EVI_RX_DEF true
/* Skip EAD-EVI advertisements by turning off this knob */
bool ead_evi_tx;
#define BGP_EVPN_MH_EAD_EVI_TX_DEF true
}; };
/****************************************************************************/ /****************************************************************************/

View File

@ -3757,6 +3757,26 @@ DEFPY (bgp_evpn_use_es_l3nhg,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFPY (bgp_evpn_ead_evi_rx_disable,
bgp_evpn_ead_evi_rx_disable_cmd,
"[no$no] disable-ead-evi-rx",
NO_STR
"Activate PE on EAD-ES even if EAD-EVI is not received\n")
{
bgp_mh_info->ead_evi_rx = no? true :false;
return CMD_SUCCESS;
}
DEFPY (bgp_evpn_ead_evi_tx_disable,
bgp_evpn_ead_evi_tx_disable_cmd,
"[no$no] disable-ead-evi-tx",
NO_STR
"Don't advertise EAD-EVI for local ESs\n")
{
bgp_mh_info->ead_evi_tx = no? true :false;
return CMD_SUCCESS;
}
DEFPY (bgp_evpn_advertise_pip_ip_mac, DEFPY (bgp_evpn_advertise_pip_ip_mac,
bgp_evpn_advertise_pip_ip_mac_cmd, bgp_evpn_advertise_pip_ip_mac_cmd,
"[no$no] advertise-pip [ip <A.B.C.D> [mac <X:X:X:X:X:X|X:X:X:X:X:X/M>]]", "[no$no] advertise-pip [ip <A.B.C.D> [mac <X:X:X:X:X:X|X:X:X:X:X:X/M>]]",
@ -5751,6 +5771,20 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
vty_out(vty, " no use-es-l3nhg\n"); vty_out(vty, " no use-es-l3nhg\n");
} }
if (bgp_mh_info->ead_evi_rx != BGP_EVPN_MH_EAD_EVI_RX_DEF) {
if (bgp_mh_info->ead_evi_rx)
vty_out(vty, " no disable-ead-evi-rx\n");
else
vty_out(vty, " disable-ead-evi-rx\n");
}
if (bgp_mh_info->ead_evi_tx != BGP_EVPN_MH_EAD_EVI_TX_DEF) {
if (bgp_mh_info->ead_evi_tx)
vty_out(vty, " no disable-ead-evi-tx\n");
else
vty_out(vty, " disable-ead-evi-tx\n");
}
if (!bgp->evpn_info->dup_addr_detect) if (!bgp->evpn_info->dup_addr_detect)
vty_out(vty, " no dup-addr-detection\n"); vty_out(vty, " no dup-addr-detection\n");
@ -5896,6 +5930,8 @@ void bgp_ethernetvpn_init(void)
install_element(BGP_EVPN_NODE, &bgp_evpn_flood_control_cmd); install_element(BGP_EVPN_NODE, &bgp_evpn_flood_control_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_pip_ip_mac_cmd); install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_pip_ip_mac_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_use_es_l3nhg_cmd); install_element(BGP_EVPN_NODE, &bgp_evpn_use_es_l3nhg_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_ead_evi_rx_disable_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_ead_evi_tx_disable_cmd);
/* test commands */ /* test commands */
install_element(BGP_EVPN_NODE, &test_es_add_cmd); install_element(BGP_EVPN_NODE, &test_es_add_cmd);

View File

@ -2682,6 +2682,20 @@ the traffic.
Similarly traffic received from ES peers via the overlay cannot be forwarded Similarly traffic received from ES peers via the overlay cannot be forwarded
to the server. This is split-horizon-filtering with local bias. to the server. This is split-horizon-filtering with local bias.
Knobs for interop
"""""""""""""""""
Some vendors do not send EAD-per-EVI routes. To interop with them we
need to relax the dependency on EAD-per-EVI routes and activate a remote
ES-PE based on just the EAD-per-ES route.
Note that by default we advertise and expect EAD-per-EVI routes.
.. index:: disable-ead-evi-rx
.. clicmd:: [no] disable-ead-evi-rx
.. index:: disable-ead-evi-tx
.. clicmd:: [no] disable-ead-evi-tx
Fast failover Fast failover
""""""""""""" """""""""""""
As the primary purpose of EVPN-MH is redundancy keeping the failover efficient As the primary purpose of EVPN-MH is redundancy keeping the failover efficient