Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH wireless 0/2] wifi: mac80211: fix link changes of 4-address MLD stations
@ 2026-10-20 12:44 Piotr Kubik
  2026-10-20 12:44 ` [PATCH wireless 1/2] wifi: mac80211: change the links of an AP_VLAN station through its AP Piotr Kubik
  2026-10-20 12:44 ` [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links Piotr Kubik
  0 siblings, 2 replies; 4+ messages in thread
From: Piotr Kubik @ 2026-10-20 12:44 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Tamizh Chelvam Raja, Muna Sinada, linux-wireless, linux-kernel,
	Piotr Kubik

A 4-address (WDS) station of an AP MLD sits on an AP_VLAN interface.
Two faults appear when the links of such a station change, for
example when the station reassociates or removes a link with ML
reconfiguration:

- drv_change_sta_links() checks the AP_VLAN, which is never in the
  driver, so every link add fails with -EIO and a link removal stays
  in the driver.
- ieee80211_set_sta_4addr() adds the AP_VLAN links before it sets
  their addresses, so a link that the station gains later gets the
  zero address, and a second such link fails with -EALREADY. The
  station then stays on the AP interface.

Both come with 469d5d5a3b7a ("wifi: mac80211: synchronize valid links
for WDS AP_VLAN interfaces"). Tested with mt7996e on a 2-link AP MLD
(5 GHz + 6 GHz) and a 4-address non-AP MLD: after repeated
reassociation and after a link removal, the station stays on its
AP_VLAN with all of its links.

Piotr Kubik (2):
  wifi: mac80211: change the links of an AP_VLAN station through its AP
  wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links

  net/mac80211/cfg.c        |   17 ++++++++++-------
  net/mac80211/driver-ops.c |    1 +
  2 files changed, 11 insertions(+), 7 deletions(-)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH wireless 1/2] wifi: mac80211: change the links of an AP_VLAN station through its AP
  2026-10-20 12:44 [PATCH wireless 0/2] wifi: mac80211: fix link changes of 4-address MLD stations Piotr Kubik
@ 2026-10-20 12:44 ` Piotr Kubik
  2026-10-20 12:44 ` [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links Piotr Kubik
  1 sibling, 0 replies; 4+ messages in thread
From: Piotr Kubik @ 2026-10-20 12:44 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Tamizh Chelvam Raja, Muna Sinada, linux-wireless, linux-kernel,
	Piotr Kubik, stable

A 4-address station of an AP MLD moves to an AP_VLAN interface, so its
sta->sdata is the AP_VLAN. The AP_VLAN is never added to the driver,
so check_sdata_in_driver() in drv_change_sta_links() warns and returns
-EIO for every link change of such a station. Adding a link fails, and
removing a link leaves it in the driver, because
ieee80211_sta_remove_link() ignores the error.

Map the AP_VLAN to its AP first, as drv_sta_state() does.

Fixes: 469d5d5a3b7a ("wifi: mac80211: synchronize valid links for WDS AP_VLAN interfaces")
Cc: stable@vger.kernel.org
Signed-off-by: Piotr Kubik <piotr@kubik.pl>
---
  net/mac80211/driver-ops.c |    1 +
  1 file changed, 1 insertion(+)

diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -593,6 +593,7 @@ int drv_change_sta_links(struct ieee8021
 	might_sleep();
 	lockdep_assert_wiphy(local->hw.wiphy);
 
+	sdata = get_bss_sdata(sdata);
 	if (!check_sdata_in_driver(sdata))
 		return -EIO;
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links
  2026-10-20 12:44 [PATCH wireless 0/2] wifi: mac80211: fix link changes of 4-address MLD stations Piotr Kubik
  2026-10-20 12:44 ` [PATCH wireless 1/2] wifi: mac80211: change the links of an AP_VLAN station through its AP Piotr Kubik
@ 2026-10-20 12:44 ` Piotr Kubik
  2026-10-21  4:05   ` kernel test robot
  1 sibling, 1 reply; 4+ messages in thread
From: Piotr Kubik @ 2026-10-20 12:44 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Tamizh Chelvam Raja, Muna Sinada, linux-wireless, linux-kernel,
	Piotr Kubik, stable

ieee80211_set_sta_4addr() gives the AP_VLAN of a 4-address MLD station
the links of that station. It added the links first and set
wdev->links[].addr afterwards, from the link_conf of the AP_VLAN
itself. ieee80211_link_init() takes the address of a new link from
wdev->links[].addr, so a link that the station gained later came up
with the zero address that an earlier call had set, and the copy from
its own link_conf kept it at zero. With two such links,
ieee80211_check_dup_link_addrs() refuses the change with -EALREADY,
and the station stays on the AP interface instead of its AP_VLAN.

Set the addresses from the link_conf of the AP before the links are
added, as the AP_VLAN link update in link.c does.

Fixes: 469d5d5a3b7a ("wifi: mac80211: synchronize valid links for WDS AP_VLAN interfaces")
Cc: stable@vger.kernel.org
Signed-off-by: Piotr Kubik <piotr@kubik.pl>
---
  net/mac80211/cfg.c |   17 ++++++++++-------
  1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2823,26 +2823,29 @@ static int ieee80211_set_sta_4addr(struc
 
 		wdev->valid_links = new_links;
 
-		err = ieee80211_vif_set_links(sdata, new_links, 0);
-		if (err) {
-			wdev->valid_links = orig_links;
-			return err;
-		}
-
 		master_iter = master->vif.valid_links;
 
+		/* ieee80211_link_init() takes the address of a new link from
+		 * wdev->links, so set it before the links are added.
+		 */
 		for_each_set_bit(link_id, &master_iter,
 				 IEEE80211_MLD_MAX_NUM_LINKS) {
 			if (!(sta_links & BIT(link_id))) {
 				eth_zero_addr(wdev->links[link_id].addr);
 			} else {
 				link_conf = wiphy_dereference(wiphy,
-							      vif->link_conf[link_id]);
+							      master->vif.link_conf[link_id]);
 
 				ether_addr_copy(wdev->links[link_id].addr,
 						link_conf->bssid);
 			}
 		}
+
+		err = ieee80211_vif_set_links(sdata, new_links, 0);
+		if (err) {
+			wdev->valid_links = orig_links;
+			return err;
+		}
 	}
 
 	rcu_assign_pointer(sdata->u.vlan.sta, sta);

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links
  2026-10-20 12:44 ` [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links Piotr Kubik
@ 2026-10-21  4:05   ` kernel test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2026-10-21  4:05 UTC (permalink / raw)
  To: Piotr Kubik, Johannes Berg
  Cc: oe-kbuild-all, Tamizh Chelvam Raja, Muna Sinada, linux-wireless,
	linux-kernel, Piotr Kubik, stable

Hi Piotr,

kernel test robot noticed the following build warnings:

[auto build test WARNING on wireless/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Piotr-Kubik/wifi-mac80211-change-the-links-of-an-AP_VLAN-station-through-its-AP/20261020-144445
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git main
patch link:    https://lore.kernel.org/r/20261020124446.188739-3-piotr%40kubik.pl
patch subject: [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links
config: powerpc-randconfig-1001-20261021 (https://download.01.org/0day-ci/archive/20261021/202610211107.BOyMUaJh-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 15.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261021/202610211107.BOyMUaJh-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610211107.BOyMUaJh-lkp@intel.com/

All warnings (new ones prefixed by >>):

   net/mac80211/cfg.c: In function 'ieee80211_set_sta_4addr':
>> net/mac80211/cfg.c:2739:31: warning: unused variable 'vif' [-Wunused-variable]
    2739 |         struct ieee80211_vif *vif = &sdata->vif;
         |                               ^~~


vim +/vif +2739 net/mac80211/cfg.c

4fd6931ebe24640 Johannes Berg       2007-12-19  2734  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2735  static int ieee80211_set_sta_4addr(struct ieee80211_local *local,
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2736  				   struct ieee80211_sub_if_data *sdata,
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2737  				   struct sta_info *sta)
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2738  {
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26 @2739  	struct ieee80211_vif *vif = &sdata->vif;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2740  	struct wiphy *wiphy = local->hw.wiphy;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2741  	struct ieee80211_sub_if_data *master;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2742  	struct ieee80211_bss_conf *link_conf;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2743  	struct wireless_dev *wdev;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2744  	unsigned long master_iter;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2745  	int link_id;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2746  	int err;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2747  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2748  	lockdep_assert_wiphy(local->hw.wiphy);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2749  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2750  	if (sdata->u.vlan.sta)
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2751  		return -EBUSY;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2752  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2753  	wdev = &sdata->wdev;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2754  	master = container_of(sdata->bss,
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2755  			      struct ieee80211_sub_if_data,
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2756  			      u.ap);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2757  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2758  	if (sta->sta.valid_links) {
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2759  		u16 sta_links = sta->sta.valid_links;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2760  		u16 new_links = master->vif.valid_links & sta_links;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2761  		u16 orig_links = wdev->valid_links;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2762  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2763  		wdev->valid_links = new_links;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2764  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2765  		master_iter = master->vif.valid_links;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2766  
5cb41f5375432b4 Piotr Kubik         2026-10-20  2767  		/* ieee80211_link_init() takes the address of a new link from
5cb41f5375432b4 Piotr Kubik         2026-10-20  2768  		 * wdev->links, so set it before the links are added.
5cb41f5375432b4 Piotr Kubik         2026-10-20  2769  		 */
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2770  		for_each_set_bit(link_id, &master_iter,
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2771  				 IEEE80211_MLD_MAX_NUM_LINKS) {
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2772  			if (!(sta_links & BIT(link_id))) {
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2773  				eth_zero_addr(wdev->links[link_id].addr);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2774  			} else {
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2775  				link_conf = wiphy_dereference(wiphy,
5cb41f5375432b4 Piotr Kubik         2026-10-20  2776  							      master->vif.link_conf[link_id]);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2777  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2778  				ether_addr_copy(wdev->links[link_id].addr,
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2779  						link_conf->bssid);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2780  			}
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2781  		}
5cb41f5375432b4 Piotr Kubik         2026-10-20  2782  
5cb41f5375432b4 Piotr Kubik         2026-10-20  2783  		err = ieee80211_vif_set_links(sdata, new_links, 0);
5cb41f5375432b4 Piotr Kubik         2026-10-20  2784  		if (err) {
5cb41f5375432b4 Piotr Kubik         2026-10-20  2785  			wdev->valid_links = orig_links;
5cb41f5375432b4 Piotr Kubik         2026-10-20  2786  			return err;
5cb41f5375432b4 Piotr Kubik         2026-10-20  2787  		}
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2788  	}
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2789  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2790  	rcu_assign_pointer(sdata->u.vlan.sta, sta);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2791  	__ieee80211_check_fast_rx_iface(sdata);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2792  	drv_sta_set_4addr(local, sta->sdata, &sta->sta, true);
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2793  
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2794  	return 0;
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2795  }
469d5d5a3b7a133 Tamizh Chelvam Raja 2026-03-26  2796  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-21  4:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-20 12:44 [PATCH wireless 0/2] wifi: mac80211: fix link changes of 4-address MLD stations Piotr Kubik
2026-10-20 12:44 ` [PATCH wireless 1/2] wifi: mac80211: change the links of an AP_VLAN station through its AP Piotr Kubik
2026-10-20 12:44 ` [PATCH wireless 2/2] wifi: mac80211: set the link addresses of a 4-address AP_VLAN before its links Piotr Kubik
2026-10-21  4:05   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox