diff mbox

[v2,6/8] cfg80211: reg: Add NL80211_RRF_USER_REGD_NEEDED flag

Message ID 1448303241-27747-7-git-send-email-sojkam1@fel.cvut.cz (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show

Commit Message

Michal Sojka Nov. 23, 2015, 6:27 p.m. UTC
In order to prevent accidental use of Intelligent Transportation System
band (5.9 GHz), we require system integrators to provide custom
userspace regulatory database enabling the use of the band. However,
drivers that provide their own regulatory database (such as ath9k) would
not enable that band in this case, because they do not allow using other
bands than those specified in their database.

The NL80211_RRF_USER_REGD_NEEDED flag introduced in this commit allows
drivers to specify that certain band is enabled only if it is
additionally enabled in user-supplied regulatory database. If the band
is not present there, the channels are simply disabled.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 include/net/cfg80211.h       |  3 +++
 include/uapi/linux/nl80211.h |  4 ++++
 net/wireless/reg.c           | 15 +++++++++++++++
 3 files changed, 22 insertions(+)

Comments

Johannes Berg Nov. 27, 2015, 8:35 a.m. UTC | #1
On Mon, 2015-11-23 at 19:27 +0100, Michal Sojka wrote:

> The NL80211_RRF_USER_REGD_NEEDED flag introduced in this commit
> allows
> drivers to specify that certain band is enabled only if it is
> additionally enabled in user-supplied regulatory database. If the
> band
> is not present there, the channels are simply disabled.

I can see why you'd want this flag internally (although it'll require
rework given the comments on the previous patch) - but is there a
reason to export it in nl80211? Then again, perhaps it *would* be good
to show this information in userspace?

johannes
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michal Sojka Nov. 27, 2015, 9:43 a.m. UTC | #2
On Fri, Nov 27 2015, Johannes Berg wrote:
> On Mon, 2015-11-23 at 19:27 +0100, Michal Sojka wrote:
>> 
>> The NL80211_RRF_USER_REGD_NEEDED flag introduced in this commit
>> allows
>> drivers to specify that certain band is enabled only if it is
>> additionally enabled in user-supplied regulatory database. If the
>> band
>> is not present there, the channels are simply disabled.
>
> I can see why you'd want this flag internally (although it'll require
> rework given the comments on the previous patch) - but is there a
> reason to export it in nl80211?

I don't see any reason either. Only all regulatory rule flags
(nl80211_reg_rule_flags) happen to be "exported". Shall I add new field
(e.g. internal_flags) to struct ieee80211_reg_rule and define new enum
for it?

> Then again, perhaps it *would* be good to show this information in
> userspace?

What do you mean by "show"? nl80211_put_regdom() already sends regdom
flags to userspace. Or do you mean introducing a new channel attribute
and send it in nl80211_msg_put_channel()?

-Michal
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Johannes Berg Nov. 27, 2015, 9:52 a.m. UTC | #3
On Fri, 2015-11-27 at 10:43 +0100, Michal Sojka wrote:

> What do you mean by "show"? nl80211_put_regdom() already sends regdom
> flags to userspace. Or do you mean introducing a new channel
> attribute and send it in nl80211_msg_put_channel()?
> 

No, I meant keeping the flag - so that people can know with "iw list"
or something that they need a special regdomain to enable the channels?

johannes
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b47ac3e..75026d3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -118,6 +118,8 @@  enum ieee80211_band {
  * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted
  *	on this channel.
  * @IEEE80211_CHAN_OCB_ONLY: only OCB mode is allowed on this channel.
+ * @IEEE80211_CHAN_USER_REGD_NEEDED: can only be used if allowed by
+ *	user-supplied regulatory domain.
  *
  */
 enum ieee80211_channel_flags {
@@ -135,6 +137,7 @@  enum ieee80211_channel_flags {
 	IEEE80211_CHAN_NO_20MHZ		= 1<<11,
 	IEEE80211_CHAN_NO_10MHZ		= 1<<12,
 	IEEE80211_CHAN_OCB_ONLY		= 1<<13,
+	IEEE80211_CHAN_USER_REGD_NEEDED	= 1<<14,
 };
 
 #define IEEE80211_CHAN_NO_HT40 \
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 07e6105..ae17589 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2866,6 +2866,9 @@  enum nl80211_sched_scan_match_attr {
  * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
  * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
  * @NL80211_RRF_OCB_ONLY: only OCB mode can be used here
+ * @NL80211_RRF_USER_REGD_NEEDED: when specified in driver's
+ *	CUSTOM_REG regulatory domain, the band can only be used if it
+ *	is also allowed in user-supplied regulatory domain.
  */
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_OFDM		= 1<<0,
@@ -2884,6 +2887,7 @@  enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_80MHZ		= 1<<15,
 	NL80211_RRF_NO_160MHZ		= 1<<16,
 	NL80211_RRF_OCB_ONLY		= 1<<17,
+	NL80211_RRF_USER_REGD_NEEDED	= 1<<18,
 };
 
 #define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 8b7110d..9d9d826 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1050,6 +1050,8 @@  static u32 map_regdom_flags(u32 rd_flags)
 		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
 	if (rd_flags & NL80211_RRF_OCB_ONLY)
 		channel_flags |= IEEE80211_CHAN_OCB_ONLY;
+	if (rd_flags & NL80211_RRF_USER_REGD_NEEDED)
+		channel_flags |= IEEE80211_CHAN_USER_REGD_NEEDED;
 	return channel_flags;
 }
 
@@ -1280,6 +1282,16 @@  static void handle_channel(struct wiphy *wiphy,
 		return;
 	}
 
+	if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
+	    flags & IEEE80211_CHAN_USER_REGD_NEEDED) {
+		/* The driver allows using this frequency only if it
+		 * is allowed in user-supplied regulatory domain,
+		 * which is the case here. This is the only place
+		 * where a disabled channel can be enabled again.
+		 */
+		flags &= ~IEEE80211_CHAN_DISABLED;
+	}
+
 	chan->dfs_state = NL80211_DFS_USABLE;
 	chan->dfs_state_entered = jiffies;
 
@@ -1798,6 +1810,9 @@  static void handle_channel_custom(struct wiphy *wiphy,
 
 	chan->beacon_found = false;
 
+	if (reg_rule->flags & NL80211_RRF_USER_REGD_NEEDED)
+		chan->flags |= IEEE80211_CHAN_DISABLED;
+
 	if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
 		chan->flags = chan->orig_flags | bw_flags |
 			      map_regdom_flags(reg_rule->flags);