diff options
-rw-r--r-- | data/config-mode-dependencies/vyos-1x.json | 3 | ||||
-rw-r--r-- | data/templates/frr/bgpd.frr.j2 | 18 | ||||
-rw-r--r-- | interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i | 1 | ||||
-rw-r--r-- | interface-definitions/include/bgp/protocol-common-config.xml.i | 35 | ||||
-rw-r--r-- | interface-definitions/system_frr.xml.in | 2 | ||||
-rw-r--r-- | op-mode-definitions/show-system.xml.in | 4 | ||||
-rw-r--r-- | op-mode-definitions/show-version.xml.in | 2 | ||||
-rw-r--r-- | python/vyos/qos/trafficshaper.py | 2 | ||||
-rw-r--r-- | python/vyos/utils/config.py | 9 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_bgp.py | 43 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_vpn_l2tp.py | 41 | ||||
-rwxr-xr-x | src/conf_mode/vpn_l2tp.py | 10 | ||||
-rwxr-xr-x | src/init/vyos-router | 6 |
13 files changed, 146 insertions, 30 deletions
diff --git a/data/config-mode-dependencies/vyos-1x.json b/data/config-mode-dependencies/vyos-1x.json index 4fd94d895..b62603e34 100644 --- a/data/config-mode-dependencies/vyos-1x.json +++ b/data/config-mode-dependencies/vyos-1x.json @@ -29,6 +29,9 @@ "openconnect": ["vpn_openconnect"], "sstp": ["vpn_sstp"] }, + "vpn_l2tp": { + "ipsec": ["vpn_ipsec"] + }, "qos": { "bonding": ["interfaces_bonding"], "bridge": ["interfaces_bridge"], diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 index e02fdd1bb..23f81348b 100644 --- a/data/templates/frr/bgpd.frr.j2 +++ b/data/templates/frr/bgpd.frr.j2 @@ -225,10 +225,10 @@ neighbor {{ neighbor }} route-map {{ afi_config.route_map.import }} in {% endif %} {% if afi_config.prefix_list.export is vyos_defined %} - neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out + neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.export }} out {% endif %} {% if afi_config.prefix_list.import is vyos_defined %} - neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in + neighbor {{ neighbor }} prefix-list {{ afi_config.prefix_list.import }} in {% endif %} {% if afi_config.soft_reconfiguration.inbound is vyos_defined %} neighbor {{ neighbor }} soft-reconfiguration inbound @@ -237,10 +237,10 @@ neighbor {{ neighbor }} unsuppress-map {{ afi_config.unsuppress_map }} {% endif %} {% if afi_config.disable_send_community.extended is vyos_defined %} - no neighbor {{ neighbor }} send-community extended + no neighbor {{ neighbor }} send-community extended {% endif %} {% if afi_config.disable_send_community.standard is vyos_defined %} - no neighbor {{ neighbor }} send-community standard + no neighbor {{ neighbor }} send-community standard {% endif %} neighbor {{ neighbor }} activate exit-address-family @@ -473,6 +473,7 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% endfor %} {% endif %} exit-address-family + ! {% endfor %} {% endif %} ! @@ -530,6 +531,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% endif %} {% endfor %} {% endif %} +{% if parameters.allow_martian_nexthop is vyos_defined %} + bgp allow-martian-nexthop +{% endif %} {% if parameters.always_compare_med is vyos_defined %} bgp always-compare-med {% endif %} @@ -590,6 +594,12 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% if parameters.graceful_shutdown is vyos_defined %} bgp graceful-shutdown {% endif %} +{% if parameters.no_hard_administrative_reset is vyos_defined %} + no bgp hard-administrative-reset +{% endif %} +{% if parameters.labeled_unicast is vyos_defined %} + bgp labeled-unicast {{ parameters.labeled_unicast }} +{% endif %} {% if parameters.log_neighbor_changes is vyos_defined %} bgp log-neighbor-changes {% endif %} diff --git a/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i b/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i index c8ad68700..a433f7cc6 100644 --- a/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i +++ b/interface-definitions/include/bgp/neighbor-afi-ipv4-ipv6-common.xml.i @@ -1,5 +1,4 @@ <!-- include start from bgp/neighbor-afi-ipv4-ipv6-common.xml.i --> - <leafNode name="addpath-tx-all"> <properties> <help>Use addpath to advertise all paths to a neighbor</help> diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index 9895b025c..ea6e75bbd 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -1219,6 +1219,12 @@ <help>BGP parameters</help> </properties> <children> + <leafNode name="allow-martian-nexthop"> + <properties> + <help>Allow Martian nexthops to be received in the NLRI from a peer</help> + <valueless/> + </properties> + </leafNode> <leafNode name="always-compare-med"> <properties> <help>Always compare MEDs from different neighbors</help> @@ -1576,6 +1582,35 @@ <valueless/> </properties> </leafNode> + <leafNode name="no-hard-administrative-reset"> + <properties> + <help>Do not send hard reset CEASE Notification for 'Administrative Reset'</help> + <valueless/> + </properties> + </leafNode> + <leafNode name="labeled-unicast"> + <properties> + <help>BGP Labeled-unicast options</help> + <completionHelp> + <list>explicit-null ipv4-explicit-null ipv6-explicit-null</list> + </completionHelp> + <valueHelp> + <format>explicit-null</format> + <description>Use explicit-null label values for all local prefixes</description> + </valueHelp> + <valueHelp> + <format>ipv4-explicit-null</format> + <description>Use IPv4 explicit-null label value for IPv4 local prefixes</description> + </valueHelp> + <valueHelp> + <format>ipv6-explicit-null</format> + <description>Use IPv6 explicit-null label value for IPv4 local prefixes</description> + </valueHelp> + <constraint> + <regex>(explicit-null|ipv4-explicit-null|ipv6-explicit-null)</regex> + </constraint> + </properties> + </leafNode> <leafNode name="log-neighbor-changes"> <properties> <help>Log neighbor up/down changes and reset reason</help> diff --git a/interface-definitions/system_frr.xml.in b/interface-definitions/system_frr.xml.in index 76001b392..28242dfe4 100644 --- a/interface-definitions/system_frr.xml.in +++ b/interface-definitions/system_frr.xml.in @@ -4,7 +4,7 @@ <children> <node name="frr" owner="${vyos_conf_scripts_dir}/system_frr.py"> <properties> - <help>Configure FRR parameters</help> + <help>Configure FRRouting parameters</help> <!-- Before components that use FRR --> <priority>150</priority> </properties> diff --git a/op-mode-definitions/show-system.xml.in b/op-mode-definitions/show-system.xml.in index 116c7460f..6873b816b 100644 --- a/op-mode-definitions/show-system.xml.in +++ b/op-mode-definitions/show-system.xml.in @@ -150,7 +150,7 @@ </children> </tagNode> </children> - </node> + </node> <node name="users"> <properties> <help>Show user account information</help> @@ -239,7 +239,7 @@ </node> <leafNode name="routing-daemons"> <properties> - <help>Show Quagga routing daemons</help> + <help>Show FRRouting daemons</help> </properties> <command>vtysh -c "show daemons"</command> </leafNode> diff --git a/op-mode-definitions/show-version.xml.in b/op-mode-definitions/show-version.xml.in index d9c4738af..36e68ff79 100644 --- a/op-mode-definitions/show-version.xml.in +++ b/op-mode-definitions/show-version.xml.in @@ -22,7 +22,7 @@ </leafNode> <leafNode name="frr"> <properties> - <help>Show Quagga version information</help> + <help>Show FRRouting version information</help> </properties> <command>vtysh -c "show version"</command> </leafNode> diff --git a/python/vyos/qos/trafficshaper.py b/python/vyos/qos/trafficshaper.py index d6705cc77..7d580baa2 100644 --- a/python/vyos/qos/trafficshaper.py +++ b/python/vyos/qos/trafficshaper.py @@ -39,7 +39,7 @@ class TrafficShaper(QoSBase): # need a bigger r2q if going fast than 16 mbits/sec if (speed_bps // r2q) >= MAXQUANTUM: # integer division - r2q = ceil(speed_bps // MAXQUANTUM) + r2q = ceil(speed_bps / MAXQUANTUM) else: # if there is a slow class then may need smaller value if 'class' in config: diff --git a/python/vyos/utils/config.py b/python/vyos/utils/config.py index bd363ce46..33047010b 100644 --- a/python/vyos/utils/config.py +++ b/python/vyos/utils/config.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 @@ -31,4 +31,9 @@ def read_saved_value(path: list): if not ct.exists(path): return '' res = ct.return_values(path) - return res[0] if len(res) == 1 else res + if len(res) == 1: + return res[0] + res = ct.list_nodes(path) + if len(res) == 1: + return ' '.join(res) + return res diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 2dbc30a41..08a6e1696 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -319,8 +319,11 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): tcp_keepalive_interval = '77' tcp_keepalive_probes = '22' - self.cli_set(base_path + ['parameters', 'router-id', router_id]) + self.cli_set(base_path + ['parameters', 'allow-martian-nexthop']) + self.cli_set(base_path + ['parameters', 'no-hard-administrative-reset']) self.cli_set(base_path + ['parameters', 'log-neighbor-changes']) + self.cli_set(base_path + ['parameters', 'labeled-unicast', 'explicit-null']) + self.cli_set(base_path + ['parameters', 'router-id', router_id]) # System AS number MUST be defined - as this is set in setUp() we remove # this once for testing of the proper error @@ -367,12 +370,15 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): frrconfig = self.getFRRconfig(f'router bgp {ASN}') self.assertIn(f'router bgp {ASN}', frrconfig) self.assertIn(f' bgp router-id {router_id}', frrconfig) + self.assertIn(f' bgp allow-martian-nexthop', frrconfig) self.assertIn(f' bgp log-neighbor-changes', frrconfig) self.assertIn(f' bgp default local-preference {local_pref}', frrconfig) self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig) self.assertIn(f' bgp fast-convergence', frrconfig) self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig) self.assertIn(f' bgp graceful-shutdown', frrconfig) + self.assertIn(f' no bgp hard-administrative-reset', frrconfig) + self.assertIn(f' bgp labeled-unicast explicit-null', frrconfig) self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig) self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig) self.assertIn(f' bgp bestpath compare-routerid', frrconfig) @@ -1178,22 +1184,15 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' sid vpn export {sid}', afiv6_config) self.assertIn(f' nexthop vpn export {nexthop_ipv6}', afiv4_config) - def test_bgp_25_ipv4_ipv6_labeled_unicast_peer_group(self): + def test_bgp_25_ipv4_labeled_unicast_peer_group(self): pg_ipv4 = 'foo4' - pg_ipv6 = 'foo6' - ipv4_max_prefix = '20' - ipv6_max_prefix = '200' ipv4_prefix = '192.0.2.0/24' - ipv6_prefix = '2001:db8:1000::/64' self.cli_set(base_path + ['listen', 'range', ipv4_prefix, 'peer-group', pg_ipv4]) - self.cli_set(base_path + ['listen', 'range', ipv6_prefix, 'peer-group', pg_ipv6]) - + self.cli_set(base_path + ['parameters', 'labeled-unicast', 'ipv4-explicit-null']) self.cli_set(base_path + ['peer-group', pg_ipv4, 'address-family', 'ipv4-labeled-unicast', 'maximum-prefix', ipv4_max_prefix]) self.cli_set(base_path + ['peer-group', pg_ipv4, 'remote-as', 'external']) - self.cli_set(base_path + ['peer-group', pg_ipv6, 'address-family', 'ipv6-labeled-unicast', 'maximum-prefix', ipv6_max_prefix]) - self.cli_set(base_path + ['peer-group', pg_ipv6, 'remote-as', 'external']) self.cli_commit() @@ -1201,15 +1200,33 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f'router bgp {ASN}', frrconfig) self.assertIn(f' neighbor {pg_ipv4} peer-group', frrconfig) self.assertIn(f' neighbor {pg_ipv4} remote-as external', frrconfig) - self.assertIn(f' neighbor {pg_ipv6} peer-group', frrconfig) - self.assertIn(f' neighbor {pg_ipv6} remote-as external', frrconfig) self.assertIn(f' bgp listen range {ipv4_prefix} peer-group {pg_ipv4}', frrconfig) - self.assertIn(f' bgp listen range {ipv6_prefix} peer-group {pg_ipv6}', frrconfig) + self.assertIn(f' bgp labeled-unicast ipv4-explicit-null', frrconfig) afiv4_config = self.getFRRconfig(' address-family ipv4 labeled-unicast') self.assertIn(f' neighbor {pg_ipv4} activate', afiv4_config) self.assertIn(f' neighbor {pg_ipv4} maximum-prefix {ipv4_max_prefix}', afiv4_config) + def test_bgp_26_ipv6_labeled_unicast_peer_group(self): + pg_ipv6 = 'foo6' + ipv6_max_prefix = '200' + ipv6_prefix = '2001:db8:1000::/64' + + self.cli_set(base_path + ['listen', 'range', ipv6_prefix, 'peer-group', pg_ipv6]) + self.cli_set(base_path + ['parameters', 'labeled-unicast', 'ipv6-explicit-null']) + + self.cli_set(base_path + ['peer-group', pg_ipv6, 'address-family', 'ipv6-labeled-unicast', 'maximum-prefix', ipv6_max_prefix]) + self.cli_set(base_path + ['peer-group', pg_ipv6, 'remote-as', 'external']) + + self.cli_commit() + + frrconfig = self.getFRRconfig(f'router bgp {ASN}') + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' neighbor {pg_ipv6} peer-group', frrconfig) + self.assertIn(f' neighbor {pg_ipv6} remote-as external', frrconfig) + self.assertIn(f' bgp listen range {ipv6_prefix} peer-group {pg_ipv6}', frrconfig) + self.assertIn(f' bgp labeled-unicast ipv6-explicit-null', frrconfig) + afiv6_config = self.getFRRconfig(' address-family ipv6 labeled-unicast') self.assertIn(f' neighbor {pg_ipv6} activate', afiv6_config) self.assertIn(f' neighbor {pg_ipv6} maximum-prefix {ipv6_max_prefix}', afiv6_config) diff --git a/smoketest/scripts/cli/test_vpn_l2tp.py b/smoketest/scripts/cli/test_vpn_l2tp.py index 3d9d94f52..e253f0e49 100755 --- a/smoketest/scripts/cli/test_vpn_l2tp.py +++ b/smoketest/scripts/cli/test_vpn_l2tp.py @@ -54,6 +54,47 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase): self.assertEqual(conf['modules']['auth_mschap_v2'], None) + def test_vpn_l2tp_dependence_ipsec_swanctl(self): + # Test config vpn for tasks T3843 and T5926 + + base_path = ['vpn', 'l2tp', 'remote-access'] + # make precondition + self.cli_set(['interfaces', 'dummy', 'dum0', 'address', '203.0.113.1/32']) + self.cli_set(['vpn', 'ipsec', 'interface', 'dum0']) + + self.cli_commit() + # check ipsec apply to swanctl + self.assertEqual('', cmd('echo vyos | sudo -S swanctl -L ')) + + self.cli_set(base_path + ['authentication', 'local-users', 'username', 'foo', 'password', 'bar']) + self.cli_set(base_path + ['authentication', 'mode', 'local']) + self.cli_set(base_path + ['authentication', 'protocols', 'chap']) + self.cli_set(base_path + ['client-ip-pool', 'first', 'range', '10.200.100.100-10.200.100.110']) + self.cli_set(base_path + ['description', 'VPN - REMOTE']) + self.cli_set(base_path + ['name-server', '1.1.1.1']) + self.cli_set(base_path + ['ipsec-settings', 'authentication', 'mode', 'pre-shared-secret']) + self.cli_set(base_path + ['ipsec-settings', 'authentication', 'pre-shared-secret', 'SeCret']) + self.cli_set(base_path + ['ipsec-settings', 'ike-lifetime', '8600']) + self.cli_set(base_path + ['ipsec-settings', 'lifetime', '3600']) + self.cli_set(base_path + ['outside-address', '203.0.113.1']) + self.cli_set(base_path + ['gateway-address', '203.0.113.1']) + + self.cli_commit() + + # check l2tp apply to swanctl + self.assertTrue('l2tp_remote_access:' in cmd('echo vyos | sudo -S swanctl -L ')) + + self.cli_delete(['vpn', 'l2tp']) + self.cli_commit() + + # check l2tp apply to swanctl after delete config + self.assertEqual('', cmd('echo vyos | sudo -S swanctl -L ')) + + # need to correct tearDown test + self.basic_config() + self.cli_set(base_path + ['authentication', 'protocols', 'chap']) + self.cli_commit() + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 36b3d2a30..4ca717814 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -19,6 +19,7 @@ import os from sys import exit from vyos.config import Config +from vyos.configdep import call_dependents, set_dependents from vyos.configdict import get_accel_dict from vyos.template import render from vyos.utils.process import call @@ -42,6 +43,9 @@ def get_config(config=None): else: conf = Config() base = ['vpn', 'l2tp', 'remote-access'] + + set_dependents('ipsec', conf) + if not conf.exists(base): return None @@ -94,10 +98,10 @@ def apply(l2tp): for file in [l2tp_chap_secrets, l2tp_conf]: if os.path.exists(file): os.unlink(file) + else: + call('systemctl restart accel-ppp@l2tp.service') - return None - - call('systemctl restart accel-ppp@l2tp.service') + call_dependents() if __name__ == '__main__': diff --git a/src/init/vyos-router b/src/init/vyos-router index ac1cf249e..2b4fac5ef 100755 --- a/src/init/vyos-router +++ b/src/init/vyos-router @@ -448,14 +448,16 @@ start () restore_if_missing_postconfig_script run_postconfig_scripts - vtysh -c "rpki start" + tmp=$(${vyos_libexec_dir}/read-saved-value.py --path "protocols rpki cache") + if [ ! -z $tmp ]; then + vtysh -c "rpki start" + fi } stop() { local -i status=0 log_daemon_msg "Stopping VyOS router" - vtysh -c "rpki stop" for ((i=${#sub_inits[@]} - 1; i >= 0; i--)) ; do s=${subinit[$i]} log_progress_msg $s |