]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/dhcp-server: introduce PersistLeases= setting
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 15 Mar 2024 17:32:50 +0000 (02:32 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 27 Mar 2024 13:21:15 +0000 (13:21 +0000)
Requested at https://github.com/systemd/systemd/pull/31772#issuecomment-2000053357.

man/networkd.conf.xml
man/systemd.network.xml
src/network/networkd-dhcp-server.c
src/network/networkd-gperf.gperf
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd.conf

index f7b3b4711ceef0d4d408db7131722cb8162963d7..3b592e9a67a43f418e36ab11e9a1872486b69e28 100644 (file)
@@ -283,6 +283,27 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
     </variablelist>
   </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>
       <title>See Also</title>
       <para><simplelist type="inline">
index e143aebb1bd39a59c384b074c602d9bf1768da89..4f0510030a7dccad4260b711603440fef3d14d82 100644 (file)
           Defaults to <literal>no</literal>. Further settings for the DHCP server may be set in the
           [DHCPServer] section described below.</para>
 
-          <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
+          <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
+          <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>
           for more details.</para>
 
@@ -3903,6 +3906,22 @@ ServerAddress=192.168.0.1/24</programlisting>
         </listitem>
       </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>
   </refsect1>
 
index 292022f32283978aff6b11cc1376edf9ad537c44..44b8aaa97741b7c70da2303988c716b7bf79e24d 100644 (file)
@@ -147,6 +147,20 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
         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) {
         struct in_addr a;
         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))
                 return -ENOENT;
 
+        if (!dhcp_server_persist_leases(link))
+                return -ENOENT;
+
         if (link->manager->persistent_storage_fd < 0)
                 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
          * 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)) {
+        if (dhcp_server_persist_leases(link)) {
 
                 if (link->manager->persistent_storage_fd < 0)
                         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) {
                 if (!link->dhcp_server)
                         continue;
-                if (sd_dhcp_server_is_in_relay_mode(link->dhcp_server))
+                if (!dhcp_server_persist_leases(link))
                         continue;
 
                 /* Even if 'start' is true, first we need to stop the server. Otherwise, we cannot (re)set
index bff64633e03da13bdcab5fd5044e54a861c7fd63..f443fa3ecef277fe6c605fe394c4e4e8399c1dcb 100644 (file)
@@ -34,6 +34,7 @@ DHCPv4.DUIDType,                         config_parse_duid_type,
 DHCPv4.DUIDRawData,                      config_parse_duid_rawdata,              0,          offsetof(Manager, dhcp_duid)
 DHCPv6.DUIDType,                         config_parse_duid_type,                 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 */
 DHCP.DUIDType,                           config_parse_manager_duid_type,         0,          0
 DHCP.DUIDRawData,                        config_parse_manager_duid_rawdata,      0,          0
index 15f5e8a6ccbc038818c9c2a1f3f809c0157c8407..77dfc65a8a7545b23112a3fa211077d53a640d46 100644 (file)
@@ -602,6 +602,7 @@ int manager_new(Manager **ret, bool test_mode) {
                 .dhcp_duid.type = DUID_TYPE_EN,
                 .dhcp6_duid.type = DUID_TYPE_EN,
                 .duid_product_uuid.type = DUID_TYPE_UUID,
+                .dhcp_server_persist_leases = true,
                 .ip_forwarding = { -1, -1, },
         };
 
index fd9ab341c83545af7d0253dc0f901e5fc72ca1d7..28a2803845a8b9c01e81c3412b1a60ea15882dcb 100644 (file)
@@ -42,6 +42,7 @@ struct Manager {
         bool manage_foreign_routes;
         bool manage_foreign_rules;
         bool manage_foreign_nexthops;
+        bool dhcp_server_persist_leases;
 
         Set *dirty_links;
         Set *new_wlan_ifindices;
index dffc40308c7966f84fa8f501859a457a12a7f647..34c81a0747807545165ecbc31c8cbf83176055e4 100644 (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.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)
+SHCPServer.PersistLeases,                    config_parse_tristate,                                    0,                             offsetof(Network, dhcp_server_persist_leases)
 DHCPServerStaticLease.Address,               config_parse_dhcp_static_lease_address,                   0,                             0
 DHCPServerStaticLease.MACAddress,            config_parse_dhcp_static_lease_hwaddr,                    0,                             0
 Bridge.Cost,                                 config_parse_uint32,                                      0,                             offsetof(Network, cost)
index 3d418006d671c78474b1770cad4e10dd492103a8..eaa3676ede8efcfd33afa8d49ab93e07a117c1d2 100644 (file)
@@ -426,6 +426,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .dhcp_server_emit_router = true,
                 .dhcp_server_emit_timezone = true,
                 .dhcp_server_rapid_commit = true,
+                .dhcp_server_persist_leases = -1,
 
                 .router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC,
                 .router_dns_lifetime_usec = RADV_DEFAULT_VALID_LIFETIME_USEC,
index 467789bd68ac845135af0747c9a8ece274726967..723091fc8ae13974cad07c31253f9396d12f0d88 100644 (file)
@@ -230,6 +230,7 @@ struct Network {
         char *dhcp_server_boot_filename;
         usec_t dhcp_server_ipv6_only_preferred_usec;
         bool dhcp_server_rapid_commit;
+        int dhcp_server_persist_leases;
 
         /* link-local addressing support */
         AddressFamily link_local;
index 2994b8b70c1c14e8341810484cda81c9ad4711fc..bad7e8855a6d300aaad513e867641bcaba303c16 100644 (file)
@@ -32,3 +32,6 @@
 [DHCPv6]
 #DUIDType=vendor
 #DUIDRawData=
+
+[DHCPServer]
+#PersistLeases=yes