mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
networkd: add support to send DHCP user class option (#7499)
This patch add support to enables to send User Class option code 77 RFC 3004. This option MAY carry multiple User Classes. The format of this option is as follows: Code Len Value +-----+-----+--------------------- . . . --+ | 77 | N | User Class Data ('Len' octets) | +-----+-----+--------------------- . . . --+ where Value consists of one or more instances of User Class Data. Each instance of User Class Data is formatted as follows: UC_Len_i User_Class_Data_i +--------+------------------------ . . . --+ | L_i | Opaque-Data ('UC_Len_i' octets) | +--------+------------------------ . . . --+ UserClass= A DHCPv4 client can use UserClass option to identify the type or category of user or applications it represents. The information contained in this option is an 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. Takes a whitespace-separated list. UserClass= hello world how are you Closes: RFC: #5134
This commit is contained in:
parent
348b44372f
commit
af1c0de0e1
@ -1245,6 +1245,16 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>UserClass=</varname></term>
|
||||
<listitem>
|
||||
<para>A DHCPv4 client can use UserClass 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. Takes a whitespace-separated list of strings.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DUIDType=</varname></term>
|
||||
<listitem>
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "utf8.h"
|
||||
#include "strv.h"
|
||||
|
||||
#include "dhcp-internal.h"
|
||||
|
||||
@ -35,6 +36,34 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
*offset += 1;
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_USER_CLASS: {
|
||||
size_t len = 0;
|
||||
char **s;
|
||||
|
||||
STRV_FOREACH(s, (char **) optval)
|
||||
len += strlen(*s) + 1;
|
||||
|
||||
if (size < *offset + len + 2)
|
||||
return -ENOBUFS;
|
||||
|
||||
options[*offset] = code;
|
||||
options[*offset + 1] = len;
|
||||
*offset += 2;
|
||||
|
||||
STRV_FOREACH(s, (char **) optval) {
|
||||
len = strlen(*s);
|
||||
|
||||
if (len > 255)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
options[*offset] = len;
|
||||
|
||||
memcpy_safe(&options[*offset + 1], *s, len);
|
||||
*offset += len + 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (size < *offset + optlen + 2)
|
||||
return -ENOBUFS;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "random-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
|
||||
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
|
||||
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
|
||||
@ -83,6 +84,7 @@ struct sd_dhcp_client {
|
||||
size_t client_id_len;
|
||||
char *hostname;
|
||||
char *vendor_class_identifier;
|
||||
char **user_class;
|
||||
uint32_t mtu;
|
||||
uint32_t xid;
|
||||
usec_t start_time;
|
||||
@ -440,6 +442,26 @@ int sd_dhcp_client_set_vendor_class_identifier(
|
||||
return free_and_strdup(&client->vendor_class_identifier, vci);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_set_user_class(
|
||||
sd_dhcp_client *client,
|
||||
const char* const* user_class) {
|
||||
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
char **p;
|
||||
|
||||
STRV_FOREACH(p, (char **) user_class)
|
||||
if (strlen(*p) > 255)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
s = strv_copy((char **) user_class);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
client->user_class = TAKE_PTR(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_client_set_client_port(
|
||||
sd_dhcp_client *client,
|
||||
uint16_t port) {
|
||||
@ -763,6 +785,15 @@ static int client_send_discover(sd_dhcp_client *client) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (client->user_class) {
|
||||
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_USER_CLASS,
|
||||
strv_length(client->user_class),
|
||||
client->user_class);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
||||
SD_DHCP_OPTION_END, 0, NULL);
|
||||
if (r < 0)
|
||||
@ -1918,6 +1949,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
|
||||
free(client->req_opts);
|
||||
free(client->hostname);
|
||||
free(client->vendor_class_identifier);
|
||||
client->user_class = strv_free(client->user_class);
|
||||
return mfree(client);
|
||||
}
|
||||
|
||||
|
@ -748,6 +748,12 @@ int dhcp4_configure(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_user_class) {
|
||||
r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (link->network->dhcp_client_port) {
|
||||
r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
|
||||
if (r < 0)
|
||||
|
@ -125,6 +125,7 @@ DHCP.Hostname, config_parse_hostname,
|
||||
DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
|
||||
DHCP.CriticalConnection, config_parse_bool, 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.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid.type)
|
||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
|
||||
DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric)
|
||||
|
@ -361,6 +361,7 @@ void network_free(Network *network) {
|
||||
|
||||
free(network->description);
|
||||
free(network->dhcp_vendor_class_identifier);
|
||||
strv_free(network->dhcp_user_class);
|
||||
free(network->dhcp_hostname);
|
||||
|
||||
free(network->mac);
|
||||
@ -1387,6 +1388,58 @@ int config_parse_ntp(
|
||||
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, r, "%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_route_table(const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
|
@ -126,6 +126,7 @@ struct Network {
|
||||
AddressFamilyBoolean dhcp;
|
||||
DHCPClientIdentifier dhcp_client_identifier;
|
||||
char *dhcp_vendor_class_identifier;
|
||||
char **dhcp_user_class;
|
||||
char *dhcp_hostname;
|
||||
unsigned dhcp_route_metric;
|
||||
uint32_t dhcp_route_table;
|
||||
@ -288,7 +289,7 @@ int config_parse_dhcp_server_ntp(const char *unit, const char *filename, unsigne
|
||||
int config_parse_dnssec_negative_trust_anchors(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);
|
||||
int config_parse_dhcp_use_domains(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);
|
||||
int config_parse_lldp_mode(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);
|
||||
int config_parse_dhcp_route_table(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);
|
||||
int config_parse_dhcp_route_table(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);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);
|
||||
int config_parse_ntp(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);
|
||||
/* Legacy IPv4LL support */
|
||||
int config_parse_ipv4ll(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);
|
||||
|
@ -82,6 +82,7 @@ enum {
|
||||
SD_DHCP_OPTION_REBINDING_T2_TIME = 59,
|
||||
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
|
||||
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61,
|
||||
SD_DHCP_OPTION_USER_CLASS = 77,
|
||||
SD_DHCP_OPTION_FQDN = 81,
|
||||
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
||||
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
||||
@ -154,6 +155,9 @@ int sd_dhcp_client_set_hostname(
|
||||
int sd_dhcp_client_set_vendor_class_identifier(
|
||||
sd_dhcp_client *client,
|
||||
const char *vci);
|
||||
int sd_dhcp_client_set_user_class(
|
||||
sd_dhcp_client *client,
|
||||
const char* const *user_class);
|
||||
int sd_dhcp_client_get_lease(
|
||||
sd_dhcp_client *client,
|
||||
sd_dhcp_lease **ret);
|
||||
|
Loading…
Reference in New Issue
Block a user