From c809756f9f01919cdab9976a71d9b52ca89c44b0 Mon Sep 17 00:00:00 2001 From: Sathishkumar Muruganandam Date: Wed, 4 Jul 2018 15:01:02 +0530 Subject: [PATCH] nl80211: Allocate nl_sock for NETLINK_ROUTE when already_in_bridge 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 --- src/drivers/driver_nl80211.c | 15 ++++++++++----- src/drivers/driver_nl80211.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 5cff47fab..9d8137e00 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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" : ""); diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index 4bdeaa066..5ac0c7dfc 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -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;