]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: bridge layer2 information records ns_id where bridge is
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 3 Oct 2019 15:11:37 +0000 (17:11 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 18 May 2020 12:11:03 +0000 (14:11 +0200)
when working with vrf netns backend, two bridges interfaces may have the
same bridge interface index, but not the same namespace. because in vrf
netns backend mode, a bridge slave always belong to the same network
namespace, then a check with the namespace id and the ns id of the
bridge interface permits to resolve correctly the interface pointer.
The problem could occur if a same index of two bridge interfaces can be
found on two different namespaces.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
zebra/if_netlink.c
zebra/zebra_l2.c
zebra/zebra_l2.h

index 782de87a7577ad241d9adb09ccd8d4c33cfd3487..55bcda81827904c657babd1be9ed8d29f9e348d6 100644 (file)
@@ -774,7 +774,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA],
                                        1, link_nsid);
        if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
-               zebra_l2if_update_bridge_slave(ifp, bridge_ifindex);
+               zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id);
        else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
                zebra_l2if_update_bond_slave(ifp, bond_ifindex);
 
@@ -1351,7 +1351,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                1, link_nsid);
                        if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
                                zebra_l2if_update_bridge_slave(ifp,
-                                                              bridge_ifindex);
+                                                              bridge_ifindex,
+                                                              ns_id);
                        else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
                                zebra_l2if_update_bond_slave(ifp, bond_ifindex);
                } else if (ifp->vrf_id != vrf_id) {
@@ -1454,7 +1455,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                0, link_nsid);
                        if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
                                zebra_l2if_update_bridge_slave(ifp,
-                                                              bridge_ifindex);
+                                                              bridge_ifindex,
+                                                              ns_id);
                        else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
                                zebra_l2if_update_bond_slave(ifp, bond_ifindex);
                }
index d12fb3e30d40740241791282900fdb68bb16f4b3..a214494492dfd1e114278a038339829aa4ecc384 100644 (file)
@@ -53,7 +53,13 @@ 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;
@@ -72,7 +78,8 @@ 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)
+                               if (br_slave->bridge_ifindex == br_if->ifindex &&
+                                   br_slave->ns_id == zns->ns_id)
                                        br_slave->br_if = br_if;
                        } else {
                                if (br_slave->br_if == br_if)
@@ -239,10 +246,12 @@ 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)
+                                   ifindex_t bridge_ifindex,
+                                   ns_id_t ns_id)
 {
        struct zebra_if *zif;
        ifindex_t old_bridge_ifindex;
+       ns_id_t old_ns_id;
        struct zebra_vrf *zvrf;
 
        zif = ifp->info;
@@ -253,9 +262,12 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
                return;
 
        old_bridge_ifindex = zif->brslave_info.bridge_ifindex;
-       if (old_bridge_ifindex == bridge_ifindex)
+       old_ns_id = zif->brslave_info.ns_id;
+       if (old_bridge_ifindex == bridge_ifindex &&
+           old_ns_id == zif->brslave_info.ns_id)
                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) {
index 3e8de79951c3d075291390fb0651926e88a70cd8..a3c780ee091e7021de70c1f5b444b7f46e50a9d1 100644 (file)
@@ -37,6 +37,7 @@ extern "C" {
 struct zebra_l2info_brslave {
        ifindex_t bridge_ifindex; /* Bridge Master */
        struct interface *br_if;  /* Pointer to master */
+       ns_id_t ns_id; /* network namespace where bridge is */
 };
 
 /* zebra L2 interface information - bridge interface */
@@ -102,7 +103,8 @@ extern void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
                                                vlanid_t access_vlan);
 extern void zebra_l2_vxlanif_del(struct interface *ifp);
 extern void zebra_l2if_update_bridge_slave(struct interface *ifp,
-                                          ifindex_t bridge_ifindex);
+                                          ifindex_t bridge_ifindex,
+                                          ns_id_t ns_id);
 
 extern void zebra_l2if_update_bond_slave(struct interface *ifp,
                                         ifindex_t bond_ifindex);