diff options
-rw-r--r-- | interface-definitions/interfaces-wireguard.xml.in | 6 | ||||
-rw-r--r-- | python/vyos/ifconfig/wireguard.py | 12 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_wireguard.py | 44 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wireguard.py | 9 |
4 files changed, 61 insertions, 10 deletions
diff --git a/interface-definitions/interfaces-wireguard.xml.in b/interface-definitions/interfaces-wireguard.xml.in index dd1e8e511..75db9f617 100644 --- a/interface-definitions/interfaces-wireguard.xml.in +++ b/interface-definitions/interfaces-wireguard.xml.in @@ -119,6 +119,12 @@ </children> </tagNode> #include <include/interface/redirect.xml.i> + <leafNode name="threaded"> + <properties> + <help>Process traffic from each peer in a dedicated thread</help> + <valueless/> + </properties> + </leafNode> #include <include/interface/vrf.xml.i> </children> </tagNode> diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py index fe5e9c519..58613813f 100644 --- a/python/vyos/ifconfig/wireguard.py +++ b/python/vyos/ifconfig/wireguard.py @@ -1,4 +1,4 @@ -# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2019-2023 VyOS maintainers and contributors <maintainers@vyos.io> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,8 @@ from hurry.filesize import alternative from vyos.ifconfig import Interface from vyos.ifconfig import Operational from vyos.template import is_ipv6 +from vyos.base import Warning + class WireGuardOperational(Operational): def _dump(self): @@ -184,7 +186,6 @@ class WireGuardIf(Interface): base_cmd += f' private-key {tmp_file.name}' base_cmd = base_cmd.format(**config) - if 'peer' in config: for peer, peer_config in config['peer'].items(): # T4702: No need to configure this peer when it was explicitly @@ -229,5 +230,12 @@ class WireGuardIf(Interface): if psk_file != no_psk_file and os.path.exists(psk_file): os.remove(psk_file) + try: + self._write_sysfs(f'/sys/devices/virtual/net/{self.ifname}/threaded', + '1' if 'threaded' in config else '0') + except Exception: + Warning(f'Update threaded status on interface "{config["ifname"]}" FAILED.\n' + f'An unexpected error occurred.') + # call base class super().update(config) diff --git a/smoketest/scripts/cli/test_interfaces_wireguard.py b/smoketest/scripts/cli/test_interfaces_wireguard.py index f84ce159d..f6f2499a6 100755 --- a/smoketest/scripts/cli/test_interfaces_wireguard.py +++ b/smoketest/scripts/cli/test_interfaces_wireguard.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020-2021 VyOS maintainers and contributors +# Copyright (C) 2020-2023 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 @@ -19,6 +19,7 @@ import unittest from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError +from vyos.utils.file import read_file base_path = ['interfaces', 'wireguard'] @@ -35,7 +36,7 @@ class WireGuardInterfaceTest(VyOSUnitTestSHIM.TestCase): self.cli_delete(base_path) self.cli_commit() - def test_wireguard_peer(self): + def test_01_wireguard_peer(self): # Create WireGuard interfaces with associated peers for intf in self._interfaces: peer = 'foo-' + intf @@ -62,7 +63,7 @@ class WireGuardInterfaceTest(VyOSUnitTestSHIM.TestCase): self.assertTrue(os.path.isdir(f'/sys/class/net/{intf}')) - def test_wireguard_add_remove_peer(self): + def test_02_wireguard_add_remove_peer(self): # T2939: Create WireGuard interfaces with associated peers. # Remove one of the configured peers. # T4774: Test prevention of duplicate peer public keys @@ -100,10 +101,9 @@ class WireGuardInterfaceTest(VyOSUnitTestSHIM.TestCase): self.cli_delete(base_path + [interface, 'peer', 'PEER01']) self.cli_commit() - def test_wireguard_same_public_key(self): - # T2939: Create WireGuard interfaces with associated peers. - # Remove one of the configured peers. - # T4774: Test prevention of duplicate peer public keys + def test_03_wireguard_same_public_key(self): + # T5413: Test prevention of equality interface public key and peer's + # public key interface = 'wg0' port = '12345' privkey = 'OOjcXGfgQlAuM6q8Z9aAYduCua7pxf7UKYvIqoUPoGQ=' @@ -129,5 +129,35 @@ class WireGuardInterfaceTest(VyOSUnitTestSHIM.TestCase): self.assertTrue(os.path.isdir(f'/sys/class/net/{interface}')) + def test_04_wireguard_threaded(self): + # T5409: Test adding threaded option on interface. + # Test prevention for adding threaded + # if no enabled peer is configured. + interface = 'wg0' + port = '12345' + privkey = 'OOjcXGfgQlAuM6q8Z9aAYduCua7pxf7UKYvIqoUPoGQ=' + pubkey = 'ebFx/1G0ti8tvuZd94sEIosAZZIznX+dBAKG/8DFm0I=' + + self.cli_set(base_path + [interface, 'address', '172.16.0.1/24']) + self.cli_set(base_path + [interface, 'private-key', privkey]) + + self.cli_set(base_path + [interface, 'peer', 'PEER01', 'port', port]) + self.cli_set(base_path + [interface, 'peer', 'PEER01', 'public-key', pubkey]) + self.cli_set(base_path + [interface, 'peer', 'PEER01', 'allowed-ips', '10.205.212.10/32']) + self.cli_set(base_path + [interface, 'peer', 'PEER01', 'address', '192.0.2.1']) + self.cli_set(base_path + [interface, 'peer', 'PEER01', 'disable']) + self.cli_set(base_path + [interface, 'threaded']) + + # Threaded is set and no enabled peer is configured + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_delete(base_path + [interface, 'peer', 'PEER01', 'disable']) + + # Commit peers + self.cli_commit() + tmp = read_file(f'/sys/devices/virtual/net/{interface}/threaded') + self.assertTrue(tmp, "1") + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py index 40404d091..ef0fdae15 100755 --- a/src/conf_mode/interfaces-wireguard.py +++ b/src/conf_mode/interfaces-wireguard.py @@ -90,7 +90,7 @@ def verify(wireguard): # run checks on individual configured WireGuard peer public_keys = [] - + peer_enabled = False for tmp in wireguard['peer']: peer = wireguard['peer'][tmp] @@ -110,8 +110,15 @@ def verify(wireguard): if 'disable' not in peer and is_wireguard_key_pair(wireguard['private_key'], peer['public_key']): raise ConfigError(f'Peer "{tmp}" has the same public key as the interface "{wireguard["ifname"]}"') + if 'disable' not in peer: + peer_enabled = True + public_keys.append(peer['public_key']) + #Threaded can be enabled only if one enabled peer exists. + if not peer_enabled and 'threaded' in wireguard: + raise ConfigError(f'Set threaded on interface "{wireguard["ifname"]}" FAILED.\nNo enabled peers are configured') + def apply(wireguard): tmp = WireGuardIf(wireguard['ifname']) if 'deleted' in wireguard: |