* [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 = ®d->reg_rules[i];
+ freq_range = ®_rule->freq_range;
+ power_rule = ®_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(®d, 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).