zebra: advertise svi ip as macip route changes

In Asymmetric and symetric routing scenario in EVPN
where each VTEP pair having different set of addresses
for the SVIs.
This knob allows reachability (ping connectivity) of
SVI IPs and resolve ARP resoultion VTEPs across racks.

This knob should not be used when same SVI IPs configured
on VTEPs across racks or when advertise default gateway
is configured.

Ticket:CM-23782
Testing Done:
Bring up EVPN symmetric routing topology with different
SVI IPs on different VTEPs. Enable advertise svi ip
at each VTEP, remote VTEPs installs arp entry for
SVI IPs via EVPN type-2 route exchange.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
Chirag Shah 2019-02-05 08:38:35 -08:00
parent 24864e4497
commit 278e26de8e
5 changed files with 162 additions and 4 deletions

View File

@ -2457,6 +2457,7 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_FEC_REGISTER] = zread_fec_register,
[ZEBRA_FEC_UNREGISTER] = zread_fec_unregister,
[ZEBRA_ADVERTISE_DEFAULT_GW] = zebra_vxlan_advertise_gw_macip,
[ZEBRA_ADVERTISE_SVI_MACIP] = zebra_vxlan_advertise_svi_macip,
[ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet,
[ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
[ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,

View File

@ -122,6 +122,8 @@ struct zebra_vrf {
*/
int advertise_gw_macip;
int advertise_svi_macip;
/* l3-vni info */
vni_t l3vni;

View File

@ -180,6 +180,7 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
struct ipaddr *ip);
struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
static int advertise_gw_macip_enabled(zebra_vni_t *zvni);
static int advertise_svi_macip_enabled(zebra_vni_t *zvni);
static int zebra_vxlan_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
zebra_mac_t *old_zmac,
zebra_mac_t *new_zmac,
@ -333,6 +334,20 @@ static int advertise_gw_macip_enabled(zebra_vni_t *zvni)
return 0;
}
static int advertise_svi_macip_enabled(zebra_vni_t *zvni)
{
struct zebra_vrf *zvrf;
zvrf = vrf_info_lookup(VRF_DEFAULT);
if (zvrf && zvrf->advertise_svi_macip)
return 1;
if (zvni && zvni->advertise_svi_macip)
return 1;
return 0;
}
/* As part Duplicate Address Detection (DAD) for IP mobility
* MAC binding changes, ensure to inherit duplicate flag
* from MAC.
@ -2874,10 +2889,48 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
/* Add primary SVI MAC-IP */
zvni_add_macip_for_intf(vlan_if, zvni);
/* Add VRR MAC-IP - if any*/
vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
if (vrr_if)
zvni_add_macip_for_intf(vrr_if, zvni);
if (advertise_gw_macip_enabled(zvni)) {
/* Add VRR MAC-IP - if any*/
vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
if (vrr_if)
zvni_add_macip_for_intf(vrr_if, zvni);
}
return;
}
static void zvni_svi_macip_del_for_vni_hash(struct hash_backet *backet,
void *ctxt)
{
zebra_vni_t *zvni = NULL;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan zl2_info;
struct interface *vlan_if = NULL;
struct interface *ifp;
/* Add primary SVI MAC*/
zvni = (zebra_vni_t *)backet->data;
if (!zvni)
return;
ifp = zvni->vxlan_if;
if (!ifp)
return;
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return;
zl2_info = zif->l2info.vxl;
vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
zif->brslave_info.br_if);
if (!vlan_if)
return;
/* Del primary MAC-IP */
zvni_del_macip_for_intf(vlan_if, zvni);
return;
}
@ -6909,6 +6962,8 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
vty_out(vty, "Advertise gateway mac-ip: %s\n",
zvrf->advertise_gw_macip ? "Yes" : "No");
vty_out(vty, "Advertise svi mac-ip: %s\n",
zvrf->advertise_svi_macip ? "Yes" : "No");
vty_out(vty, "Duplicate address detection: %s\n",
zvrf->dup_addr_detect ? "Enable" : "Disable");
vty_out(vty, " Detection max-moves %u, time %d\n",
@ -8711,6 +8766,102 @@ stream_failure:
return;
}
/*
* Handle message from client to enable/disable advertisement of svi macip
* routes
*/
void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
{
struct stream *s;
int advertise;
vni_t vni = 0;
zebra_vni_t *zvni = NULL;
struct interface *ifp = NULL;
if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
zvrf_id(zvrf));
return;
}
s = msg;
STREAM_GETC(s, advertise);
STREAM_GETL(s, vni);
if (!vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("EVPN gateway macip Adv %s, currently %s",
advertise ? "enabled" : "disabled",
advertise_gw_macip_enabled(NULL)
? "enabled"
: "disabled");
if (zvrf->advertise_svi_macip == advertise)
return;
if (advertise) {
zvrf->advertise_svi_macip = advertise;
hash_iterate(zvrf->vni_table,
zvni_gw_macip_add_for_vni_hash, NULL);
} else {
hash_iterate(zvrf->vni_table,
zvni_svi_macip_del_for_vni_hash, NULL);
zvrf->advertise_svi_macip = advertise;
}
} else {
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan zl2_info;
struct interface *vlan_if = NULL;
zvni = zvni_lookup(vni);
if (!zvni)
return;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"EVPN SVI macip Adv %s on VNI %d , currently %s",
advertise ? "enabled" : "disabled", vni,
advertise_svi_macip_enabled(zvni)
? "enabled"
: "disabled");
if (zvni->advertise_svi_macip == advertise)
return;
ifp = zvni->vxlan_if;
if (!ifp)
return;
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return;
zl2_info = zif->l2info.vxl;
vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
zif->brslave_info.br_if);
if (!vlan_if)
return;
if (advertise) {
zvni->advertise_svi_macip = advertise;
/* Add primary SVI MAC-IP */
zvni_add_macip_for_intf(vlan_if, zvni);
} else {
/* Del primary MAC-IP */
zvni_del_macip_for_intf(vlan_if, zvni);
zvni->advertise_svi_macip = advertise;
}
}
stream_failure:
return;
}
/*
* Handle message from client to enable/disable advertisement of g/w macip
* routes

View File

@ -68,6 +68,7 @@ extern void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS);
extern void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS);

View File

@ -70,6 +70,9 @@ struct zebra_vni_t_ {
/* Flag for advertising gw macip */
uint8_t advertise_gw_macip;
/* Flag for advertising svi macip */
uint8_t advertise_svi_macip;
/* Flag for advertising gw macip */
uint8_t advertise_subnet;