mirror of
https://github.com/systemd/systemd
synced 2025-10-05 16:03:15 +02:00
network/dhcp-server: improvements for saving/loading leases (#37835)
This commit is contained in:
4
NEWS
4
NEWS
@@ -398,6 +398,10 @@ CHANGES WITH 258 in spe:
|
|||||||
networkd.conf. (Previously this had to be configured individually in
|
networkd.conf. (Previously this had to be configured individually in
|
||||||
each .network file.)
|
each .network file.)
|
||||||
|
|
||||||
|
* PersistLeases= setting in [DHCPServer] section now also accepts
|
||||||
|
"runtime", to make the DHCP server saves and loads bound leases on
|
||||||
|
the runtime storage.
|
||||||
|
|
||||||
* A new Preference= setting has been added to the [IPv6RoutePrefix]
|
* A new Preference= setting has been added to the [IPv6RoutePrefix]
|
||||||
section to configure the route preference field.
|
section to configure the route preference field.
|
||||||
|
|
||||||
|
@@ -404,7 +404,7 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
|
|||||||
<term><varname>PersistLeases=</varname></term>
|
<term><varname>PersistLeases=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Specifies the default value for per-network <varname>PersistLeases=</varname>.
|
<para>Specifies the default value for per-network <varname>PersistLeases=</varname>.
|
||||||
Takes a boolean. See for details in
|
Takes a boolean or special value <literal>runtime</literal>. See for details in
|
||||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
Defaults to <literal>yes</literal>.</para>
|
Defaults to <literal>yes</literal>.</para>
|
||||||
|
|
||||||
|
@@ -443,7 +443,7 @@
|
|||||||
|
|
||||||
<para>Even if this is enabled, the DHCP server will not be started automatically and wait for the
|
<para>Even if this is enabled, the DHCP server will not be started automatically and wait for the
|
||||||
persistent storage being ready to load/save leases in the storage, unless
|
persistent storage being ready to load/save leases in the storage, unless
|
||||||
<varname>RelayTarget=</varname> or <varname>PersistLeases=no</varname> are specified in the
|
<varname>RelayTarget=</varname> or <varname>PersistLeases=no/runtime</varname> are specified in the
|
||||||
[DHCPServer] section. It will be started after
|
[DHCPServer] section. It will be started after
|
||||||
<filename>systemd-networkd-persistent-storage.service</filename> is started, which calls
|
<filename>systemd-networkd-persistent-storage.service</filename> is started, which calls
|
||||||
<command>networkctl persistent-storage yes</command>. See
|
<command>networkctl persistent-storage yes</command>. See
|
||||||
@@ -4140,16 +4140,24 @@ ServerAddress=192.168.0.1/24</programlisting>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>PersistLeases=</varname></term>
|
<term><varname>PersistLeases=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Takes a boolean. When true, the DHCP server will load and save leases in the persistent
|
<para>Takes a boolean or special value <literal>runtime</literal>. When <literal>yes</literal>, the
|
||||||
storage. When false, the DHCP server will neither load nor save leases in the persistent storage.
|
DHCP server will load and save leases in the persistent storage. When <literal>runtime</literal>,
|
||||||
Hence, bound leases will be lost when the interface is reconfigured e.g. by
|
the DHCP server will load and save leases in the runtime storage, hence bound leases will be lost
|
||||||
|
when the runtime storage is cleared by e.g. by calling
|
||||||
|
<command>systemctl clean systemd-networkd.service</command> or the system is rebooted. When
|
||||||
|
<literal>no</literal>, 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
|
<command>networkctl reconfigure</command>, or
|
||||||
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
is restarted. That may cause address conflict on the network. So, please take an extra care when
|
is restarted. Using <literal>runtime</literal> and <literal>no</literal> may cause address conflict
|
||||||
disable this setting. When unspecified, the value specified in the same setting in
|
on the network after the leases are lost. 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>,
|
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
which defaults to <literal>yes</literal>, will be used.</para>
|
which defaults to <literal>yes</literal>, will be used.</para>
|
||||||
|
|
||||||
|
<para>When <varname>RelayTarget=</varname> is specified, this setting will be ignored and no leases
|
||||||
|
will be saved, as there will be no bound lease on the server.</para>
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v256"/>
|
<xi:include href="version-info.xml" xpointer="v256"/>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@@ -29,4 +29,4 @@ IPv6AcceptRA=no
|
|||||||
IPv6SendRA=yes
|
IPv6SendRA=yes
|
||||||
|
|
||||||
[DHCPServer]
|
[DHCPServer]
|
||||||
PersistLeases=no
|
PersistLeases=runtime
|
||||||
|
@@ -28,4 +28,4 @@ IPv6AcceptRA=no
|
|||||||
IPv6SendRA=yes
|
IPv6SendRA=yes
|
||||||
|
|
||||||
[DHCPServer]
|
[DHCPServer]
|
||||||
PersistLeases=no
|
PersistLeases=runtime
|
||||||
|
@@ -29,4 +29,4 @@ IPv6AcceptRA=no
|
|||||||
IPv6SendRA=yes
|
IPv6SendRA=yes
|
||||||
|
|
||||||
[DHCPServer]
|
[DHCPServer]
|
||||||
PersistLeases=no
|
PersistLeases=runtime
|
||||||
|
@@ -29,4 +29,4 @@ IPv6AcceptRA=no
|
|||||||
IPv6SendRA=yes
|
IPv6SendRA=yes
|
||||||
|
|
||||||
[DHCPServer]
|
[DHCPServer]
|
||||||
PersistLeases=no
|
PersistLeases=runtime
|
||||||
|
@@ -28,4 +28,4 @@ IPv6AcceptRA=no
|
|||||||
IPv6SendRA=yes
|
IPv6SendRA=yes
|
||||||
|
|
||||||
[DHCPServer]
|
[DHCPServer]
|
||||||
PersistLeases=no
|
PersistLeases=runtime
|
||||||
|
@@ -1605,9 +1605,13 @@ int sd_dhcp_server_set_lease_file(sd_dhcp_server *server, int dir_fd, const char
|
|||||||
if (!path_is_safe(path))
|
if (!path_is_safe(path))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
_cleanup_close_ int fd = fd_reopen(dir_fd, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
_cleanup_close_ int fd = AT_FDCWD; /* Unlike our usual coding style, AT_FDCWD needs to be set,
|
||||||
if (fd < 0)
|
* to pass a 'valid' fd. */
|
||||||
return fd;
|
if (dir_fd >= 0) {
|
||||||
|
fd = fd_reopen(dir_fd, O_CLOEXEC | O_DIRECTORY | O_PATH);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
r = free_and_strdup(&server->lease_file, path);
|
r = free_and_strdup(&server->lease_file, path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "socket-netlink.h"
|
#include "socket-netlink.h"
|
||||||
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
|
||||||
@@ -150,13 +151,13 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dhcp_server_persist_leases(Link *link) {
|
static DHCPServerPersistLeases link_get_dhcp_server_persist_leases(Link *link) {
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->manager);
|
assert(link->manager);
|
||||||
assert(link->network);
|
assert(link->network);
|
||||||
|
|
||||||
if (in4_addr_is_set(&link->network->dhcp_server_relay_target))
|
if (in4_addr_is_set(&link->network->dhcp_server_relay_target))
|
||||||
return false; /* On relay mode. Nothing saved in the persistent storage. */
|
return DHCP_SERVER_PERSIST_LEASES_NO; /* On relay mode. Nothing saved in the persistent storage. */
|
||||||
|
|
||||||
if (link->network->dhcp_server_persist_leases >= 0)
|
if (link->network->dhcp_server_persist_leases >= 0)
|
||||||
return link->network->dhcp_server_persist_leases;
|
return link->network->dhcp_server_persist_leases;
|
||||||
@@ -164,9 +165,47 @@ static bool dhcp_server_persist_leases(Link *link) {
|
|||||||
return link->manager->dhcp_server_persist_leases;
|
return link->manager->dhcp_server_persist_leases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int link_get_dhcp_server_lease_file(Link *link, int *ret_dir_fd, char **ret_path) {
|
||||||
|
assert(link);
|
||||||
|
assert(link->ifname);
|
||||||
|
assert(ret_dir_fd);
|
||||||
|
assert(ret_path);
|
||||||
|
|
||||||
|
/* This does not copy fd. Do not close fd stored in ret_dir_fd. */
|
||||||
|
|
||||||
|
switch (link_get_dhcp_server_persist_leases(link)) {
|
||||||
|
case DHCP_SERVER_PERSIST_LEASES_NO:
|
||||||
|
*ret_dir_fd = -EBADF;
|
||||||
|
*ret_path = NULL;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case DHCP_SERVER_PERSIST_LEASES_YES: {
|
||||||
|
if (link->manager->persistent_storage_fd < 0)
|
||||||
|
return -EBUSY; /* persistent storage is not ready. */
|
||||||
|
|
||||||
|
char *p = path_join("dhcp-server-lease", link->ifname);
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*ret_dir_fd = link->manager->persistent_storage_fd;
|
||||||
|
*ret_path = p;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case DHCP_SERVER_PERSIST_LEASES_RUNTIME: {
|
||||||
|
char *p = path_join("/run/systemd/netif/dhcp-server-lease", link->ifname);
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*ret_dir_fd = AT_FDCWD;
|
||||||
|
*ret_path = p;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
uint8_t prefixlen;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
@@ -185,18 +224,18 @@ 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))
|
_cleanup_free_ char *lease_file = NULL;
|
||||||
|
int dir_fd;
|
||||||
|
r = link_get_dhcp_server_lease_file(link, &dir_fd, &lease_file);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0) /* persistent leases is disabled */
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
if (link->manager->persistent_storage_fd < 0)
|
struct in_addr a;
|
||||||
return -EBUSY; /* The persistent storage is not ready, try later again. */
|
uint8_t prefixlen;
|
||||||
|
|
||||||
_cleanup_free_ char *lease_file = path_join("dhcp-server-lease", link->ifname);
|
|
||||||
if (!lease_file)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
r = dhcp_server_leases_file_get_server_address(
|
r = dhcp_server_leases_file_get_server_address(
|
||||||
link->manager->persistent_storage_fd,
|
dir_fd,
|
||||||
lease_file,
|
lease_file,
|
||||||
&a,
|
&a,
|
||||||
&prefixlen);
|
&prefixlen);
|
||||||
@@ -234,16 +273,15 @@ 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 (dhcp_server_persist_leases(link)) {
|
_cleanup_free_ char *lease_file = NULL;
|
||||||
|
int dir_fd;
|
||||||
if (link->manager->persistent_storage_fd < 0)
|
r = link_get_dhcp_server_lease_file(link, &dir_fd, &lease_file);
|
||||||
return 0; /* persistent storage is not ready. */
|
if (r == -EBUSY)
|
||||||
|
return 0; /* persistent storage is not ready. */
|
||||||
_cleanup_free_ char *lease_file = path_join("dhcp-server-lease", link->ifname);
|
if (r < 0)
|
||||||
if (!lease_file)
|
return r;
|
||||||
return -ENOMEM;
|
if (r > 0) {
|
||||||
|
r = sd_dhcp_server_set_lease_file(link->dhcp_server, dir_fd, lease_file);
|
||||||
r = sd_dhcp_server_set_lease_file(link->dhcp_server, link->manager->persistent_storage_fd, lease_file);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -265,7 +303,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 (!dhcp_server_persist_leases(link))
|
if (link_get_dhcp_server_persist_leases(link) != DHCP_SERVER_PERSIST_LEASES_YES)
|
||||||
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
|
||||||
@@ -916,3 +954,19 @@ int config_parse_dhcp_server_ipv6_only_preferred(
|
|||||||
*usec = t;
|
*usec = t;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* const dhcp_server_persist_leases_table[_DHCP_SERVER_PERSIST_LEASES_MAX] = {
|
||||||
|
[DHCP_SERVER_PERSIST_LEASES_NO] = "no",
|
||||||
|
[DHCP_SERVER_PERSIST_LEASES_YES] = "yes",
|
||||||
|
[DHCP_SERVER_PERSIST_LEASES_RUNTIME] = "runtime",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(
|
||||||
|
dhcp_server_persist_leases,
|
||||||
|
DHCPServerPersistLeases,
|
||||||
|
DHCP_SERVER_PERSIST_LEASES_YES);
|
||||||
|
|
||||||
|
DEFINE_CONFIG_PARSE_ENUM(
|
||||||
|
config_parse_dhcp_server_persist_leases,
|
||||||
|
dhcp_server_persist_leases,
|
||||||
|
DHCPServerPersistLeases);
|
||||||
|
@@ -3,6 +3,14 @@
|
|||||||
|
|
||||||
#include "networkd-forward.h"
|
#include "networkd-forward.h"
|
||||||
|
|
||||||
|
typedef enum DHCPServerPersistLeases {
|
||||||
|
DHCP_SERVER_PERSIST_LEASES_NO,
|
||||||
|
DHCP_SERVER_PERSIST_LEASES_YES,
|
||||||
|
DHCP_SERVER_PERSIST_LEASES_RUNTIME,
|
||||||
|
_DHCP_SERVER_PERSIST_LEASES_MAX,
|
||||||
|
_DHCP_SERVER_PERSIST_LEASES_INVALID = -EINVAL,
|
||||||
|
} DHCPServerPersistLeases;
|
||||||
|
|
||||||
int network_adjust_dhcp_server(Network *network, Set **addresses);
|
int network_adjust_dhcp_server(Network *network, Set **addresses);
|
||||||
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);
|
||||||
int link_request_dhcp_server(Link *link);
|
int link_request_dhcp_server(Link *link);
|
||||||
@@ -14,3 +22,4 @@ 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_emit);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_address);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_address);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ipv6_only_preferred);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ipv6_only_preferred);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_persist_leases);
|
||||||
|
@@ -44,7 +44,7 @@ DHCPv4.DUIDRawData, config_parse_duid_rawdata,
|
|||||||
DHCPv6.UseDomains, config_parse_use_domains, 0, offsetof(Manager, dhcp6_use_domains)
|
DHCPv6.UseDomains, config_parse_use_domains, 0, offsetof(Manager, dhcp6_use_domains)
|
||||||
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)
|
DHCPServer.PersistLeases, config_parse_dhcp_server_persist_leases, 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
|
||||||
|
@@ -635,7 +635,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,
|
.dhcp_server_persist_leases = DHCP_SERVER_PERSIST_LEASES_YES,
|
||||||
.serialization_fd = -EBADF,
|
.serialization_fd = -EBADF,
|
||||||
.ip_forwarding = { -1, -1, },
|
.ip_forwarding = { -1, -1, },
|
||||||
#if HAVE_VMLINUX_H
|
#if HAVE_VMLINUX_H
|
||||||
|
@@ -36,7 +36,7 @@ typedef 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;
|
DHCPServerPersistLeases dhcp_server_persist_leases;
|
||||||
|
|
||||||
Set *dirty_links;
|
Set *dirty_links;
|
||||||
Set *new_wlan_ifindices;
|
Set *new_wlan_ifindices;
|
||||||
|
@@ -389,7 +389,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)
|
||||||
DHCPServer.PersistLeases, config_parse_tristate, 0, offsetof(Network, dhcp_server_persist_leases)
|
DHCPServer.PersistLeases, config_parse_dhcp_server_persist_leases, 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)
|
||||||
|
@@ -435,7 +435,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,
|
.dhcp_server_persist_leases = _DHCP_SERVER_PERSIST_LEASES_INVALID,
|
||||||
|
|
||||||
.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,
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "network-util.h"
|
#include "network-util.h"
|
||||||
#include "networkd-bridge-vlan.h"
|
#include "networkd-bridge-vlan.h"
|
||||||
#include "networkd-dhcp-common.h"
|
#include "networkd-dhcp-common.h"
|
||||||
|
#include "networkd-dhcp-server.h"
|
||||||
#include "networkd-dhcp4.h"
|
#include "networkd-dhcp4.h"
|
||||||
#include "networkd-dhcp6.h"
|
#include "networkd-dhcp6.h"
|
||||||
#include "networkd-dns.h"
|
#include "networkd-dns.h"
|
||||||
@@ -228,7 +229,7 @@ typedef 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;
|
DHCPServerPersistLeases dhcp_server_persist_leases;
|
||||||
|
|
||||||
/* link-local addressing support */
|
/* link-local addressing support */
|
||||||
AddressFamily link_local;
|
AddressFamily link_local;
|
||||||
|
@@ -69,8 +69,9 @@ static int run(int argc, char *argv[]) {
|
|||||||
/* Always create the directories people can create inotify watches in. It is necessary to create the
|
/* Always create the directories people can create inotify watches in. It is necessary to create the
|
||||||
* following subdirectories after drop_privileges() to make them owned by systemd-network. */
|
* following subdirectories after drop_privileges() to make them owned by systemd-network. */
|
||||||
FOREACH_STRING(p,
|
FOREACH_STRING(p,
|
||||||
"/run/systemd/netif/links/",
|
"/run/systemd/netif/dhcp-server-lease/",
|
||||||
"/run/systemd/netif/leases/") {
|
"/run/systemd/netif/leases/",
|
||||||
|
"/run/systemd/netif/links/") {
|
||||||
r = mkdir_safe_label(p, 0755, UID_INVALID, GID_INVALID, MKDIR_WARN_MODE);
|
r = mkdir_safe_label(p, 0755, UID_INVALID, GID_INVALID, MKDIR_WARN_MODE);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Could not create directory '%s': %m", p);
|
log_warning_errno(r, "Could not create directory '%s': %m", p);
|
||||||
|
3
test/test-network/conf/persist-leases-runtime.conf
Normal file
3
test/test-network/conf/persist-leases-runtime.conf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
[DHCPServer]
|
||||||
|
PersistLeases=runtime
|
@@ -7110,7 +7110,7 @@ class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
tear_down_common()
|
tear_down_common()
|
||||||
|
|
||||||
def check_dhcp_server(self, persist_leases=True):
|
def check_dhcp_server(self, persist_leases='yes'):
|
||||||
output = networkctl_status('veth99')
|
output = networkctl_status('veth99')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, r'Address: 192.168.5.[0-9]* \(DHCPv4 via 192.168.5.1\)')
|
self.assertRegex(output, r'Address: 192.168.5.[0-9]* \(DHCPv4 via 192.168.5.1\)')
|
||||||
@@ -7122,11 +7122,16 @@ class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
|
|||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, "Offered DHCP leases: 192.168.5.[0-9]*")
|
self.assertRegex(output, "Offered DHCP leases: 192.168.5.[0-9]*")
|
||||||
|
|
||||||
if persist_leases:
|
if persist_leases == 'yes':
|
||||||
with open('/var/lib/systemd/network/dhcp-server-lease/veth-peer', encoding='utf-8') as f:
|
path = '/var/lib/systemd/network/dhcp-server-lease/veth-peer'
|
||||||
check_json(f.read())
|
elif persist_leases == 'runtime':
|
||||||
|
path = '/run/systemd/netif/dhcp-server-lease/veth-peer'
|
||||||
else:
|
else:
|
||||||
self.assertFalse(os.path.exists('/var/lib/systemd/network/dhcp-server-lease/veth-peer'))
|
path = None
|
||||||
|
|
||||||
|
if path:
|
||||||
|
with open(path, encoding='utf-8') as f:
|
||||||
|
check_json(f.read())
|
||||||
|
|
||||||
def test_dhcp_server(self):
|
def test_dhcp_server(self):
|
||||||
copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server.network')
|
copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server.network')
|
||||||
@@ -7152,7 +7157,7 @@ class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
|
|||||||
start_networkd()
|
start_networkd()
|
||||||
self.wait_online('veth99:routable', 'veth-peer:routable')
|
self.wait_online('veth99:routable', 'veth-peer:routable')
|
||||||
|
|
||||||
self.check_dhcp_server(persist_leases=False)
|
self.check_dhcp_server(persist_leases='no')
|
||||||
|
|
||||||
remove_networkd_conf_dropin('persist-leases-no.conf')
|
remove_networkd_conf_dropin('persist-leases-no.conf')
|
||||||
with open(os.path.join(network_unit_dir, '25-dhcp-server.network'), mode='a', encoding='utf-8') as f:
|
with open(os.path.join(network_unit_dir, '25-dhcp-server.network'), mode='a', encoding='utf-8') as f:
|
||||||
@@ -7160,7 +7165,23 @@ class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
|
|||||||
restart_networkd()
|
restart_networkd()
|
||||||
self.wait_online('veth99:routable', 'veth-peer:routable')
|
self.wait_online('veth99:routable', 'veth-peer:routable')
|
||||||
|
|
||||||
self.check_dhcp_server(persist_leases=False)
|
self.check_dhcp_server(persist_leases='no')
|
||||||
|
|
||||||
|
def test_dhcp_server_persist_leases_runtime(self):
|
||||||
|
copy_networkd_conf_dropin('persist-leases-runtime.conf')
|
||||||
|
copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server.network')
|
||||||
|
start_networkd()
|
||||||
|
self.wait_online('veth99:routable', 'veth-peer:routable')
|
||||||
|
|
||||||
|
self.check_dhcp_server(persist_leases='runtime')
|
||||||
|
|
||||||
|
remove_networkd_conf_dropin('persist-leases-runtime.conf')
|
||||||
|
with open(os.path.join(network_unit_dir, '25-dhcp-server.network'), mode='a', encoding='utf-8') as f:
|
||||||
|
f.write('[DHCPServer]\nPersistLeases=runtime')
|
||||||
|
restart_networkd()
|
||||||
|
self.wait_online('veth99:routable', 'veth-peer:routable')
|
||||||
|
|
||||||
|
self.check_dhcp_server(persist_leases='runtime')
|
||||||
|
|
||||||
def test_dhcp_server_null_server_address(self):
|
def test_dhcp_server_null_server_address(self):
|
||||||
copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server-null-server-address.network')
|
copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server-null-server-address.network')
|
||||||
|
Reference in New Issue
Block a user