]> git.puffer.fish Git - matthieu/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, 21 Sep 2020 07:17:10 +0000 (09:17 +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 c3eab60148a9ff9dc43ac6fe67bb58a6aa1ab75b..90a08bbd6c4d897154f4945705be465739a57cc3 100644 (file)
@@ -850,7 +850,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);
 
@@ -1442,7 +1442,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) {
@@ -1543,7 +1544,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 d8674beb415fa3e469f13a306acf595fc4f1a6a4..417056ecb0ee7e3e6237ff914b8dd43057ecf6f3 100644 (file)
@@ -54,7 +54,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;
@@ -73,7 +79,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)
@@ -250,10 +257,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;
@@ -264,9 +273,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 79d2e4feca3b082c36212373bfa48a1f30b07168..f3b15c777057eb7768b09d3be77d36e97921b88b 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);