From 8a15595e1ac3d9e3e15f40f8b2256768f8d71f0c Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 5 Aug 2023 09:02:59 +0200 Subject: dhcpv6: T5428: client renewal fails when running inside VRF --- data/templates/dhcp-client/dhcp6c_daemon-options.j2 | 2 -- data/templates/dhcp-client/ipv6.override.conf.j2 | 12 ++++++++++++ python/vyos/defaults.py | 3 ++- python/vyos/ifconfig/interface.py | 14 +++++++++++--- src/systemd/dhcp6c@.service | 12 ++++++------ 5 files changed, 31 insertions(+), 12 deletions(-) delete mode 100644 data/templates/dhcp-client/dhcp6c_daemon-options.j2 create mode 100644 data/templates/dhcp-client/ipv6.override.conf.j2 diff --git a/data/templates/dhcp-client/dhcp6c_daemon-options.j2 b/data/templates/dhcp-client/dhcp6c_daemon-options.j2 deleted file mode 100644 index d33d418fc..000000000 --- a/data/templates/dhcp-client/dhcp6c_daemon-options.j2 +++ /dev/null @@ -1,2 +0,0 @@ -{% set no_release = '-n' if dhcpv6_options.no_release is vyos_defined else '' %} -DHCP6C_OPTS="-D -k /run/dhcp6c/dhcp6c.{{ ifname }}.sock -c /run/dhcp6c/dhcp6c.{{ ifname }}.conf -p /run/dhcp6c/dhcp6c.{{ ifname }}.pid {{ no_release }} {{ ifname }}" diff --git a/data/templates/dhcp-client/ipv6.override.conf.j2 b/data/templates/dhcp-client/ipv6.override.conf.j2 new file mode 100644 index 000000000..b0c0e0544 --- /dev/null +++ b/data/templates/dhcp-client/ipv6.override.conf.j2 @@ -0,0 +1,12 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +{% set no_release = '-n' if dhcpv6_options.no_release is vyos_defined else '' %} +{% set dhcp6c_options = '-D -k ' ~ dhcp6_client_dir ~ '/dhcp6c.' ~ ifname ~ '.sock -c ' ~ dhcp6_client_dir ~ '/dhcp6c.' ~ ifname ~ '.conf -p ' ~ dhcp6_client_dir ~ '/dhcp6c.' ~ ifname ~ '.pid ' ~ no_release %} + +[Unit] +ConditionPathExists={{ dhcp6_client_dir }}/dhcp6c.%i.conf + +[Service] +ExecStart= +ExecStart={{ vrf_command }}/usr/sbin/dhcp6c {{ dhcp6c_options }} {{ ifname }} +WorkingDirectory={{ dhcp6_client_dir }} +PIDFile={{ dhcp6_client_dir }}/dhcp6c.%i.pid diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py index cb3e9b654..a5314790d 100644 --- a/python/vyos/defaults.py +++ b/python/vyos/defaults.py @@ -33,7 +33,8 @@ directories = { 'api_client_op': f'{base_dir}/services/api/graphql/graphql/client_op/', 'api_templates': f'{base_dir}/services/api/graphql/session/templates/', 'vyos_udev_dir' : '/run/udev/vyos', - 'isc_dhclient_dir' : '/run/dhclient' + 'isc_dhclient_dir' : '/run/dhclient', + 'dhcp6_client_dir' : '/run/dhcp6c', } config_status = '/tmp/vyos-config-status' diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index c2787136d..48eb68cae 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -1247,6 +1247,7 @@ class Interface(Control): systemd_override_file = f'/run/systemd/system/dhclient@{ifname}.service.d/10-override.conf' systemd_service = f'dhclient@{ifname}.service' + # Rendered client configuration files require the apsolute config path self.config['isc_dhclient_dir'] = directories['isc_dhclient_dir'] # 'up' check is mandatory b/c even if the interface is A/D, as soon as @@ -1292,14 +1293,21 @@ class Interface(Control): raise ValueError() ifname = self.ifname - config_file = f'/run/dhcp6c/dhcp6c.{ifname}.conf' - options_file = f'/run/dhcp6c/dhcp6c.{ifname}.options' + config_base = directories['dhcp6_client_dir'] + config_file = f'{config_base}/dhcp6c.{ifname}.conf' + systemd_override_file = f'/run/systemd/system/dhcp6c@{ifname}.service.d/10-override.conf' systemd_service = f'dhcp6c@{ifname}.service' + # Rendered client configuration files require the apsolute config path + self.config['dhcp6_client_dir'] = directories['dhcp6_client_dir'] + if enable and 'disable' not in self.config: - render(options_file, 'dhcp-client/dhcp6c_daemon-options.j2', self.config) + render(systemd_override_file, 'dhcp-client/ipv6.override.conf.j2', self.config) render(config_file, 'dhcp-client/ipv6.j2', self.config) + # Reload systemd unit definitons as some options are dynamically generated + self._cmd('systemctl daemon-reload') + # We must ignore any return codes. This is required to enable # DHCPv6-PD for interfaces which are yet not up and running. return self._popen(f'systemctl restart {systemd_service}') diff --git a/src/systemd/dhcp6c@.service b/src/systemd/dhcp6c@.service index 495cb7e26..f634bd944 100644 --- a/src/systemd/dhcp6c@.service +++ b/src/systemd/dhcp6c@.service @@ -1,19 +1,19 @@ [Unit] Description=WIDE DHCPv6 client on %i Documentation=man:dhcp6c(8) man:dhcp6c.conf(5) -ConditionPathExists=/run/dhcp6c/dhcp6c.%i.conf -ConditionPathExists=/run/dhcp6c/dhcp6c.%i.options -After=vyos-router.service StartLimitIntervalSec=0 +After=vyos-router.service [Service] +Type=forking WorkingDirectory=/run/dhcp6c EnvironmentFile=-/run/dhcp6c/dhcp6c.%i.options -Type=forking PIDFile=/run/dhcp6c/dhcp6c.%i.pid ExecStart=/usr/sbin/dhcp6c $DHCP6C_OPTS -Restart=on-failure -RestartSec=20 +Restart=always +RestartPreventExitStatus= +RestartSec=10 +RuntimeDirectoryPreserve=yes [Install] WantedBy=multi-user.target -- cgit v1.2.3