Skip to content

Commit

Permalink
Merge pull request #4044 from vyos/mergify/bp/sagitta/pr-4028
Browse files Browse the repository at this point in the history
T6693: wireless: Enable WiFi-6 (802.11ax) for 2.4GHz AccessPoints (backport #4028)
  • Loading branch information
dmbaturin authored Sep 11, 2024
2 parents dc1da7c + 6b57f03 commit eb9e562
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 18 deletions.
12 changes: 11 additions & 1 deletion data/templates/wifi/hostapd.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}
Expand Down Expand Up @@ -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
Expand All @@ -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' }}
Expand Down
68 changes: 52 additions & 16 deletions interface-definitions/interfaces_wireless.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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">
Expand All @@ -554,18 +590,18 @@
</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>
<format>u32:1-233</format>
<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>
Expand Down
89 changes: 88 additions & 1 deletion smoketest/scripts/cli/test_interfaces_wireless.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,89 @@ def test_wireless_hostapd_vht_su_beamformer_config(self):
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'
Expand All @@ -327,6 +409,7 @@ def test_wireless_hostapd_he_config(self):
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'])

Expand Down Expand Up @@ -374,6 +457,10 @@ def test_wireless_hostapd_he_config(self):
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)
Expand Down

0 comments on commit eb9e562

Please sign in to comment.