diff options
Diffstat (limited to 'zebra/zebra_l2.c')
| -rw-r--r-- | zebra/zebra_l2.c | 85 |
1 files changed, 59 insertions, 26 deletions
diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 4c0cc62fbf..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 */ @@ -53,13 +54,7 @@ static void map_slaves_to_bridge(struct interface *br_if, int link) { struct vrf *vrf; struct interface *ifp; - struct zebra_vrf *zvrf; - struct zebra_ns *zns; - zvrf = zebra_vrf_lookup_by_id(br_if->vrf_id); - assert(zvrf); - zns = zvrf->zns; - assert(zns); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { FOR_ALL_INTERFACES (vrf, ifp) { struct zebra_if *zif; @@ -78,8 +73,7 @@ static void map_slaves_to_bridge(struct interface *br_if, int link) br_slave = &zif->brslave_info; if (link) { - if (br_slave->bridge_ifindex == br_if->ifindex && - br_slave->ns_id == zns->ns_id) + if (br_slave->bridge_ifindex == br_if->ifindex) br_slave->br_if = br_if; } else { if (br_slave->br_if == br_if) @@ -90,14 +84,12 @@ static void map_slaves_to_bridge(struct interface *br_if, int link) } /* Public functions */ -void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave, - struct zebra_ns *zns) +void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave) { struct interface *br_if; /* TODO: Handle change of master */ - assert(zns); - br_if = if_lookup_by_index_per_ns(zebra_ns_lookup(zns->ns_id), + br_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), br_slave->bridge_ifindex); if (br_if) br_slave->br_if = br_if; @@ -119,7 +111,7 @@ void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, bond_slave->bond_if = bond_if; else bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex, - vrf_id, NULL); + vrf_id); } void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave) @@ -191,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; } @@ -229,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); } @@ -237,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); } @@ -246,32 +248,23 @@ void zebra_l2_vxlanif_del(struct interface *ifp) * from a bridge before it can be mapped to another bridge. */ void zebra_l2if_update_bridge_slave(struct interface *ifp, - ifindex_t bridge_ifindex, - ns_id_t ns_id) + ifindex_t bridge_ifindex) { struct zebra_if *zif; ifindex_t old_bridge_ifindex; - ns_id_t old_ns_id; - struct zebra_vrf *zvrf; zif = ifp->info; assert(zif); - zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id); - if (!zvrf) - return; - old_bridge_ifindex = zif->brslave_info.bridge_ifindex; - old_ns_id = zif->brslave_info.ns_id; - if (old_bridge_ifindex == bridge_ifindex && - old_ns_id == zif->brslave_info.ns_id) + if (old_bridge_ifindex == bridge_ifindex) return; - zif->brslave_info.ns_id = ns_id; zif->brslave_info.bridge_ifindex = bridge_ifindex; + /* Set up or remove link with master */ if (bridge_ifindex != IFINDEX_INTERNAL) { - zebra_l2_map_slave_to_bridge(&zif->brslave_info, zvrf->zns); + zebra_l2_map_slave_to_bridge(&zif->brslave_info); /* In the case of VxLAN, invoke the handler for EVPN. */ if (zif->zif_type == ZEBRA_IF_VXLAN) zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE); @@ -307,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); + } +} |
