Skip to content

Commit

Permalink
mac80211: allow driver to prevent two stations w/ same address
Browse files Browse the repository at this point in the history
commit 3110489 upstream.

Some devices or drivers cannot deal with having the same station
address for different virtual interfaces, say as a client to two
virtual AP interfaces. Rather than requiring each driver with a
limitation like that to enforce it, add a hardware flag for it.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Johannes Berg authored and Greg Kroah-Hartman committed Nov 24, 2020
1 parent 5eb47f3 commit fa62f06
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
6 changes: 6 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,11 @@ struct ieee80211_txq {
* @IEEE80211_HW_BEACON_TX_STATUS: The device/driver provides TX status
* for sent beacons.
*
* @IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR: Hardware (or driver) requires that each
* station has a unique address, i.e. each station entry can be identified
* by just its MAC address; this prevents, for example, the same station
* from connecting to two virtual AP interfaces at the same time.
*
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
Expand Down Expand Up @@ -1950,6 +1955,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_TDLS_WIDER_BW,
IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
IEEE80211_HW_BEACON_TX_STATUS,
IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,

/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
Expand Down
1 change: 1 addition & 0 deletions net/mac80211/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ static const char *hw_flag_names[] = {
FLAG(TDLS_WIDER_BW),
FLAG(SUPPORTS_AMSDU_IN_AMPDU),
FLAG(BEACON_TX_STATUS),
FLAG(NEEDS_UNIQUE_STA_ADDR),
#undef FLAG
};

Expand Down
18 changes: 16 additions & 2 deletions net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,19 @@ static int sta_info_insert_check(struct sta_info *sta)
is_multicast_ether_addr(sta->sta.addr)))
return -EINVAL;

/* Strictly speaking this isn't necessary as we hold the mutex, but
* the rhashtable code can't really deal with that distinction. We
* do require the mutex for correctness though.
*/
rcu_read_lock();
lockdep_assert_held(&sdata->local->sta_mtx);
if (ieee80211_hw_check(&sdata->local->hw, NEEDS_UNIQUE_STA_ADDR) &&
ieee80211_find_sta_by_ifaddr(&sdata->local->hw, sta->addr, NULL)) {
rcu_read_unlock();
return -ENOTUNIQ;
}
rcu_read_unlock();

return 0;
}

Expand Down Expand Up @@ -585,14 +598,15 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)

might_sleep();

mutex_lock(&local->sta_mtx);

err = sta_info_insert_check(sta);
if (err) {
mutex_unlock(&local->sta_mtx);
rcu_read_lock();
goto out_free;
}

mutex_lock(&local->sta_mtx);

err = sta_info_insert_finish(sta);
if (err)
goto out_free;
Expand Down

0 comments on commit fa62f06

Please sign in to comment.