1
0
mirror of https://github.com/systemd/systemd.git synced 2025-08-30 05:49:54 +03:00

network/dhcp-server: introduce PersistLeases= setting

Requested at https://github.com/systemd/systemd/pull/31772#issuecomment-2000053357.
This commit is contained in:
Yu Watanabe
2024-03-16 02:32:50 +09:00
committed by Luca Boccassi
parent f824cd660a
commit a3ed665a29
10 changed files with 71 additions and 5 deletions

View File

@ -283,6 +283,27 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
</variablelist> </variablelist>
</refsect1> </refsect1>
<refsect1>
<title>[DHCPServer] Section Options</title>
<para>This section configures the default setting of the DHCP server. The following options are available
in the [DHCPServer] section:</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>PersistLeases=</varname></term>
<listitem>
<para>Specifies the default value for per-network <varname>PersistLeases=</varname>.
Takes a boolean. See for details in
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
Defaults to <literal>yes</literal>.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para><simplelist type="inline"> <para><simplelist type="inline">

View File

@ -428,9 +428,12 @@
Defaults to <literal>no</literal>. Further settings for the DHCP server may be set in the Defaults to <literal>no</literal>. Further settings for the DHCP server may be set in the
[DHCPServer] section described below.</para> [DHCPServer] section described below.</para>
<para>Even if this is enabled, the DHCP server will not be started automatically. It will be <para>Even if this is enabled, the DHCP server will not be started automatically and wait for the
started after <filename>systemd-networkd-persistent-storage.service</filename> is started, which persistent storage being ready to load/save leases in the storage, unless
calls <command>networkctl persistent-storage yes</command>. See <varname>RelayTarget=</varname> or <varname>PersistLeases=no</varname> are specified in the
[DHCPServer] section. 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> <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for more details.</para> for more details.</para>
@ -3903,6 +3906,22 @@ ServerAddress=192.168.0.1/24</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>PersistLeases=</varname></term>
<listitem>
<para>Takes a boolean. When true, the DHCP server will load and save leases in the persistent
storage. When false, the DHCP server will neither load nor save leases in the persistent storage.
Hence, bound leases will be lost when the interface is reconfigured e.g. by
<command>networkctl reconfigure</command>, or <filename>systemd-networkd.service</filename>
is restarted. That may cause address conflict on the network. So, please take an extra care when
disable this setting. When unspecified, the value specified in the same setting in
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which defaults to <literal>yes</literal>, will be used.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -147,6 +147,20 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
return 0; return 0;
} }
static bool dhcp_server_persist_leases(Link *link) {
assert(link);
assert(link->manager);
assert(link->network);
if (in4_addr_is_set(&link->network->dhcp_server_relay_target))
return false; /* On relay mode. Nothing saved in the persistent storage. */
if (link->network->dhcp_server_persist_leases >= 0)
return link->network->dhcp_server_persist_leases;
return link->manager->dhcp_server_persist_leases;
}
int address_acquire_from_dhcp_server_leases_file(Link *link, const Address *address, union in_addr_union *ret) { int address_acquire_from_dhcp_server_leases_file(Link *link, const Address *address, union in_addr_union *ret) {
struct in_addr a; struct in_addr a;
uint8_t prefixlen; uint8_t prefixlen;
@ -168,6 +182,9 @@ int address_acquire_from_dhcp_server_leases_file(Link *link, const Address *addr
if (!link_dhcp4_server_enabled(link)) if (!link_dhcp4_server_enabled(link))
return -ENOENT; return -ENOENT;
if (!dhcp_server_persist_leases(link))
return -ENOENT;
if (link->manager->persistent_storage_fd < 0) if (link->manager->persistent_storage_fd < 0)
return -EBUSY; /* The persistent storage is not ready, try later again. */ return -EBUSY; /* The persistent storage is not ready, try later again. */
@ -208,7 +225,7 @@ int link_start_dhcp4_server(Link *link) {
/* TODO: Maybe, also check the system time is synced. If the system does not have RTC battery, then /* 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 * the realtime clock in not usable in the early boot stage, and all saved leases may be wrongly
* handled as expired and dropped. */ * handled as expired and dropped. */
if (!sd_dhcp_server_is_in_relay_mode(link->dhcp_server)) { if (dhcp_server_persist_leases(link)) {
if (link->manager->persistent_storage_fd < 0) if (link->manager->persistent_storage_fd < 0)
return 0; /* persistent storage is not ready. */ return 0; /* persistent storage is not ready. */
@ -239,7 +256,7 @@ void manager_toggle_dhcp4_server_state(Manager *manager, bool start) {
HASHMAP_FOREACH(link, manager->links_by_index) { HASHMAP_FOREACH(link, manager->links_by_index) {
if (!link->dhcp_server) if (!link->dhcp_server)
continue; continue;
if (sd_dhcp_server_is_in_relay_mode(link->dhcp_server)) if (!dhcp_server_persist_leases(link))
continue; continue;
/* Even if 'start' is true, first we need to stop the server. Otherwise, we cannot (re)set /* Even if 'start' is true, first we need to stop the server. Otherwise, we cannot (re)set

View File

@ -34,6 +34,7 @@ DHCPv4.DUIDType, config_parse_duid_type,
DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp_duid) DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp_duid)
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp6_duid) DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp6_duid)
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp6_duid) DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp6_duid)
DHCPServer.PersistLeases, config_parse_bool, 0, offsetof(Manager, dhcp_server_persist_leases)
/* Deprecated */ /* Deprecated */
DHCP.DUIDType, config_parse_manager_duid_type, 0, 0 DHCP.DUIDType, config_parse_manager_duid_type, 0, 0
DHCP.DUIDRawData, config_parse_manager_duid_rawdata, 0, 0 DHCP.DUIDRawData, config_parse_manager_duid_rawdata, 0, 0

View File

@ -602,6 +602,7 @@ int manager_new(Manager **ret, bool test_mode) {
.dhcp_duid.type = DUID_TYPE_EN, .dhcp_duid.type = DUID_TYPE_EN,
.dhcp6_duid.type = DUID_TYPE_EN, .dhcp6_duid.type = DUID_TYPE_EN,
.duid_product_uuid.type = DUID_TYPE_UUID, .duid_product_uuid.type = DUID_TYPE_UUID,
.dhcp_server_persist_leases = true,
.ip_forwarding = { -1, -1, }, .ip_forwarding = { -1, -1, },
}; };

View File

@ -42,6 +42,7 @@ struct Manager {
bool manage_foreign_routes; bool manage_foreign_routes;
bool manage_foreign_rules; bool manage_foreign_rules;
bool manage_foreign_nexthops; bool manage_foreign_nexthops;
bool dhcp_server_persist_leases;
Set *dirty_links; Set *dirty_links;
Set *new_wlan_ifindices; Set *new_wlan_ifindices;

View File

@ -350,6 +350,7 @@ DHCPServer.BootServerAddress, config_parse_in_addr_non_null,
DHCPServer.BootServerName, config_parse_dns_name, 0, offsetof(Network, dhcp_server_boot_server_name) DHCPServer.BootServerName, config_parse_dns_name, 0, offsetof(Network, dhcp_server_boot_server_name)
DHCPServer.BootFilename, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, dhcp_server_boot_filename) DHCPServer.BootFilename, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, dhcp_server_boot_filename)
DHCPServer.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp_server_rapid_commit) DHCPServer.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp_server_rapid_commit)
SHCPServer.PersistLeases, config_parse_tristate, 0, offsetof(Network, dhcp_server_persist_leases)
DHCPServerStaticLease.Address, config_parse_dhcp_static_lease_address, 0, 0 DHCPServerStaticLease.Address, config_parse_dhcp_static_lease_address, 0, 0
DHCPServerStaticLease.MACAddress, config_parse_dhcp_static_lease_hwaddr, 0, 0 DHCPServerStaticLease.MACAddress, config_parse_dhcp_static_lease_hwaddr, 0, 0
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost) Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)

View File

@ -426,6 +426,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_server_emit_router = true, .dhcp_server_emit_router = true,
.dhcp_server_emit_timezone = true, .dhcp_server_emit_timezone = true,
.dhcp_server_rapid_commit = true, .dhcp_server_rapid_commit = true,
.dhcp_server_persist_leases = -1,
.router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC, .router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC,
.router_dns_lifetime_usec = RADV_DEFAULT_VALID_LIFETIME_USEC, .router_dns_lifetime_usec = RADV_DEFAULT_VALID_LIFETIME_USEC,

View File

@ -230,6 +230,7 @@ struct Network {
char *dhcp_server_boot_filename; char *dhcp_server_boot_filename;
usec_t dhcp_server_ipv6_only_preferred_usec; usec_t dhcp_server_ipv6_only_preferred_usec;
bool dhcp_server_rapid_commit; bool dhcp_server_rapid_commit;
int dhcp_server_persist_leases;
/* link-local addressing support */ /* link-local addressing support */
AddressFamily link_local; AddressFamily link_local;

View File

@ -32,3 +32,6 @@
[DHCPv6] [DHCPv6]
#DUIDType=vendor #DUIDType=vendor
#DUIDRawData= #DUIDRawData=
[DHCPServer]
#PersistLeases=yes