summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml8
-rw-r--r--src/network/networkd-dhcp-server.c63
-rw-r--r--src/network/networkd-dhcp-server.h3
-rw-r--r--src/network/networkd-manager-varlink.c3
4 files changed, 74 insertions, 3 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 9be90e17c5..472add2f98 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -428,7 +428,13 @@
Defaults to <literal>no</literal>. Further settings for the DHCP server may be set in the
[DHCPServer] section described below.</para>
- <xi:include href="version-info.xml" xpointer="v215"/>
+ <para>Even if this is enabled, the DHCP server will not be started automatically. It will be
+ started after <filename>systemd-networkd-persistent-storage.service</filename> is started, which
+ calls <command>networkctl persistent-storage yes</command>. See
+ <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ for more details.</para>
+
+ <xi:include href="version-info.xml" xpointer="v215"/>
</listitem>
</varlistentry>
diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c
index 81ef6d80f7..57019400e6 100644
--- a/src/network/networkd-dhcp-server.c
+++ b/src/network/networkd-dhcp-server.c
@@ -20,6 +20,7 @@
#include "networkd-queue.h"
#include "networkd-route-util.h"
#include "parse-util.h"
+#include "path-util.h"
#include "socket-netlink.h"
#include "string-table.h"
#include "string-util.h"
@@ -143,6 +144,55 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
return 0;
}
+static int link_start_dhcp4_server(Link *link) {
+ int r;
+
+ assert(link);
+ assert(link->manager);
+
+ if (!link->dhcp_server)
+ return 0; /* Not configured yet. */
+
+ if (!link_has_carrier(link))
+ return 0;
+
+ /* TODO: Maybe, also check the system time is synced. If the system does not have RTC battery, then
+ * the realtime clock in not usable in the early boot stage, and all saved leases may be wrongly
+ * handled as expired and dropped. */
+ if (!sd_dhcp_server_is_in_relay_mode(link->dhcp_server) &&
+ !link->manager->persistent_storage_is_ready)
+ return 0;
+
+ r = sd_dhcp_server_start(link->dhcp_server);
+ if (r < 0)
+ return r;
+
+ log_link_debug(link, "Offering DHCPv4 leases");
+ return 0;
+}
+
+void manager_toggle_dhcp4_server_state(Manager *manager, bool start) {
+ Link *link;
+ int r;
+
+ assert(manager);
+
+ HASHMAP_FOREACH(link, manager->links_by_index) {
+ if (!link->dhcp_server)
+ continue;
+ if (sd_dhcp_server_is_in_relay_mode(link->dhcp_server))
+ continue;
+
+ if (start)
+ r = link_start_dhcp4_server(link);
+ else
+ r = sd_dhcp_server_stop(link->dhcp_server);
+ if (r < 0)
+ log_link_debug_errno(link, r, "Failed to %s DHCP server, ignoring: %m",
+ start ? "start" : "stop");
+ }
+}
+
static int dhcp_server_find_uplink(Link *link, Link **ret) {
assert(link);
@@ -522,11 +572,20 @@ static int dhcp4_server_configure(Link *link) {
return log_link_error_errno(link, r, "Failed to set DHCPv4 static lease for DHCP server: %m");
}
- r = sd_dhcp_server_start(link->dhcp_server);
+ if (!sd_dhcp_server_is_in_relay_mode(link->dhcp_server)) {
+ _cleanup_free_ char *lease_file = path_join("/var/lib/systemd/network/dhcp-server-lease/", link->ifname);
+ if (!lease_file)
+ return log_oom();
+
+ r = sd_dhcp_server_set_lease_file(link->dhcp_server, lease_file);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Failed to load DHCPv4 server leases, ignoring: %m");
+ }
+
+ r = link_start_dhcp4_server(link);
if (r < 0)
return log_link_error_errno(link, r, "Could not start DHCPv4 server instance: %m");
- log_link_debug(link, "Offering DHCPv4 leases");
return 0;
}
diff --git a/src/network/networkd-dhcp-server.h b/src/network/networkd-dhcp-server.h
index 960232ade6..b845a6d1c7 100644
--- a/src/network/networkd-dhcp-server.h
+++ b/src/network/networkd-dhcp-server.h
@@ -5,12 +5,15 @@
#include "set.h"
typedef struct Link Link;
+typedef struct Manager Manager;
typedef struct Network Network;
int network_adjust_dhcp_server(Network *network, Set **addresses);
int link_request_dhcp_server(Link *link);
+void manager_toggle_dhcp4_server_state(Manager *manager, bool start);
+
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_address);
diff --git a/src/network/networkd-manager-varlink.c b/src/network/networkd-manager-varlink.c
index a85751491e..f3b265fed5 100644
--- a/src/network/networkd-manager-varlink.c
+++ b/src/network/networkd-manager-varlink.c
@@ -5,6 +5,7 @@
#include "bus-polkit.h"
#include "fs-util.h"
#include "lldp-rx-internal.h"
+#include "networkd-dhcp-server.h"
#include "networkd-manager-varlink.h"
#include "stat-util.h"
#include "varlink.h"
@@ -211,6 +212,8 @@ static int vl_method_set_persistent_storage(Varlink *vlink, JsonVariant *paramet
log_debug_errno(errno, "Failed to remove /run/systemd/netif/persistent-storage-ready, ignoring: %m");
}
+ manager_toggle_dhcp4_server_state(manager, ready);
+
return varlink_reply(vlink, NULL);
}