nl80211: Fix interface-in-different-bridge case
authorJouni Malinen <j@w1.fi>
Sat, 20 Dec 2014 19:00:08 +0000 (21:00 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 20 Dec 2014 19:00:08 +0000 (21:00 +0200)
The local ifindex list needs to be updated only if the current bridge
interface is the correct one. If hostapd is going to move the interface
to another bridge, the old bridge ifindex must not be added. In
addition, when removing the bridge interface on deinit, it may need to
be set down to allow bridge removal.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/drivers/driver_nl80211.c

index c4eba58..c04286c 100644 (file)
@@ -2162,6 +2162,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
                        nl80211_handle_destroy(drv->rtnl_sk);
        }
        if (bss->added_bridge) {
+               linux_set_iface_flags(drv->global->ioctl_sock, bss->brname, 0);
                if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
                        wpa_printf(MSG_INFO, "nl80211: Failed to remove "
                                   "bridge %s: %s",
@@ -5501,16 +5502,21 @@ static void *i802_init(struct hostapd_data *hapd,
                                br_added = 1;
                }
        }
-       if (!br_added && br_ifindex &&
-           (params->num_bridge == 0 || !params->bridge[0]))
-               add_ifidx(drv, br_ifindex);
 
        /* start listening for EAPOL on the default AP interface */
        add_ifidx(drv, drv->ifindex);
 
-       if (params->num_bridge && params->bridge[0] &&
-           i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
-               goto failed;
+       if (params->num_bridge && params->bridge[0]) {
+               if (i802_check_bridge(drv, bss, params->bridge[0],
+                                     params->ifname) < 0)
+                       goto failed;
+               if (os_strcmp(params->bridge[0], brname) != 0)
+                       br_added = 1;
+       }
+
+       if (!br_added && br_ifindex &&
+           (params->num_bridge == 0 || !params->bridge[0]))
+               add_ifidx(drv, br_ifindex);
 
 #ifdef CONFIG_LIBNL3_ROUTE
        if (bss->added_if_into_bridge) {