summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/dhcp-client/daemon-options.j24
-rw-r--r--data/templates/dhcp-client/override.conf.j215
-rw-r--r--python/vyos/configdict.py4
-rw-r--r--python/vyos/ifconfig/interface.py52
-rw-r--r--src/systemd/dhclient@.service7
5 files changed, 48 insertions, 34 deletions
diff --git a/data/templates/dhcp-client/daemon-options.j2 b/data/templates/dhcp-client/daemon-options.j2
deleted file mode 100644
index b21ad08ab..000000000
--- a/data/templates/dhcp-client/daemon-options.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-### Autogenerated by interface.py ###
-{% set if_metric = '-e IF_METRIC=' ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is vyos_defined else '' %}
-DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ ifname }}.conf -pf /var/lib/dhcp/dhclient_{{ ifname }}.pid -lf /var/lib/dhcp/dhclient_{{ ifname }}.leases {{ if_metric }} {{ ifname }}"
-
diff --git a/data/templates/dhcp-client/override.conf.j2 b/data/templates/dhcp-client/override.conf.j2
new file mode 100644
index 000000000..fcb23cb52
--- /dev/null
+++ b/data/templates/dhcp-client/override.conf.j2
@@ -0,0 +1,15 @@
+### Autogenerated by interface.py ###
+{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %}
+{% set if_metric = '-e IF_METRIC=' ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is vyos_defined else '' %}
+{% set dhclient_options = '-d -nw -cf /var/lib/dhcp/dhclient_' ~ ifname ~ '.conf -pf /var/lib/dhcp/dhclient_' ~ ifname ~ '.pid -lf /var/lib/dhcp/dhclient_' ~ ifname ~ '.leases ' ~ if_metric %}
+
+[Unit]
+ConditionPathExists={{ isc_dhclient_dir }}/dhclient_%i.conf
+
+[Service]
+ExecStart=
+ExecStart={{ vrf_command }}/sbin/dhclient -4 {{ dhclient_options }} {{ ifname }}
+ExecStop=
+ExecStop={{ vrf_command }}/sbin/dhclient -4 {{ dhclient_options }} {{ ifname }} -r
+WorkingDirectory={{ isc_dhclient_dir }}
+PIDFile={{ isc_dhclient_dir }}/dhclient_%i.pid
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index f642d38f2..fd7b1b997 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -455,6 +455,10 @@ def get_interface_dict(config, base, ifname='', recursive_defaults=True):
dhcp = is_node_changed(config, base + [ifname, 'dhcp-options'])
if dhcp: dict.update({'dhcp_options_changed' : {}})
+ # Changine interface VRF assignemnts require a DHCP restart, too
+ dhcp = is_node_changed(config, base + [ifname, 'vrf'])
+ if dhcp: dict.update({'dhcp_options_changed' : {}})
+
# Some interfaces come with a source_interface which must also not be part
# of any other bond or bridge interface as it is exclusivly assigned as the
# Kernels "lower" interface to this new "virtual/upper" interface.
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index fe8752d24..c2787136d 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -1242,40 +1242,44 @@ class Interface(Control):
ifname = self.ifname
config_base = directories['isc_dhclient_dir'] + '/dhclient'
- config_file = f'{config_base}_{ifname}.conf'
- options_file = f'{config_base}_{ifname}.options'
- pid_file = f'{config_base}_{ifname}.pid'
- lease_file = f'{config_base}_{ifname}.leases'
+ dhclient_config_file = f'{config_base}_{ifname}.conf'
+ dhclient_lease_file = f'{config_base}_{ifname}.leases'
+ systemd_override_file = f'/run/systemd/system/dhclient@{ifname}.service.d/10-override.conf'
systemd_service = f'dhclient@{ifname}.service'
+ 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
# the DHCP client is started the interface will be placed in u/u state.
# This is not what we intended to do when disabling an interface.
- if enable and 'disable' not in self._config:
- if dict_search('dhcp_options.host_name', self._config) == None:
+ if enable and 'disable' not in self.config:
+ if dict_search('dhcp_options.host_name', self.config) == None:
# read configured system hostname.
# maybe change to vyos hostd client ???
hostname = 'vyos'
with open('/etc/hostname', 'r') as f:
hostname = f.read().rstrip('\n')
tmp = {'dhcp_options' : { 'host_name' : hostname}}
- self._config = dict_merge(tmp, self._config)
+ self.config = dict_merge(tmp, self.config)
+
+ render(systemd_override_file, 'dhcp-client/override.conf.j2', self.config)
+ render(dhclient_config_file, 'dhcp-client/ipv4.j2', self.config)
- render(options_file, 'dhcp-client/daemon-options.j2', self._config)
- render(config_file, 'dhcp-client/ipv4.j2', self._config)
+ # Reload systemd unit definitons as some options are dynamically generated
+ self._cmd('systemctl daemon-reload')
# When the DHCP client is restarted a brief outage will occur, as
# the old lease is released a new one is acquired (T4203). We will
# only restart DHCP client if it's option changed, or if it's not
# running, but it should be running (e.g. on system startup)
- if 'dhcp_options_changed' in self._config or not is_systemd_service_active(systemd_service):
+ if 'dhcp_options_changed' in self.config or not is_systemd_service_active(systemd_service):
return self._cmd(f'systemctl restart {systemd_service}')
return None
else:
if is_systemd_service_active(systemd_service):
self._cmd(f'systemctl stop {systemd_service}')
# cleanup old config files
- for file in [config_file, options_file, pid_file, lease_file]:
+ for file in [dhclient_config_file, systemd_override_file, dhclient_lease_file]:
if os.path.isfile(file):
os.remove(file)
@@ -1292,9 +1296,9 @@ class Interface(Control):
options_file = f'/run/dhcp6c/dhcp6c.{ifname}.options'
systemd_service = f'dhcp6c@{ifname}.service'
- if enable and 'disable' not in self._config:
- render(options_file, 'dhcp-client/dhcp6c_daemon-options.j2', self._config)
- render(config_file, 'dhcp-client/ipv6.j2', self._config)
+ if enable and 'disable' not in self.config:
+ render(options_file, 'dhcp-client/dhcp6c_daemon-options.j2', self.config)
+ render(config_file, 'dhcp-client/ipv6.j2', self.config)
# We must ignore any return codes. This is required to enable
# DHCPv6-PD for interfaces which are yet not up and running.
@@ -1311,20 +1315,20 @@ class Interface(Control):
# - https://man7.org/linux/man-pages/man8/tc-mirred.8.html
# Depening if we are the source or the target interface of the port
# mirror we need to setup some variables.
- source_if = self._config['ifname']
+ source_if = self.config['ifname']
mirror_config = None
- if 'mirror' in self._config:
- mirror_config = self._config['mirror']
- if 'is_mirror_intf' in self._config:
- source_if = next(iter(self._config['is_mirror_intf']))
- mirror_config = self._config['is_mirror_intf'][source_if].get('mirror', None)
+ if 'mirror' in self.config:
+ mirror_config = self.config['mirror']
+ if 'is_mirror_intf' in self.config:
+ source_if = next(iter(self.config['is_mirror_intf']))
+ mirror_config = self.config['is_mirror_intf'][source_if].get('mirror', None)
redirect_config = None
# clear existing ingess - ignore errors (e.g. "Error: Cannot find specified
# qdisc on specified device") - we simply cleanup all stuff here
- if not 'traffic_policy' in self._config:
+ if not 'traffic_policy' in self.config:
self._popen(f'tc qdisc del dev {source_if} parent ffff: 2>/dev/null');
self._popen(f'tc qdisc del dev {source_if} parent 1: 2>/dev/null');
@@ -1348,11 +1352,11 @@ class Interface(Control):
if err: print('tc qdisc(filter for mirror port failed')
# Apply interface traffic redirection policy
- elif 'redirect' in self._config:
+ elif 'redirect' in self.config:
_, err = self._popen(f'tc qdisc add dev {source_if} handle ffff: ingress')
if err: print(f'tc qdisc add for redirect failed!')
- target_if = self._config['redirect']
+ target_if = self.config['redirect']
_, err = self._popen(f'tc filter add dev {source_if} parent ffff: protocol '\
f'all prio 10 u32 match u32 0 0 flowid 1:1 action mirred '\
f'egress redirect dev {target_if}')
@@ -1371,7 +1375,7 @@ class Interface(Control):
# Cache the configuration - it will be reused inside e.g. DHCP handler
# XXX: maybe pass the option via __init__ in the future and rename this
# method to apply()?
- self._config = config
+ self.config = config
# Change interface MAC address - re-set to real hardware address (hw-id)
# if custom mac is removed. Skip if bond member.
diff --git a/src/systemd/dhclient@.service b/src/systemd/dhclient@.service
index 4711a0d70..6d41de232 100644
--- a/src/systemd/dhclient@.service
+++ b/src/systemd/dhclient@.service
@@ -1,18 +1,13 @@
[Unit]
Description=DHCP client on %i
Documentation=man:dhclient(8)
-ConditionPathExists=/var/lib/dhcp/dhclient_%i.conf
-ConditionPathExists=/var/lib/dhcp/dhclient_%i.options
StartLimitIntervalSec=0
After=vyos-router.service
[Service]
-WorkingDirectory=/var/lib/dhcp
Type=exec
-EnvironmentFile=-/var/lib/dhcp/dhclient_%i.options
-PIDFile=/var/lib/dhcp/dhclient_%i.pid
ExecStart=/sbin/dhclient -4 -d $DHCLIENT_OPTS
-ExecStop=/sbin/dhclient -4 $DHCLIENT_OPTS -r
+ExecStop=/sbin/dhclient -4 -d $DHCLIENT_OPTS -r
Restart=always
RestartPreventExitStatus=
RestartSec=10