difos/package/network/services/hostapd/patches/370-preserve_radio_mask.patch
Felix Fietkau bb279e1a69 hostapd: revert a broken upstream patch that was breaking multi-band operation
nl80211 events were propagated to the wrong interfaces

Fixes: 2ac791e87d ("hostapd: update to version 2025-06-27")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2025-07-06 18:47:41 +02:00

158 lines
5.1 KiB
Diff

--- 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)
{
@@ -6236,7 +6254,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)
{
@@ -6256,6 +6274,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.
@@ -6311,14 +6333,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)) {
@@ -6344,7 +6366,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)) {
@@ -8685,8 +8707,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)
@@ -9057,7 +9079,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",
@@ -9074,7 +9097,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);
@@ -9144,6 +9168,8 @@ static int wpa_driver_nl80211_if_add(voi
new_bss->ctx = bss_ctx;
new_bss->added_if = added;
+ 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;