Skip to content

Commit 3f2355c

Browse files
Luis R. Rodriguezlinvjw
Luis R. Rodriguez
authored andcommitted
cfg80211/mac80211: Add 802.11d support
This adds country IE parsing to mac80211 and enables its usage within the new regulatory infrastructure in cfg80211. We parse the country IEs only on management beacons for the BSSID you are associated to and disregard the IEs when the country and environment (indoor, outdoor, any) matches the already processed country IE. To avoid following misinformed or outdated APs we build and use a regulatory domain out of the intersection between what the AP provides us on the country IE and what CRDA is aware is allowed on the same country. A secondary device is allowed to follow only the same country IE as it make no sense for two devices on a system to be in two different countries. In the case the AP is using country IEs for an incorrect country the user may help compliance further by setting the regulatory domain before or after the IE is parsed and in that case another intersection will be performed. CONFIG_WIRELESS_OLD_REGULATORY is supported but requires CRDA present. Signed-off-by: Luis R. Rodriguez <[email protected]> Acked-by: Johannes Berg <[email protected]> Signed-off-by: John W. Linville <[email protected]>
1 parent 88dc1c3 commit 3f2355c

File tree

9 files changed

+591
-24
lines changed

9 files changed

+591
-24
lines changed

include/linux/ieee80211.h

+62
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,68 @@ enum ieee80211_spectrum_mgmt_actioncode {
10421042
WLAN_ACTION_SPCT_CHL_SWITCH = 4,
10431043
};
10441044

1045+
/*
1046+
* IEEE 802.11-2007 7.3.2.9 Country information element
1047+
*
1048+
* Minimum length is 8 octets, ie len must be evenly
1049+
* divisible by 2
1050+
*/
1051+
1052+
/* Although the spec says 8 I'm seeing 6 in practice */
1053+
#define IEEE80211_COUNTRY_IE_MIN_LEN 6
1054+
1055+
/*
1056+
* For regulatory extension stuff see IEEE 802.11-2007
1057+
* Annex I (page 1141) and Annex J (page 1147). Also
1058+
* review 7.3.2.9.
1059+
*
1060+
* When dot11RegulatoryClassesRequired is true and the
1061+
* first_channel/reg_extension_id is >= 201 then the IE
1062+
* compromises of the 'ext' struct represented below:
1063+
*
1064+
* - Regulatory extension ID - when generating IE this just needs
1065+
* to be monotonically increasing for each triplet passed in
1066+
* the IE
1067+
* - Regulatory class - index into set of rules
1068+
* - Coverage class - index into air propagation time (Table 7-27),
1069+
* in microseconds, you can compute the air propagation time from
1070+
* the index by multiplying by 3, so index 10 yields a propagation
1071+
* of 10 us. Valid values are 0-31, values 32-255 are not defined
1072+
* yet. A value of 0 inicates air propagation of <= 1 us.
1073+
*
1074+
* See also Table I.2 for Emission limit sets and table
1075+
* I.3 for Behavior limit sets. Table J.1 indicates how to map
1076+
* a reg_class to an emission limit set and behavior limit set.
1077+
*/
1078+
#define IEEE80211_COUNTRY_EXTENSION_ID 201
1079+
1080+
/*
1081+
* Channels numbers in the IE must be monotonically increasing
1082+
* if dot11RegulatoryClassesRequired is not true.
1083+
*
1084+
* If dot11RegulatoryClassesRequired is true consecutive
1085+
* subband triplets following a regulatory triplet shall
1086+
* have monotonically increasing first_channel number fields.
1087+
*
1088+
* Channel numbers shall not overlap.
1089+
*
1090+
* Note that max_power is signed.
1091+
*/
1092+
struct ieee80211_country_ie_triplet {
1093+
union {
1094+
struct {
1095+
u8 first_channel;
1096+
u8 num_channels;
1097+
s8 max_power;
1098+
} __attribute__ ((packed)) chans;
1099+
struct {
1100+
u8 reg_extension_id;
1101+
u8 reg_class;
1102+
u8 coverage_class;
1103+
} __attribute__ ((packed)) ext;
1104+
};
1105+
} __attribute__ ((packed));
1106+
10451107
/* BACK action code */
10461108
enum ieee80211_back_actioncode {
10471109
WLAN_ACTION_ADDBA_REQ = 0,

include/net/wireless.h

+15
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,19 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
373373
* for a regulatory domain structure for the respective country.
374374
*/
375375
extern void regulatory_hint(struct wiphy *wiphy, const char *alpha2);
376+
377+
/**
378+
* regulatory_hint_11d - hints a country IE as a regulatory domain
379+
* @wiphy: the wireless device giving the hint (used only for reporting
380+
* conflicts)
381+
* @country_ie: pointer to the country IE
382+
* @country_ie_len: length of the country IE
383+
*
384+
* We will intersect the rd with the what CRDA tells us should apply
385+
* for the alpha2 this country IE belongs to, this prevents APs from
386+
* sending us incorrect or outdated information against a country.
387+
*/
388+
extern void regulatory_hint_11d(struct wiphy *wiphy,
389+
u8 *country_ie,
390+
u8 country_ie_len);
376391
#endif /* __NET_WIRELESS_H */

net/mac80211/mlme.c

+7
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
17361736
ap_ht_cap_flags);
17371737
}
17381738

1739+
if (elems.country_elem) {
1740+
/* Note we are only reviewing this on beacons
1741+
* for the BSSID we are associated to */
1742+
regulatory_hint_11d(local->hw.wiphy,
1743+
elems.country_elem, elems.country_elem_len);
1744+
}
1745+
17391746
ieee80211_bss_info_change_notify(sdata, changed);
17401747
}
17411748

net/wireless/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
config CFG80211
22
tristate "Improved wireless configuration API"
33

4+
config CFG80211_REG_DEBUG
5+
bool "cfg80211 regulatory debugging"
6+
depends on CFG80211
7+
default n
8+
---help---
9+
You can enable this if you want to debug regulatory changes.
10+
11+
If unsure, say N.
12+
413
config NL80211
514
bool "nl80211 new netlink interface support"
615
depends on CFG80211
@@ -40,6 +49,8 @@ config WIRELESS_OLD_REGULATORY
4049
ieee80211_regdom module parameter. This is being phased out and you
4150
should stop using them ASAP.
4251

52+
Note: You will need CRDA if you want 802.11d support
53+
4354
Say Y unless you have installed a new userspace application.
4455
Also say Y if have one currently depending on the ieee80211_regdom
4556
module parameter and cannot port it to use the new userspace

net/wireless/core.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "nl80211.h"
2020
#include "core.h"
2121
#include "sysfs.h"
22-
#include "reg.h"
2322

2423
/* name for sysfs, %d is appended */
2524
#define PHY_NAME "phy"
@@ -348,6 +347,10 @@ void wiphy_unregister(struct wiphy *wiphy)
348347
/* unlock again before freeing */
349348
mutex_unlock(&drv->mtx);
350349

350+
/* If this device got a regulatory hint tell core its
351+
* free to listen now to a new shiny device regulatory hint */
352+
reg_device_remove(wiphy);
353+
351354
list_del(&drv->list);
352355
device_del(&drv->wiphy.dev);
353356
debugfs_remove(drv->wiphy.debugfsdir);

net/wireless/core.h

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <net/genetlink.h>
1212
#include <net/wireless.h>
1313
#include <net/cfg80211.h>
14+
#include "reg.h"
1415

1516
struct cfg80211_registered_device {
1617
struct cfg80211_ops *ops;
@@ -21,6 +22,18 @@ struct cfg80211_registered_device {
2122
* any call is in progress */
2223
struct mutex mtx;
2324

25+
/* ISO / IEC 3166 alpha2 for which this device is receiving
26+
* country IEs on, this can help disregard country IEs from APs
27+
* on the same alpha2 quickly. The alpha2 may differ from
28+
* cfg80211_regdomain's alpha2 when an intersection has occurred.
29+
* If the AP is reconfigured this can also be used to tell us if
30+
* the country on the country IE changed. */
31+
char country_ie_alpha2[2];
32+
33+
/* If a Country IE has been received this tells us the environment
34+
* which its telling us its in. This defaults to ENVIRON_ANY */
35+
enum environment_cap env;
36+
2437
/* wiphy index, internal only */
2538
int idx;
2639

net/wireless/nl80211.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1760,7 +1760,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
17601760
return -EINVAL;
17611761
#endif
17621762
mutex_lock(&cfg80211_drv_mutex);
1763-
r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data);
1763+
r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
17641764
mutex_unlock(&cfg80211_drv_mutex);
17651765
return r;
17661766
}

0 commit comments

Comments
 (0)