summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/config-mode-dependencies/vyos-1x.json3
-rw-r--r--data/templates/wifi/hostapd.conf.j27
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py11
-rwxr-xr-xsrc/conf_mode/interfaces_bridge.py31
4 files changed, 44 insertions, 8 deletions
diff --git a/data/config-mode-dependencies/vyos-1x.json b/data/config-mode-dependencies/vyos-1x.json
index afe3dd838..13de434bd 100644
--- a/data/config-mode-dependencies/vyos-1x.json
+++ b/data/config-mode-dependencies/vyos-1x.json
@@ -11,7 +11,8 @@
"ethernet": ["interfaces_ethernet"]
},
"interfaces_bridge": {
- "vxlan": ["interfaces_vxlan"]
+ "vxlan": ["interfaces_vxlan"],
+ "wlan": ["interfaces_wireless"]
},
"load_balancing_wan": {
"conntrack": ["system_conntrack"]
diff --git a/data/templates/wifi/hostapd.conf.j2 b/data/templates/wifi/hostapd.conf.j2
index 83009242b..769325b49 100644
--- a/data/templates/wifi/hostapd.conf.j2
+++ b/data/templates/wifi/hostapd.conf.j2
@@ -28,6 +28,12 @@ interface={{ ifname }}
{% for bridge in is_bridge_member %}
bridge={{ bridge }}
{% endfor %}
+
+# WDS (4-address frame) mode with per-station virtual interfaces
+# (only supported with driver=nl80211)
+# This mode allows associated stations to use 4-address frames to allow layer 2
+# bridging to be used.
+wds_sta=1
{% endif %}
# Driver interface type (hostap/wired/none/nl80211/bsd);
@@ -739,4 +745,3 @@ wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
-
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index 83b00ac0c..b45754cae 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.py
@@ -236,6 +236,17 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase):
self.assertIn(interface, bridge_members)
+ # Now generate a VLAN on the bridge
+ self.cli_set(bridge_path + ['enable-vlan'])
+ self.cli_set(bridge_path + ['vif', '20', 'address', '10.0.0.1/24'])
+
+ self.cli_commit()
+
+ tmp = get_config_value(interface, 'bridge')
+ self.assertEqual(tmp, bridge)
+ tmp = get_config_value(interface, 'wds_sta')
+ self.assertEqual(tmp, '1')
+
self.cli_delete(bridge_path)
def test_wireless_security_station_address(self):
diff --git a/src/conf_mode/interfaces_bridge.py b/src/conf_mode/interfaces_bridge.py
index 9789f7bd3..7b2c1ee0b 100755
--- a/src/conf_mode/interfaces_bridge.py
+++ b/src/conf_mode/interfaces_bridge.py
@@ -56,6 +56,17 @@ def get_config(config=None):
bridge['member'].update({'interface_remove' : tmp })
else:
bridge.update({'member' : {'interface_remove' : tmp }})
+ for interface in tmp:
+ # When using VXLAN member interfaces that are configured for Single
+ # VXLAN Device (SVD) we need to call the VXLAN conf-mode script to
+ # re-create VLAN to VNI mappings if required, but only if the interface
+ # is already live on the system - this must not be done on first commit
+ if interface.startswith('vxlan') and interface_exists(interface):
+ set_dependents('vxlan', conf, interface)
+ # When using Wireless member interfaces we need to inform hostapd
+ # to properly set-up the bridge
+ elif interface.startswith('wlan') and interface_exists(interface):
+ set_dependents('wlan', conf, interface)
if dict_search('member.interface', bridge) is not None:
for interface in list(bridge['member']['interface']):
@@ -91,6 +102,10 @@ def get_config(config=None):
# is already live on the system - this must not be done on first commit
if interface.startswith('vxlan') and interface_exists(interface):
set_dependents('vxlan', conf, interface)
+ # When using Wireless member interfaces we need to inform hostapd
+ # to properly set-up the bridge
+ elif interface.startswith('wlan') and interface_exists(interface):
+ set_dependents('wlan', conf, interface)
# delete empty dictionary keys - no need to run code paths if nothing is there to do
if 'member' in bridge:
@@ -140,9 +155,6 @@ def verify(bridge):
if 'enable_vlan' in bridge:
if 'has_vlan' in interface_config:
raise ConfigError(error_msg + 'it has VLAN subinterface(s) assigned!')
-
- if 'wlan' in interface:
- raise ConfigError(error_msg + 'VLAN aware cannot be set!')
else:
for option in ['allowed_vlan', 'native_vlan']:
if option in interface_config:
@@ -168,12 +180,19 @@ def apply(bridge):
else:
br.update(bridge)
- for interface in dict_search('member.interface', bridge) or []:
- if interface.startswith('vxlan') and interface_exists(interface):
+ tmp = []
+ if 'member' in bridge:
+ if 'interface_remove' in bridge['member']:
+ tmp.extend(bridge['member']['interface_remove'])
+ if 'interface' in bridge['member']:
+ tmp.extend(bridge['member']['interface'])
+
+ for interface in tmp:
+ if interface.startswith(tuple(['vxlan', 'wlan'])) and interface_exists(interface):
try:
call_dependents()
except ConfigError:
- raise ConfigError('Error in updating VXLAN interface after changing bridge!')
+ raise ConfigError('Error updating member interface configuration after changing bridge!')
return None