summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2022-07-04 20:23:27 +0200
committerChristian Poessinger <christian@poessinger.com>2022-07-04 20:23:27 +0200
commit6732df1edd632b56d3d02970939f51d05d4262e9 (patch)
treec79a000f0b75334cbf9fb4e30056ac6f1b0693a3
parent6bcb2b15babbb2a580439aad2463b1b18d5508a9 (diff)
downloadvyos-1x-6732df1edd632b56d3d02970939f51d05d4262e9.tar.gz
vyos-1x-6732df1edd632b56d3d02970939f51d05d4262e9.zip
ntp: T4456: support listening on specified interface
When clients only use DHCP for interface addressing we can not bind NTPd to an address - as it will fail if the address changes. This commit adds support to bind ntpd to a given interface in addition to a given address. set system ntp interface <name>
-rw-r--r--data/templates/ntp/ntpd.conf.j213
-rw-r--r--interface-definitions/ntp.xml.in1
-rwxr-xr-xsmoketest/scripts/cli/test_system_ntp.py17
-rwxr-xr-xsrc/conf_mode/ntp.py19
4 files changed, 45 insertions, 5 deletions
diff --git a/data/templates/ntp/ntpd.conf.j2 b/data/templates/ntp/ntpd.conf.j2
index da610051e..8921826fa 100644
--- a/data/templates/ntp/ntpd.conf.j2
+++ b/data/templates/ntp/ntpd.conf.j2
@@ -33,10 +33,17 @@ restrict {{ address | address_from_cidr }} mask {{ address | netmask_from_cidr }
{% endfor %}
{% endif %}
-{% if listen_address %}
+{% if listen_address is vyos_defined or interface is vyos_defined %}
# NTP should listen on configured addresses only
interface ignore wildcard
-{% for address in listen_address %}
+{% if listen_address is vyos_defined %}
+{% for address in listen_address %}
interface listen {{ address }}
-{% endfor %}
+{% endfor %}
+{% endif %}
+{% if interface is vyos_defined %}
+{% for ifname in interface %}
+interface listen {{ ifname }}
+{% endfor %}
+{% endif %}
{% endif %}
diff --git a/interface-definitions/ntp.xml.in b/interface-definitions/ntp.xml.in
index a518a9def..85636a50f 100644
--- a/interface-definitions/ntp.xml.in
+++ b/interface-definitions/ntp.xml.in
@@ -81,6 +81,7 @@
</leafNode>
</children>
</node>
+ #include <include/generic-interface-multi.xml.i>
#include <include/listen-address.xml.i>
#include <include/interface/vrf.xml.i>
</children>
diff --git a/smoketest/scripts/cli/test_system_ntp.py b/smoketest/scripts/cli/test_system_ntp.py
index e2821687c..a0806acf0 100755
--- a/smoketest/scripts/cli/test_system_ntp.py
+++ b/smoketest/scripts/cli/test_system_ntp.py
@@ -108,5 +108,22 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):
for listen in listen_address:
self.assertIn(f'interface listen {listen}', config)
+ def test_03_ntp_interface(self):
+ interfaces = ['eth0', 'eth1']
+ for interface in interfaces:
+ self.cli_set(base_path + ['interface', interface])
+
+ servers = ['time1.vyos.net', 'time2.vyos.net']
+ for server in servers:
+ self.cli_set(base_path + ['server', server])
+
+ self.cli_commit()
+
+ # Check generated client address configuration
+ config = read_file(NTP_CONF)
+ self.assertIn('interface ignore wildcard', config)
+ for interface in interfaces:
+ self.assertIn(f'interface listen {interface}', config)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py
index 0d6ec9ace..7be150ed2 100755
--- a/src/conf_mode/ntp.py
+++ b/src/conf_mode/ntp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 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
@@ -18,9 +18,11 @@ import os
from vyos.config import Config
from vyos.configverify import verify_vrf
-from vyos import ConfigError
+from vyos.configverify import verify_interface_exists
from vyos.util import call
+from vyos.util import get_interface_config
from vyos.template import render
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -48,6 +50,19 @@ def verify(ntp):
if 'allow_clients' in ntp and 'server' not in ntp:
raise ConfigError('NTP server not configured')
+ if 'interface' in ntp:
+ # If ntpd should listen on a given interface, ensure it exists
+ for interface in ntp['interface']:
+ verify_interface_exists(interface)
+
+ # If we run in a VRF, our interface must belong to this VRF, too
+ if 'vrf' in ntp:
+ tmp = get_interface_config(interface)
+ vrf_name = ntp['vrf']
+ if 'master' not in tmp or tmp['master'] != vrf_name:
+ raise ConfigError(f'NTP runs in VRF "{vrf_name}" - "{interface}" '\
+ f'does not belong to this VRF!')
+
verify_vrf(ntp)
return None