cfg80211: allow wiphy specific regdomain management
Add a new regulatory flag that allows a driver to manage regdomain changes/updates for its own wiphy. A self-managed wiphys only employs regulatory information obtained from the FW and driver and does not use other cfg80211 sources like beacon-hints, country-code IEs and hints from other devices on the same system. Conversely, a self-managed wiphy does not share its regulatory hints with other devices in the system. If a system contains several devices, one or more of which are self-managed, there might be contradictory regulatory settings between them. Usage of flag is generally discouraged. Only use it if the FW/driver is incompatible with non-locally originated hints. A new API lets the driver send a complete regdomain, to be applied on its wiphy only. After a wiphy-specific regdomain change takes place, usermode will get a new type of change notification. The regulatory core also takes care enforce regulatory restrictions, in case some interfaces are on forbidden channels. Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com> Reviewed-by: Luis R. Rodriguez <mcgrof@suse.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:

committed by
Johannes Berg

parent
ad30ca2c03
commit
b0d7aa5959
@@ -11042,25 +11042,9 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
|
||||
NL80211_MCGRP_SCAN, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* This can happen on global regulatory changes or device specific settings
|
||||
* based on custom world regulatory domains.
|
||||
*/
|
||||
void nl80211_send_reg_change_event(struct regulatory_request *request)
|
||||
static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Userspace can always count this one always being set */
|
||||
if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
|
||||
goto nla_put_failure;
|
||||
@@ -11094,6 +11078,35 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
nla_put_failure:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can happen on global regulatory changes or device specific settings
|
||||
* based on custom regulatory domains.
|
||||
*/
|
||||
void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nl80211_reg_change_event_fill(msg, request) == false)
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
rcu_read_lock();
|
||||
|
Reference in New Issue
Block a user