summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/dns-forwarding/recursor.conf.j210
-rw-r--r--interface-definitions/service_dns_forwarding.xml.in41
-rw-r--r--op-mode-definitions/show-ipv6-route.xml.in19
-rw-r--r--python/vyos/utils/process.py27
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py16
-rwxr-xr-xsmoketest/scripts/cli/test_service_dns_forwarding.py42
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>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</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>&lt;h:h:h:h:h:h:h:h&gt; &lt;h:h:h:h:h:h:h:h/x&gt;</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']: