linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cfg80211: add get reg command
@ 2009-01-28  2:52 Luis R. Rodriguez
  2009-01-28 10:17 ` Johannes Berg
  0 siblings, 1 reply; 6+ messages in thread
From: Luis R. Rodriguez @ 2009-01-28  2:52 UTC (permalink / raw)
  To: johannes, johannes, linville; +Cc: Luis R. Rodriguez, linux-wireless

This lets userspace request to get the currently set
regulatory domain.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 include/linux/nl80211.h |    4 ++
 net/wireless/nl80211.c  |   82 +++++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/reg.c      |    8 ++++
 net/wireless/reg.h      |    2 +
 4 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 3357907..ef5c1d3 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -113,6 +113,8 @@
  * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
  *	%NL80211_ATTR_IFINDEX.
  *
+ * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
+ * 	regulatory domain.
  * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
  *	after being queried by the kernel. CRDA replies by sending a regulatory
  *	domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
@@ -188,6 +190,8 @@ enum nl80211_commands {
 
 	NL80211_CMD_SET_MGMT_EXTRA_IE,
 
+	NL80211_CMD_GET_REG,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3c6327d..7fbd359 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2094,6 +2094,82 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
 
 #undef FILL_IN_MESH_PARAM_IF_SET
 
+static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
+{
+	struct sk_buff *msg;
+	const struct ieee80211_regdomain *regd;
+	void *hdr = NULL;
+	struct nlattr *nl_reg_rules;
+	unsigned int i;
+	int err = -EINVAL;
+
+	mutex_lock(&cfg80211_drv_mutex);
+	regd = reg_get_current_rd();
+	mutex_unlock(&cfg80211_drv_mutex);
+
+	if (!regd)
+		goto out;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg) {
+		err = -ENOBUFS;
+		goto out;
+	}
+
+	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+			     NL80211_CMD_GET_REG);
+	if (!hdr)
+		goto nla_put_failure;
+
+	NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, regd->alpha2);
+
+	nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
+	if (!nl_reg_rules)
+		goto nla_put_failure;
+
+	for (i = 0; i < regd->n_reg_rules; i++) {
+		struct nlattr *nl_reg_rule;
+		const struct ieee80211_reg_rule *reg_rule;
+		const struct ieee80211_freq_range *freq_range;
+		const struct ieee80211_power_rule *power_rule;
+
+		reg_rule = &regd->reg_rules[i];
+		freq_range = &reg_rule->freq_range;
+		power_rule = &reg_rule->power_rule;
+
+		nl_reg_rule = nla_nest_start(msg, i);
+		if (!nl_reg_rule)
+			goto nla_put_failure;
+
+		NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS,
+			reg_rule->flags);
+		NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
+			freq_range->start_freq_khz);
+		NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
+			freq_range->end_freq_khz);
+		NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
+			freq_range->max_bandwidth_khz);
+		NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
+			power_rule->max_antenna_gain);
+		NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
+			power_rule->max_eirp);
+
+		nla_nest_end(msg, nl_reg_rule);
+	}
+
+	nla_nest_end(msg, nl_reg_rules);
+
+	genlmsg_end(msg, hdr);
+	err = genlmsg_unicast(msg, info->snd_pid);
+	goto out;
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	err = -EMSGSIZE;
+out:
+	return err;
+}
+
 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -2334,6 +2410,12 @@ static struct genl_ops nl80211_ops[] = {
 		.flags = GENL_ADMIN_PERM,
 	},
 	{
+		.cmd = NL80211_CMD_GET_REG,
+		.doit = nl80211_get_reg,
+		.policy = nl80211_policy,
+		/* can be retrieved by unprivileged users */
+	},
+	{
 		.cmd = NL80211_CMD_SET_REG,
 		.doit = nl80211_set_reg,
 		.policy = nl80211_policy,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f643d39..50d8328 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1598,6 +1598,14 @@ void reg_device_remove(struct wiphy *wiphy)
 	last_request->country_ie_env = ENVIRON_ANY;
 }
 
+/* caller is reponsible for locking */
+const struct ieee80211_regdomain *reg_get_current_rd(void)
+{
+	const struct ieee80211_regdomain *regd;
+	reg_copy_regd(&regd, cfg80211_regdomain);
+	return regd;
+}
+
 int regulatory_init(void)
 {
 	int err;
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index eb1dd5b..1dcbdfe 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -34,4 +34,6 @@ extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
 			     const char *alpha2, u32 country_ie_checksum,
 			     enum environment_cap country_ie_env);
 
+const struct ieee80211_regdomain *reg_get_current_rd(void);
+
 #endif  /* __NET_WIRELESS_REG_H */
-- 
1.6.1.rc3.51.g5832d


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] cfg80211: add get reg command
  2009-01-28  2:52 [PATCH] cfg80211: add get reg command Luis R. Rodriguez
@ 2009-01-28 10:17 ` Johannes Berg
  2009-01-28 14:44   ` Luis R. Rodriguez
  0 siblings, 1 reply; 6+ messages in thread
From: Johannes Berg @ 2009-01-28 10:17 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linville, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 305 bytes --]

On Tue, 2009-01-27 at 18:52 -0800, Luis R. Rodriguez wrote:

> +	mutex_lock(&cfg80211_drv_mutex);
> +	regd = reg_get_current_rd();
> +	mutex_unlock(&cfg80211_drv_mutex);
> +
> +	if (!regd)
> +		goto out;

Any reason you need to copy and can't just build the whole thing under
lock?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] cfg80211: add get reg command
  2009-01-28 10:17 ` Johannes Berg
@ 2009-01-28 14:44   ` Luis R. Rodriguez
  2009-01-28 14:50     ` Johannes Berg
  0 siblings, 1 reply; 6+ messages in thread
From: Luis R. Rodriguez @ 2009-01-28 14:44 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Luis Rodriguez, linville@tuxdriver.com,
	linux-wireless@vger.kernel.org

On Wed, Jan 28, 2009 at 02:17:21AM -0800, Johannes Berg wrote:
> On Tue, 2009-01-27 at 18:52 -0800, Luis R. Rodriguez wrote:
> 
> > +	mutex_lock(&cfg80211_drv_mutex);
> > +	regd = reg_get_current_rd();
> > +	mutex_unlock(&cfg80211_drv_mutex);
> > +
> > +	if (!regd)
> > +		goto out;
> 
> Any reason you need to copy and can't just build the whole thing under
> lock?

Glad you asked, we can lock the entire call or we can do the above to
copy. I picked a copy to not let a regular user (get reg can be called
by anyone) abuse the lock as cfg80211_drv_mutex is used in a lot of places,
I guess its silly but other's input on this is appreciated as well. Not sure
if the copy was the best choice.

  Luis

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] cfg80211: add get reg command
  2009-01-28 14:44   ` Luis R. Rodriguez
@ 2009-01-28 14:50     ` Johannes Berg
  2009-01-28 15:20       ` Luis R. Rodriguez
  0 siblings, 1 reply; 6+ messages in thread
From: Johannes Berg @ 2009-01-28 14:50 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Luis Rodriguez, linville@tuxdriver.com,
	linux-wireless@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 1034 bytes --]

On Wed, 2009-01-28 at 06:44 -0800, Luis R. Rodriguez wrote:
> On Wed, Jan 28, 2009 at 02:17:21AM -0800, Johannes Berg wrote:
> > On Tue, 2009-01-27 at 18:52 -0800, Luis R. Rodriguez wrote:
> > 
> > > +	mutex_lock(&cfg80211_drv_mutex);
> > > +	regd = reg_get_current_rd();
> > > +	mutex_unlock(&cfg80211_drv_mutex);
> > > +
> > > +	if (!regd)
> > > +		goto out;
> > 
> > Any reason you need to copy and can't just build the whole thing under
> > lock?
> 
> Glad you asked, we can lock the entire call or we can do the above to
> copy. I picked a copy to not let a regular user (get reg can be called
> by anyone) abuse the lock as cfg80211_drv_mutex is used in a lot of places,
> I guess its silly but other's input on this is appreciated as well. Not sure
> if the copy was the best choice.

I don't really see much difference between locking to create a copy and
locking to create a copy in a different format, do you? Except to create
a copy needs to allocate memory which could take even longer.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] cfg80211: add get reg command
  2009-01-28 14:50     ` Johannes Berg
@ 2009-01-28 15:20       ` Luis R. Rodriguez
  2009-01-28 16:16         ` Luis R. Rodriguez
  0 siblings, 1 reply; 6+ messages in thread
From: Luis R. Rodriguez @ 2009-01-28 15:20 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Luis Rodriguez, linville@tuxdriver.com,
	linux-wireless@vger.kernel.org

On Wed, Jan 28, 2009 at 06:50:34AM -0800, Johannes Berg wrote:
> On Wed, 2009-01-28 at 06:44 -0800, Luis R. Rodriguez wrote:
> > On Wed, Jan 28, 2009 at 02:17:21AM -0800, Johannes Berg wrote:
> > > On Tue, 2009-01-27 at 18:52 -0800, Luis R. Rodriguez wrote:
> > > 
> > > > +	mutex_lock(&cfg80211_drv_mutex);
> > > > +	regd = reg_get_current_rd();
> > > > +	mutex_unlock(&cfg80211_drv_mutex);
> > > > +
> > > > +	if (!regd)
> > > > +		goto out;
> > > 
> > > Any reason you need to copy and can't just build the whole thing under
> > > lock?
> > 
> > Glad you asked, we can lock the entire call or we can do the above to
> > copy. I picked a copy to not let a regular user (get reg can be called
> > by anyone) abuse the lock as cfg80211_drv_mutex is used in a lot of places,
> > I guess its silly but other's input on this is appreciated as well. Not sure
> > if the copy was the best choice.
> 
> I don't really see much difference between locking to create a copy and
> locking to create a copy in a different format, do you? 
> Except to create
> a copy needs to allocate memory which could take even longer.

Agreed, that's the thing I was not thinking about those two paths I was
thinking of either using a copy of cfg80211_regdomain for nl80211.c to move
forward without having to keep cfg80211_drv_mutex *or* having
reg_get_current_rd() just return cfg80211_regdomain and have the reg_reg
lock during its entire access.

I am honestly not sure which is the best approach but I picked a copy
since I figure having a user do a kmalloc() is less harmless then contending
the lock more time if he wanted to abuse the system. I also thought about
using a static regd in place just to copy the cfg80211_regdomain but then
that would mean having a large static regd with max num rules and I didn't
like that either. Seemed to me a kmalloc() was in the middle. Let me know
if you guys have better advice.

  Luis

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] cfg80211: add get reg command
  2009-01-28 15:20       ` Luis R. Rodriguez
@ 2009-01-28 16:16         ` Luis R. Rodriguez
  0 siblings, 0 replies; 6+ messages in thread
From: Luis R. Rodriguez @ 2009-01-28 16:16 UTC (permalink / raw)
  To: Luis Rodriguez
  Cc: Johannes Berg, linville@tuxdriver.com,
	linux-wireless@vger.kernel.org

On Wed, Jan 28, 2009 at 07:20:11AM -0800, Luis Rodriguez wrote:
> On Wed, Jan 28, 2009 at 06:50:34AM -0800, Johannes Berg wrote:
> > On Wed, 2009-01-28 at 06:44 -0800, Luis R. Rodriguez wrote:
> > > On Wed, Jan 28, 2009 at 02:17:21AM -0800, Johannes Berg wrote:
> > > > On Tue, 2009-01-27 at 18:52 -0800, Luis R. Rodriguez wrote:
> > > >
> > > > > +       mutex_lock(&cfg80211_drv_mutex);
> > > > > +       regd = reg_get_current_rd();
> > > > > +       mutex_unlock(&cfg80211_drv_mutex);
> > > > > +
> > > > > +       if (!regd)
> > > > > +               goto out;
> > > >
> > > > Any reason you need to copy and can't just build the whole thing under
> > > > lock?
> > >
> > > Glad you asked, we can lock the entire call or we can do the above to
> > > copy. I picked a copy to not let a regular user (get reg can be called
> > > by anyone) abuse the lock as cfg80211_drv_mutex is used in a lot of places,
> > > I guess its silly but other's input on this is appreciated as well. Not sure
> > > if the copy was the best choice.
> >
> > I don't really see much difference between locking to create a copy and
> > locking to create a copy in a different format, do you?
> > Except to create
> > a copy needs to allocate memory which could take even longer.
> 
> Agreed, that's the thing I was not thinking about those two paths I was
> thinking of either using a copy of cfg80211_regdomain for nl80211.c to move
> forward without having to keep cfg80211_drv_mutex *or* having
> reg_get_current_rd() just return cfg80211_regdomain and have the reg_reg
> lock during its entire access.
> 
> I am honestly not sure which is the best approach but I picked a copy
> since I figure having a user do a kmalloc() is less harmless then contending
> the lock more time if he wanted to abuse the system. I also thought about
> using a static regd in place just to copy the cfg80211_regdomain but then
> that would mean having a large static regd with max num rules and I didn't
> like that either. Seemed to me a kmalloc() was in the middle. Let me know
> if you guys have better advice.

Actually nevermind, I see your point now, we would be iterating over 
cfg80211_regdomain anyway, will resend, thanks.

  Luis

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-01-28 16:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-28  2:52 [PATCH] cfg80211: add get reg command Luis R. Rodriguez
2009-01-28 10:17 ` Johannes Berg
2009-01-28 14:44   ` Luis R. Rodriguez
2009-01-28 14:50     ` Johannes Berg
2009-01-28 15:20       ` Luis R. Rodriguez
2009-01-28 16:16         ` Luis R. Rodriguez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).