diff options
author | Felix Fietkau <nbd@openwrt.org> | 2014-11-24 12:12:16 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-11-27 11:36:47 -0500 |
commit | 2967e031d4d737d9cc8252d878a17924d7b704f0 (patch) | |
tree | f868e9a0fb7c1282d3a5c92f3280dd38431173f4 /net/mac80211 | |
parent | 601555cd75ddfc2b95ebbb5eb1224c6a995e8203 (diff) |
mac80211: copy chandef from AP vif to VLANs
Instead of keeping track of all those special cases where
VLAN interfaces have no bss_conf.chandef, just make sure
they have the same as the AP interface they belong to.
Among others, this fixes a crash getting a VLAN's channel
from userspace since a NULL channel is returned as a good
result (return value 0) for VLANs since the commit below.
Cc: stable@vger.kernel.org [3.18 only]
Fixes: c12bc4885f4b3 ("mac80211: return the vif's chandef in ieee80211_cfg_get_channel()")
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
[rewrite commit log]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/chan.c | 23 | ||||
-rw-r--r-- | net/mac80211/iface.c | 1 |
2 files changed, 20 insertions, 4 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index c7c514220298..5d6dae9e4aac 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -932,6 +932,21 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata) | |||
932 | } | 932 | } |
933 | } | 933 | } |
934 | 934 | ||
935 | static void | ||
936 | ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata, | ||
937 | const struct cfg80211_chan_def *chandef) | ||
938 | { | ||
939 | struct ieee80211_sub_if_data *vlan; | ||
940 | |||
941 | sdata->vif.bss_conf.chandef = *chandef; | ||
942 | |||
943 | if (sdata->vif.type != NL80211_IFTYPE_AP) | ||
944 | return; | ||
945 | |||
946 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
947 | vlan->vif.bss_conf.chandef = *chandef; | ||
948 | } | ||
949 | |||
935 | static int | 950 | static int |
936 | ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) | 951 | ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) |
937 | { | 952 | { |
@@ -994,7 +1009,7 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) | |||
994 | if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width) | 1009 | if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width) |
995 | changed = BSS_CHANGED_BANDWIDTH; | 1010 | changed = BSS_CHANGED_BANDWIDTH; |
996 | 1011 | ||
997 | sdata->vif.bss_conf.chandef = sdata->reserved_chandef; | 1012 | ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef); |
998 | 1013 | ||
999 | if (changed) | 1014 | if (changed) |
1000 | ieee80211_bss_info_change_notify(sdata, changed); | 1015 | ieee80211_bss_info_change_notify(sdata, changed); |
@@ -1336,7 +1351,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) | |||
1336 | sdata->reserved_chandef.width) | 1351 | sdata->reserved_chandef.width) |
1337 | changed = BSS_CHANGED_BANDWIDTH; | 1352 | changed = BSS_CHANGED_BANDWIDTH; |
1338 | 1353 | ||
1339 | sdata->vif.bss_conf.chandef = sdata->reserved_chandef; | 1354 | ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef); |
1340 | if (changed) | 1355 | if (changed) |
1341 | ieee80211_bss_info_change_notify(sdata, | 1356 | ieee80211_bss_info_change_notify(sdata, |
1342 | changed); | 1357 | changed); |
@@ -1507,7 +1522,7 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
1507 | goto out; | 1522 | goto out; |
1508 | } | 1523 | } |
1509 | 1524 | ||
1510 | sdata->vif.bss_conf.chandef = *chandef; | 1525 | ieee80211_vif_update_chandef(sdata, chandef); |
1511 | 1526 | ||
1512 | ret = ieee80211_assign_vif_chanctx(sdata, ctx); | 1527 | ret = ieee80211_assign_vif_chanctx(sdata, ctx); |
1513 | if (ret) { | 1528 | if (ret) { |
@@ -1649,7 +1664,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, | |||
1649 | break; | 1664 | break; |
1650 | } | 1665 | } |
1651 | 1666 | ||
1652 | sdata->vif.bss_conf.chandef = *chandef; | 1667 | ieee80211_vif_update_chandef(sdata, chandef); |
1653 | 1668 | ||
1654 | ieee80211_recalc_chanctx_chantype(local, ctx); | 1669 | ieee80211_recalc_chanctx_chantype(local, ctx); |
1655 | 1670 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 82473d909bb6..96c4572c023e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -520,6 +520,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
520 | sdata->vif.cab_queue = master->vif.cab_queue; | 520 | sdata->vif.cab_queue = master->vif.cab_queue; |
521 | memcpy(sdata->vif.hw_queue, master->vif.hw_queue, | 521 | memcpy(sdata->vif.hw_queue, master->vif.hw_queue, |
522 | sizeof(sdata->vif.hw_queue)); | 522 | sizeof(sdata->vif.hw_queue)); |
523 | sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef; | ||
523 | break; | 524 | break; |
524 | } | 525 | } |
525 | case NL80211_IFTYPE_AP: | 526 | case NL80211_IFTYPE_AP: |