]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: DHCPv6 - Add support to send user class
authorSusant Sahani <ssahani@vmware.com>
Mon, 18 May 2020 12:49:47 +0000 (14:49 +0200)
committerSusant Sahani <ssahani@vmware.com>
Tue, 19 May 2020 09:48:30 +0000 (11:48 +0200)
Frame 115: 171 bytes on wire (1368 bits), 171 bytes captured (1368 bits) on interface veth-peer, id 0
Ethernet II, Src: 1e:04:f8:b8:2f:d4 (1e:04:f8:b8:2f:d4), Dst: IPv6mcast_01:00:02 (33:33:00:01:00:02)
Internet Protocol Version 6, Src: fe80::1c04:f8ff:feb8:2fd4, Dst: ff02::1:2
User Datagram Protocol, Src Port: 546, Dst Port: 547
DHCPv6
    Message type: Solicit (1)
    Transaction ID: 0x673257
    Rapid Commit
        Option: Rapid Commit (14)
        Length: 0
    Identity Association for Non-temporary Address
        Option: Identity Association for Non-temporary Address (3)
        Length: 12
        Value: d0cc94090000000000000000
        IAID: d0cc9409
        T1: 0
        T2: 0
    Fully Qualified Domain Name
        Option: Fully Qualified Domain Name (39)
        Length: 6
        Value: 01045a657573
        0000 0... = Reserved: 0x00
        .... .0.. = N bit: Server should perform DNS updates
        .... ..0. = O bit: Server has not overridden client's S bit preference
        .... ...1 = S bit: Server should perform forward DNS updates
        Client FQDN: Zeus
    User Class
        Option: User Class (15)
        Length: 17
        Value: 000f68656c6c6f30313233343031323334
    Identity Association for Prefix Delegation
        Option: Identity Association for Prefix Delegation (25)
        Length: 12
        Value: d0cc94090000000000000000
        IAID: d0cc9409
        T1: 0
        T2: 0
    Option Request
        Option: Option Request (6)
        Length: 10
        Value: 001700180038001f000e
        Requested Option code: DNS recursive name server (23)
        Requested Option code: Domain Search List (24)
        Requested Option code: NTP Server (56)
        Requested Option code: Simple Network Time Protocol Server (31)
        Requested Option code: Rapid Commit (14)
    Client Identifier
        Option: Client Identifier (1)
        Length: 14
        Value: 00020000ab11d258482fc7eee651
        DUID: 00020000ab11d258482fc7eee651
        DUID Type: assigned by vendor based on Enterprise number (2)
        Enterprise ID: Tom Gundersen (systemd) (43793)
        Identifier: d258482fc7eee651
    Elapsed time
        Option: Elapsed time (8)
        Length: 2
        Value: 0bd0
        Elapsed time: 30240ms

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 e6d005400bc2f5defa3c117b2810c00800f2e9d7..19b49702f362b7a87aec5f454f263f80d48d7a35 100644 (file)
             option numbers, the option number is an integer in the range 1..65536.</para>
           </listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term><varname>UserClass=</varname></term>
+          <listitem>
+            <para>A DHCPv6 client can use User Class option to identify the type or category of user or applications
+            it represents. The information contained in this option is a string that represents the user class of which
+            the client is a member. Each class sets an identifying string of information to be used by the DHCP
+            service to classify clients. Special characters in the data string may be escaped using
+            <ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
+            escapes</ulink>. This setting can be specified multiple times. If an empty string is specified,
+            then all options specified earlier are cleared. Takes a whitespace-separated list of strings. Note that
+            currently NUL bytes are not allowed.</para>
+          </listitem>
+        </varlistentry>
       </variablelist>
   </refsect1>
 
index ae1c4493c774cf5a1ba1ee937644992b0639e843..71ee9554321bbcb6892d352164b8083c8820d43a 100644 (file)
@@ -267,7 +267,7 @@ int config_parse_dhcp6_pd_hint(
         return 0;
 }
 
-int config_parse_dhcp6_mud_url(
+int config_parse_dhcp_user_class(
                 const char *unit,
                 const char *filename,
                 unsigned line,
@@ -279,6 +279,67 @@ int config_parse_dhcp6_mud_url(
                 void *data,
                 void *userdata) {
 
+        char ***l = data;
+        int r;
+
+        assert(l);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                *l = strv_free(*l);
+                return 0;
+        }
+
+        for (;;) {
+                _cleanup_free_ char *w = NULL;
+
+                r = extract_first_word(&rvalue, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "Failed to split user classes option, ignoring: %s", rvalue);
+                        break;
+                }
+                if (r == 0)
+                        break;
+
+                if (ltype == AF_INET) {
+                        if (strlen(w) > UINT8_MAX) {
+                                log_syntax(unit, LOG_ERR, filename, line, 0,
+                                           "%s length is not in the range 1-255, ignoring.", w);
+                                continue;
+                        }
+                } else {
+                        if (strlen(w) > UINT16_MAX) {
+                                log_syntax(unit, LOG_ERR, filename, line, 0,
+                                           "%s length is not in the range 1-65535, ignoring.", w);
+                                continue;
+                        }
+                }
+
+                r = strv_push(l, w);
+                if (r < 0)
+                        return log_oom();
+
+                w = NULL;
+        }
+
+        return 0;
+}
+
+int config_parse_dhcp6_mud_url(
+                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) {
         _cleanup_free_ char *unescaped = NULL;
         Network *network = data;
         int r;
@@ -362,7 +423,7 @@ int config_parse_dhcp_send_option(
                                    "Invalid DHCP option, ignoring assignment: %s", rvalue);
                          return 0;
                 }
-                if (u16 < 1 || u16 >= 65535) {
+                if (u16 < 1 || u16 >= UINT16_MAX) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
                                    "Invalid DHCP option, valid range is 1-65535, ignoring assignment: %s", rvalue);
                         return 0;
index efadcebe21e83c4a8871fe089756f2de80352413..bf8bc2bf6710b30ad24bb04ad65abde39a445d74 100644 (file)
@@ -50,5 +50,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
 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_user_class);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
index 7d52a3a6a1c635e2a83509b5970c591754475af2..6bfa6e6dd0945598339acbdd7842b6b1777bf832 100644 (file)
@@ -1605,60 +1605,6 @@ int config_parse_dhcp_black_listed_ip_address(
         return 0;
 }
 
-int config_parse_dhcp_user_class(
-                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) {
-
-        char ***l = data;
-        int r;
-
-        assert(l);
-        assert(lvalue);
-        assert(rvalue);
-
-        if (isempty(rvalue)) {
-                *l = strv_free(*l);
-                return 0;
-        }
-
-        for (;;) {
-                _cleanup_free_ char *w = NULL;
-
-                r = extract_first_word(&rvalue, &w, NULL, 0);
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to split user classes option, ignoring: %s", rvalue);
-                        break;
-                }
-                if (r == 0)
-                        break;
-
-                if (strlen(w) > 255) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0,
-                                   "%s length is not in the range 1-255, ignoring.", w);
-                        continue;
-                }
-
-                r = strv_push(l, w);
-                if (r < 0)
-                        return log_oom();
-
-                w = NULL;
-        }
-
-        return 0;
-}
-
 int config_parse_dhcp_ip_service_type(
                 const char *unit,
                 const char *filename,
index 78e10d9299050d1f9b7560ca082dc87e40b6370d..93fa7d372cfa047a24feb7e4c289703415150535 100644 (file)
@@ -25,6 +25,5 @@ int dhcp4_set_promote_secondaries(Link *link);
 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_ip_service_type);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);
index 05df41cd3a7bb448633fd38fce51dbebe9e71fcc..a33f22880b8c3e15c1bdf82fd049c3d1ce98ac05 100644 (file)
@@ -706,6 +706,12 @@ int dhcp6_configure(Link *link) {
                         return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for '%u': %m", option);
         }
 
+        if (link->network->dhcp6_user_class) {
+                r = sd_dhcp6_client_set_request_user_class(client, link->network->dhcp6_user_class);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set user class: %m");
+        }
+
         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 711bec7588e2317ad89e0efba54c1e4c4e4e54d6..798781cfe4eb127c3f9fea0786a669a937041b4e 100644 (file)
@@ -174,7 +174,7 @@ DHCPv4.RequestBroadcast,                     config_parse_bool,
 DHCPv4.VendorClassIdentifier,                config_parse_string,                                      0,                             offsetof(Network, dhcp_vendor_class_identifier)
 DHCPv4.MUDURL,                               config_parse_dhcp_mud_url,                                0,                             0
 DHCPv4.MaxAttempts,                          config_parse_dhcp_max_attempts,                           0,                             0
-DHCPv4.UserClass,                            config_parse_dhcp_user_class,                             0,                             offsetof(Network, dhcp_user_class)
+DHCPv4.UserClass,                            config_parse_dhcp_user_class,                             AF_INET,                       offsetof(Network, dhcp_user_class)
 DHCPv4.DUIDType,                             config_parse_duid_type,                                   0,                             offsetof(Network, duid)
 DHCPv4.DUIDRawData,                          config_parse_duid_rawdata,                                0,                             offsetof(Network, duid)
 DHCPv4.RouteMetric,                          config_parse_unsigned,                                    0,                             offsetof(Network, dhcp_route_metric)
@@ -194,6 +194,7 @@ DHCPv6.UseNTP,                               config_parse_bool,
 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.UserClass,                            config_parse_dhcp_user_class,                             AF_INET6,                      offsetof(Network, dhcp6_user_class)
 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)
@@ -384,7 +385,7 @@ DHCP.Hostname,                               config_parse_hostname,
 DHCP.RequestBroadcast,                       config_parse_bool,                                        0,                             offsetof(Network, dhcp_broadcast)
 DHCP.CriticalConnection,                     config_parse_tristate,                                    0,                             offsetof(Network, dhcp_critical)
 DHCP.VendorClassIdentifier,                  config_parse_string,                                      0,                             offsetof(Network, dhcp_vendor_class_identifier)
-DHCP.UserClass,                              config_parse_dhcp_user_class,                             0,                             offsetof(Network, dhcp_user_class)
+DHCP.UserClass,                              config_parse_dhcp_user_class,                             AF_INET,                       offsetof(Network, dhcp_user_class)
 DHCP.DUIDType,                               config_parse_duid_type,                                   0,                             offsetof(Network, duid)
 DHCP.DUIDRawData,                            config_parse_duid_rawdata,                                0,                             offsetof(Network, duid)
 DHCP.RouteMetric,                            config_parse_unsigned,                                    0,                             offsetof(Network, dhcp_route_metric)
index a15f884ab080a74716c221013d533938f77a6c9b..1c2100d89f1dc69602fe5672e34d79d383334e80 100644 (file)
@@ -653,6 +653,7 @@ static Network *network_free(Network *network) {
         set_free(network->dhcp6_request_options);
         free(network->mac);
         free(network->dhcp6_mudurl);
+        strv_free(network->dhcp6_user_class);
 
         if (network->dhcp_acd)
                 sd_ipv4acd_unref(network->dhcp_acd);
index 019bd7676b18256cd11a49b305d6554ab3a6ec75..8a6de4df01b32b030a14c694d2e7dc6282c860a2 100644 (file)
@@ -132,6 +132,7 @@ struct Network {
         bool dhcp6_without_ra;
         uint8_t dhcp6_pd_length;
         char *dhcp6_mudurl;
+        char **dhcp6_user_class;
         struct in6_addr dhcp6_pd_address;
         OrderedHashmap *dhcp6_client_send_options;
         Set *dhcp6_request_options;
index 743ab903ea8cff9c5d14956e6d630bce69d6d9a8..9ce0fc3f9995c5211c7c3ab857e111acb786e9d1 100644 (file)
@@ -115,6 +115,7 @@ WithoutRA=
 MUDURL=
 SendOption=
 RequestOptions=
+UserClass=
 [Route]
 Destination=
 Protocol=