]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: Allow DHCPv6 client to be started even if no O or M bit in RA.
authorSusant Sahani <ssahani@vmware.com>
Wed, 8 Apr 2020 14:01:21 +0000 (16:01 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 16 Apr 2020 07:32:19 +0000 (09:32 +0200)
man/systemd.network.xml
src/network/networkd-ndisc.c
src/network/networkd-ndisc.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h

index d7c3eeadef67c85b4cdd4312e23b7d4278e9eb7a..75a581816d3877c4336376dc095df04f879a98b4 100644 (file)
         <varlistentry>
           <term><varname>DHCPv6Client=</varname></term>
           <listitem>
-            <para>Takes a boolean. When true (the default), the DHCPv6 client will be started when the
-            RA has the managed or other information flag.</para>
+            <para>Takes a boolean, or the special value <literal>always</literal>. When true (the default), the DHCPv6 client will be started when the
+            RA has the managed or other information flag. If set to <literal>always</literal>, the DHCPv6 client will be started even if there is no
+            managed or other information flag in the RA.</para>
           </listitem>
         </varlistentry>
-
       </variablelist>
   </refsect1>
 
index fe1de6387ee2c1969a5d18773e9a82016869aa34..8af7b3c0c3c83645f6e5eda991ba046d8e9b2e58 100644 (file)
@@ -13,6 +13,7 @@
 #include "networkd-manager.h"
 #include "networkd-ndisc.h"
 #include "networkd-route.h"
+#include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
 
@@ -794,10 +795,14 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get RA flags: %m");
 
-        if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) &&
-            link->network->ipv6_accept_ra_start_dhcp6_client) {
-                /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
-                r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED));
+        if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) && link->network->ipv6_accept_ra_start_dhcp6_client)) {
+
+                if (link->network->ipv6_accept_ra_start_dhcp6_client == IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS)
+                        r = dhcp6_request_address(link, false);
+                else
+                        /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
+                        r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED));
+
                 if (r < 0 && r != -EBUSY)
                         log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
                 else {
@@ -1065,3 +1070,13 @@ int config_parse_address_generation_type(
 
         return 0;
 }
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_start_dhcp6_client, ipv6_accept_ra_start_dhcp6_client, IPv6AcceptRAStartDHCP6Client,
+                         "Failed to parse DHCPv6Client= setting")
+static const char* const ipv6_accept_ra_start_dhcp6_client_table[_IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX] = {
+        [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO]     = "no",
+        [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS] = "always",
+        [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES]    = "yes",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_accept_ra_start_dhcp6_client, IPv6AcceptRAStartDHCP6Client, IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES);
index 02c2f8afda5432a3f96c0ffed94b5a2bcfaaa7b8..68cd1c2bd7bb4b9f5d997c19c57906983af64877 100644 (file)
@@ -15,6 +15,14 @@ typedef enum IPv6TokenAddressGeneration {
         _IPV6_TOKEN_ADDRESS_GENERATION_INVALID = -1,
 } IPv6TokenAddressGeneration;
 
+typedef enum IPv6AcceptRAStartDHCP6Client {
+        IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO,
+        IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS,
+        IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
+        _IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX,
+        _IPV6_ACCEPT_RA_START_DHCP6_CLIENT_INVALID = -1,
+} IPv6AcceptRAStartDHCP6Client;
+
 typedef struct NDiscRDNSS {
         usec_t valid_until;
         struct in6_addr address;
@@ -45,3 +53,7 @@ void ndisc_flush(Link *link);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_black_listed_prefix);
 CONFIG_PARSER_PROTOTYPE(config_parse_address_generation_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_accept_ra_start_dhcp6_client);
+
+const char* ipv6_accept_ra_start_dhcp6_client_to_string(IPv6AcceptRAStartDHCP6Client i) _const_;
+IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client_from_string(const char *s) _pure_;
index c63f57f96249761677f4063acc4ad200e64c2e54..9597176b1c678fe710f41c12af8ea3092d533dcb 100644 (file)
@@ -199,7 +199,7 @@ IPv6AcceptRA.UseAutonomousPrefix,            config_parse_bool,
 IPv6AcceptRA.UseOnLinkPrefix,                config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
 IPv6AcceptRA.UseDNS,                         config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_dns)
 IPv6AcceptRA.UseDomains,                     config_parse_dhcp_use_domains,                            0,                             offsetof(Network, ipv6_accept_ra_use_domains)
-IPv6AcceptRA.DHCPv6Client,                   config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
+IPv6AcceptRA.DHCPv6Client,                   config_parse_ipv6_accept_ra_start_dhcp6_client,           0,                             offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
 IPv6AcceptRA.RouteTable,                     config_parse_section_route_table,                         0,                             0
 IPv6AcceptRA.BlackList,                      config_parse_ndisc_black_listed_prefix,                   0,                             0
 DHCPServer.MaxLeaseTimeSec,                  config_parse_sec,                                         0,                             offsetof(Network, dhcp_server_max_lease_time_usec)
index 1c600ae7bd81bd5e98bea95bca5f88e931bb8c16..240f6689dd2ba4532cf56aaf07ac883cb96bb4c4 100644 (file)
@@ -230,12 +230,12 @@ struct Network {
         bool ipv6_accept_ra_use_dns;
         bool ipv6_accept_ra_use_autonomous_prefix;
         bool ipv6_accept_ra_use_onlink_prefix;
-        bool ipv6_accept_ra_start_dhcp6_client;
         bool active_slave;
         bool primary_slave;
+        bool ipv6_accept_ra_route_table_set;
         DHCPUseDomains ipv6_accept_ra_use_domains;
+        IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client;
         uint32_t ipv6_accept_ra_route_table;
-        bool ipv6_accept_ra_route_table_set;
         Set *ndisc_black_listed_prefix;
         OrderedHashmap *ipv6_tokens;