Skip to content

Commit

Permalink
cfg80211/mac80211: Add 802.11d support
Browse files Browse the repository at this point in the history
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 <lrodriguez@atheros.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Luis R. Rodriguez authored and John W. Linville committed Nov 25, 2008
1 parent 88dc1c3 commit 3f2355c
Show file tree
Hide file tree
Showing 9 changed files with 591 additions and 24 deletions.
62 changes: 62 additions & 0 deletions include/linux/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,68 @@ enum ieee80211_spectrum_mgmt_actioncode {
WLAN_ACTION_SPCT_CHL_SWITCH = 4,
};

/*
* IEEE 802.11-2007 7.3.2.9 Country information element
*
* Minimum length is 8 octets, ie len must be evenly
* divisible by 2
*/

/* Although the spec says 8 I'm seeing 6 in practice */
#define IEEE80211_COUNTRY_IE_MIN_LEN 6

/*
* For regulatory extension stuff see IEEE 802.11-2007
* Annex I (page 1141) and Annex J (page 1147). Also
* review 7.3.2.9.
*
* When dot11RegulatoryClassesRequired is true and the
* first_channel/reg_extension_id is >= 201 then the IE
* compromises of the 'ext' struct represented below:
*
* - Regulatory extension ID - when generating IE this just needs
* to be monotonically increasing for each triplet passed in
* the IE
* - Regulatory class - index into set of rules
* - Coverage class - index into air propagation time (Table 7-27),
* in microseconds, you can compute the air propagation time from
* the index by multiplying by 3, so index 10 yields a propagation
* of 10 us. Valid values are 0-31, values 32-255 are not defined
* yet. A value of 0 inicates air propagation of <= 1 us.
*
* See also Table I.2 for Emission limit sets and table
* I.3 for Behavior limit sets. Table J.1 indicates how to map
* a reg_class to an emission limit set and behavior limit set.
*/
#define IEEE80211_COUNTRY_EXTENSION_ID 201

/*
* Channels numbers in the IE must be monotonically increasing
* if dot11RegulatoryClassesRequired is not true.
*
* If dot11RegulatoryClassesRequired is true consecutive
* subband triplets following a regulatory triplet shall
* have monotonically increasing first_channel number fields.
*
* Channel numbers shall not overlap.
*
* Note that max_power is signed.
*/
struct ieee80211_country_ie_triplet {
union {
struct {
u8 first_channel;
u8 num_channels;
s8 max_power;
} __attribute__ ((packed)) chans;
struct {
u8 reg_extension_id;
u8 reg_class;
u8 coverage_class;
} __attribute__ ((packed)) ext;
};
} __attribute__ ((packed));

/* BACK action code */
enum ieee80211_back_actioncode {
WLAN_ACTION_ADDBA_REQ = 0,
Expand Down
15 changes: 15 additions & 0 deletions include/net/wireless.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,19 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
* for a regulatory domain structure for the respective country.
*/
extern void regulatory_hint(struct wiphy *wiphy, const char *alpha2);

/**
* regulatory_hint_11d - hints a country IE as a regulatory domain
* @wiphy: the wireless device giving the hint (used only for reporting
* conflicts)
* @country_ie: pointer to the country IE
* @country_ie_len: length of the country IE
*
* We will intersect the rd with the what CRDA tells us should apply
* for the alpha2 this country IE belongs to, this prevents APs from
* sending us incorrect or outdated information against a country.
*/
extern void regulatory_hint_11d(struct wiphy *wiphy,
u8 *country_ie,
u8 country_ie_len);
#endif /* __NET_WIRELESS_H */
7 changes: 7 additions & 0 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ap_ht_cap_flags);
}

if (elems.country_elem) {
/* Note we are only reviewing this on beacons
* for the BSSID we are associated to */
regulatory_hint_11d(local->hw.wiphy,
elems.country_elem, elems.country_elem_len);
}

ieee80211_bss_info_change_notify(sdata, changed);
}

Expand Down
11 changes: 11 additions & 0 deletions net/wireless/Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
config CFG80211
tristate "Improved wireless configuration API"

config CFG80211_REG_DEBUG
bool "cfg80211 regulatory debugging"
depends on CFG80211
default n
---help---
You can enable this if you want to debug regulatory changes.

If unsure, say N.

config NL80211
bool "nl80211 new netlink interface support"
depends on CFG80211
Expand Down Expand Up @@ -40,6 +49,8 @@ config WIRELESS_OLD_REGULATORY
ieee80211_regdom module parameter. This is being phased out and you
should stop using them ASAP.

Note: You will need CRDA if you want 802.11d support

Say Y unless you have installed a new userspace application.
Also say Y if have one currently depending on the ieee80211_regdom
module parameter and cannot port it to use the new userspace
Expand Down
5 changes: 4 additions & 1 deletion net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "nl80211.h"
#include "core.h"
#include "sysfs.h"
#include "reg.h"

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

/* If this device got a regulatory hint tell core its
* free to listen now to a new shiny device regulatory hint */
reg_device_remove(wiphy);

list_del(&drv->list);
device_del(&drv->wiphy.dev);
debugfs_remove(drv->wiphy.debugfsdir);
Expand Down
13 changes: 13 additions & 0 deletions net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <net/genetlink.h>
#include <net/wireless.h>
#include <net/cfg80211.h>
#include "reg.h"

struct cfg80211_registered_device {
struct cfg80211_ops *ops;
Expand All @@ -21,6 +22,18 @@ struct cfg80211_registered_device {
* any call is in progress */
struct mutex mtx;

/* ISO / IEC 3166 alpha2 for which this device is receiving
* country IEs on, this can help disregard country IEs from APs
* on the same alpha2 quickly. The alpha2 may differ from
* cfg80211_regdomain's alpha2 when an intersection has occurred.
* If the AP is reconfigured this can also be used to tell us if
* the country on the country IE changed. */
char country_ie_alpha2[2];

/* If a Country IE has been received this tells us the environment
* which its telling us its in. This defaults to ENVIRON_ANY */
enum environment_cap env;

/* wiphy index, internal only */
int idx;

Expand Down
2 changes: 1 addition & 1 deletion net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1760,7 +1760,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
#endif
mutex_lock(&cfg80211_drv_mutex);
r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data);
r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
mutex_unlock(&cfg80211_drv_mutex);
return r;
}
Expand Down
Loading

0 comments on commit 3f2355c

Please sign in to comment.