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 <murugana@codeaurora.org>
This commit is contained in:
Sathishkumar Muruganandam 2018-07-04 15:01:02 +05:30 committed by Jouni Malinen
parent 946e35eace
commit c809756f9f
2 changed files with 11 additions and 5 deletions

View 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" : "");

View 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;