]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_l2.c
Merge pull request #3465 from donaldsharp/nexthop_active_update
[mirror_frr.git] / zebra / zebra_l2.c
index 5d059a4502e691596232a77f9fe14c0464860e8a..f4b2fe4794da14d73d453b445d86820d2cde6c3c 100644 (file)
 static void map_slaves_to_bridge(struct interface *br_if, int link)
 {
        struct vrf *vrf;
-       struct listnode *node;
        struct interface *ifp;
 
-       RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
-       {
-               for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) {
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+               FOR_ALL_INTERFACES (vrf, ifp) {
                        struct zebra_if *zif;
                        struct zebra_l2info_brslave *br_slave;
 
@@ -101,6 +99,23 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
        br_slave->br_if = NULL;
 }
 
+void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave)
+{
+       struct interface *bond_if;
+
+       /* TODO: Handle change of master */
+       bond_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
+                                           bond_slave->bond_ifindex);
+       if (bond_if)
+               bond_slave->bond_if = bond_if;
+}
+
+void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave)
+{
+       if (bond_slave != NULL)
+               bond_slave->bond_if = NULL;
+}
+
 /*
  * Handle Bridge interface add or update. Update relevant info,
  * map slaves (if any) to the bridge.
@@ -224,12 +239,40 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
        zif->brslave_info.bridge_ifindex = bridge_ifindex;
 
        /* Set up or remove link with master */
-       if (bridge_ifindex != IFINDEX_INTERNAL)
+       if (bridge_ifindex != IFINDEX_INTERNAL) {
                zebra_l2_map_slave_to_bridge(&zif->brslave_info);
-       else if (old_bridge_ifindex != IFINDEX_INTERNAL)
+               /* 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);
+       } else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
+               /*
+                * In the case of VxLAN, invoke the handler for EVPN.
+                * Note that this should be done *prior*
+                * to unmapping the interface from the bridge.
+                */
+               if (zif->zif_type == ZEBRA_IF_VXLAN)
+                       zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
                zebra_l2_unmap_slave_from_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);
+void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex)
+{
+       struct zebra_if *zif;
+       ifindex_t old_bond_ifindex;
+
+       zif = ifp->info;
+       assert(zif);
+
+       old_bond_ifindex = zif->bondslave_info.bond_ifindex;
+       if (old_bond_ifindex == bond_ifindex)
+               return;
+
+       zif->bondslave_info.bond_ifindex = bond_ifindex;
+
+       /* Set up or remove link with master */
+       if (bond_ifindex != IFINDEX_INTERNAL)
+               zebra_l2_map_slave_to_bond(&zif->bondslave_info);
+       else if (old_bond_ifindex != IFINDEX_INTERNAL)
+               zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
 }