diff options
-rw-r--r-- | data/templates/ntp/ntpd.conf.j2 | 13 | ||||
-rw-r--r-- | interface-definitions/ntp.xml.in | 1 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_system_ntp.py | 17 | ||||
-rwxr-xr-x | src/conf_mode/ntp.py | 19 |
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 |