]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: DHCPv6 - Add support set arbitary request options
authorSusant Sahani <ssahani@vmware.com>
Thu, 23 Apr 2020 12:31:47 +0000 (14:31 +0200)
committerSusant Sahani <ssahani@vmware.com>
Sun, 17 May 2020 09:18:29 +0000 (11:18 +0200)
man/systemd.network.xml
src/network/networkd-dhcp-common.c
src/network/networkd-dhcp-common.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp4.h
src/network/networkd-dhcp6.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index d891873c7eb193580d966f9ebf475041940c4e1a..e6d005400bc2f5defa3c117b2810c00800f2e9d7 100644 (file)
         <varlistentry>
           <term><varname>RequestOptions=</varname></term>
           <listitem>
-            <para>A whitespace-separated list of integers in the range 1–254.</para>
+            <para>When configured, allows to set arbitrary request options in the DHCPv4 request options list and will be
+            sent to the DHCPV4 server. A whitespace-separated list of integers in the range 1..254. Defaults to unset.</para>
           </listitem>
         </varlistentry>
 
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>RequestOptions=</varname></term>
+          <listitem>
+            <para>When configured, allows to set arbitrary request options in the DHCPv6 request options list and will
+            sent to the DHCPV6 server. A whitespace-separated list of integers in the range 1..254. Defaults to unset.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>ForceDHCPv6PDOtherInformation=</varname></term>
           <listitem>
           <listitem>
             <para>Takes an IPv6 address with prefix length as <varname>Address=</varname> in
             the "[Network]" section. Specifies the DHCPv6 client for the requesting router to include
-            a prefix-hint in the DHCPv6 solicitation. Prefix ranges 1-128. Defaults to unset.</para>
+            a prefix-hint in the DHCPv6 solicitation. Prefix ranges 1..128. Defaults to unset.</para>
           </listitem>
         </varlistentry>
 
index e94de0cfe0b856ad63e4ae1bb6c90ad7d6a45686..ae1c4493c774cf5a1ba1ee937644992b0639e843 100644 (file)
@@ -519,6 +519,82 @@ int config_parse_dhcp_send_option(
         return 0;
 }
 
+int config_parse_dhcp_request_options(
+                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) {
+
+        Network *network = data;
+        const char *p;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                if (ltype == AF_INET)
+                        network->dhcp_request_options = set_free(network->dhcp_request_options);
+                else
+                        network->dhcp6_request_options = set_free(network->dhcp6_request_options);
+
+                return 0;
+        }
+
+        for (p = rvalue;;) {
+                _cleanup_free_ char *n = NULL;
+                uint32_t i;
+
+                r = extract_first_word(&p, &n, NULL, 0);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "Failed to parse DHCP request option, ignoring assignment: %s",
+                                   rvalue);
+                        return 0;
+                }
+                if (r == 0)
+                        return 0;
+
+                r = safe_atou32(n, &i);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "DHCP request option is invalid, ignoring assignment: %s", n);
+                        continue;
+                }
+
+                if (i < 1 || i >= 255) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "DHCP request option is invalid, valid range is 1-254, ignoring assignment: %s", n);
+                        continue;
+                }
+
+                if (ltype == AF_INET)
+                        r = set_ensure_allocated(&network->dhcp_request_options, NULL);
+                else
+                        r = set_ensure_allocated(&network->dhcp6_request_options, NULL);
+                if (r < 0)
+                        return log_oom();
+
+                if (ltype == AF_INET)
+                        r = set_put(network->dhcp_request_options, UINT32_TO_PTR(i));
+                else
+                        r = set_put(network->dhcp6_request_options, UINT32_TO_PTR(i));
+                if (r < 0)
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "Failed to store DHCP request option '%s', ignoring assignment: %m", n);
+        }
+
+        return 0;
+}
+
 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
                          "Failed to parse DHCP use domains setting");
 
index 0511413a5154b5b194d7941256939b09bc01d5ca..efadcebe21e83c4a8871fe089756f2de80352413 100644 (file)
@@ -51,3 +51,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
index ada14ecd18c8f46ac63e6425fb60261872011937..7d52a3a6a1c635e2a83509b5970c591754475af2 100644 (file)
@@ -1659,72 +1659,6 @@ int config_parse_dhcp_user_class(
         return 0;
 }
 
-int config_parse_dhcp_request_options(
-                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) {
-
-        Network *network = data;
-        const char *p;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        if (isempty(rvalue)) {
-                network->dhcp_request_options = set_free(network->dhcp_request_options);
-                return 0;
-        }
-
-        for (p = rvalue;;) {
-                _cleanup_free_ char *n = NULL;
-                uint32_t i;
-
-                r = extract_first_word(&p, &n, NULL, 0);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to parse DHCP request option, ignoring assignment: %s",
-                                   rvalue);
-                        return 0;
-                }
-                if (r == 0)
-                        return 0;
-
-                r = safe_atou32(n, &i);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "DHCP request option is invalid, ignoring assignment: %s", n);
-                        continue;
-                }
-
-                if (i < 1 || i >= 255) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "DHCP request option is invalid, valid range is 1-254, ignoring assignment: %s", n);
-                        continue;
-                }
-
-                r = set_ensure_allocated(&network->dhcp_request_options, NULL);
-                if (r < 0)
-                        return log_oom();
-
-                r = set_put(network->dhcp_request_options, UINT32_TO_PTR(i));
-                if (r < 0)
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to store DHCP request option '%s', ignoring assignment: %m", n);
-        }
-
-        return 0;
-}
-
 int config_parse_dhcp_ip_service_type(
                 const char *unit,
                 const char *filename,
index b0c30b598ce9ce8cc1962856c289462dbcf3b1e1..78e10d9299050d1f9b7560ca082dc87e40b6370d 100644 (file)
@@ -26,6 +26,5 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_black_listed_ip_address);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
-CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);
index 78c99e95bb4b8e0e33e539ce0155fc91ec6f6949..05df41cd3a7bb448633fd38fce51dbebe9e71fcc 100644 (file)
@@ -621,6 +621,7 @@ static int dhcp6_set_hostname(sd_dhcp6_client *client, Link *link) {
 int dhcp6_configure(Link *link) {
         _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
         sd_dhcp6_option *send_option;
+        void *request_options;
         const DUID *duid;
         Iterator i;
         int r;
@@ -692,6 +693,19 @@ int dhcp6_configure(Link *link) {
                         return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set MUD URL: %m");
         }
 
+        SET_FOREACH(request_options, link->network->dhcp6_request_options, i) {
+                uint32_t option = PTR_TO_UINT32(request_options);
+
+                r = sd_dhcp6_client_set_request_option(client, option);
+                if (r == -EEXIST) {
+                        log_link_debug(link, "DHCP6 CLIENT: Failed to set request flag for '%u' already exists, ignoring.", option);
+                        continue;
+                }
+
+                if (r < 0)
+                        return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for '%u': %m", option);
+        }
+
         r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link);
         if (r < 0)
                 return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set callback: %m");
index d709633df34012f34005741f8965d1b4015dfd0f..711bec7588e2317ad89e0efba54c1e4c4e4e54d6 100644 (file)
@@ -166,7 +166,7 @@ DHCPv4.UseHostname,                          config_parse_bool,
 DHCPv4.UseDomains,                           config_parse_dhcp_use_domains,                            0,                             offsetof(Network, dhcp_use_domains)
 DHCPv4.UseRoutes,                            config_parse_bool,                                        0,                             offsetof(Network, dhcp_use_routes)
 DHCPv4.UseGateway,                           config_parse_tristate,                                    0,                             offsetof(Network, dhcp_use_gateway)
-DHCPv4.RequestOptions,                       config_parse_dhcp_request_options,                        0,                             0
+DHCPv4.RequestOptions,                       config_parse_dhcp_request_options,                        AF_INET,                       0
 DHCPv4.Anonymize,                            config_parse_bool,                                        0,                             offsetof(Network, dhcp_anonymize)
 DHCPv4.SendHostname,                         config_parse_bool,                                        0,                             offsetof(Network, dhcp_send_hostname)
 DHCPv4.Hostname,                             config_parse_hostname,                                    0,                             offsetof(Network, dhcp_hostname)
@@ -193,6 +193,7 @@ DHCPv6.UseDNS,                               config_parse_bool,
 DHCPv6.UseNTP,                               config_parse_bool,                                        0,                             offsetof(Network, dhcp6_use_ntp)
 DHCPv6.RapidCommit,                          config_parse_bool,                                        0,                             offsetof(Network, rapid_commit)
 DHCPv6.MUDURL,                               config_parse_dhcp6_mud_url,                               0,                             0
+DHCPv6.RequestOptions,                       config_parse_dhcp_request_options,                        AF_INET6,                      0
 DHCPv6.ForceDHCPv6PDOtherInformation,        config_parse_bool,                                        0,                             offsetof(Network, dhcp6_force_pd_other_information)
 DHCPv6.PrefixDelegationHint,                 config_parse_dhcp6_pd_hint,                               0,                             0
 DHCPv6.WithoutRA,                            config_parse_bool,                                        0,                             offsetof(Network, dhcp6_without_ra)
index 4ba46d28e308752c826e35d39a275ad22eb76a3f..a15f884ab080a74716c221013d533938f77a6c9b 100644 (file)
@@ -650,6 +650,7 @@ static Network *network_free(Network *network) {
         free(network->dhcp_hostname);
         set_free(network->dhcp_black_listed_ip);
         set_free(network->dhcp_request_options);
+        set_free(network->dhcp6_request_options);
         free(network->mac);
         free(network->dhcp6_mudurl);
 
index 092e58d42c9c98f804ea63e3ee24615e84e92168..019bd7676b18256cd11a49b305d6554ab3a6ec75 100644 (file)
@@ -134,6 +134,7 @@ struct Network {
         char *dhcp6_mudurl;
         struct in6_addr dhcp6_pd_address;
         OrderedHashmap *dhcp6_client_send_options;
+        Set *dhcp6_request_options;
 
         /* DHCP Server Support */
         bool dhcp_server;
index 82399f7b1a7808b8d13ef3dcb1eef92cf253c6ce..743ab903ea8cff9c5d14956e6d630bce69d6d9a8 100644 (file)
@@ -114,6 +114,7 @@ PrefixDelegationHint=
 WithoutRA=
 MUDURL=
 SendOption=
+RequestOptions=
 [Route]
 Destination=
 Protocol=