summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/configd-include.json3
-rw-r--r--data/templates/wifi/hostapd.conf.tmpl12
-rw-r--r--interface-definitions/interfaces-wireless.xml.in59
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py19
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py8
-rwxr-xr-xsrc/conf_mode/system-wifi-regdom.py90
-rwxr-xr-xsrc/migration-scripts/interfaces/13-to-1412
7 files changed, 61 insertions, 142 deletions
diff --git a/data/configd-include.json b/data/configd-include.json
index 95aef65ad..da6fb915f 100644
--- a/data/configd-include.json
+++ b/data/configd-include.json
@@ -48,7 +48,6 @@
"system-options.py",
"system-syslog.py",
"system-timezone.py",
-"system-wifi-regdom.py",
"system_console.py",
"system_lcd.py",
"task_scheduler.py",
@@ -59,4 +58,4 @@
"vrf.py",
"vrrp.py",
"vyos_cert.py"
-] \ No newline at end of file
+]
diff --git a/data/templates/wifi/hostapd.conf.tmpl b/data/templates/wifi/hostapd.conf.tmpl
index 95837da95..16d9f7c98 100644
--- a/data/templates/wifi/hostapd.conf.tmpl
+++ b/data/templates/wifi/hostapd.conf.tmpl
@@ -72,18 +72,18 @@ ssid={{ ssid }}
channel={{ channel }}
{% endif %}
-{% if mode %}
+{% if mode is defined and mode is not none %}
# Operation mode (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz),
# g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz); a/g options are used
# with IEEE 802.11n (HT), too, to specify band). For IEEE 802.11ac (VHT), this
-# needs to be set to hw_mode=a. For IEEE 802.11ax (HE) on 6 GHz this needs
-# to be set to hw_mode=a. When using ACS (see channel parameter), a
+# needs to be set to hw_mode a. For IEEE 802.11ax (HE) on 6 GHz this needs
+# to be set to hw_mode a. When using ACS (see channel parameter), a
# special value "any" can be used to indicate that any support band can be used.
# This special case is currently supported only with drivers with which
# offloaded ACS is used.
-{% if 'n' in mode %}
+{% if mode == 'n' %}
hw_mode=g
-{% elif 'ac' in mode %}
+{% elif mode == 'ac' %}
hw_mode=a
ieee80211h=1
ieee80211ac=1
@@ -533,7 +533,7 @@ wep_key{{ loop.index -1 }}={{ security.wep.key }}
# bit0 = WPA
# bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled)
# Note that WPA3 is also configured with bit1 since it uses RSN just like WPA2.
-# In other words, for WPA3, wpa=2 is used the configuration (and
+# In other words, for WPA3, wpa 2 is used the configuration (and
# wpa_key_mgmt=SAE for WPA3-Personal instead of wpa_key_mgmt=WPA-PSK).
{% if security.wpa.mode is defined %}
{% if security.wpa.mode == 'wpa+wpa2' %}
diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in
index c805e488a..78c40d876 100644
--- a/interface-definitions/interfaces-wireless.xml.in
+++ b/interface-definitions/interfaces-wireless.xml.in
@@ -58,7 +58,7 @@
<description>Supported channel set width both 20 MHz and 40 MHz with secondary channel below primary channel</description>
</valueHelp>
<constraint>
- <regex>(ht20|ht40\+|ht40-)</regex>
+ <regex>^(ht20|ht40\+|ht40-)$</regex>
</constraint>
<multi/>
</properties>
@@ -108,7 +108,7 @@
<description>Set maximum A-MSDU length to 7935 octets</description>
</valueHelp>
<constraint>
- <regex>(3839|7935)</regex>
+ <regex>^(3839|7935)$</regex>
</constraint>
</properties>
</leafNode>
@@ -127,7 +127,7 @@
<description>Short GI for 40 MHz</description>
</valueHelp>
<constraint>
- <regex>(20|40)</regex>
+ <regex>^(20|40)$</regex>
</constraint>
<multi/>
</properties>
@@ -147,7 +147,7 @@
<description>DYNAMIC Spatial Multiplexing (SM) Power Save</description>
</valueHelp>
<constraint>
- <regex>(static|dynamic)</regex>
+ <regex>^(static|dynamic)$</regex>
</constraint>
</properties>
</leafNode>
@@ -164,7 +164,7 @@
<description>Number of spacial streams that can use RX STBC</description>
</valueHelp>
<constraint>
- <regex>[1-3]+</regex>
+ <regex>^[1-3]+$</regex>
</constraint>
<constraintErrorMessage>Invalid capability item</constraintErrorMessage>
</properties>
@@ -243,7 +243,7 @@
<description>Support for operation as multi user beamformee</description>
</valueHelp>
<constraint>
- <regex>(single-user-beamformer|single-user-beamformee|multi-user-beamformer|multi-user-beamformee)</regex>
+ <regex>^(single-user-beamformer|single-user-beamformee|multi-user-beamformer|multi-user-beamformee)$</regex>
</constraint>
<multi/>
</properties>
@@ -329,7 +329,7 @@
<description>Station can provide VHT MFB in response to VHT MRQ and unsolicited VHT MFB</description>
</valueHelp>
<constraint>
- <regex>(unsolicited|both)</regex>
+ <regex>^(unsolicited|both)$</regex>
</constraint>
<constraintErrorMessage>Invalid capability item</constraintErrorMessage>
</properties>
@@ -361,7 +361,7 @@
<description>ncrease Maximum MPDU length to 11454 octets</description>
</valueHelp>
<constraint>
- <regex>(7991|11454)</regex>
+ <regex>^(7991|11454)$</regex>
</constraint>
</properties>
</leafNode>
@@ -380,7 +380,7 @@
<description>Short GI for 160 MHz</description>
</valueHelp>
<constraint>
- <regex>(80|160)</regex>
+ <regex>^(80|160)$</regex>
</constraint>
<multi/>
</properties>
@@ -398,7 +398,7 @@
<description>Number of spacial streams that can use RX STBC</description>
</valueHelp>
<constraint>
- <regex>[1-4]+</regex>
+ <regex>^[1-4]+$</regex>
</constraint>
<constraintErrorMessage>Invalid capability item</constraintErrorMessage>
</properties>
@@ -443,6 +443,22 @@
</constraint>
</properties>
</leafNode>
+ <leafNode name="country-code">
+ <properties>
+ <help>Indicate country in which device is operating</help>
+ <completionHelp>
+ <list>US EU JP DE UK CN ES FR RU</list>
+ </completionHelp>
+ <valueHelp>
+ <format>&lt;code%gt;</format>
+ <description>ISO/IEC 3166-1 Country Code</description>
+ </valueHelp>
+ <constraint>
+ <regex>^[A-Z][A-Z]$</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid ISO/IEC 3166-1 Country Code</constraintErrorMessage>
+ </properties>
+ </leafNode>
#include <include/interface-description.xml.i>
#include <include/dhcp-options.xml.i>
#include <include/dhcpv6-options.xml.i>
@@ -520,7 +536,7 @@
<description>MFP enforced</description>
</valueHelp>
<constraint>
- <regex>(disabled|optional|required)</regex>
+ <regex>^(disabled|optional|required)$</regex>
</constraint>
</properties>
</leafNode>
@@ -782,25 +798,4 @@
</tagNode>
</children>
</node>
- <node name="system">
- <children>
- <leafNode name="wifi-regulatory-domain" owner="${vyos_conf_scripts_dir}/system-wifi-regdom.py">
- <properties>
- <help>Wireless regulatory domain (mandatory)</help>
- <priority>305</priority>
- <completionHelp>
- <list>US EU JP DE UK CN</list>
- </completionHelp>
- <valueHelp>
- <format>&lt;code%gt;</format>
- <description>Country code (ISO/IEC 3166-1)</description>
- </valueHelp>
- <constraint>
- <regex>[A-Z][A-Z]$</regex>
- </constraint>
- <constraintErrorMessage>invalid country code</constraintErrorMessage>
- </properties>
- </leafNode>
- </children>
- </node>
</interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index a62b44ee5..65cf127ce 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.py
@@ -38,15 +38,14 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
self._options = {
'wlan0': ['physical-device phy0', 'ssid VyOS-WIFI-0',
'type station', 'address 192.0.2.1/30'],
- 'wlan1': ['physical-device phy0', 'ssid VyOS-WIFI-1',
+ 'wlan1': ['physical-device phy0', 'ssid VyOS-WIFI-1', 'country-code SE',
'type access-point', 'address 192.0.2.5/30', 'channel 0'],
'wlan10': ['physical-device phy1', 'ssid VyOS-WIFI-2',
'type station', 'address 192.0.2.9/30'],
- 'wlan11': ['physical-device phy1', 'ssid VyOS-WIFI-3',
+ 'wlan11': ['physical-device phy1', 'ssid VyOS-WIFI-3', 'country-code SE',
'type access-point', 'address 192.0.2.13/30', 'channel 0'],
}
self._interfaces = list(self._options)
- self.session.set(['system', 'wifi-regulatory-domain', 'SE'])
def test_add_address_single(self):
""" derived method to check if member interfaces are enslaved properly """
@@ -75,6 +74,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
self.session.set(self._base_path + [interface, 'ssid', ssid])
self.session.set(self._base_path + [interface, 'type', 'access-point'])
self.session.set(self._base_path + [interface, 'channel', channel])
+ self.session.set(self._base_path + [interface, 'country-code', 'SE'])
# auto-powersave is special
self.session.set(self._base_path + [interface, 'capabilities', 'ht', 'auto-powersave'])
@@ -152,10 +152,11 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
channel = '0'
wpa_key = 'VyOSVyOSVyOS'
mode = 'n'
+ country = 'DE'
self.session.set(self._base_path + [interface, 'physical-device', phy])
self.session.set(self._base_path + [interface, 'type', 'access-point'])
- self.session.set(self._base_path + [interface, 'mode', 'mode'])
+ self.session.set(self._base_path + [interface, 'mode', mode])
# SSID must be set
with self.assertRaises(ConfigSessionError):
@@ -167,6 +168,10 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
self.session.commit()
self.session.set(self._base_path + [interface, 'channel', channel])
+ # Country-Code must be set
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+ self.session.set(self._base_path + [interface, 'country-code', country])
self.session.set(self._base_path + [interface, 'security', 'wpa', 'mode', 'wpa2'])
self.session.set(self._base_path + [interface, 'security', 'wpa', 'passphrase', wpa_key])
@@ -180,6 +185,8 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
self.assertEqual(interface, tmp)
tmp = get_config_value(interface, 'hw_mode')
+ # rewrite special mode
+ if mode == 'n': mode = 'g'
self.assertEqual(mode, tmp)
# WPA key
@@ -196,6 +203,10 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
tmp = get_config_value(interface, 'channel')
self.assertEqual(channel, tmp)
+ # Country code
+ tmp = get_config_value(interface, 'country_code')
+ self.assertEqual(country, tmp)
+
# Check for running process
self.assertTrue(process_named_running('hostapd'))
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index a18a21b83..5d723bbfd 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -109,11 +109,6 @@ def get_config(config=None):
if tmp: wifi = dict_merge(tmp, wifi)
- # retrieve configured regulatory domain
- conf.set_level(['system'])
- if conf.exists(['wifi-regulatory-domain']):
- wifi['country_code'] = conf.return_value(['wifi-regulatory-domain'])
-
# Only one wireless interface per phy can be in station mode
tmp = find_other_stations(conf, base, wifi['ifname'])
if tmp: wifi['station_interfaces'] = tmp
@@ -144,8 +139,7 @@ def verify(wifi):
if wifi['type'] == 'access-point':
if 'country_code' not in wifi:
- raise ConfigError('Wireless regulatory domain is mandatory,\n' \
- 'use "set system wifi-regulatory-domain" for configuration.')
+ raise ConfigError('Wireless country-code is mandatory')
if 'channel' not in wifi:
raise ConfigError('Wireless channel must be configured!')
diff --git a/src/conf_mode/system-wifi-regdom.py b/src/conf_mode/system-wifi-regdom.py
deleted file mode 100755
index 874f93923..000000000
--- a/src/conf_mode/system-wifi-regdom.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from copy import deepcopy
-from sys import exit
-
-from vyos.config import Config
-from vyos import ConfigError
-from vyos.template import render
-
-from vyos import airbag
-airbag.enable()
-
-config_80211_file='/etc/modprobe.d/cfg80211.conf'
-config_crda_file='/etc/default/crda'
-
-default_config_data = {
- 'regdom' : '',
- 'deleted' : False
-}
-
-def get_config(config=None):
- regdom = deepcopy(default_config_data)
- if config:
- conf = config
- else:
- conf = Config()
- base = ['system', 'wifi-regulatory-domain']
-
- # Check if interface has been removed
- if not conf.exists(base):
- regdom['deleted'] = True
- return regdom
- else:
- regdom['regdom'] = conf.return_value(base)
-
- return regdom
-
-def verify(regdom):
- if regdom['deleted']:
- return None
-
- if not regdom['regdom']:
- raise ConfigError("Wireless regulatory domain is mandatory.")
-
- return None
-
-def generate(regdom):
- print("Changing the wireless regulatory domain requires a system reboot.")
-
- if regdom['deleted']:
- if os.path.isfile(config_80211_file):
- os.unlink(config_80211_file)
-
- if os.path.isfile(config_crda_file):
- os.unlink(config_crda_file)
-
- return None
-
- render(config_80211_file, 'wifi/cfg80211.conf.tmpl', regdom)
- render(config_crda_file, 'wifi/crda.tmpl', regdom)
- return None
-
-def apply(regdom):
- return None
-
-if __name__ == '__main__':
- try:
- c = get_config()
- verify(c)
- generate(c)
- apply(c)
- except ConfigError as e:
- print(e)
- exit(1)
diff --git a/src/migration-scripts/interfaces/13-to-14 b/src/migration-scripts/interfaces/13-to-14
index 545b57ab2..fc6d7f443 100755
--- a/src/migration-scripts/interfaces/13-to-14
+++ b/src/migration-scripts/interfaces/13-to-14
@@ -14,7 +14,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Rename Wireless interface security mode 'both' to 'wpa+wpa2'
+# T3043: rename Wireless interface security mode 'both' to 'wpa+wpa2'
+# T3043: move "system wifi-regulatory-domain" to indicidual wireless interface
import os
@@ -36,6 +37,12 @@ if __name__ == '__main__':
# Nothing to do
exit(0)
+ country_code = ''
+ cc_cli = ['system', 'wifi-regulatory-domain']
+ if config.exists(cc_cli):
+ country_code = config.return_value(cc_cli)
+ config.delete(cc_cli)
+
for wifi in config.list_nodes(base):
sec_mode = base + [wifi, 'security', 'wpa', 'mode']
if config.exists(sec_mode):
@@ -43,6 +50,9 @@ if __name__ == '__main__':
if mode == 'both':
config.set(sec_mode, value='wpa+wpa2', replace=True)
+ if country_code:
+ config.set(base + [wifi, 'country-code'], value=country_code)
+
try:
with open(file_name, 'w') as f:
f.write(config.to_string())