]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: advertise svi ip as macip route changes 3745/head
authorChirag Shah <chirag@cumulusnetworks.com>
Tue, 5 Feb 2019 16:38:35 +0000 (08:38 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Thu, 7 Feb 2019 03:57:53 +0000 (19:57 -0800)
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>
zebra/zapi_msg.c
zebra/zebra_vrf.h
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zebra_vxlan_private.h

index 3bf03039b1227a8a0aa9b1b05a1ac2a34c8eaf01..9b91289decb20f34c8d4a9005f721c1b75f0f9fc 100644 (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,
index 2473299d1763e06db5b90c54185533ba85b38530..e35101d83313d6ba6a92c2df525cb505fd812bfc 100644 (file)
@@ -122,6 +122,8 @@ struct zebra_vrf {
         */
        int advertise_gw_macip;
 
+       int advertise_svi_macip;
+
        /* l3-vni info */
        vni_t l3vni;
 
index 069da828508c78ba33a534b9eedc86fd89acaeb7..560cd89abd781dde7fbaa1d3890d6855c232df92 100644 (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
index c25e7357edd532e793ae41e3995d2a9197cc901f..2cf21ff90b649c0a2997e54513f0a97e05347294 100644 (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);
index cae0d62bb307910e890ff8a324c1658a1e98c9b8..c36d156359f305d965108169864d5346e62204b1 100644 (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;