]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Accept a global nl80211 event to a bridged interface
authorAndrew Pope <andrew.pope@morsemicro.com>
Fri, 9 May 2025 00:00:30 +0000 (10:00 +1000)
committerJouni Malinen <j@w1.fi>
Thu, 19 Jun 2025 09:36:47 +0000 (12:36 +0300)
Global events originating/directed toward a bridged (i.e., WDS) station
are ignored by hostapd. These events are currently considered 'foreign'
and are dropped.

This problem was initially discovered while testing the configuration
parameter 'disassoc_low_ack=1' for bridged stations. It was observed
that the event 'STATION_LOW_ACK', communicated in
'NL80211_CMD_NOTIFY_CQM', would be ignored and the AP would fail to
disassociate the low ack station from the BSS.

Signed-off-by: Andrew Pope <andrew.pope@morsemicro.com>
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h
src/drivers/driver_nl80211_event.c

index 6c87e3c94d0a6da0af2dce73b1b40c95f76924c2..9e8d395939d757d434caad6a887eabae42f27ffe 100644 (file)
@@ -182,8 +182,6 @@ static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
                      int ifidx_reason);
 static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
                      int ifidx_reason);
-static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
-                     int ifidx_reason);
 
 static int nl80211_set_channel(struct i802_bss *bss,
                               struct hostapd_freq_params *freq, int set_chan);
@@ -1272,7 +1270,7 @@ nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len,
                                *init_failed = 1;
                        return drv;
                }
-               if (res > 0 || have_ifidx(drv, idx, IFIDX_ANY))
+               if (res > 0 || nl80211_has_ifidx(drv, idx, IFIDX_ANY))
                        return drv;
        }
        return NULL;
@@ -8585,7 +8583,7 @@ static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
        wpa_printf(MSG_DEBUG,
                   "nl80211: Add own interface ifindex %d (ifidx_reason %d)",
                   ifidx, ifidx_reason);
-       if (have_ifidx(drv, ifidx, ifidx_reason)) {
+       if (nl80211_has_ifidx(drv, ifidx, ifidx_reason)) {
                wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
                           ifidx);
                return;
@@ -8645,7 +8643,7 @@ static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
 }
 
 
-static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
+int nl80211_has_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
                      int ifidx_reason)
 {
        int i;
@@ -8752,7 +8750,7 @@ static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
                return;
        }
 
-       if (have_ifidx(drv, lladdr.sll_ifindex, IFIDX_ANY)) {
+       if (nl80211_has_ifidx(drv, lladdr.sll_ifindex, IFIDX_ANY)) {
                for (bss = drv->first_bss; bss; bss = bss->next)
                        drv_event_eapol_rx(bss->ctx, lladdr.sll_addr, buf, len);
        }
index c570fba1c8c5567993f22bd9edd0bb1d22270b96..674c26a71ada6b8b49e1e92e720b234b1d9c283e 100644 (file)
@@ -371,6 +371,8 @@ struct i802_link * nl80211_get_link(struct i802_bss *bss, s8 link_id);
 u8 nl80211_get_link_id_from_link(struct i802_bss *bss, struct i802_link *link);
 int nl80211_remove_link(struct i802_bss *bss, int link_id);
 void nl80211_update_active_links(struct i802_bss *bss, int link_id);
+int nl80211_has_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx,
+                     int ifidx_reason);
 
 static inline bool nl80211_link_valid(u16 links, s8 link_id)
 {
index 60e5f589244ffb5e821ee4695fd995a1296a656f..b331d92d06dae8ee340bd86eeaba59b09546f952 100644 (file)
@@ -4436,6 +4436,8 @@ int process_global_event(struct nl_msg *msg, void *arg)
                                wiphy_idx = nl80211_get_wiphy_index(bss);
                        if ((ifidx == -1 && !wiphy_idx_set && !wdev_id_set) ||
                            ifidx == bss->ifindex ||
+                           (bss->br_ifindex > 0 &&
+                            nl80211_has_ifidx(drv, bss->br_ifindex, ifidx)) ||
                            (wiphy_idx_set && wiphy_idx == wiphy_idx_rx) ||
                            (wdev_id_set && bss->wdev_id_set &&
                             wdev_id == bss->wdev_id)) {