diff options
| -rw-r--r-- | data/templates/wifi/hostapd.conf.j2 | 32 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_interfaces_wireless.py | 140 | 
2 files changed, 156 insertions, 16 deletions
diff --git a/data/templates/wifi/hostapd.conf.j2 b/data/templates/wifi/hostapd.conf.j2 index 769325b49..e1a08f7e4 100644 --- a/data/templates/wifi/hostapd.conf.j2 +++ b/data/templates/wifi/hostapd.conf.j2 @@ -383,23 +383,25 @@ vht_oper_chwidth={{ capabilities.vht.channel_set_width }}  {%     for short_gi in capabilities.vht.short_gi if capabilities.vht.short_gi is vyos_defined %}  {%         set output.value = output.value ~ '[SHORT-GI-' ~ short_gi | upper ~ ']'  %}  {%     endfor %} -{%     for beamform in capabilities.vht.beamform if capabilities.vht.beamform is vyos_defined %} -{%         set output.value = output.value ~ '[SU-BEAMFORMER]' if beamform is vyos_defined('single-user-beamformer') else '' %} -{%         set output.value = output.value ~ '[SU-BEAMFORMEE]' if beamform is vyos_defined('single-user-beamformee') else '' %} -{%         set output.value = output.value ~ '[MU-BEAMFORMER]' if beamform is vyos_defined('multi-user-beamformer')  else '' %} -{%         set output.value = output.value ~ '[MU-BEAMFORMEE]' if beamform is vyos_defined('multi-user-beamformee')  else '' %} -{%     endfor %} -{%     if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1  %} -{%         if capabilities.vht.beamform is vyos_defined %} -{%             if capabilities.vht.beamform == 'single-user-beamformer' %} +{%     if capabilities.vht.beamform is vyos_defined %} +{%         for bf in capabilities.vht.beamform %} +{%             set output.value = output.value ~ '[SU-BEAMFORMER]' if bf is vyos_defined('single-user-beamformer') else output.value %} +{%             set output.value = output.value ~ '[SU-BEAMFORMEE]' if bf is vyos_defined('single-user-beamformee') else output.value %} +{%             set output.value = output.value ~ '[MU-BEAMFORMER]' if bf is vyos_defined('multi-user-beamformer') else output.value %} +{%             set output.value = output.value ~ '[MU-BEAMFORMEE]' if bf is vyos_defined('multi-user-beamformee') else output.value %} +{%         endfor %} +{%         if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1  %} +{%             if 'single-user-beamformer' in capabilities.vht.beamform %}  {%                 if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 6  %} -{%                     set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count | int -1 ~ ']' %} -{%                     set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count | int -1 ~ ']' %} +{%                     set dimension = capabilities.vht.antenna_count | int - 1 %} +{%                     set output.value = output.value ~ '[BF-ANTENNA-' ~ dimension ~ ']' %} +{%                     set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ dimension ~ ']' %} +{%                 endif %} +{%             else %} +{%                 if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 5  %} +{%                     set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count ~ ']' %} +{%                     set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count ~ ']' %}  {%                 endif %} -{%             endif %} -{%             if capabilities.vht.antenna_count is vyos_defined and capabilities.vht.antenna_count | int > 1 and capabilities.vht.antenna_count | int < 5  %} -{%                 set output.value = output.value ~ '[BF-ANTENNA-' ~ capabilities.vht.antenna_count ~ ']' %} -{%                 set output.value = output.value ~ '[SOUNDING-DIMENSION-' ~ capabilities.vht.antenna_count ~ ']' %}  {%             endif %}  {%         endif %}  {%     endif %} diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py index b45754cae..5ade36e7d 100755 --- a/smoketest/scripts/cli/test_interfaces_wireless.py +++ b/smoketest/scripts/cli/test_interfaces_wireless.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2020-2023 VyOS maintainers and contributors +# Copyright (C) 2020-2024 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 @@ -146,6 +146,144 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase):          # Check for running process          self.assertTrue(process_named_running('hostapd')) +    def test_wireless_hostapd_vht_mu_beamformer_config(self): +        # Multi-User-Beamformer +        interface = 'wlan1' +        ssid = 'vht_mu-beamformer' +        antennas = '3' + +        self.cli_set(self._base_path + [interface, 'ssid', ssid]) +        self.cli_set(self._base_path + [interface, 'type', 'access-point']) +        self.cli_set(self._base_path + [interface, 'channel', '36']) + +        ht_opt = { +            # VyOS CLI option           hostapd - ht_capab setting +            'channel-set-width ht20'  : '[HT20]', +            'channel-set-width ht40-' : '[HT40-]', +            'channel-set-width ht40+' : '[HT40+]', +            'dsss-cck-40'             : '[DSSS_CCK-40]', +            'short-gi 20'             : '[SHORT-GI-20]', +            'short-gi 40'             : '[SHORT-GI-40]', +            'max-amsdu 7935'          : '[MAX-AMSDU-7935]', +        } +        for key in ht_opt: +            self.cli_set(self._base_path + [interface, 'capabilities', 'ht'] + key.split()) + +        vht_opt = { +            # VyOS CLI option           hostapd - ht_capab setting +            'max-mpdu 11454'          : '[MAX-MPDU-11454]', +            'max-mpdu-exp 2'          : '[MAX-A-MPDU-LEN-EXP-2]', +            '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]', +            'link-adaptation both'    : '[VHT-LINK-ADAPT3]', +            'short-gi 80'             : '[SHORT-GI-80]', +            'short-gi 160'            : '[SHORT-GI-160]', +            'beamform multi-user-beamformer' : '[MU-BEAMFORMER][BF-ANTENNA-3][SOUNDING-DIMENSION-3]', +        } + +        self.cli_set(self._base_path + [interface, 'capabilities', 'vht', 'channel-set-width', '1']) +        self.cli_set(self._base_path + [interface, 'capabilities', 'vht', 'center-channel-freq', 'freq-1', '42']) +        self.cli_set(self._base_path + [interface, 'capabilities', 'vht', 'antenna-count', antennas]) +        for key in vht_opt: +            self.cli_set(self._base_path + [interface, 'capabilities', 'vht'] + key.split()) + +        self.cli_commit() + +        # +        # Validate Config +        # +        tmp = get_config_value(interface, 'interface') +        self.assertEqual(interface, tmp) + +        # ssid +        tmp = get_config_value(interface, 'ssid') +        self.assertEqual(ssid, tmp) + +        # channel +        tmp = get_config_value(interface, 'channel') +        self.assertEqual('36', 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) + +    def test_wireless_hostapd_vht_su_beamformer_config(self): +        # Single-User-Beamformer +        interface = 'wlan1' +        ssid = 'vht_su-beamformer' +        antennas = '3' + +        self.cli_set(self._base_path + [interface, 'ssid', ssid]) +        self.cli_set(self._base_path + [interface, 'type', 'access-point']) +        self.cli_set(self._base_path + [interface, 'channel', '36']) + +        ht_opt = { +            # VyOS CLI option           hostapd - ht_capab setting +            'channel-set-width ht20'  : '[HT20]', +            'channel-set-width ht40-' : '[HT40-]', +            'channel-set-width ht40+' : '[HT40+]', +            'dsss-cck-40'             : '[DSSS_CCK-40]', +            'short-gi 20'             : '[SHORT-GI-20]', +            'short-gi 40'             : '[SHORT-GI-40]', +            'max-amsdu 7935'          : '[MAX-AMSDU-7935]', +        } +        for key in ht_opt: +            self.cli_set(self._base_path + [interface, 'capabilities', 'ht'] + key.split()) + +        vht_opt = { +            # VyOS CLI option           hostapd - ht_capab setting +            'max-mpdu 11454'          : '[MAX-MPDU-11454]', +            'max-mpdu-exp 2'          : '[MAX-A-MPDU-LEN-EXP-2]', +            '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]', +            'link-adaptation both'    : '[VHT-LINK-ADAPT3]', +            'short-gi 80'             : '[SHORT-GI-80]', +            'short-gi 160'            : '[SHORT-GI-160]', +            'beamform single-user-beamformer' : '[SU-BEAMFORMER][BF-ANTENNA-2][SOUNDING-DIMENSION-2]', +        } + +        self.cli_set(self._base_path + [interface, 'capabilities', 'vht', 'channel-set-width', '1']) +        self.cli_set(self._base_path + [interface, 'capabilities', 'vht', 'center-channel-freq', 'freq-1', '42']) +        self.cli_set(self._base_path + [interface, 'capabilities', 'vht', 'antenna-count', antennas]) +        for key in vht_opt: +            self.cli_set(self._base_path + [interface, 'capabilities', 'vht'] + key.split()) + +        self.cli_commit() + +        # +        # Validate Config +        # +        tmp = get_config_value(interface, 'interface') +        self.assertEqual(interface, tmp) + +        # ssid +        tmp = get_config_value(interface, 'ssid') +        self.assertEqual(ssid, tmp) + +        # channel +        tmp = get_config_value(interface, 'channel') +        self.assertEqual('36', 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) +      def test_wireless_hostapd_wpa_config(self):          # Only set the hostapd (access-point) options          interface = 'wlan0'  | 
