summaryrefslogtreecommitdiffstats
path: root/src/network/networkd-dhcp4.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-11-06 19:26:39 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-11-11 03:53:24 +0100
commit82df2e0f0496834064f32e4f09cc32728c1cbddd (patch)
tree262b813819d886ffa0c7ec380277237087a8d67a /src/network/networkd-dhcp4.c
parentnetwork: drop static configs later (diff)
downloadsystemd-82df2e0f0496834064f32e4f09cc32728c1cbddd.tar.xz
systemd-82df2e0f0496834064f32e4f09cc32728c1cbddd.zip
network: make 'networkctl reconfigure' work safely even when KeepConfiguration=dhcp or yes
Previously, even if KeepConfiguration=dhcp or yes is specified in the new .network file, dynamic configurations like DHCP address and routes were dropped when 'networkctl reconfigure INTERFACE' is invoked. If the setting is specified, let's gracefully handle the dynamic configurations. Then, 'networkctl reconfigure' can be also used for an interface that has critical connections.
Diffstat (limited to 'src/network/networkd-dhcp4.c')
-rw-r--r--src/network/networkd-dhcp4.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index dae1a7b7f4..684580f5b6 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1837,15 +1837,22 @@ int link_drop_dhcp4_config(Link *link, Network *network) {
int ret = 0;
assert(link);
- assert(network);
+ assert(link->network);
- if (!link_dhcp4_enabled(link))
- return 0; /* Currently DHCPv4 client is not enabled, there is nothing we need to drop. */
+ if (link->network == network)
+ return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
- if (!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4))
- /* Currently enabled but will be disabled. Stop the client and drop the lease. */
+ if (!link_dhcp4_enabled(link)) {
+ /* DHCP client is disabled. Stop the client if it is running and drop the lease. */
ret = sd_dhcp_client_stop(link->dhcp_client);
+ /* Also explicitly drop DHCPv4 address and routes. Why? This is for the case when the DHCPv4
+ * client was enabled on the previous invocation of networkd, but when it is restarted, a new
+ * .network file may match to the interface, and DHCPv4 client may be disabled. In that case,
+ * the DHCPv4 client is not running, hence sd_dhcp_client_stop() in the above does nothing. */
+ RET_GATHER(ret, dhcp4_remove_address_and_routes(link, /* only_marked = */ false));
+ }
+
/* Even if the client is currently enabled and also enabled in the new .network file, detailed
* settings for the client may be different. Let's unref() the client. But do not unref() the lease.
* it will be unref()ed later when a new lease is acquired. */