From f940f7c1ac85b07374bf7801e5a7f551a67521ff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 23 Jun 2025 11:21:48 +0200 Subject: [PATCH] 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 Signed-off-by: Felix Fietkau --- .../patches/370-preserve_radio_mask.patch | 158 ++++++++++++++++++ .../patches/463-add-mcast_rate-to-11s.patch | 4 +- .../hostapd/patches/601-ucode_support.patch | 20 +-- .../hostapd/patches/740-snoop_iface.patch | 4 +- ...ment-APuP-Access-Point-Micro-Peering.patch | 2 +- 5 files changed, 173 insertions(+), 15 deletions(-) create mode 100644 package/network/services/hostapd/patches/370-preserve_radio_mask.patch diff --git a/package/network/services/hostapd/patches/370-preserve_radio_mask.patch b/package/network/services/hostapd/patches/370-preserve_radio_mask.patch new file mode 100644 index 00000000000..77bcfa8dbb0 --- /dev/null +++ b/package/network/services/hostapd/patches/370-preserve_radio_mask.patch @@ -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; diff --git a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch index 917b4ac3b62..262c398015a 100644 --- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch @@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich struct wpa_driver_set_key_params { --- a/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 static int nl80211_put_mesh_config(struct nl_msg *msg, 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_mesh_id(msg, params->meshid, params->meshid_len) || nl80211_put_beacon_int(msg, params->beacon_int) || diff --git a/package/network/services/hostapd/patches/601-ucode_support.patch b/package/network/services/hostapd/patches/601-ucode_support.patch index 7bf464f2d9b..865a01cc987 100644 --- a/package/network/services/hostapd/patches/601-ucode_support.patch +++ b/package/network/services/hostapd/patches/601-ucode_support.patch @@ -322,7 +322,7 @@ as adding/removing interfaces. 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; } @@ -330,7 +330,7 @@ as adding/removing interfaces. 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); @@ -339,7 +339,7 @@ as adding/removing interfaces. 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); @@ -348,7 +348,7 @@ as adding/removing interfaces. 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); @@ -356,7 +356,7 @@ as adding/removing interfaces. 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; @@ -364,7 +364,7 @@ as adding/removing interfaces. 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; @@ -372,7 +372,7 @@ as adding/removing interfaces. 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); @@ -404,7 +404,7 @@ as adding/removing interfaces. } 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; } @@ -455,7 +455,7 @@ as adding/removing interfaces. 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 */ @@ -493,7 +493,7 @@ as adding/removing interfaces. 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, diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch index 1933247f8c9..6dc62a53287 100644 --- a/package/network/services/hostapd/patches/740-snoop_iface.patch +++ b/package/network/services/hostapd/patches/740-snoop_iface.patch @@ -123,7 +123,7 @@ untagged DHCP packets * get_wowlan - Get wake-on-wireless status --- a/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, @@ -132,7 +132,7 @@ untagged DHCP packets { struct i802_bss *bss = priv; 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; } diff --git a/package/network/services/hostapd/patches/780-Implement-APuP-Access-Point-Micro-Peering.patch b/package/network/services/hostapd/patches/780-Implement-APuP-Access-Point-Micro-Peering.patch index 72c48a3d003..5f50f46869f 100644 --- a/package/network/services/hostapd/patches/780-Implement-APuP-Access-Point-Micro-Peering.patch +++ b/package/network/services/hostapd/patches/780-Implement-APuP-Access-Point-Micro-Peering.patch @@ -429,7 +429,7 @@ Hotfix-by: Sebastian Gottschall https://github.com/mirror/dd-wrt/commit/0c3001a6 * send_action - Transmit an Action frame --- a/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, -- 2.47.2