Skip to content

Commit 0e77eff

Browse files
authored
Merge pull request #4012 from vyos/mergify/bp/circinus/pr-3656
wireless: T6318: move country-code to a system wide configuration (backport #3656)
2 parents 92c261e + 549a16f commit 0e77eff

File tree

10 files changed

+262
-23
lines changed

10 files changed

+262
-23
lines changed

data/config-mode-dependencies/vyos-1x.json

+3
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,8 @@
6363
"system_option": {
6464
"ip": ["system_ip"],
6565
"ipv6": ["system_ipv6"]
66+
},
67+
"system_wireless": {
68+
"wireless": ["interfaces_wireless"]
6669
}
6770
}

data/configd-include.json

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
"system_task-scheduler.py",
105105
"system_timezone.py",
106106
"system_update-check.py",
107+
"system_wireless.py",
107108
"vpn_ipsec.py",
108109
"vpn_l2tp.py",
109110
"vpn_openconnect.py",
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<!-- include start from include/version/interfaces-version.xml.i -->
2-
<syntaxVersion component='interfaces' version='32'></syntaxVersion>
2+
<syntaxVersion component='interfaces' version='33'></syntaxVersion>
33
<!-- include end -->

interface-definitions/interfaces_wireless.xml.in

-20
Original file line numberDiff line numberDiff line change
@@ -570,26 +570,6 @@
570570
</properties>
571571
<defaultValue>0</defaultValue>
572572
</leafNode>
573-
<leafNode name="country-code">
574-
<properties>
575-
<help>Indicate country in which device is operating</help>
576-
<completionHelp>
577-
<list>00 ad ae af ai al am an ar as at au aw az ba bb bd be bf bg bh bl bm bn bo br bs bt by bz ca cf ch ci cl cn co cr cu cx cy cz de dk dm do dz ec ee eg es et fi fm fr gb gd ge gf gh gl gp gr gt gu gy hk hn hr ht hu id ie il in ir is it jm jo jp ke kh kn kp kr kw ky kz lb lc li lk ls lt lu lv ma mc md me mf mh mk mn mo mp mq mr mt mu mv mw mx my ng ni nl no np nz om pa pe pf pg ph pk pl pm pr pt pw py qa re ro rs ru rw sa se sg si sk sn sr sv sy tc td tg th tn tr tt tw tz ua ug us uy uz vc ve vi vn vu wf ws ye yt za zw</list>
578-
</completionHelp>
579-
<valueHelp>
580-
<format>00</format>
581-
<description>World regulatory domain</description>
582-
</valueHelp>
583-
<valueHelp>
584-
<format>txt</format>
585-
<description>ISO/IEC 3166-1 Country Code</description>
586-
</valueHelp>
587-
<constraint>
588-
<regex>(00|ad|ae|af|ai|al|am|an|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bl|bm|bn|bo|br|bs|bt|by|bz|ca|cf|ch|ci|cl|cn|co|cr|cu|cx|cy|cz|de|dk|dm|do|dz|ec|ee|eg|es|et|fi|fm|fr|gb|gd|ge|gf|gh|gl|gp|gr|gt|gu|gy|hk|hn|hr|ht|hu|id|ie|il|in|ir|is|it|jm|jo|jp|ke|kh|kn|kp|kr|kw|ky|kz|lb|lc|li|lk|ls|lt|lu|lv|ma|mc|md|me|mf|mh|mk|mn|mo|mp|mq|mr|mt|mu|mv|mw|mx|my|ng|ni|nl|no|np|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pr|pt|pw|py|qa|re|ro|rs|ru|rw|sa|se|sg|si|sk|sn|sr|sv|sy|tc|td|tg|th|tn|tr|tt|tw|tz|ua|ug|us|uy|uz|vc|ve|vi|vn|vu|wf|ws|ye|yt|za|zw)</regex>
589-
</constraint>
590-
<constraintErrorMessage>Invalid ISO/IEC 3166-1 Country Code</constraintErrorMessage>
591-
</properties>
592-
</leafNode>
593573
#include <include/generic-description.xml.i>
594574
#include <include/interface/dhcp-options.xml.i>
595575
#include <include/interface/dhcpv6-options.xml.i>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0"?>
2+
<interfaceDefinition>
3+
<node name="system">
4+
<children>
5+
<node name="wireless" owner="${vyos_conf_scripts_dir}/system_wireless.py">
6+
<properties>
7+
<help>Wireless (IEEE-802.11) subsystem settings</help>
8+
<!-- must be before interface wireless, check /opt/vyatta/sbin/priority.pl -->
9+
<priority>317</priority>
10+
</properties>
11+
<children>
12+
<leafNode name="country-code">
13+
<properties>
14+
<help>Indicate country in which device is operating</help>
15+
<completionHelp>
16+
<list>00 ad ae af ai al am an ar as at au aw az ba bb bd be bf bg bh bl bm bn bo br bs bt by bz ca cf ch ci cl cn co cr cu cx cy cz de dk dm do dz ec ee eg es et fi fm fr gb gd ge gf gh gl gp gr gt gu gy hk hn hr ht hu id ie il in ir is it jm jo jp ke kh kn kp kr kw ky kz lb lc li lk ls lt lu lv ma mc md me mf mh mk mn mo mp mq mr mt mu mv mw mx my ng ni nl no np nz om pa pe pf pg ph pk pl pm pr pt pw py qa re ro rs ru rw sa se sg si sk sn sr sv sy tc td tg th tn tr tt tw tz ua ug us uy uz vc ve vi vn vu wf ws ye yt za zw</list>
17+
</completionHelp>
18+
<valueHelp>
19+
<format>00</format>
20+
<description>World regulatory domain</description>
21+
</valueHelp>
22+
<valueHelp>
23+
<format>txt</format>
24+
<description>ISO/IEC 3166-1 Country Code</description>
25+
</valueHelp>
26+
<constraint>
27+
<regex>(00|ad|ae|af|ai|al|am|an|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bl|bm|bn|bo|br|bs|bt|by|bz|ca|cf|ch|ci|cl|cn|co|cr|cu|cx|cy|cz|de|dk|dm|do|dz|ec|ee|eg|es|et|fi|fm|fr|gb|gd|ge|gf|gh|gl|gp|gr|gt|gu|gy|hk|hn|hr|ht|hu|id|ie|il|in|ir|is|it|jm|jo|jp|ke|kh|kn|kp|kr|kw|ky|kz|lb|lc|li|lk|ls|lt|lu|lv|ma|mc|md|me|mf|mh|mk|mn|mo|mp|mq|mr|mt|mu|mv|mw|mx|my|ng|ni|nl|no|np|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pr|pt|pw|py|qa|re|ro|rs|ru|rw|sa|se|sg|si|sk|sn|sr|sv|sy|tc|td|tg|th|tn|tr|tt|tw|tz|ua|ug|us|uy|uz|vc|ve|vi|vn|vu|wf|ws|ye|yt|za|zw)</regex>
28+
</constraint>
29+
<constraintErrorMessage>Invalid ISO/IEC 3166-1 Country Code</constraintErrorMessage>
30+
</properties>
31+
</leafNode>
32+
</children>
33+
</node>
34+
</children>
35+
</node>
36+
</interfaceDefinition>

smoketest/config-tests/wireless-basic

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
set interfaces ethernet eth0 duplex 'auto'
2+
set interfaces ethernet eth0 speed 'auto'
3+
set interfaces ethernet eth1 duplex 'auto'
4+
set interfaces ethernet eth1 speed 'auto'
5+
set interfaces wireless wlan0 address '192.168.0.1/24'
6+
set interfaces wireless wlan0 channel '1'
7+
set interfaces wireless wlan0 mode 'n'
8+
set interfaces wireless wlan0 security wpa cipher 'CCMP'
9+
set interfaces wireless wlan0 security wpa mode 'wpa2'
10+
set interfaces wireless wlan0 security wpa passphrase '12345678'
11+
set interfaces wireless wlan0 ssid 'VyOS'
12+
set interfaces wireless wlan0 type 'access-point'
13+
set interfaces wireless wlan1 address '192.168.1.1/24'
14+
set interfaces wireless wlan1 channel '2'
15+
set interfaces wireless wlan1 mode 'n'
16+
set interfaces wireless wlan1 ssid 'VyOS-PUBLIC'
17+
set interfaces wireless wlan1 type 'access-point'
18+
set system config-management commit-revisions '200'
19+
set system console device ttyS0 speed 115200
20+
set system domain-name 'dev.vyos.net'
21+
set system host-name 'WR1'
22+
set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0'
23+
set system wireless country-code 'es'
24+
set system syslog global facility all level 'info'
25+
set system syslog global facility local7 level 'debug'

smoketest/configs/wireless-basic

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
interfaces {
2+
ethernet eth0 {
3+
duplex "auto"
4+
speed "auto"
5+
}
6+
ethernet eth1 {
7+
duplex "auto"
8+
speed "auto"
9+
}
10+
wireless wlan0 {
11+
address 192.168.0.1/24
12+
channel 1
13+
country-code es
14+
mode n
15+
security {
16+
wpa {
17+
cipher CCMP
18+
mode wpa2
19+
passphrase 12345678
20+
}
21+
}
22+
ssid VyOS
23+
type access-point
24+
}
25+
wireless wlan1 {
26+
address 192.168.1.1/24
27+
channel 2
28+
country-code de
29+
mode n
30+
ssid VyOS-PUBLIC
31+
type access-point
32+
}
33+
}
34+
system {
35+
config-management {
36+
commit-revisions "200"
37+
}
38+
console {
39+
device ttyS0 {
40+
speed 115200
41+
}
42+
}
43+
domain-name "dev.vyos.net"
44+
host-name "WR1"
45+
login {
46+
user vyos {
47+
authentication {
48+
encrypted-password "$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0"
49+
}
50+
}
51+
}
52+
syslog {
53+
global {
54+
facility all {
55+
level "info"
56+
}
57+
facility local7 {
58+
level "debug"
59+
}
60+
}
61+
}
62+
}
63+
64+
// Warning: Do not remove the following line.
65+
// vyos-config-version: "bgp@5:broadcast-relay@1:cluster@2:config-management@1:conntrack@5:conntrack-sync@2:container@2:dhcp-relay@2:dhcp-server@8:dhcpv6-server@1:dns-dynamic@4:dns-forwarding@4:firewall@15:flow-accounting@1:https@6:ids@1:interfaces@32:ipoe-server@3:ipsec@13:isis@3:l2tp@9:lldp@2:mdns@1:monitoring@1:nat@8:nat66@3:ntp@3:openconnect@3:ospf@2:pim@1:policy@8:pppoe-server@10:pptp@5:qos@2:quagga@11:reverse-proxy@1:rip@1:rpki@2:salt@1:snmp@3:ssh@2:sstp@6:system@27:vrf@3:vrrp@4:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2"
66+
// Release version: 1.4.0

src/conf_mode/interfaces_wireless.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
hostapd_accept_station_conf = '/run/hostapd/{ifname}_station_accept.conf'
4949
hostapd_deny_station_conf = '/run/hostapd/{ifname}_station_deny.conf'
5050

51+
country_code_path = ['system', 'wireless', 'country-code']
52+
5153
def find_other_stations(conf, base, ifname):
5254
"""
5355
Only one wireless interface per phy can be in station mode -
@@ -82,7 +84,11 @@ def get_config(config=None):
8284
conf = Config()
8385
base = ['interfaces', 'wireless']
8486

85-
ifname, wifi = get_interface_dict(conf, base)
87+
_, wifi = get_interface_dict(conf, base)
88+
89+
# retrieve global Wireless regulatory domain setting
90+
if conf.exists(country_code_path):
91+
wifi['country_code'] = conf.return_value(country_code_path)
8692

8793
if 'deleted' not in wifi:
8894
# then get_interface_dict provides default keys
@@ -149,7 +155,8 @@ def verify(wifi):
149155

150156
if wifi['type'] == 'access-point':
151157
if 'country_code' not in wifi:
152-
raise ConfigError('Wireless country-code is mandatory')
158+
raise ConfigError(f'Wireless country-code is mandatory, use: '\
159+
f'"set {" ".join(country_code_path)}"!')
153160

154161
if 'channel' not in wifi:
155162
raise ConfigError('Wireless channel must be configured!')

src/conf_mode/system_wireless.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (C) 2024 VyOS maintainers and contributors
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License version 2 or later as
7+
# published by the Free Software Foundation.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
from sys import exit
18+
19+
from vyos.config import Config
20+
from vyos.configdep import set_dependents
21+
from vyos.configdep import call_dependents
22+
from vyos import ConfigError
23+
from vyos import airbag
24+
airbag.enable()
25+
26+
def get_config(config=None):
27+
if config:
28+
conf = config
29+
else:
30+
conf = Config()
31+
base = ['system', 'wireless']
32+
interface_base = ['interfaces', 'wireless']
33+
34+
wireless = conf.get_config_dict(base, key_mangling=('-', '_'),
35+
get_first_key=True)
36+
37+
38+
if conf.exists(interface_base):
39+
wireless['interfaces'] = conf.list_nodes(interface_base)
40+
for interface in wireless['interfaces']:
41+
set_dependents('wireless', conf, interface)
42+
43+
return wireless
44+
45+
def verify(wireless):
46+
pass
47+
48+
def generate(wireless):
49+
pass
50+
51+
def apply(wireless):
52+
if 'interfaces' in wireless:
53+
call_dependents()
54+
pass
55+
56+
if __name__ == '__main__':
57+
try:
58+
c = get_config()
59+
verify(c)
60+
generate(c)
61+
apply(c)
62+
except ConfigError as e:
63+
print(e)
64+
exit(1)
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (C) 2024 VyOS maintainers and contributors
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License version 2 or later as
7+
# published by the Free Software Foundation.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
#
17+
# T6318: WiFi country-code should be set system-wide instead of per-device
18+
19+
from sys import argv
20+
from sys import exit
21+
from vyos.configtree import ConfigTree
22+
23+
if len(argv) < 2:
24+
print("Must specify file name!")
25+
exit(1)
26+
27+
file_name = argv[1]
28+
with open(file_name, 'r') as f:
29+
config_file = f.read()
30+
31+
base = ['interfaces', 'wireless']
32+
33+
config = ConfigTree(config_file)
34+
if not config.exists(base):
35+
# Nothing to do
36+
exit(0)
37+
38+
installed = False
39+
for interface in config.list_nodes(base):
40+
cc_path = base + [interface, 'country-code']
41+
if config.exists(cc_path):
42+
tmp = config.return_value(cc_path)
43+
config.delete(cc_path)
44+
45+
# There can be only ONE wireless country-code per device, everything
46+
# else makes no sense as a WIFI router can not operate in two
47+
# different countries
48+
if not installed:
49+
config.set(['system', 'wireless', 'country-code'], value=tmp)
50+
installed = True
51+
52+
try:
53+
with open(file_name, 'w') as f:
54+
f.write(config.to_string())
55+
except OSError as e:
56+
print(f'Failed to save the modified config: {e}')
57+
exit(1)

0 commit comments

Comments
 (0)