ifconfig: set by default FCC regulatory domain for wireless interfaces.

Change default regulatory domain from DEBUG (no limitations;
exposes all device channels) to FCC; as a result, newly created wireless
interface with default settings will have less chances to violate
country-specific regulations.

This change will not affect drivers with pre-initialized regdomain
structure (currentry ath(4) and mwl(4)); in that case, the default
channel list must correspond to the default regdomain / country setting.

You can switch to another regdomain / country via corresponding
ifconfig(8) options; the driver must implement ic_getradiocaps()
method to restore full channel list.

Full country / regdomain list may be obtained via
'ifconfig <iface> list countries' command.

Example: change country to Germany:
ifconfig wlan0 down	# all wlans on the device must be down
ifconfig wlan0 country DE
ifconfig wlan0 up
# wpa_supplicant(8), dhclient(8) etc

At the creation time:
ifconfig wlan0 create wlandev wpi0 country DE

To make changes permanent add the following line to the rc.conf(5):
create_args_wlan0="country DE"

Tested with
 - Intel 3945BG (wpi(4)).
 - WUSB54GC (rum(4)).

Reviewed by:	adrian
Relnotes:	yes
Differential Revision:	https://reviews.freebsd.org/D6228
This commit is contained in:
Andriy Voskoboinyk 2016-05-26 13:14:08 +00:00
parent bcec64bc61
commit b628bdccce
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=300738
2 changed files with 40 additions and 3 deletions

View File

@ -5141,6 +5141,44 @@ print_string(const u_int8_t *buf, int len)
}
}
static void
setdefregdomain(int s)
{
struct regdata *rdp = getregdata();
const struct regdomain *rd;
/* Check if regdomain/country was already set by a previous call. */
/* XXX is it possible? */
if (regdomain.regdomain != 0 ||
regdomain.country != CTRY_DEFAULT)
return;
getregdomain(s);
/* Check if it was already set by the driver. */
if (regdomain.regdomain != 0 ||
regdomain.country != CTRY_DEFAULT)
return;
/* Set FCC/US as default. */
rd = lib80211_regdomain_findbysku(rdp, SKU_FCC);
if (rd == NULL)
errx(1, "FCC regdomain was not found");
regdomain.regdomain = rd->sku;
if (rd->cc != NULL)
defaultcountry(rd);
/* Send changes to net80211. */
setregdomain_cb(s, &regdomain);
/* Cleanup (so it can be overriden by subsequent parameters). */
regdomain.regdomain = 0;
regdomain.country = CTRY_DEFAULT;
regdomain.isocc[0] = 0;
regdomain.isocc[1] = 0;
}
/*
* Virtual AP cloning support.
*/
@ -5162,6 +5200,8 @@ wlan_create(int s, struct ifreq *ifr)
ifr->ifr_data = (caddr_t) &params;
if (ioctl(s, SIOCIFCREATE2, ifr) < 0)
err(1, "SIOCIFCREATE2");
setdefregdomain(s);
}
static

View File

@ -69,10 +69,7 @@ ieee80211_regdomain_attach(struct ieee80211com *ic)
{
if (ic->ic_regdomain.regdomain == 0 &&
ic->ic_regdomain.country == CTRY_DEFAULT) {
ic->ic_regdomain.country = CTRY_UNITED_STATES; /* XXX */
ic->ic_regdomain.location = ' '; /* both */
ic->ic_regdomain.isocc[0] = 'U'; /* XXX */
ic->ic_regdomain.isocc[1] = 'S'; /* XXX */
/* NB: driver calls ieee80211_init_channels or similar */
}
ic->ic_getradiocaps = null_getradiocaps;