From fe94f3a4ffaa20c7470038c69ffc8e545ef5f90a Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 29 Jan 2014 17:53:43 +0100 Subject: cfg80211: fix channel configuration in IBSS join When receiving an IBSS_JOINED event select the BSS object based on the {bssid, channel} couple rather than the bssid only. With the current approach if another cell having the same BSSID (but using a different channel) exists then cfg80211 picks up the wrong BSS object. The result is a mismatching channel configuration between cfg80211 and the driver, that can lead to any sort of problem. The issue can be triggered by having an IBSS sitting on given channel and then asking the driver to create a new cell using the same BSSID but with a different frequency. By passing the channel to cfg80211_get_bss() we can solve this ambiguity and retrieve/create the correct BSS object. All the users of cfg80211_ibss_joined() have been changed accordingly. Moreover WARN when cfg80211_ibss_joined() gets a NULL channel as argument and remove a bogus call of the same function in ath6kl (it does not make sense to call cfg80211_ibss_joined() with a zero BSSID on ibss-leave). Cc: Kalle Valo Cc: Arend van Spriel Cc: Bing Zhao Cc: Jussi Kivilinna Cc: libertas-dev@lists.infradead.org Acked-by: Kalle Valo Signed-off-by: Antonio Quartulli [minor code cleanup in ath6kl] Signed-off-by: Johannes Berg --- net/wireless/util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/wireless/util.c') diff --git a/net/wireless/util.c b/net/wireless/util.c index d39c37104ae2..7526a4d8aa16 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) ev->dc.reason, true); break; case EVENT_IBSS_JOINED: - __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid); + __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, + ev->ij.channel); break; } wdev_unlock(wdev); -- cgit v1.2.3 From 9e0e29615a2077be852b1245b57c5b00fa609522 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Wed, 29 Jan 2014 14:22:27 +0100 Subject: cfg80211: consider existing DFS interfaces It was possible to break interface combinations in the following way: combo 1: iftype = AP, num_ifaces = 2, num_chans = 2, combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20 With the above interface combinations it was possible to: step 1. start AP on DFS channel by matching combo 2 step 2. start AP on non-DFS channel by matching combo 1 This was possible beacuse (step 2) did not consider if other interfaces require radar detection. The patch changes how cfg80211 tracks channels - instead of channel itself now a complete chandef is stored. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/wireless/util.c') diff --git a/net/wireless/util.c b/net/wireless/util.c index 7526a4d8aa16..780b4546c9c7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1357,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, */ mutex_lock_nested(&wdev_iter->mtx, 1); __acquire(wdev_iter->mtx); - cfg80211_get_chan_state(wdev_iter, &ch, &chmode); + cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect); wdev_unlock(wdev_iter); switch (chmode) { -- cgit v1.2.3 From 7b2106aea2638948806df248215b14efd84c5ffc Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 20 Feb 2014 16:36:21 +0200 Subject: cfg80211: remove radar requirements check from cfg80211_can_use_iftype_chan() We don't have to double check whether the parameters passed to cfg80211_can_use_iftype_chan() are correct. We should just make sure they *are* when we call this function. Remove the radar_detect argument check in cfg80211_can_use_iftype_chan() to simplify the code. Signed-off-by: Luciano Coelho [keep braces around a long comment + single statement] Signed-off-by: Johannes Berg --- net/wireless/util.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'net/wireless/util.c') diff --git a/net/wireless/util.c b/net/wireless/util.c index 780b4546c9c7..57b3ce7a6b92 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1269,7 +1269,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, enum cfg80211_chan_mode chmode; int num_different_channels = 0; int total = 1; - bool radar_required = false; int i, j; ASSERT_RTNL(); @@ -1277,35 +1276,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, if (WARN_ON(hweight32(radar_detect) > 1)) return -EINVAL; - switch (iftype) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_WDS: - /* if the interface could potentially choose a DFS channel, - * then mark DFS as required. - */ - if (!chan) { - if (chanmode != CHAN_MODE_UNDEFINED && radar_detect) - radar_required = true; - break; - } - radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR); - break; - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_DEVICE: - case NL80211_IFTYPE_MONITOR: - break; - case NUM_NL80211_IFTYPES: - case NL80211_IFTYPE_UNSPECIFIED: - default: - return -EINVAL; - } - - if (radar_required && !radar_detect) + if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) return -EINVAL; /* Always allow software iftypes */ -- cgit v1.2.3 From 7c8d5e03acc680eb433b0d5dbacbb6cc9db663a1 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Tue, 25 Feb 2014 15:33:38 +0200 Subject: cfg80211: send stop AP event only due to internal reason Commit "nl80211: send event when AP operation is stopped" added an event to notify user space that an AP interface has been stopped, to handle cases such as suspend etc. The event is sent regardless if the stop AP flow was triggered by user space or due to internal state change. This might cause issues with wpa_supplicant/hostapd flows that consider stop AP flow as a synchronous one, e.g., AP/GO channel change in the absence of CSA support. In such cases, the flow will restart the AP immediately after the stop AP flow is done, and only handle the stop AP event after the current flow is done, and as a result stop the AP again. Change the current implementation to only send the event in case the stop AP was triggered due to an internal reason. Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/wireless/util.c') diff --git a/net/wireless/util.c b/net/wireless/util.c index 57b3ce7a6b92..dadc934d987f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -886,7 +886,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, switch (otype) { case NL80211_IFTYPE_AP: - cfg80211_stop_ap(rdev, dev); + cfg80211_stop_ap(rdev, dev, true); break; case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, false); -- cgit v1.2.3 From 960d97f9518ef6fb8ff87450d6b0c88ce5df9532 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Mon, 3 Mar 2014 17:23:12 +0100 Subject: cfg80211: add MPLS and 802.21 classification MPLS labels may contain traffic control information, which should be evaluated and used by the wireless subsystem if present. Also check for IEEE 802.21 which is always network control traffic. Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer Acked-by: Johannes Berg Signed-off-by: David S. Miller --- net/wireless/util.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'net/wireless/util.c') diff --git a/net/wireless/util.c b/net/wireless/util.c index 780b4546c9c7..ad03af385556 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "core.h" #include "rdev-ops.h" @@ -717,6 +718,21 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb, case htons(ETH_P_IPV6): dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc; break; + case htons(ETH_P_MPLS_UC): + case htons(ETH_P_MPLS_MC): { + struct mpls_label mpls_tmp, *mpls; + + mpls = skb_header_pointer(skb, sizeof(struct ethhdr), + sizeof(*mpls), &mpls_tmp); + if (!mpls) + return 0; + + return (ntohl(mpls->entry) & MPLS_LS_TC_MASK) + >> MPLS_LS_TC_SHIFT; + } + case htons(ETH_P_80221): + /* 802.21 is always network control traffic */ + return 7; default: return 0; } -- cgit v1.2.3 From 73fb08e24ae840bc518facc2c605dd6bb3751fec Mon Sep 17 00:00:00 2001 From: "Zhao, Gang" Date: Wed, 19 Mar 2014 17:04:36 +0800 Subject: cfg80211: remove macro ASSERT_RDEV_LOCK(rdev) Macro ASSERT_RDEV_LOCK(rdev) is equal to ASSERT_RTNL(), so replace it with ASSERT_RTNL() and remove it. Signed-off-by: Zhao, Gang Signed-off-by: Johannes Berg --- net/wireless/util.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net/wireless/util.c') diff --git a/net/wireless/util.c b/net/wireless/util.c index dadc934d987f..39fc1d70da69 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -838,7 +838,6 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev) struct wireless_dev *wdev; ASSERT_RTNL(); - ASSERT_RDEV_LOCK(rdev); list_for_each_entry(wdev, &rdev->wdev_list, list) cfg80211_process_wdev_events(wdev); @@ -851,7 +850,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, int err; enum nl80211_iftype otype = dev->ieee80211_ptr->iftype; - ASSERT_RDEV_LOCK(rdev); + ASSERT_RTNL(); /* don't support changing VLANs, you just re-create them */ if (otype == NL80211_IFTYPE_AP_VLAN) -- cgit v1.2.3