network: DHCPv6 - Add support to send user class
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
This commit is contained in:
parent
3392392518
commit
f37f2a6b8a
|
@ -1774,6 +1774,20 @@
|
|||
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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -115,6 +115,7 @@ WithoutRA=
|
|||
MUDURL=
|
||||
SendOption=
|
||||
RequestOptions=
|
||||
UserClass=
|
||||
[Route]
|
||||
Destination=
|
||||
Protocol=
|
||||
|
|
Loading…
Reference in New Issue