summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/wifi/hostapd.conf.tmpl11
-rw-r--r--interface-definitions/interfaces-wireless.xml.in2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py87
-rwxr-xr-xsmoketest/scripts/system/test_kernel_options.py2
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py6
5 files changed, 96 insertions, 12 deletions
diff --git a/data/templates/wifi/hostapd.conf.tmpl b/data/templates/wifi/hostapd.conf.tmpl
index b00515d76..132c4ce40 100644
--- a/data/templates/wifi/hostapd.conf.tmpl
+++ b/data/templates/wifi/hostapd.conf.tmpl
@@ -51,10 +51,6 @@ ssid={{ ssid }}
# (default: 0, i.e., not set)
# Please note that some drivers do not use this value from hostapd and the
# channel will need to be configured separately with iwconfig.
-#
-# If CONFIG_ACS build option is enabled, the channel can be selected
-# automatically at run time by setting channel=acs_survey or channel=0, both of
-# which will enable the ACS survey based algorithm.
channel={{ channel }}
{% endif %}
@@ -341,13 +337,10 @@ vht_oper_chwidth={{ capabilities.vht.channel_set_width }}
{% set output.value = output.value + '[HTC-VHT]' %}
{% endif %}
{% if capabilities.vht.antenna_pattern_fixed is defined %}
-{% set output.value = output.value + '[RX-ANTENNA-PATTERN]' %}
-{% endif %}
-{% if capabilities.vht.antenna_pattern_fixed is defined %}
-{% set output.value = output.value + '[TX-ANTENNA-PATTERN]' %}
+{% set output.value = output.value + '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]' %}
{% endif %}
{% if capabilities.vht.max_mpdu is defined %}
-{% set output.value = output.value + '[MAX-MPDU-' + capabilities.vht.max_mpdu + ']' %}
+{% set output.value = output.value + '[MAX-MPDU-' + capabilities.vht.max_mpdu + ']' %}
{% endif %}
{% if capabilities.vht.max_mpdu_exp is defined %}
{% set output.value = output.value + '[MAX-A-MPDU-LEN-EXP-' + capabilities.vht.max_mpdu_exp + ']' %}
diff --git a/interface-definitions/interfaces-wireless.xml.in b/interface-definitions/interfaces-wireless.xml.in
index 6f0ec9e71..a0caf810f 100644
--- a/interface-definitions/interfaces-wireless.xml.in
+++ b/interface-definitions/interfaces-wireless.xml.in
@@ -110,7 +110,6 @@
<constraint>
<regex>(3839|7935)</regex>
</constraint>
- <multi/>
</properties>
</leafNode>
<leafNode name="short-gi">
@@ -150,7 +149,6 @@
<constraint>
<regex>(static|dynamic)</regex>
</constraint>
- <multi/>
</properties>
</leafNode>
<node name="stbc">
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index fae233244..691f633b7 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.py
@@ -15,11 +15,19 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import re
import unittest
from base_interfaces_test import BasicInterfaceTest
from psutil import process_iter
+
from vyos.util import check_kmod
+from vyos.util import read_file
+
+def get_config_value(interface, key):
+ tmp = read_file(f'/run/hostapd/{interface}.conf')
+ tmp = re.findall(r'\n?{}=+(.*)'.format(key), tmp)
+ return tmp[0]
class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
def setUp(self):
@@ -53,6 +61,85 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
else:
self.assertTrue(False)
+ def test_hostapd_config(self):
+ """ Check if hostapd config is properly generated """
+
+ # Only set the hostapd (access-point) options
+ interface = 'wlan0'
+ phy = 'phy0'
+ ssid = 'ssid'
+ channel = '1'
+
+ self.session.set(self._base_path + [interface, 'physical-device', phy])
+ 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])
+ # auto-powersave is special
+ self.session.set(self._base_path + [interface, 'capabilities', 'ht', 'auto-powersave'])
+
+ ht_opt = {
+ # VyOS CLI option hostapd - ht_capab setting
+ '40mhz-incapable' : '[40-INTOLERANT]',
+ 'delayed-block-ack' : '[DELAYED-BA]',
+ 'greenfield' : '[GF]',
+ 'ldpc' : '[LDPC]',
+ 'lsig-protection' : '[LSIG-TXOP-PROT]',
+ 'channel-set-width ht40+' : '[HT40+]',
+ 'stbc tx' : '[TX-STBC]',
+ 'stbc rx 123' : '[RX-STBC-123]',
+ 'max-amsdu 7935' : '[MAX-AMSDU-7935]',
+ 'smps static' : '[SMPS-STATIC]',
+ }
+ for key in ht_opt:
+ self.session.set(self._base_path + [interface, 'capabilities', 'ht'] + key.split())
+
+ vht_opt = {
+ # VyOS CLI option hostapd - ht_capab setting
+ 'stbc tx' : '[TX-STBC-2BY1]',
+ 'stbc rx 12' : '[RX-STBC-12]',
+ 'ldpc' : '[RXLDPC]',
+ 'tx-powersave' : '[VHT-TXOP-PS]',
+ 'vht-cf' : '[HTC-VHT]',
+ 'antenna-pattern-fixed' : '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]',
+ 'max-mpdu 11454' : '[MAX-MPDU-11454]',
+ 'max-mpdu-exp 2' : '[MAX-A-MPDU-LEN-EXP-2][VHT160]',
+ 'link-adaptation both' : '[VHT-LINK-ADAPT3]',
+ 'short-gi 80' : '[SHORT-GI-80]',
+ 'short-gi 160' : '[SHORT-GI-160]',
+ }
+ for key in vht_opt:
+ self.session.set(self._base_path + [interface, 'capabilities', 'vht'] + key.split())
+
+ self.session.commit()
+
+ #
+ # Validate Config
+ #
+
+ # ssid
+ tmp = get_config_value(interface, 'ssid')
+ self.assertEqual(ssid, tmp)
+
+ # channel
+ tmp = get_config_value(interface, 'channel')
+ self.assertEqual(channel, tmp)
+
+ # auto-powersave is special
+ tmp = get_config_value(interface, 'uapsd_advertisement_enabled')
+ self.assertEqual('1', tmp)
+
+ tmp = get_config_value(interface, 'ht_capab')
+ for key, value in ht_opt.items():
+ self.assertIn(value, tmp)
+
+ tmp = get_config_value(interface, 'vht_capab')
+ for key, value in vht_opt.items():
+ self.assertIn(value, tmp)
+
+ # Check for running process
+ self.assertIn('hostapd', (p.name() for p in process_iter()))
+
+
if __name__ == '__main__':
check_kmod('mac80211_hwsim')
unittest.main()
diff --git a/smoketest/scripts/system/test_kernel_options.py b/smoketest/scripts/system/test_kernel_options.py
index 861132127..8c96d96fb 100755
--- a/smoketest/scripts/system/test_kernel_options.py
+++ b/smoketest/scripts/system/test_kernel_options.py
@@ -30,7 +30,7 @@ class TestKernelModules(unittest.TestCase):
for option in ['CONFIG_AUDIT', 'CONFIG_HAVE_ARCH_AUDITSYSCALL',
'CONFIG_AUDITSYSCALL', 'CONFIG_AUDIT_WATCH',
'CONFIG_AUDIT_TREE', 'CONFIG_AUDIT_ARCH']:
- self.asserIn(f'{option}=y', config)
+ self.assertIn(f'{option}=y', config)
if __name__ == '__main__':
unittest.main()
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index 9861f72db..c6c843e7b 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -33,6 +33,7 @@ from vyos.configverify import verify_vrf
from vyos.ifconfig import WiFiIf
from vyos.template import render
from vyos.util import call
+from vyos.util import vyos_dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -213,6 +214,11 @@ def generate(wifi):
mac.dialect = mac_unix_expanded
wifi['mac'] = str(mac)
+ # XXX: Jinja2 can not operate on a dictionary key when it starts of with a number
+ if '40mhz_incapable' in (vyos_dict_search('capabilities.ht', wifi) or []):
+ wifi['capabilities']['ht']['fourtymhz_incapable'] = wifi['capabilities']['ht']['40mhz_incapable']
+ del wifi['capabilities']['ht']['40mhz_incapable']
+
# render appropriate new config files depending on access-point or station mode
if wifi['type'] == 'access-point':
render(hostapd_conf.format(**wifi), 'wifi/hostapd.conf.tmpl', wifi, trim_blocks=True)