diff options
31 files changed, 465 insertions, 138 deletions
diff --git a/data/templates/accel-ppp/config_ipv6_pool.j2 b/data/templates/accel-ppp/config_ipv6_pool.j2 index a1562a1eb..86efdc1e1 100644 --- a/data/templates/accel-ppp/config_ipv6_pool.j2 +++ b/data/templates/accel-ppp/config_ipv6_pool.j2 @@ -3,20 +3,19 @@ AdvAutonomousFlag=1 verbose=1 -{% if client_ipv6_pool.prefix is vyos_defined %} [ipv6-pool] -{% for prefix, options in client_ipv6_pool.prefix.items() %} -{{ prefix }},{{ options.mask }} -{% endfor %} -{% if client_ipv6_pool.delegate is vyos_defined %} -{% for prefix, options in client_ipv6_pool.delegate.items() %} -delegate={{ prefix }},{{ options.delegation_prefix }} +{% for pool_name, pool_config in client_ipv6_pool.items() %} +{% if pool_config.prefix is vyos_defined %} +{% for prefix, options in pool_config.prefix.items() %} +{{ prefix }},{{ options.mask }},name={{ pool_name }} {% endfor %} {% endif %} -{% endif %} - -{% if client_ipv6_pool.delegate is vyos_defined %} +{% if pool_config.delegate is vyos_defined %} +{% for prefix, options in pool_config.delegate.items() %} +delegate={{ prefix }},{{ options.delegation_prefix }},name={{ pool_name }} +{% endfor %} +{% endif %} +{% endfor %} [ipv6-dhcp] verbose=1 -{% endif %} {% endif %} diff --git a/data/templates/accel-ppp/ipoe.config.j2 b/data/templates/accel-ppp/ipoe.config.j2 index 588f3d462..8b022eaa5 100644 --- a/data/templates/accel-ppp/ipoe.config.j2 +++ b/data/templates/accel-ppp/ipoe.config.j2 @@ -58,6 +58,10 @@ password=csid {% if default_pool is vyos_defined %} ip-pool={{ default_pool }} {% endif %} +{% if default_ipv6_pool is vyos_defined %} +ipv6-pool={{ default_ipv6_pool }} +ipv6-pool-delegate={{ default_ipv6_pool }} +{% endif %} {% if gateway_address is vyos_defined %} {% for gw_addr in gateway_address %} gw-ip-address={{ gw_addr }} diff --git a/data/templates/accel-ppp/l2tp.config.j2 b/data/templates/accel-ppp/l2tp.config.j2 index 49755254a..f041e278e 100644 --- a/data/templates/accel-ppp/l2tp.config.j2 +++ b/data/templates/accel-ppp/l2tp.config.j2 @@ -51,6 +51,10 @@ host-name={{ lns.host_name }} {% if default_pool is vyos_defined %} ip-pool={{ default_pool }} {% endif %} +{% if default_ipv6_pool is vyos_defined %} +ipv6-pool={{ default_ipv6_pool }} +ipv6-pool-delegate={{ default_ipv6_pool }} +{% endif %} [client-ip-range] 0.0.0.0/0 diff --git a/data/templates/accel-ppp/pppoe.config.j2 b/data/templates/accel-ppp/pppoe.config.j2 index 4bb1c4450..fb8a11366 100644 --- a/data/templates/accel-ppp/pppoe.config.j2 +++ b/data/templates/accel-ppp/pppoe.config.j2 @@ -143,6 +143,10 @@ noauth=1 {% if default_pool is vyos_defined %} ip-pool={{ default_pool }} {% endif %} +{% if default_ipv6_pool is vyos_defined %} +ipv6-pool={{ default_ipv6_pool }} +ipv6-pool-delegate={{ default_ipv6_pool }} +{% endif %} {% if limits is vyos_defined %} [connlimit] diff --git a/data/templates/accel-ppp/sstp.config.j2 b/data/templates/accel-ppp/sstp.config.j2 index 014ae1235..51f7dfca8 100644 --- a/data/templates/accel-ppp/sstp.config.j2 +++ b/data/templates/accel-ppp/sstp.config.j2 @@ -39,6 +39,10 @@ ssl-keyfile=/run/accel-pppd/sstp-cert.key {% if default_pool is vyos_defined %} ip-pool={{ default_pool }} {% endif %} +{% if default_ipv6_pool is vyos_defined %} +ipv6-pool={{ default_ipv6_pool }} +ipv6-pool-delegate={{ default_ipv6_pool }} +{% endif %} {# Common IP pool definitions #} {% include 'accel-ppp/config_ip_pool.j2' %} diff --git a/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i b/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i index 774741a5e..0c8c2e34c 100644 --- a/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i +++ b/interface-definitions/include/accel-ppp/client-ipv6-pool.xml.i @@ -1,7 +1,14 @@ <!-- include start from accel-ppp/client-ipv6-pool.xml.i --> -<node name="client-ipv6-pool"> +<tagNode name="client-ipv6-pool"> <properties> <help>Pool of client IPv6 addresses</help> + <valueHelp> + <format>txt</format> + <description>Name of IPv6 pool</description> + </valueHelp> + <constraint> + #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> + </constraint> </properties> <children> <tagNode name="prefix"> @@ -58,5 +65,5 @@ </children> </tagNode> </children> -</node> +</tagNode> <!-- include end --> diff --git a/interface-definitions/include/accel-ppp/default-ipv6-pool.xml.i b/interface-definitions/include/accel-ppp/default-ipv6-pool.xml.i new file mode 100644 index 000000000..1093f6713 --- /dev/null +++ b/interface-definitions/include/accel-ppp/default-ipv6-pool.xml.i @@ -0,0 +1,17 @@ +<!-- include start from accel-ppp/default-pool.xml.i --> +<leafNode name="default-ipv6-pool"> + <properties> + <help>Default client IPv6 pool name</help> + <completionHelp> + <path>${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-3} client-ipv6-pool</path> + </completionHelp> + <valueHelp> + <format>txt</format> + <description>Default IPv6 pool</description> + </valueHelp> + <constraint> + #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> + </constraint> + </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/version/ipoe-server-version.xml.i b/interface-definitions/include/version/ipoe-server-version.xml.i index e5983ab39..659433382 100644 --- a/interface-definitions/include/version/ipoe-server-version.xml.i +++ b/interface-definitions/include/version/ipoe-server-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/ipoe-server-version.xml.i --> -<syntaxVersion component='ipoe-server' version='2'></syntaxVersion> +<syntaxVersion component='ipoe-server' version='3'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/include/version/l2tp-version.xml.i b/interface-definitions/include/version/l2tp-version.xml.i index f4507d93b..793cd5d0c 100644 --- a/interface-definitions/include/version/l2tp-version.xml.i +++ b/interface-definitions/include/version/l2tp-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/l2tp-version.xml.i --> -<syntaxVersion component='l2tp' version='6'></syntaxVersion> +<syntaxVersion component='l2tp' version='7'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/include/version/pppoe-server-version.xml.i b/interface-definitions/include/version/pppoe-server-version.xml.i index deed702f0..02f98cc16 100644 --- a/interface-definitions/include/version/pppoe-server-version.xml.i +++ b/interface-definitions/include/version/pppoe-server-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/pppoe-server-version.xml.i --> -<syntaxVersion component='pppoe-server' version='7'></syntaxVersion> +<syntaxVersion component='pppoe-server' version='8'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/include/version/sstp-version.xml.i b/interface-definitions/include/version/sstp-version.xml.i index 3ac54a3de..5e30950d8 100644 --- a/interface-definitions/include/version/sstp-version.xml.i +++ b/interface-definitions/include/version/sstp-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/sstp-version.xml.i --> -<syntaxVersion component='sstp' version='5'></syntaxVersion> +<syntaxVersion component='sstp' version='6'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in index edfe6a34c..eeec2aeef 100644 --- a/interface-definitions/service_ipoe-server.xml.in +++ b/interface-definitions/service_ipoe-server.xml.in @@ -183,6 +183,7 @@ </children> </node> #include <include/accel-ppp/default-pool.xml.i> + #include <include/accel-ppp/default-ipv6-pool.xml.i> </children> </node> </children> diff --git a/interface-definitions/service_pppoe-server.xml.in b/interface-definitions/service_pppoe-server.xml.in index f1b369936..6fdc2a65a 100644 --- a/interface-definitions/service_pppoe-server.xml.in +++ b/interface-definitions/service_pppoe-server.xml.in @@ -274,6 +274,7 @@ </children> </node> #include <include/accel-ppp/default-pool.xml.i> + #include <include/accel-ppp/default-ipv6-pool.xml.i> </children> </node> </children> diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in index 3e2d00e6b..d3fb58433 100644 --- a/interface-definitions/vpn_l2tp.xml.in +++ b/interface-definitions/vpn_l2tp.xml.in @@ -154,6 +154,7 @@ </children> </node> #include <include/accel-ppp/default-pool.xml.i> + #include <include/accel-ppp/default-ipv6-pool.xml.i> </children> </node> </children> diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in index 7bb8db798..ec622b5d0 100644 --- a/interface-definitions/vpn_pptp.xml.in +++ b/interface-definitions/vpn_pptp.xml.in @@ -134,6 +134,7 @@ </children> </node> #include <include/accel-ppp/default-pool.xml.i> + #include <include/accel-ppp/default-ipv6-pool.xml.i> </children> </node> </children> diff --git a/interface-definitions/vpn_sstp.xml.in b/interface-definitions/vpn_sstp.xml.in index a1b69f990..2727540be 100644 --- a/interface-definitions/vpn_sstp.xml.in +++ b/interface-definitions/vpn_sstp.xml.in @@ -36,6 +36,7 @@ <defaultValue>443</defaultValue> </leafNode> #include <include/accel-ppp/default-pool.xml.i> + #include <include/accel-ppp/default-ipv6-pool.xml.i> <node name="ppp-options"> <properties> <help>PPP (Point-to-Point Protocol) settings</help> diff --git a/python/vyos/accel_ppp_util.py b/python/vyos/accel_ppp_util.py index 757d447a2..2f029e042 100644 --- a/python/vyos/accel_ppp_util.py +++ b/python/vyos/accel_ppp_util.py @@ -1,4 +1,4 @@ -# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2023-2024 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 @@ -22,9 +22,9 @@ # makes use of it! from vyos import ConfigError +from vyos.base import Warning from vyos.utils.dict import dict_search - def get_pools_in_order(data: dict) -> list: """Return a list of dictionaries representing pool data in the order in which they should be allocated. Pool must be defined before we can @@ -156,38 +156,47 @@ def verify_accel_ppp_base_service(config, local_users=True): "Not more then three IPv6 DNS name-servers " "can be configured" ) - if "client_ipv6_pool" in config: - ipv6_pool = config["client_ipv6_pool"] - if "delegate" in ipv6_pool: - if "prefix" not in ipv6_pool: - raise ConfigError( - 'IPv6 "delegate" also requires "prefix" to be defined!' - ) - - for delegate in ipv6_pool["delegate"]: - if "delegation_prefix" not in ipv6_pool["delegate"][delegate]: - raise ConfigError("delegation-prefix length required!") def verify_accel_ppp_ip_pool(vpn_config): """ Common helper function which must be used by Accel-PPP services (pptp, l2tp, sstp, pppoe) to verify client-ip-pool + and client-ipv6-pool """ if dict_search("client_ip_pool", vpn_config): for pool_name, pool_config in vpn_config["client_ip_pool"].items(): next_pool = dict_search(f"next_pool", pool_config) if next_pool: if next_pool not in vpn_config["client_ip_pool"]: - raise ConfigError(f'Next pool "{next_pool}" does not exist') + raise ConfigError( + f'Next pool "{next_pool}" does not exist') if not dict_search(f"range", pool_config): raise ConfigError( f'Pool "{pool_name}" does not contain range but next-pool exists' ) - if not dict_search("gateway_address", vpn_config): - raise ConfigError("Server requires gateway-address to be configured!") + Warning("IPv4 Server requires gateway-address to be configured!") + default_pool = dict_search("default_pool", vpn_config) if default_pool: if default_pool not in dict_search("client_ip_pool", vpn_config): raise ConfigError(f'Default pool "{default_pool}" does not exists') + + if 'client_ipv6_pool' in vpn_config: + for ipv6_pool, ipv6_pool_config in vpn_config['client_ipv6_pool'].items(): + if 'delegate' in ipv6_pool_config and 'prefix' not in ipv6_pool_config: + raise ConfigError( + f'IPoE IPv6 deletate-prefix requires IPv6 prefix to be configured in "{ipv6_pool}"!') + + if dict_search('authentication.mode', vpn_config) in ['local', 'noauth']: + if not dict_search('client_ip_pool', vpn_config) and not dict_search( + 'client_ipv6_pool', vpn_config): + raise ConfigError( + "L2TP local auth mode requires local client-ip-pool or client-ipv6-pool to be configured!") + if dict_search('client_ip_pool', vpn_config) and not dict_search( + 'default_pool', vpn_config): + Warning("'default-pool' is not defined") + if dict_search('client_ipv6_pool', vpn_config) and not dict_search( + 'default_ipv6_pool', vpn_config): + Warning("'default-ipv6-pool' is not defined") diff --git a/smoketest/scripts/cli/base_accel_ppp_test.py b/smoketest/scripts/cli/base_accel_ppp_test.py index 1ea5db898..6219a0a4c 100644 --- a/smoketest/scripts/cli/base_accel_ppp_test.py +++ b/smoketest/scripts/cli/base_accel_ppp_test.py @@ -1,4 +1,4 @@ -# 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 @@ -441,3 +441,54 @@ class BasicAccelPPPTest: {second_subnet},name={second_pool},next={third_pool} {first_subnet},name={first_pool},next={second_pool}""" self.assertIn(pool_config, config) + + def test_accel_ipv6_pool(self): + # Test configuration of IPv6 client pools + self.basic_config(is_gateway=False, is_client_pool=False) + + # Enable IPv6 + allow_ipv6 = 'allow' + self.set(['ppp-options', 'ipv6', allow_ipv6]) + + pool_name = 'ipv6_test_pool' + prefix_1 = '2001:db8:fffe::/56' + prefix_mask = '64' + prefix_2 = '2001:db8:ffff::/56' + client_prefix_1 = f'{prefix_1},{prefix_mask}' + client_prefix_2 = f'{prefix_2},{prefix_mask}' + self.set( + ['client-ipv6-pool', pool_name, 'prefix', prefix_1, 'mask', + prefix_mask]) + self.set( + ['client-ipv6-pool', pool_name, 'prefix', prefix_2, 'mask', + prefix_mask]) + + delegate_1_prefix = '2001:db8:fff1::/56' + delegate_2_prefix = '2001:db8:fff2::/56' + delegate_mask = '64' + self.set( + ['client-ipv6-pool', pool_name, 'delegate', delegate_1_prefix, + 'delegation-prefix', delegate_mask]) + self.set( + ['client-ipv6-pool', pool_name, 'delegate', delegate_2_prefix, + 'delegation-prefix', delegate_mask]) + + # commit changes + self.cli_commit() + + # Validate configuration values + conf = ConfigParser(allow_no_value=True, delimiters='=', + strict=False) + conf.read(self._config_file) + + for tmp in ['ipv6pool', 'ipv6_nd', 'ipv6_dhcp']: + self.assertEqual(conf['modules'][tmp], None) + + self.assertEqual(conf['ppp']['ipv6'], allow_ipv6) + + config = self.getConfig("ipv6-pool") + pool_config = f"""{client_prefix_1},name={pool_name} +{client_prefix_2},name={pool_name} +delegate={delegate_1_prefix},{delegate_mask},name={pool_name} +delegate={delegate_2_prefix},{delegate_mask},name={pool_name}""" + self.assertIn(pool_config, config) diff --git a/smoketest/scripts/cli/test_service_ipoe-server.py b/smoketest/scripts/cli/test_service_ipoe-server.py index 6e95b3bd1..cec6adb09 100755 --- a/smoketest/scripts/cli/test_service_ipoe-server.py +++ b/smoketest/scripts/cli/test_service_ipoe-server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2022-2023 VyOS maintainers and contributors +# Copyright (C) 2022-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 @@ -188,6 +188,45 @@ gw-ip-address={third_gateway.split('/')[0]} {first_subnet},name={first_pool},next={second_pool}""" self.assertIn(pool_config, config) + def test_accel_ipv6_pool(self): + # Test configuration of IPv6 client pools + self.basic_config(is_gateway=False, is_client_pool=False) + + pool_name = 'ipv6_test_pool' + prefix_1 = '2001:db8:fffe::/56' + prefix_mask = '64' + prefix_2 = '2001:db8:ffff::/56' + client_prefix_1 = f'{prefix_1},{prefix_mask}' + client_prefix_2 = f'{prefix_2},{prefix_mask}' + self.set(['client-ipv6-pool', pool_name, 'prefix', prefix_1, 'mask', + prefix_mask]) + self.set(['client-ipv6-pool', pool_name, 'prefix', prefix_2, 'mask', + prefix_mask]) + + delegate_1_prefix = '2001:db8:fff1::/56' + delegate_2_prefix = '2001:db8:fff2::/56' + delegate_mask = '64' + self.set(['client-ipv6-pool', pool_name, 'delegate', delegate_1_prefix, + 'delegation-prefix', delegate_mask]) + self.set(['client-ipv6-pool', pool_name, 'delegate', delegate_2_prefix, + 'delegation-prefix', delegate_mask]) + + # commit changes + self.cli_commit() + + # Validate configuration values + conf = ConfigParser(allow_no_value=True, delimiters='=', strict=False) + conf.read(self._config_file) + + for tmp in ['ipv6pool', 'ipv6_nd', 'ipv6_dhcp']: + self.assertEqual(conf['modules'][tmp], None) + + config = self.getConfig("ipv6-pool") + pool_config = f"""{client_prefix_1},name={pool_name} +{client_prefix_2},name={pool_name} +delegate={delegate_1_prefix},{delegate_mask},name={pool_name} +delegate={delegate_2_prefix},{delegate_mask},name={pool_name}""" + self.assertIn(pool_config, config) if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_service_pppoe-server.py b/smoketest/scripts/cli/test_service_pppoe-server.py index fa3bb87db..11d5b8b78 100755 --- a/smoketest/scripts/cli/test_service_pppoe-server.py +++ b/smoketest/scripts/cli/test_service_pppoe-server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2022-2023 VyOS maintainers and contributors +# Copyright (C) 2022-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 @@ -93,6 +93,13 @@ class TestServicePPPoEServer(BasicAccelPPPTest.TestCase): interface_cache = '128000' self.set(['ppp-options', 'interface-cache', interface_cache]) + # ipv6 + allow_ipv6 = 'allow' + random = 'random' + self.set(['ppp-options', 'ipv6', allow_ipv6]) + self.set(['ppp-options', 'ipv6-intf-id', random]) + self.set(['ppp-options', 'ipv6-accept-peer-intf-id']) + self.set(['ppp-options', 'ipv6-peer-intf-id', random]) # commit changes self.cli_commit() @@ -118,6 +125,15 @@ class TestServicePPPoEServer(BasicAccelPPPTest.TestCase): # check interface-cache self.assertEqual(conf['ppp']['unit-cache'], interface_cache) + #check ipv6 + for tmp in ['ipv6pool', 'ipv6_nd', 'ipv6_dhcp']: + self.assertEqual(conf['modules'][tmp], None) + + self.assertEqual(conf['ppp']['ipv6'], allow_ipv6) + self.assertEqual(conf['ppp']['ipv6-intf-id'], random) + self.assertEqual(conf['ppp']['ipv6-peer-intf-id'], random) + self.assertTrue(conf['ppp'].getboolean('ipv6-accept-peer-intf-id')) + def test_pppoe_server_authentication_protocols(self): # Test configuration of local authentication for PPPoE server self.basic_config() @@ -154,45 +170,6 @@ class TestServicePPPoEServer(BasicAccelPPPTest.TestCase): self.assertEqual(conf['shaper']['fwmark'], fwmark) self.assertEqual(conf['shaper']['down-limiter'], limiter) - def test_pppoe_server_client_ipv6_pool(self): - # Test configuration of IPv6 client pools - self.basic_config() - - # Enable IPv6 - allow_ipv6 = 'allow' - random = 'random' - self.set(['ppp-options', 'ipv6', allow_ipv6]) - self.set(['ppp-options', 'ipv6-intf-id', random]) - self.set(['ppp-options', 'ipv6-accept-peer-intf-id']) - self.set(['ppp-options', 'ipv6-peer-intf-id', random]) - - prefix = '2001:db8:ffff::/64' - prefix_mask = '128' - client_prefix = f'{prefix},{prefix_mask}' - self.set(['client-ipv6-pool', 'prefix', prefix, 'mask', prefix_mask]) - - delegate_prefix = '2001:db8::/40' - delegate_mask = '56' - self.set(['client-ipv6-pool', 'delegate', delegate_prefix, 'delegation-prefix', delegate_mask]) - - # commit changes - self.cli_commit() - - # Validate configuration values - conf = ConfigParser(allow_no_value=True, delimiters='=') - conf.read(self._config_file) - - for tmp in ['ipv6pool', 'ipv6_nd', 'ipv6_dhcp']: - self.assertEqual(conf['modules'][tmp], None) - - self.assertEqual(conf['ppp']['ipv6'], allow_ipv6) - self.assertEqual(conf['ppp']['ipv6-intf-id'], random) - self.assertEqual(conf['ppp']['ipv6-peer-intf-id'], random) - self.assertTrue(conf['ppp'].getboolean('ipv6-accept-peer-intf-id')) - - self.assertEqual(conf['ipv6-pool'][client_prefix], None) - self.assertEqual(conf['ipv6-pool']['delegate'], f'{delegate_prefix},{delegate_mask}') - def test_accel_radius_authentication(self): radius_called_sid = 'ifname:mac' diff --git a/smoketest/scripts/cli/test_vpn_l2tp.py b/smoketest/scripts/cli/test_vpn_l2tp.py index 5b3e419bd..129a9c602 100755 --- a/smoketest/scripts/cli/test_vpn_l2tp.py +++ b/smoketest/scripts/cli/test_vpn_l2tp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2023 VyOS maintainers and contributors +# Copyright (C) 2023-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 @@ -55,6 +55,13 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase): self.set(['ppp-options', 'lcp-echo-interval', lcp_echo_interval]) self.set(['ppp-options', 'lcp-echo-timeout', lcp_echo_timeout]) + allow_ipv6 = 'allow' + random = 'random' + self.set(['ppp-options', 'ipv6', allow_ipv6]) + self.set(['ppp-options', 'ipv6-intf-id', random]) + self.set(['ppp-options', 'ipv6-accept-peer-intf-id']) + self.set(['ppp-options', 'ipv6-peer-intf-id', random]) + # commit changes self.cli_commit() @@ -76,6 +83,13 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase): self.assertEqual(conf['ppp']['lcp-echo-timeout'], lcp_echo_timeout) self.assertEqual(conf['ppp']['lcp-echo-failure'], lcp_echo_failure) + for tmp in ['ipv6pool', 'ipv6_nd', 'ipv6_dhcp']: + self.assertEqual(conf['modules'][tmp], None) + self.assertEqual(conf['ppp']['ipv6'], allow_ipv6) + self.assertEqual(conf['ppp']['ipv6-intf-id'], random) + self.assertEqual(conf['ppp']['ipv6-peer-intf-id'], random) + self.assertTrue(conf['ppp'].getboolean('ipv6-accept-peer-intf-id')) + def test_l2tp_server_authentication_protocols(self): # Test configuration of local authentication for PPPoE server self.basic_config() @@ -92,44 +106,6 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase): self.assertEqual(conf['modules']['auth_mschap_v2'], None) - def test_l2tp_server_client_ipv6_pool(self): - # Test configuration of IPv6 client pools - self.basic_config() - - # Enable IPv6 - allow_ipv6 = 'allow' - random = 'random' - self.set(['ppp-options', 'ipv6', allow_ipv6]) - self.set(['ppp-options', 'ipv6-intf-id', random]) - self.set(['ppp-options', 'ipv6-accept-peer-intf-id']) - self.set(['ppp-options', 'ipv6-peer-intf-id', random]) - - prefix = '2001:db8:ffff::/64' - prefix_mask = '128' - client_prefix = f'{prefix},{prefix_mask}' - self.set(['client-ipv6-pool', 'prefix', prefix, 'mask', prefix_mask]) - - delegate_prefix = '2001:db8::/40' - delegate_mask = '56' - self.set(['client-ipv6-pool', 'delegate', delegate_prefix, 'delegation-prefix', delegate_mask]) - - # commit changes - self.cli_commit() - - # Validate configuration values - conf = ConfigParser(allow_no_value=True, delimiters='=') - conf.read(self._config_file) - - for tmp in ['ipv6pool', 'ipv6_nd', 'ipv6_dhcp']: - self.assertEqual(conf['modules'][tmp], None) - - self.assertEqual(conf['ppp']['ipv6'], allow_ipv6) - self.assertEqual(conf['ppp']['ipv6-intf-id'], random) - self.assertEqual(conf['ppp']['ipv6-peer-intf-id'], random) - self.assertTrue(conf['ppp'].getboolean('ipv6-accept-peer-intf-id')) - - self.assertEqual(conf['ipv6-pool'][client_prefix], None) - self.assertEqual(conf['ipv6-pool']['delegate'], f'{delegate_prefix},{delegate_mask}') if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_vpn_pptp.py b/smoketest/scripts/cli/test_vpn_pptp.py index 0d9ea312e..f3fce822b 100755 --- a/smoketest/scripts/cli/test_vpn_pptp.py +++ b/smoketest/scripts/cli/test_vpn_pptp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2023 VyOS maintainers and contributors +# Copyright (C) 2023-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 @@ -218,6 +218,10 @@ class TestVPNPPTPServer(BasicAccelPPPTest.TestCase): self.assertEqual(f"req-limit=0", server[4]) self.assertEqual(f"fail-time=0", server[5]) + @unittest.skip("IPv6 is not implemented in PPTP") + def test_accel_ipv6_pool(self): + pass + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py index 36f00dec5..6df6f3dc7 100755 --- a/src/conf_mode/service_ipoe-server.py +++ b/src/conf_mode/service_ipoe-server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018-2023 VyOS maintainers and contributors +# Copyright (C) 2018-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 @@ -79,9 +79,6 @@ def verify(ipoe): if 'key' not in radius_config: raise ConfigError(f'Missing RADIUS secret key for server "{server}"') - if 'client_ipv6_pool' in ipoe: - if 'delegate' in ipoe['client_ipv6_pool'] and 'prefix' not in ipoe['client_ipv6_pool']: - raise ConfigError('IPoE IPv6 deletate-prefix requires IPv6 prefix to be configured!') return None diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index 7c624f034..31299a15c 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018-2023 VyOS maintainers and contributors +# Copyright (C) 2018-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 @@ -85,6 +85,7 @@ def verify(pppoe): if not dict_search('authentication.radius.dynamic_author.key', pppoe): raise ConfigError('DA/CoE server key required!') + return None diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 1a91951b4..b569ca140 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2023 VyOS maintainers and contributors +# Copyright (C) 2019-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 @@ -70,15 +70,9 @@ def verify(l2tp): if not dict_search('authentication.radius.dynamic_author.key', l2tp): raise ConfigError('DA/CoE server key required!') - if dict_search('authentication.mode', l2tp) in ['local', 'noauth']: - if not dict_search('client_ip_pool', l2tp) and not dict_search('client_ipv6_pool', l2tp): - raise ConfigError( - "L2TP local auth mode requires local client-ip-pool or client-ipv6-pool to be configured!") - if dict_search('client_ip_pool', l2tp) and not dict_search('default_pool', l2tp): - Warning("'default-pool' is not defined") - verify_accel_ppp_ip_pool(l2tp) + if 'wins_server' in l2tp and len(l2tp['wins_server']) > 2: raise ConfigError( 'Not more then two WINS name-servers can be configured') diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index f769be39f..0629625bf 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -80,12 +80,6 @@ def verify(pptp): raise ConfigError( f'Missing RADIUS secret key for server "{server}"') - if auth_mode == 'local' or auth_mode == 'noauth': - if not dict_search('client_ip_pool', pptp): - raise ConfigError( - 'PPTP local auth mode requires local client-ip-pool ' - 'to be configured!') - verify_accel_ppp_ip_pool(pptp) if 'name_server' in pptp: diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index 6bf9307e1..a84513a0f 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -74,11 +74,8 @@ def verify(sstp): raise ConfigError(f'"{proto}" port "{port}" is used by another service') verify_accel_ppp_base_service(sstp) - - if 'client_ip_pool' not in sstp and 'client_ipv6_pool' not in sstp: - raise ConfigError('Client IP subnet required') - verify_accel_ppp_ip_pool(sstp) + # # SSL certificate checks # diff --git a/src/migration-scripts/ipoe-server/2-to-3 b/src/migration-scripts/ipoe-server/2-to-3 new file mode 100755 index 000000000..d4ae0a7ba --- /dev/null +++ b/src/migration-scripts/ipoe-server/2-to-3 @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Migrating to named ipv6 pools + +import os + +from sys import argv +from sys import exit +from vyos.configtree import ConfigTree + + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['service', 'ipoe-server'] +pool_base = base + ['client-ipv6-pool'] +if not config.exists(base): + exit(0) + +if not config.exists(pool_base): + exit(0) + +ipv6_pool_name = 'ipv6-pool' +config.copy(pool_base, pool_base + [ipv6_pool_name]) + +if config.exists(pool_base + ['prefix']): + config.delete(pool_base + ['prefix']) + config.set(base + ['default-ipv6-pool'], value=ipv6_pool_name) +if config.exists(pool_base + ['delegate']): + config.delete(pool_base + ['delegate']) + +# format as tag node +config.set_tag(pool_base) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) diff --git a/src/migration-scripts/l2tp/6-to-7 b/src/migration-scripts/l2tp/6-to-7 new file mode 100755 index 000000000..f49c4ab08 --- /dev/null +++ b/src/migration-scripts/l2tp/6-to-7 @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Migrating to named ipv6 pools + +import os + +from sys import argv +from sys import exit +from vyos.configtree import ConfigTree + + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['vpn', 'l2tp', 'remote-access'] +pool_base = base + ['client-ipv6-pool'] +if not config.exists(base): + exit(0) + +if not config.exists(pool_base): + exit(0) + +ipv6_pool_name = 'ipv6-pool' +config.copy(pool_base, pool_base + [ipv6_pool_name]) + +if config.exists(pool_base + ['prefix']): + config.delete(pool_base + ['prefix']) + config.set(base + ['default-ipv6-pool'], value=ipv6_pool_name) +if config.exists(pool_base + ['delegate']): + config.delete(pool_base + ['delegate']) +# format as tag node +config.set_tag(pool_base) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) diff --git a/src/migration-scripts/pppoe-server/7-to-8 b/src/migration-scripts/pppoe-server/7-to-8 new file mode 100755 index 000000000..b0d9bb464 --- /dev/null +++ b/src/migration-scripts/pppoe-server/7-to-8 @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Migrating to named ipv6 pools + +import os + +from sys import argv +from sys import exit +from vyos.configtree import ConfigTree + + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['service', 'pppoe-server'] +pool_base = base + ['client-ipv6-pool'] +if not config.exists(base): + exit(0) + +if not config.exists(pool_base): + exit(0) + +ipv6_pool_name = 'ipv6-pool' +config.copy(pool_base, pool_base + [ipv6_pool_name]) + +if config.exists(pool_base + ['prefix']): + config.delete(pool_base + ['prefix']) + config.set(base + ['default-ipv6-pool'], value=ipv6_pool_name) +if config.exists(pool_base + ['delegate']): + config.delete(pool_base + ['delegate']) + +# format as tag node +config.set_tag(pool_base) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) diff --git a/src/migration-scripts/sstp/5-to-6 b/src/migration-scripts/sstp/5-to-6 new file mode 100755 index 000000000..bac9975b2 --- /dev/null +++ b/src/migration-scripts/sstp/5-to-6 @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Migrating to named ipv6 pools + +import os +import pprint + +from sys import argv +from sys import exit +from vyos.configtree import ConfigTree + + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['vpn', 'sstp'] +pool_base = base + ['client-ipv6-pool'] +if not config.exists(base): + exit(0) + +if not config.exists(pool_base): + exit(0) + +ipv6_pool_name = 'ipv6-pool' +config.copy(pool_base, pool_base + [ipv6_pool_name]) + +if config.exists(pool_base + ['prefix']): + config.delete(pool_base + ['prefix']) + config.set(base + ['default-ipv6-pool'], value=ipv6_pool_name) +if config.exists(pool_base + ['delegate']): + config.delete(pool_base + ['delegate']) + +# format as tag node +config.set_tag(pool_base) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) |