diff options
-rw-r--r-- | man/systemd.network.xml | 8 | ||||
-rw-r--r-- | src/network/networkd-dhcp-server.c | 63 | ||||
-rw-r--r-- | src/network/networkd-dhcp-server.h | 3 | ||||
-rw-r--r-- | src/network/networkd-manager-varlink.c | 3 |
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); } |