diff options
-rw-r--r-- | data/templates/dns-forwarding/recursor.conf.j2 | 10 | ||||
-rw-r--r-- | interface-definitions/service_dns_forwarding.xml.in | 41 | ||||
-rw-r--r-- | op-mode-definitions/show-ipv6-route.xml.in | 19 | ||||
-rw-r--r-- | python/vyos/utils/process.py | 27 | ||||
-rw-r--r-- | smoketest/scripts/cli/base_interfaces_test.py | 16 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_dns_forwarding.py | 42 |
6 files changed, 138 insertions, 17 deletions
diff --git a/data/templates/dns-forwarding/recursor.conf.j2 b/data/templates/dns-forwarding/recursor.conf.j2 index ea700406c..55b37732b 100644 --- a/data/templates/dns-forwarding/recursor.conf.j2 +++ b/data/templates/dns-forwarding/recursor.conf.j2 @@ -40,6 +40,16 @@ dnssec={{ dnssec }} dns64-prefix={{ dns64_prefix }} {% endif %} +{% if exclude_throttle_address is vyos_defined %} +# dont-throttle-netmasks +dont-throttle-netmasks={{ exclude_throttle_address | join(',') }} +{% endif %} + +{% if serve_stale_extension is vyos_defined %} +# serve-stale-extensions +serve-stale-extensions={{ serve_stale_extension }} +{% endif %} + # serve rfc1918 records serve-rfc1918={{ 'no' if no_serve_rfc1918 is vyos_defined else 'yes' }} diff --git a/interface-definitions/service_dns_forwarding.xml.in b/interface-definitions/service_dns_forwarding.xml.in index 7dce9b548..0f8863438 100644 --- a/interface-definitions/service_dns_forwarding.xml.in +++ b/interface-definitions/service_dns_forwarding.xml.in @@ -670,6 +670,19 @@ </properties> <defaultValue>3600</defaultValue> </leafNode> + <leafNode name="serve-stale-extension"> + <properties> + <help>Number of times the expired TTL of a record is extended by 30 seconds when serving stale</help> + <valueHelp> + <format>u32:0-65535</format> + <description>Number of times to extend the TTL</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-65535"/> + </constraint> + </properties> + <defaultValue>0</defaultValue> + </leafNode> <leafNode name="timeout"> <properties> <help>Number of milliseconds to wait for a remote authoritative server to respond</help> @@ -694,6 +707,34 @@ <valueless/> </properties> </leafNode> + <leafNode name="exclude-throttle-address"> + <properties> + <help>IP address or subnet</help> + <valueHelp> + <format>ipv4</format> + <description>IPv4 address to match</description> + </valueHelp> + <valueHelp> + <format>ipv4net</format> + <description>IPv4 prefix to match</description> + </valueHelp> + <valueHelp> + <format>ipv6</format> + <description>IPv6 address</description> + </valueHelp> + <valueHelp> + <format>ipv6net</format> + <description>IPv6 address</description> + </valueHelp> + <multi/> + <constraint> + <validator name="ipv4-address"/> + <validator name="ipv4-prefix"/> + <validator name="ipv6-address"/> + <validator name="ipv6-prefix"/> + </constraint> + </properties> + </leafNode> </children> </node> </children> diff --git a/op-mode-definitions/show-ipv6-route.xml.in b/op-mode-definitions/show-ipv6-route.xml.in index 7df1a873a..d73fb46b4 100644 --- a/op-mode-definitions/show-ipv6-route.xml.in +++ b/op-mode-definitions/show-ipv6-route.xml.in @@ -82,6 +82,23 @@ </properties> <command>${vyos_op_scripts_dir}/route.py show_summary --family inet6 --vrf $5</command> </node> + <node name="node.tag"> + <properties> + <help>Show IPv6 routes of given address or prefix</help> + <completionHelp> + <list><h:h:h:h:h:h:h:h> <h:h:h:h:h:h:h:h/x></list> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <children> + <node name="longer-prefixes"> + <properties> + <help>Show longer prefixes of routes for given prefix</help> + </properties> + <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + </node> + </children> + </node> #include <include/show-route-bgp.xml.i> #include <include/show-route-connected.xml.i> #include <include/show-route-isis.xml.i> @@ -103,6 +120,7 @@ <list><h:h:h:h:h:h:h:h> <h:h:h:h:h:h:h:h/x></list> </completionHelp> </properties> + <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> <children> <node name="longer-prefixes"> <properties> @@ -111,7 +129,6 @@ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> </node> </children> - <command>vtysh -c "show ipv6 route $4"</command> </tagNode> </children> </node> diff --git a/python/vyos/utils/process.py b/python/vyos/utils/process.py index e09c7d86d..cd58b4be2 100644 --- a/python/vyos/utils/process.py +++ b/python/vyos/utils/process.py @@ -204,17 +204,32 @@ def process_running(pid_file): pid = f.read().strip() return pid_exists(int(pid)) -def process_named_running(name, cmdline: str=None): +def process_named_running(name, cmdline: str=None, timeout=0): """ Checks if process with given name is running and returns its PID. If Process is not running, return None """ from psutil import process_iter - for p in process_iter(['name', 'pid', 'cmdline']): - if cmdline: - if p.info['name'] == name and cmdline in p.info['cmdline']: + def check_process(name, cmdline): + for p in process_iter(['name', 'pid', 'cmdline']): + if cmdline: + if name in p.info['name'] and cmdline in p.info['cmdline']: + return p.info['pid'] + elif name in p.info['name']: return p.info['pid'] - elif p.info['name'] == name: - return p.info['pid'] + return None + if timeout: + import time + time_expire = time.time() + timeout + while True: + tmp = check_process(name, cmdline) + if not tmp: + if time.time() > time_expire: + break + time.sleep(0.100) # wait 250ms + continue + return tmp + else: + return check_process(name, cmdline) return None def is_systemd_service_active(service): diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index 3f42196f7..7219fe622 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -127,9 +127,9 @@ class BasicInterfaceTest: # by also checking the cmd arguments passed to the daemon if self._interfaces: for tmp in self._interfaces: - self.assertFalse(process_named_running(daemon, tmp)) + self.assertFalse(process_named_running(daemon, tmp, timeout=10)) else: - self.assertFalse(process_named_running(daemon)) + self.assertFalse(process_named_running(daemon, timeout=10)) def test_dhcp_disable_interface(self): if not self._test_dhcp: @@ -179,7 +179,7 @@ class BasicInterfaceTest: for interface in self._interfaces: # Check if dhclient process runs - dhclient_pid = process_named_running(dhclient_process_name, cmdline=interface) + dhclient_pid = process_named_running(dhclient_process_name, cmdline=interface, timeout=10) self.assertTrue(dhclient_pid) dhclient_config = read_file(f'{dhclient_base_dir}/dhclient_{interface}.conf') @@ -216,7 +216,7 @@ class BasicInterfaceTest: self.assertEqual(tmp, vrf_name) # Check if dhclient process runs - dhclient_pid = process_named_running(dhclient_process_name, cmdline=interface) + dhclient_pid = process_named_running(dhclient_process_name, cmdline=interface, timeout=10) self.assertTrue(dhclient_pid) # .. inside the appropriate VRF instance vrf_pids = cmd(f'ip vrf pids {vrf_name}') @@ -251,7 +251,7 @@ class BasicInterfaceTest: self.assertEqual(tmp, vrf_name) # Check if dhclient process runs - tmp = process_named_running(dhcp6c_process_name, cmdline=interface) + tmp = process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10) self.assertTrue(tmp) # .. inside the appropriate VRF instance vrf_pids = cmd(f'ip vrf pids {vrf_name}') @@ -945,7 +945,7 @@ class BasicInterfaceTest: duid_base += 1 # Better ask the process about it's commandline in the future - pid = process_named_running(dhcp6c_process_name, cmdline=interface) + pid = process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10) self.assertTrue(pid) dhcp6c_options = read_file(f'/proc/{pid}/cmdline') @@ -1004,7 +1004,7 @@ class BasicInterfaceTest: address = str(int(address) + 1) # Check for running process - self.assertTrue(process_named_running(dhcp6c_process_name, cmdline=interface)) + self.assertTrue(process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10)) for delegatee in delegatees: # we can already cleanup the test delegatee interface here @@ -1070,7 +1070,7 @@ class BasicInterfaceTest: address = str(int(address) + 1) # Check for running process - self.assertTrue(process_named_running(dhcp6c_process_name, cmdline=interface)) + self.assertTrue(process_named_running(dhcp6c_process_name, cmdline=interface, timeout=10)) for delegatee in delegatees: # we can already cleanup the test delegatee interface here diff --git a/smoketest/scripts/cli/test_service_dns_forwarding.py b/smoketest/scripts/cli/test_service_dns_forwarding.py index bc50a4ffe..85a5f1448 100755 --- a/smoketest/scripts/cli/test_service_dns_forwarding.py +++ b/smoketest/scripts/cli/test_service_dns_forwarding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2022 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 @@ -43,7 +43,6 @@ class TestServicePowerDNS(VyOSUnitTestSHIM.TestCase): @classmethod def setUpClass(cls): super(TestServicePowerDNS, cls).setUpClass() - # ensure we can also run this test on a live system - so lets clean # out the current configuration :) cls.cli_delete(cls, base_path) @@ -239,6 +238,45 @@ class TestServicePowerDNS(VyOSUnitTestSHIM.TestCase): tmp = get_config_value('dns64-prefix') self.assertEqual(tmp, dns_prefix) + def test_exclude_throttle_adress(self): + exclude_throttle_adress_examples = [ + '192.168.128.255', + '10.0.0.0/25', + '2001:db8:85a3:8d3:1319:8a2e:370:7348', + '64:ff9b::/96' + ] + + for network in allow_from: + self.cli_set(base_path + ['allow-from', network]) + for address in listen_adress: + self.cli_set(base_path + ['listen-address', address]) + + for exclude_throttle_adress in exclude_throttle_adress_examples: + self.cli_set(base_path + ['exclude-throttle-address', exclude_throttle_adress]) + + # commit changes + self.cli_commit() + + # verify dont-throttle-netmasks configuration + tmp = get_config_value('dont-throttle-netmasks') + self.assertEqual(tmp, ','.join(exclude_throttle_adress_examples)) + + def test_serve_stale_extension(self): + server_stale = '20' + for network in allow_from: + self.cli_set(base_path + ['allow-from', network]) + for address in listen_adress: + self.cli_set(base_path + ['listen-address', address]) + + self.cli_set(base_path + ['serve-stale-extension', server_stale]) + + # commit changes + self.cli_commit() + + # verify configuration + tmp = get_config_value('serve-stale-extensions') + self.assertEqual(tmp, server_stale) + def test_listening_port(self): # We can listen on a different port compared to '53' but only one at a time for port in ['1053', '5353']: |