]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Allocate nl_sock for NETLINK_ROUTE when already_in_bridge
authorSathishkumar Muruganandam <murugana@codeaurora.org>
Wed, 4 Jul 2018 09:31:02 +0000 (15:01 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 5 Jul 2018 10:36:27 +0000 (13:36 +0300)
When we start hostapd having Hotspot 2.0 configuration with interface
already added to bridge interface, addition and deletion of new neighbor
to bridge ip neighbor table fails.

This is since 'bss->added_if_into_bridge' is not set which only allows
'drv->rtnl_sk' (nl_sock for NETLINK_ROUTE) allocation needed for bridge
ip neighbor table.

Add a new bit 'already_in_bridge' and set it when interface is already
added to bridge by some external component. Check this bit in addition
to 'bss->added_if_into_bridge' for 'drv->rtnl_sk' allocation done in
i802_init().

Now 'drv->rtnl_sk' is closed in wpa_driver_nl80211_deinit() regardless of
'bss->added_if_into_bridge' since when we have 'bss->already_in_bridge'
case too, this need to be removed.

brctl show

bridge name     bridge id               STP enabled     interfaces
br0             8000.8efdf006b050       no              ap

hostapd_cli raw STATUS-DRIVER

Selected interface 'ap'
ifindex=15
ifname=ap
brname=br0
addr=8e:fd:f0:06:b0:50
freq=5180
beacon_set=1
already_in_bridge=1
..

Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h

index 5cff47fab6da49baca82195917f405172a0d0636..9d8137e009b6db0919e59cf7b697e3b98af83c84 100644 (file)
@@ -2603,9 +2603,11 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
                        wpa_printf(MSG_INFO, "nl80211: Failed to remove "
                                   "interface %s from bridge %s: %s",
                                   bss->ifname, bss->brname, strerror(errno));
-               if (drv->rtnl_sk)
-                       nl80211_handle_destroy(drv->rtnl_sk);
        }
+
+       if (drv->rtnl_sk)
+               nl80211_handle_destroy(drv->rtnl_sk);
+
        if (bss->added_bridge) {
                if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname,
                                          0) < 0)
@@ -6610,8 +6612,10 @@ static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
        bss->br_ifindex = br_ifindex;
 
        if (linux_br_get(in_br, ifname) == 0) {
-               if (os_strcmp(in_br, brname) == 0)
+               if (os_strcmp(in_br, brname) == 0) {
+                       bss->already_in_bridge = 1;
                        return 0; /* already in the bridge */
+               }
 
                wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
                           "bridge %s", ifname, in_br);
@@ -6708,7 +6712,7 @@ static void *i802_init(struct hostapd_data *hapd,
                add_ifidx(drv, br_ifindex, drv->ifindex);
 
 #ifdef CONFIG_LIBNL3_ROUTE
-       if (bss->added_if_into_bridge) {
+       if (bss->added_if_into_bridge || bss->already_in_bridge) {
                drv->rtnl_sk = nl_socket_alloc();
                if (drv->rtnl_sk == NULL) {
                        wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
@@ -8500,7 +8504,7 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
                          "brname=%s\n"
                          "addr=" MACSTR "\n"
                          "freq=%d\n"
-                         "%s%s%s%s%s",
+                         "%s%s%s%s%s%s",
                          bss->ifindex,
                          bss->ifname,
                          bss->brname,
@@ -8509,6 +8513,7 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
                          bss->beacon_set ? "beacon_set=1\n" : "",
                          bss->added_if_into_bridge ?
                          "added_if_into_bridge=1\n" : "",
+                         bss->already_in_bridge ? "already_in_bridge=1\n" : "",
                          bss->added_bridge ? "added_bridge=1\n" : "",
                          bss->in_deinit ? "in_deinit=1\n" : "",
                          bss->if_dynamic ? "if_dynamic=1\n" : "");
index 4bdeaa066cc95a7282a840aa3cd15e52228f0356..5ac0c7dfc8e856c238cf55e480f6f4b5de6fad10 100644 (file)
@@ -60,6 +60,7 @@ struct i802_bss {
        char brname[IFNAMSIZ];
        unsigned int beacon_set:1;
        unsigned int added_if_into_bridge:1;
+       unsigned int already_in_bridge:1;
        unsigned int added_bridge:1;
        unsigned int in_deinit:1;
        unsigned int wdev_id_set:1;