diff options
-rw-r--r-- | data/templates/wifi/hostapd.conf.j2 | 12 | ||||
-rw-r--r-- | interface-definitions/interfaces_wireless.xml.in | 68 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_wireless.py | 89 |
3 files changed, 151 insertions, 18 deletions
diff --git a/data/templates/wifi/hostapd.conf.j2 b/data/templates/wifi/hostapd.conf.j2 index 0459fbc69..5f3757216 100644 --- a/data/templates/wifi/hostapd.conf.j2 +++ b/data/templates/wifi/hostapd.conf.j2 @@ -46,7 +46,14 @@ hw_mode=a ieee80211h=1 ieee80211ac=1 {% elif mode is vyos_defined('ax') %} +{#{% if capabilities.ht is vyos_defined and capabilities.vht not vyos_defined %}#} +{% if capabilities.he.channel_set_width is vyos_defined('81') or capabilities.he.channel_set_width is vyos_defined('83') or capabilities.he.channel_set_width is vyos_defined('84') %} +{# This is almost certainly a 2.4GHz network #} +hw_mode=g +{% else %} +{# This is likely a 5GHz or 6GHz network #} hw_mode=a +{% endif %} ieee80211h=1 ieee80211ax=1 {% else %} @@ -202,7 +209,7 @@ require_he=1 {% else %} ieee80211n={{ '1' if 'n' in mode or 'ac' in mode or 'ax' in mode else '0' }} {% endif %} -{# HE (802.11ax 6GHz) #} +{# HE (802.11ax) #} {% if capabilities.he is vyos_defined and mode in 'ax' %} {# For now, hard-code power levels for indoor-only AP #} he_6ghz_reg_pwr_type=0 @@ -220,6 +227,9 @@ op_class={{ capabilities.he.channel_set_width }} {% if capabilities.he.bss_color is vyos_defined %} he_bss_color={{ capabilities.he.bss_color }} {% endif %} +{% if capabilities.he.coding_scheme is vyos_defined %} +he_basic_mcs_nss_set={{ capabilities.he.coding_scheme }} +{% endif %} he_6ghz_rx_ant_pat={{ '1' if capabilities.he.antenna_pattern_fixed is vyos_defined else '0' }} he_su_beamformer={{ '1' if capabilities.he.beamform.single_user_beamformer is vyos_defined else '0' }} he_su_beamformee={{ '1' if capabilities.he.beamform.single_user_beamformee is vyos_defined else '0' }} diff --git a/interface-definitions/interfaces_wireless.xml.in b/interface-definitions/interfaces_wireless.xml.in index d69daa485..830bad1aa 100644 --- a/interface-definitions/interfaces_wireless.xml.in +++ b/interface-definitions/interfaces_wireless.xml.in @@ -248,26 +248,26 @@ <properties> <help>VHT operating channel center frequency - center freq 1 (for use with 80, 80+80 and 160 modes)</help> <valueHelp> - <format>u32:34-173</format> + <format>u32:34-177</format> <description>5Ghz (802.11 a/h/j/n/ac) center channel index (use 42 for primary 80MHz channel 36)</description> </valueHelp> <constraint> - <validator name="numeric" argument="--range 34-173"/> + <validator name="numeric" argument="--range 34-177"/> </constraint> - <constraintErrorMessage>Channel center value must be between 34 and 173</constraintErrorMessage> + <constraintErrorMessage>Channel center value must be between 34 and 177</constraintErrorMessage> </properties> </leafNode> <leafNode name="freq-2"> <properties> <help>VHT operating channel center frequency - center freq 2 (for use with the 80+80 mode)</help> <valueHelp> - <format>u32:34-173</format> + <format>u32:34-177</format> <description>5Ghz (802.11 ac) center channel index (use 58 for secondary 80MHz channel 52)</description> </valueHelp> <constraint> - <validator name="numeric" argument="--range 34-173"/> + <validator name="numeric" argument="--range 34-177"/> </constraint> - <constraintErrorMessage>Channel center value must be between 34 and 173</constraintErrorMessage> + <constraintErrorMessage>Channel center value must be between 34 and 177</constraintErrorMessage> </properties> </leafNode> </children> @@ -436,30 +436,42 @@ https://w1.fi/cgit/hostap/tree/src/common/ieee802_11_common.c?id=195cc3d919503fb0d699d9a56a58a72602b25f51#n1525 802.11ax (WiFi-6e - HE) can use up to 160MHz bandwidth channels --> - <list>131 132 133 134 135</list> + <list>81 83 84 131 132 133 134 135</list> </completionHelp> <valueHelp> + <format>81</format> + <description>2.4GHz, 20 MHz channel width</description> + </valueHelp> + <valueHelp> + <format>83</format> + <description>2.4GHz, 40 MHz channel width, secondary 20MHz channel above primary channel</description> + </valueHelp> + <valueHelp> + <format>84</format> + <description>2.4GHz, 40 MHz channel width, secondary 20MHz channel below primary channel</description> + </valueHelp> + <valueHelp> <format>131</format> - <description>20 MHz channel width</description> + <description>6GHz, 20 MHz channel width</description> </valueHelp> <valueHelp> <format>132</format> - <description>40 MHz channel width</description> + <description>6GHz, 40 MHz channel width</description> </valueHelp> <valueHelp> <format>133</format> - <description>80 MHz channel width</description> + <description>6GHz, 80 MHz channel width</description> </valueHelp> <valueHelp> <format>134</format> - <description>160 MHz channel width</description> + <description>6GHz, 160 MHz channel width</description> </valueHelp> <valueHelp> <format>135</format> - <description>80+80 MHz channel width</description> + <description>6GHz, 80+80 MHz channel width</description> </valueHelp> <constraint> - <regex>(131|132|133|134|135)</regex> + <regex>(81|83|84|131|132|133|134|135)</regex> </constraint> </properties> </leafNode> @@ -535,6 +547,30 @@ </constraint> </properties> </leafNode> + <leafNode name="coding-scheme"> + <properties> + <help>Spacial Stream and Modulation Coding Scheme settings</help> + <valueHelp> + <format>u32:0</format> + <description>HE-MCS 0-7</description> + </valueHelp> + <valueHelp> + <format>u32:1</format> + <description>HE-MCS 0-9</description> + </valueHelp> + <valueHelp> + <format>u32:2</format> + <description>HE-MCS 0-11</description> + </valueHelp> + <valueHelp> + <format>u32:3</format> + <description>HE-MCS is not supported</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-3"/> + </constraint> + </properties> + </leafNode> </children> </node> <leafNode name="require-he"> @@ -554,10 +590,10 @@ </valueHelp> <valueHelp> <format>u32:1-14</format> - <description>2.4Ghz (802.11 b/g/n) Channel</description> + <description>2.4Ghz (802.11 b/g/n/ax) Channel</description> </valueHelp> <valueHelp> - <format>u32:34-173</format> + <format>u32:34-177</format> <description>5Ghz (802.11 a/h/j/n/ac) Channel</description> </valueHelp> <valueHelp> @@ -565,7 +601,7 @@ <description>6Ghz (802.11 ax) Channel</description> </valueHelp> <constraint> - <validator name="numeric" argument="--range 0-0 --range 1-14 --range 34-173 --range 1-233"/> + <validator name="numeric" argument="--range 0-0 --range 1-14 --range 34-177 --range 1-233"/> </constraint> </properties> <defaultValue>0</defaultValue> diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py index ba2f60a89..86ddc9f4d 100755 --- a/smoketest/scripts/cli/test_interfaces_wireless.py +++ b/smoketest/scripts/cli/test_interfaces_wireless.py @@ -303,7 +303,89 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase): for key, value in vht_opt.items(): self.assertIn(value, tmp) - def test_wireless_hostapd_he_config(self): + def test_wireless_hostapd_he_2ghz_config(self): + # Only set the hostapd (access-point) options - HE mode for 802.11ax at 2.4GHz + interface = self._interfaces[1] # wlan1 + ssid = 'ssid' + channel = '1' + sae_pw = 'VyOSVyOSVyOS' + bss_color = '13' + channel_set_width = '81' + + 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', channel]) + self.cli_set(self._base_path + [interface, 'mode', 'ax']) + self.cli_set(self._base_path + [interface, 'security', 'wpa', 'mode', 'wpa2']) + self.cli_set(self._base_path + [interface, 'security', 'wpa', 'passphrase', sae_pw]) + self.cli_set(self._base_path + [interface, 'security', 'wpa', 'cipher', 'CCMP']) + self.cli_set(self._base_path + [interface, 'security', 'wpa', 'cipher', 'GCMP']) + self.cli_set(self._base_path + [interface, 'capabilities', 'ht', '40mhz-incapable']) + self.cli_set(self._base_path + [interface, 'capabilities', 'ht', 'channel-set-width', 'ht20']) + self.cli_set(self._base_path + [interface, 'capabilities', 'ht', 'channel-set-width', 'ht40+']) + self.cli_set(self._base_path + [interface, 'capabilities', 'ht', 'channel-set-width', 'ht40-']) + self.cli_set(self._base_path + [interface, 'capabilities', 'ht', 'short-gi', '20']) + self.cli_set(self._base_path + [interface, 'capabilities', 'ht', 'short-gi', '40']) + self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'bss-color', bss_color]) + self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'channel-set-width', channel_set_width]) + self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'beamform', 'multi-user-beamformer']) + self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'beamform', 'single-user-beamformer']) + self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'beamform', 'single-user-beamformee']) + + 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) + + # mode of operation resulting from [interface, 'mode', 'ax'] + tmp = get_config_value(interface, 'hw_mode') + self.assertEqual('g', tmp) + tmp = get_config_value(interface, 'ieee80211h') + self.assertEqual('1', tmp) + tmp = get_config_value(interface, 'ieee80211ax') + self.assertEqual('1', tmp) + + # channel and channel width + tmp = get_config_value(interface, 'channel') + self.assertEqual(channel, tmp) + tmp = get_config_value(interface, 'op_class') + self.assertEqual(channel_set_width, tmp) + + # BSS coloring + tmp = get_config_value(interface, 'he_bss_color') + self.assertEqual(bss_color, tmp) + + # sae_password + tmp = get_config_value(interface, 'wpa_passphrase') + self.assertEqual(sae_pw, tmp) + + # WPA3 and dependencies + tmp = get_config_value(interface, 'wpa') + self.assertEqual('2', tmp) + tmp = get_config_value(interface, 'rsn_pairwise') + self.assertEqual('CCMP GCMP', tmp) + tmp = get_config_value(interface, 'wpa_key_mgmt') + self.assertEqual('WPA-PSK WPA-PSK-SHA256', tmp) + + # beamforming + tmp = get_config_value(interface, 'he_mu_beamformer') + self.assertEqual('1', tmp) + tmp = get_config_value(interface, 'he_su_beamformee') + self.assertEqual('1', tmp) + tmp = get_config_value(interface, 'he_mu_beamformer') + self.assertEqual('1', tmp) + + # Check for running process + self.assertTrue(process_named_running('hostapd')) + + def test_wireless_hostapd_he_6ghz_config(self): # Only set the hostapd (access-point) options - HE mode for 802.11ax at 6GHz interface = self._interfaces[1] # wlan1 ssid = 'ssid' @@ -327,6 +409,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase): self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'bss-color', bss_color]) self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'channel-set-width', channel_set_width]) self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'center-channel-freq', 'freq-1', center_channel_freq_1]) + self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'antenna-pattern-fixed']) self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'beamform', 'multi-user-beamformer']) self.cli_set(self._base_path + [interface, 'capabilities', 'he', 'beamform', 'single-user-beamformer']) @@ -374,6 +457,10 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase): tmp = get_config_value(interface, 'wpa_key_mgmt') self.assertEqual('SAE', tmp) + # antenna pattern + tmp = get_config_value(interface, 'he_6ghz_rx_ant_pat') + self.assertEqual('1', tmp) + # beamforming tmp = get_config_value(interface, 'he_mu_beamformer') self.assertEqual('1', tmp) |