summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2026-08-14 14:04:48 +0100
committerGitHub <noreply@github.com>2026-08-14 14:04:48 +0100
commitc30f15ae89e9c67d065cc033131da44bd8b4d9c8 (patch)
treeeb5a638829f48855eea7bda3bc88dd19d951f8d7 /src
parent0775edcd1eaa668d789f0ee9d00da14f11e7c1dd (diff)
parentd3b48b76bd71fec1d09db6c72963de797f8ccb93 (diff)
downloadvyos-1x-c30f15ae89e9c67d065cc033131da44bd8b4d9c8.tar.gz
vyos-1x-c30f15ae89e9c67d065cc033131da44bd8b4d9c8.zip
Merge pull request #5371 from ruben-herold/T9159-ntp-source-address
ntp: T9159: add source-address option for client requests
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/service_ntp.py50
1 files changed, 47 insertions, 3 deletions
diff --git a/src/conf_mode/service_ntp.py b/src/conf_mode/service_ntp.py
index e734eeb76..66cf775a3 100755
--- a/src/conf_mode/service_ntp.py
+++ b/src/conf_mode/service_ntp.py
@@ -25,6 +25,7 @@ from vyos.netlink import timestamp
from vyos.utils.process import call
from vyos.utils.permission import chmod_750
from vyos.utils.network import get_interface_config
+from vyos.utils.network import is_addr_assigned
from vyos.template import render
from vyos.template import is_ipv4
from vyos import ConfigError
@@ -49,7 +50,8 @@ def get_config(config=None):
ntp['user'] = user_group
tmp = is_node_changed(conf, base + ['vrf'])
- if tmp: ntp.update({'restart_required': {}})
+ if tmp:
+ ntp.update({'restart_required': {}})
# We have gathered the dict representation of the CLI, but there are default
# options which we need to update into the dictionary retrieved.
@@ -81,6 +83,22 @@ def verify(ntp):
raise ConfigError(f'NTP runs in VRF "{vrf_name}" - "{interface}" '\
f'does not belong to this VRF!')
+ if 'source_interface' in ntp:
+ # If outgoing NTP client requests should be bound to a given
+ # interface (device), ensure it exists
+ source_interface = ntp['source_interface']
+ verify_interface_exists(ntp, source_interface)
+
+ # If we run in a VRF, our source interface must belong to this VRF, too
+ if 'vrf' in ntp:
+ tmp = get_interface_config(source_interface)
+ vrf_name = ntp['vrf']
+ if 'master' not in tmp or tmp['master'] != vrf_name:
+ raise ConfigError(
+ f'NTP runs in VRF "{vrf_name}" - "{source_interface}" '
+ f'does not belong to this VRF!'
+ )
+
if 'listen_address' in ntp:
ipv4_addresses = 0
ipv6_addresses = 0
@@ -90,9 +108,35 @@ def verify(ntp):
else:
ipv6_addresses += 1
if ipv4_addresses > 1:
- raise ConfigError(f'NTP Only admits one ipv4 value for listen-address parameter ')
+ raise ConfigError(
+ 'NTP Only admits one ipv4 value for listen-address parameter'
+ )
+ if ipv6_addresses > 1:
+ raise ConfigError(
+ 'NTP Only admits one ipv6 value for listen-address parameter'
+ )
+
+ if 'source_address' in ntp:
+ ipv4_addresses = 0
+ ipv6_addresses = 0
+ vrf = ntp.get('vrf')
+ for address in ntp['source_address']:
+ if is_ipv4(address):
+ ipv4_addresses += 1
+ else:
+ ipv6_addresses += 1
+ if not is_addr_assigned(address, vrf):
+ raise ConfigError(
+ f'NTP source-address "{address}" not assigned ' 'to any interface!'
+ )
+ if ipv4_addresses > 1:
+ raise ConfigError(
+ 'NTP Only admits one ipv4 value for source-address parameter'
+ )
if ipv6_addresses > 1:
- raise ConfigError(f'NTP Only admits one ipv6 value for listen-address parameter ')
+ raise ConfigError(
+ 'NTP Only admits one ipv6 value for source-address parameter'
+ )
if 'server' in ntp:
for host, server in ntp['server'].items():