summaryrefslogtreecommitdiff
path: root/zebra/zebra_l2.c
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2020-03-27 17:14:45 -0700
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>2020-08-05 06:46:12 -0700
commitce5160c08141db3002060189d624398409bd6317 (patch)
treedf19f2619fa3d2db3a186720f1cb341fee9550be /zebra/zebra_l2.c
parent506efd379b4ed72454650a32049028a7f5b4c5c8 (diff)
zebra: Ethernet segment management and support for MAC-ECMP
1. Local ethernet segments are configured in zebra by attaching a local-es-id and sys-mac to a access interface - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! interface hostbond1 evpn mh es-id 1 evpn mh es-sys-mac 00:00:00:00:01:11 ! >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> This info is then sent to BGP and used for the generation of EAD-per-ES routes. 2. Access VLANs associated with an (ES) access port are translated into ES-EVI objects and sent to BGP. This is used by BGP for the generation of EAD-EVI routes. 3. Remote ESs are imported by BGP and sent to zebra. A list of VTEPs is maintained per-remote ES in zebra. This list is used for the creation of the L2-NHG that is used for forwarding traffic. 4. MAC entries with a non-zero ESI destination use the L2-NHG associated with the ESI for forwarding traffic over the VxLAN overlay. Please see zebra_evpn_mh.h for the datastruct organization details. Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Diffstat (limited to 'zebra/zebra_l2.c')
-rw-r--r--zebra/zebra_l2.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c
index e549d80a5c..1758c8f96a 100644
--- a/zebra/zebra_l2.c
+++ b/zebra/zebra_l2.c
@@ -43,6 +43,7 @@
#include "zebra/rt_netlink.h"
#include "zebra/zebra_l2.h"
#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_evpn_mh.h"
/* definitions */
@@ -182,6 +183,7 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
if (add) {
memcpy(&zif->l2info.vxl, vxlan_info, sizeof(*vxlan_info));
+ zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
zebra_vxlan_if_add(ifp);
return;
}
@@ -220,6 +222,9 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
return;
zif->l2info.vxl.access_vlan = access_vlan;
+
+ zebra_evpn_vl_vxl_deref(old_access_vlan, zif);
+ zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_VLAN_CHANGE);
}
@@ -228,6 +233,12 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
*/
void zebra_l2_vxlanif_del(struct interface *ifp)
{
+ struct zebra_if *zif;
+
+ zif = ifp->info;
+ assert(zif);
+
+ zebra_evpn_vl_vxl_deref(zif->l2info.vxl.access_vlan, zif);
zebra_vxlan_if_del(ifp);
}
@@ -289,3 +300,43 @@ void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex)
else if (old_bond_ifindex != IFINDEX_INTERNAL)
zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
}
+
+void zebra_vlan_bitmap_compute(struct interface *ifp,
+ uint32_t vid_start, uint16_t vid_end)
+{
+ uint32_t vid;
+ struct zebra_if *zif;
+
+ zif = (struct zebra_if *)ifp->info;
+ assert(zif);
+
+ for (vid = vid_start; vid <= vid_end; ++vid)
+ bf_set_bit(zif->vlan_bitmap, vid);
+}
+
+void zebra_vlan_mbr_re_eval(struct interface *ifp, bitfield_t old_vlan_bitmap)
+{
+ uint32_t vid;
+ struct zebra_if *zif;
+
+ zif = (struct zebra_if *)ifp->info;
+ assert(zif);
+
+ if (!bf_cmp(zif->vlan_bitmap, old_vlan_bitmap))
+ /* no change */
+ return;
+
+ bf_for_each_set_bit(zif->vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
+ /* if not already set create new reference */
+ if (!bf_test_index(old_vlan_bitmap, vid))
+ zebra_evpn_vl_mbr_ref(vid, zif);
+
+ /* also clear from the old vlan bitmap */
+ bf_release_index(old_vlan_bitmap, vid);
+ }
+
+ /* any bits remaining in the old vlan bitmap are stale references */
+ bf_for_each_set_bit(old_vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
+ zebra_evpn_vl_mbr_deref(vid, zif);
+ }
+}