hostapd: preserve vif radio mask for extra bss interfaces
Fixes status information and scanning on extra BSS interfaces when operating on multi-radio devices. Reported-by: Chad Monroe <chad.monroe@adtran.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
e3cf7088f1
commit
f940f7c1ac
5 changed files with 173 additions and 15 deletions
|
@ -0,0 +1,158 @@
|
||||||
|
--- a/src/drivers/driver_nl80211.h
|
||||||
|
+++ b/src/drivers/driver_nl80211.h
|
||||||
|
@@ -77,6 +77,7 @@ struct i802_bss {
|
||||||
|
u64 wdev_id;
|
||||||
|
char ifname[IFNAMSIZ + 1];
|
||||||
|
char brname[IFNAMSIZ];
|
||||||
|
+ u32 radio_mask;
|
||||||
|
unsigned int added_if_into_bridge:1;
|
||||||
|
unsigned int already_in_bridge:1;
|
||||||
|
unsigned int added_bridge:1;
|
||||||
|
@@ -325,7 +326,7 @@ send_and_recv_resp(struct wpa_driver_nl8
|
||||||
|
|
||||||
|
int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
|
const char *ifname, enum nl80211_iftype iftype,
|
||||||
|
- const u8 *addr, int wds,
|
||||||
|
+ const u8 *addr, int wds, u32 radio_mask,
|
||||||
|
int (*handler)(struct nl_msg *, void *),
|
||||||
|
void *arg, int use_existing);
|
||||||
|
void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx);
|
||||||
|
--- a/src/drivers/driver_nl80211.c
|
||||||
|
+++ b/src/drivers/driver_nl80211.c
|
||||||
|
@@ -755,6 +755,7 @@ struct wiphy_idx_data {
|
||||||
|
enum nl80211_iftype nlmode;
|
||||||
|
u8 *macaddr;
|
||||||
|
u8 use_4addr;
|
||||||
|
+ u32 radio_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -780,6 +781,9 @@ static int netdev_info_handler(struct nl
|
||||||
|
if (tb[NL80211_ATTR_4ADDR])
|
||||||
|
info->use_4addr = nla_get_u8(tb[NL80211_ATTR_4ADDR]);
|
||||||
|
|
||||||
|
+ if (tb[NL80211_ATTR_VIF_RADIO_MASK])
|
||||||
|
+ info->radio_mask = nla_get_u32(tb[NL80211_ATTR_VIF_RADIO_MASK]);
|
||||||
|
+
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -846,6 +850,20 @@ static int nl80211_get_4addr(struct i802
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+static u32 nl80211_get_radio_mask(struct i802_bss *bss)
|
||||||
|
+{
|
||||||
|
+ struct nl_msg *msg;
|
||||||
|
+ struct wiphy_idx_data data = {
|
||||||
|
+ .radio_mask = 0,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)) ||
|
||||||
|
+ send_and_recv_resp(bss->drv, msg, netdev_info_handler, &data))
|
||||||
|
+ return 0;
|
||||||
|
+ return data.radio_mask;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
|
||||||
|
struct nl80211_wiphy_data *w)
|
||||||
|
{
|
||||||
|
@@ -6171,7 +6189,7 @@ const char * nl80211_iftype_str(enum nl8
|
||||||
|
static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
|
||||||
|
const char *ifname,
|
||||||
|
enum nl80211_iftype iftype,
|
||||||
|
- const u8 *addr, int wds,
|
||||||
|
+ const u8 *addr, int wds, u32 radio_mask,
|
||||||
|
int (*handler)(struct nl_msg *, void *),
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
@@ -6191,6 +6209,10 @@ static int nl80211_create_iface_once(str
|
||||||
|
if (wds && nla_put_u8(msg, NL80211_ATTR_4ADDR, wds))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
+ if (radio_mask &&
|
||||||
|
+ nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, radio_mask))
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Tell cfg80211 that the interface belongs to the socket that created
|
||||||
|
* it, and the interface should be deleted when the socket is closed.
|
||||||
|
@@ -6246,14 +6268,14 @@ static int nl80211_create_iface_once(str
|
||||||
|
|
||||||
|
int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
|
const char *ifname, enum nl80211_iftype iftype,
|
||||||
|
- const u8 *addr, int wds,
|
||||||
|
+ const u8 *addr, int wds, u32 radio_mask,
|
||||||
|
int (*handler)(struct nl_msg *, void *),
|
||||||
|
void *arg, int use_existing)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
|
||||||
|
- arg);
|
||||||
|
+ ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, radio_mask,
|
||||||
|
+ handler, arg);
|
||||||
|
|
||||||
|
/* if error occurred and interface exists already */
|
||||||
|
if (ret < 0 && if_nametoindex(ifname)) {
|
||||||
|
@@ -6279,7 +6301,7 @@ int nl80211_create_iface(struct wpa_driv
|
||||||
|
|
||||||
|
/* Try to create the interface again */
|
||||||
|
ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
|
||||||
|
- wds, handler, arg);
|
||||||
|
+ wds, radio_mask, handler, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret >= 0 && is_p2p_net_interface(iftype)) {
|
||||||
|
@@ -8619,8 +8641,8 @@ static int i802_set_wds_sta(void *priv,
|
||||||
|
if (!if_nametoindex(name)) {
|
||||||
|
if (nl80211_create_iface(drv, name,
|
||||||
|
NL80211_IFTYPE_AP_VLAN,
|
||||||
|
- bss->addr, 1, NULL, NULL, 0) <
|
||||||
|
- 0)
|
||||||
|
+ bss->addr, 1, bss->radio_mask,
|
||||||
|
+ NULL, NULL, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (bridge_ifname)
|
||||||
|
@@ -8991,7 +9013,8 @@ static int wpa_driver_nl80211_if_add(voi
|
||||||
|
|
||||||
|
os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
|
||||||
|
ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
|
||||||
|
- 0, nl80211_wdev_handler,
|
||||||
|
+ 0, bss->radio_mask,
|
||||||
|
+ nl80211_wdev_handler,
|
||||||
|
&p2pdev_info, use_existing);
|
||||||
|
if (!p2pdev_info.wdev_id_set || ifidx != 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
|
||||||
|
@@ -9008,7 +9031,8 @@ static int wpa_driver_nl80211_if_add(voi
|
||||||
|
(long long unsigned int) p2pdev_info.wdev_id);
|
||||||
|
} else {
|
||||||
|
ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
|
||||||
|
- 0, NULL, NULL, use_existing);
|
||||||
|
+ 0, bss->radio_mask,
|
||||||
|
+ NULL, NULL, use_existing);
|
||||||
|
if (use_existing && ifidx == -ENFILE) {
|
||||||
|
added = 0;
|
||||||
|
ifidx = if_nametoindex(ifname);
|
||||||
|
@@ -9103,6 +9127,8 @@ static int wpa_driver_nl80211_if_add(voi
|
||||||
|
*drv_priv = new_bss;
|
||||||
|
nl80211_init_bss(new_bss);
|
||||||
|
|
||||||
|
+ new_bss->radio_mask = nl80211_get_radio_mask(new_bss);
|
||||||
|
+
|
||||||
|
/* Set interface mode to NL80211_IFTYPE_AP */
|
||||||
|
if (nl80211_set_mode(new_bss, nlmode))
|
||||||
|
return -1;
|
||||||
|
--- a/src/drivers/driver_nl80211_monitor.c
|
||||||
|
+++ b/src/drivers/driver_nl80211_monitor.c
|
||||||
|
@@ -98,7 +98,7 @@ static int nl80211_create_monitor_interf
|
||||||
|
buf[IFNAMSIZ - 1] = '\0';
|
||||||
|
|
||||||
|
*ifidx = nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
|
||||||
|
- 0, NULL, NULL, 0);
|
||||||
|
+ 0, 0, NULL, NULL, 0);
|
||||||
|
|
||||||
|
if (*ifidx < 0)
|
||||||
|
return -1;
|
|
@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||||
struct wpa_driver_set_key_params {
|
struct wpa_driver_set_key_params {
|
||||||
--- a/src/drivers/driver_nl80211.c
|
--- a/src/drivers/driver_nl80211.c
|
||||||
+++ b/src/drivers/driver_nl80211.c
|
+++ b/src/drivers/driver_nl80211.c
|
||||||
@@ -12269,6 +12269,18 @@ static int nl80211_put_mesh_id(struct nl
|
@@ -12295,6 +12295,18 @@ static int nl80211_put_mesh_id(struct nl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||||
static int nl80211_put_mesh_config(struct nl_msg *msg,
|
static int nl80211_put_mesh_config(struct nl_msg *msg,
|
||||||
struct wpa_driver_mesh_bss_params *params)
|
struct wpa_driver_mesh_bss_params *params)
|
||||||
{
|
{
|
||||||
@@ -12330,6 +12342,7 @@ static int nl80211_join_mesh(struct i802
|
@@ -12356,6 +12368,7 @@ static int nl80211_join_mesh(struct i802
|
||||||
nl80211_put_basic_rates(msg, params->basic_rates) ||
|
nl80211_put_basic_rates(msg, params->basic_rates) ||
|
||||||
nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
|
nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
|
||||||
nl80211_put_beacon_int(msg, params->beacon_int) ||
|
nl80211_put_beacon_int(msg, params->beacon_int) ||
|
||||||
|
|
|
@ -322,7 +322,7 @@ as adding/removing interfaces.
|
||||||
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
|
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
|
||||||
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err);
|
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err);
|
||||||
if (ack_handler_custom) {
|
if (ack_handler_custom) {
|
||||||
@@ -955,6 +973,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
|
@@ -973,6 +991,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
|
||||||
os_free(w);
|
os_free(w);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ as adding/removing interfaces.
|
||||||
nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
|
nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
|
||||||
no_seq_check, NULL);
|
no_seq_check, NULL);
|
||||||
nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
|
nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
|
||||||
@@ -1370,7 +1389,7 @@ static void wpa_driver_nl80211_event_rtm
|
@@ -1388,7 +1407,7 @@ static void wpa_driver_nl80211_event_rtm
|
||||||
}
|
}
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
|
wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
|
||||||
namebuf, ifname);
|
namebuf, ifname);
|
||||||
|
@ -339,7 +339,7 @@ as adding/removing interfaces.
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"nl80211: Not the main interface (%s) - do not indicate interface down",
|
"nl80211: Not the main interface (%s) - do not indicate interface down",
|
||||||
drv->first_bss->ifname);
|
drv->first_bss->ifname);
|
||||||
@@ -1406,7 +1425,7 @@ static void wpa_driver_nl80211_event_rtm
|
@@ -1424,7 +1443,7 @@ static void wpa_driver_nl80211_event_rtm
|
||||||
}
|
}
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
|
wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
|
||||||
namebuf, ifname);
|
namebuf, ifname);
|
||||||
|
@ -348,7 +348,7 @@ as adding/removing interfaces.
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"nl80211: Not the main interface (%s) - do not indicate interface up",
|
"nl80211: Not the main interface (%s) - do not indicate interface up",
|
||||||
drv->first_bss->ifname);
|
drv->first_bss->ifname);
|
||||||
@@ -2052,6 +2071,7 @@ static int wpa_driver_nl80211_init_nl_gl
|
@@ -2070,6 +2089,7 @@ static int wpa_driver_nl80211_init_nl_gl
|
||||||
genl_family_put(family);
|
genl_family_put(family);
|
||||||
nl_cache_free(cache);
|
nl_cache_free(cache);
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ as adding/removing interfaces.
|
||||||
nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
|
nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
|
||||||
no_seq_check, NULL);
|
no_seq_check, NULL);
|
||||||
nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
|
nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
|
||||||
@@ -2222,6 +2242,7 @@ static int nl80211_init_bss(struct i802_
|
@@ -2240,6 +2260,7 @@ static int nl80211_init_bss(struct i802_
|
||||||
if (!bss->nl_cb)
|
if (!bss->nl_cb)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ as adding/removing interfaces.
|
||||||
nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
|
nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
|
||||||
no_seq_check, NULL);
|
no_seq_check, NULL);
|
||||||
nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
|
nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
|
||||||
@@ -8763,6 +8784,7 @@ static void *i802_init(struct hostapd_da
|
@@ -8785,6 +8806,7 @@ static void *i802_init(struct hostapd_da
|
||||||
char master_ifname[IFNAMSIZ];
|
char master_ifname[IFNAMSIZ];
|
||||||
int ifindex, br_ifindex = 0;
|
int ifindex, br_ifindex = 0;
|
||||||
int br_added = 0;
|
int br_added = 0;
|
||||||
|
@ -372,7 +372,7 @@ as adding/removing interfaces.
|
||||||
|
|
||||||
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
|
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
|
||||||
params->global_priv, 1,
|
params->global_priv, 1,
|
||||||
@@ -8823,21 +8845,17 @@ static void *i802_init(struct hostapd_da
|
@@ -8845,21 +8867,17 @@ static void *i802_init(struct hostapd_da
|
||||||
(params->num_bridge == 0 || !params->bridge[0]))
|
(params->num_bridge == 0 || !params->bridge[0]))
|
||||||
add_ifidx(drv, br_ifindex, drv->ifindex);
|
add_ifidx(drv, br_ifindex, drv->ifindex);
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ as adding/removing interfaces.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
|
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
|
||||||
@@ -9210,6 +9228,50 @@ static int wpa_driver_nl80211_if_remove(
|
@@ -9236,6 +9254,50 @@ static int wpa_driver_nl80211_if_remove(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ as adding/removing interfaces.
|
||||||
|
|
||||||
static int cookie_handler(struct nl_msg *msg, void *arg)
|
static int cookie_handler(struct nl_msg *msg, void *arg)
|
||||||
{
|
{
|
||||||
@@ -11088,6 +11150,37 @@ static bool nl80211_is_drv_shared(void *
|
@@ -11114,6 +11176,37 @@ static bool nl80211_is_drv_shared(void *
|
||||||
#endif /* CONFIG_IEEE80211BE */
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ as adding/removing interfaces.
|
||||||
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
|
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
|
||||||
size_t data_len, int noack,
|
size_t data_len, int noack,
|
||||||
unsigned int freq,
|
unsigned int freq,
|
||||||
@@ -14813,6 +14906,8 @@ const struct wpa_driver_ops wpa_driver_n
|
@@ -14839,6 +14932,8 @@ const struct wpa_driver_ops wpa_driver_n
|
||||||
.set_acl = wpa_driver_nl80211_set_acl,
|
.set_acl = wpa_driver_nl80211_set_acl,
|
||||||
.if_add = wpa_driver_nl80211_if_add,
|
.if_add = wpa_driver_nl80211_if_add,
|
||||||
.if_remove = driver_nl80211_if_remove,
|
.if_remove = driver_nl80211_if_remove,
|
||||||
|
|
|
@ -123,7 +123,7 @@ untagged DHCP packets
|
||||||
* get_wowlan - Get wake-on-wireless status
|
* get_wowlan - Get wake-on-wireless status
|
||||||
--- a/src/drivers/driver_nl80211.c
|
--- a/src/drivers/driver_nl80211.c
|
||||||
+++ b/src/drivers/driver_nl80211.c
|
+++ b/src/drivers/driver_nl80211.c
|
||||||
@@ -12789,7 +12789,7 @@ static const char * drv_br_net_param_str
|
@@ -12815,7 +12815,7 @@ static const char * drv_br_net_param_str
|
||||||
|
|
||||||
|
|
||||||
static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
|
static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
|
||||||
|
@ -132,7 +132,7 @@ untagged DHCP packets
|
||||||
{
|
{
|
||||||
struct i802_bss *bss = priv;
|
struct i802_bss *bss = priv;
|
||||||
char path[128];
|
char path[128];
|
||||||
@@ -12815,8 +12815,11 @@ static int wpa_driver_br_set_net_param(v
|
@@ -12841,8 +12841,11 @@ static int wpa_driver_br_set_net_param(v
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -429,7 +429,7 @@ Hotfix-by: Sebastian Gottschall https://github.com/mirror/dd-wrt/commit/0c3001a6
|
||||||
* send_action - Transmit an Action frame
|
* send_action - Transmit an Action frame
|
||||||
--- a/src/drivers/driver_nl80211.c
|
--- a/src/drivers/driver_nl80211.c
|
||||||
+++ b/src/drivers/driver_nl80211.c
|
+++ b/src/drivers/driver_nl80211.c
|
||||||
@@ -8615,25 +8615,15 @@ static int have_ifidx(struct wpa_driver_
|
@@ -8637,25 +8637,15 @@ static int have_ifidx(struct wpa_driver_
|
||||||
|
|
||||||
|
|
||||||
static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
|
static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
|
||||||
|
|
Loading…
Reference in a new issue