]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/dhcp-server: allow to configure IPv6 only preferred option
authorSusant Sahani <ssahani@gmail.com>
Wed, 20 Sep 2023 01:14:07 +0000 (10:14 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Oct 2023 12:42:13 +0000 (21:42 +0900)
Co-authored-by: Yu Watanabe <watanabe.yu+github@gmail.com>
man/systemd.network.xml
src/network/networkd-dhcp-server.c
src/network/networkd-dhcp-server.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h

index 33c559cddb5223a073ab3ad6c03a9c735c421b90..804d51be11c08cd341094fb2dea1eb766d467502 100644 (file)
@@ -3604,6 +3604,20 @@ ServerAddress=192.168.0.1/24</programlisting>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>IPv6OnlyPreferredSec=</varname></term>
+
+        <listitem>
+          <para>Takes a timespan. Controls the
+          <ulink url="https://tools.ietf.org/html/rfc8925">RFC 8925</ulink> IPv6-Only Preferred option.
+          Specifies the DHCPv4 option to indicate that a host supports an IPv6-only mode and is willing to
+          forgo obtaining an IPv4 address if the network provides IPv6 connectivity. Defaults to unset, and
+          not send the option. The minimum allowed value is 300 seconds.</para>
+
+          <xi:include href="version-info.xml" xpointer="v255"/>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>SendOption=</varname></term>
         <listitem>
index dacbb7e129b60549c184f204edca2a9b223fe422..569398571c02796a36e90705be0dcddcaf0e774c 100644 (file)
@@ -6,8 +6,10 @@
 
 #include "sd-dhcp-server.h"
 
+#include "dhcp-protocol.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "network-common.h"
 #include "networkd-address.h"
 #include "networkd-dhcp-server-bus.h"
 #include "networkd-dhcp-server-static-lease.h"
@@ -402,6 +404,10 @@ static int dhcp4_server_configure(Link *link) {
                         return log_link_error_errno(link, r, "Failed to set default lease time for DHCPv4 server instance: %m");
         }
 
+        r = sd_dhcp_server_set_ipv6_only_preferred_usec(link->dhcp_server, link->network->dhcp_server_ipv6_only_preferred_usec);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Failed to set IPv6 only preferred time for DHCPv4 server instance: %m");
+
         r = sd_dhcp_server_set_boot_server_address(link->dhcp_server, &link->network->dhcp_server_boot_server_address);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to set boot server address for DHCPv4 server instance: %m");
@@ -726,3 +732,45 @@ int config_parse_dhcp_server_address(
         network->dhcp_server_address_prefixlen = prefixlen;
         return 0;
 }
+
+int config_parse_dhcp_server_ipv6_only_preferred(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        usec_t t, *usec = ASSERT_PTR(data);
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                *usec = 0;
+                return 0;
+        }
+
+        r = parse_sec(rvalue, &t);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse [%s] %s=, ignoring assignment: %s", section, lvalue, rvalue);
+                return 0;
+        }
+
+        if (t < MIN_V6ONLY_WAIT_USEC && !network_test_mode_enabled()) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Invalid [%s] %s=, ignoring assignment: %s", section, lvalue, rvalue);
+                return 0;
+        }
+
+        *usec = t;
+        return 0;
+}
index 4fd4429deb3dd9c488424538cedea8b0fe48e0e3..960232ade6b9ed68ed0d2be0df766cbc10632a97 100644 (file)
@@ -14,3 +14,4 @@ int link_request_dhcp_server(Link *link);
 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);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ipv6_only_preferred);
index 42e989e11608499b23b47c9e0358b1d504fc9907..6b3609989fcad5f178b7b113e1fb0130b2722f65 100644 (file)
@@ -313,6 +313,7 @@ DHCPServer.RelayAgentCircuitId,              config_parse_dhcp_server_relay_agen
 DHCPServer.RelayAgentRemoteId,               config_parse_dhcp_server_relay_agent_suboption,           0,                             offsetof(Network, dhcp_server_relay_agent_remote_id)
 DHCPServer.MaxLeaseTimeSec,                  config_parse_sec,                                         0,                             offsetof(Network, dhcp_server_max_lease_time_usec)
 DHCPServer.DefaultLeaseTimeSec,              config_parse_sec,                                         0,                             offsetof(Network, dhcp_server_default_lease_time_usec)
+DHCPServer.IPv6OnlyPreferredSec,             config_parse_dhcp_server_ipv6_only_preferred,             0,                             offsetof(Network, dhcp_server_ipv6_only_preferred_usec)
 DHCPServer.EmitDNS,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_DNS].emit)
 DHCPServer.DNS,                              config_parse_dhcp_server_emit,                            0,                             offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_DNS])
 DHCPServer.EmitNTP,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_NTP].emit)
index cc2cf36f5ce6049617d2fe585f46f4d7d05fcbee..0fc08517977d1ed79f940b9f605c84364abec8ee 100644 (file)
@@ -221,6 +221,7 @@ struct Network {
         struct in_addr dhcp_server_boot_server_address;
         char *dhcp_server_boot_server_name;
         char *dhcp_server_boot_filename;
+        usec_t dhcp_server_ipv6_only_preferred_usec;
 
         /* link-local addressing support */
         AddressFamily link_local;