--- /dev/null
+--- 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;
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err);
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);
return NULL;
}
nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
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)",
namebuf, ifname);
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface down",
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)",
namebuf, ifname);
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface up",
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);
nl_cache_free(cache);
nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
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)
return -1;
nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
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];
int ifindex, br_ifindex = 0;
int br_added = 0;
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
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]))
add_ifidx(drv, br_ifindex, drv->ifindex);
}
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;
}
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 */
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
size_t data_len, int noack,
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,
.if_add = wpa_driver_nl80211_if_add,
.if_remove = driver_nl80211_if_remove,