mirror of
https://github.com/systemd/systemd.git
synced 2025-02-24 17:57:34 +03:00
network: Inroduce DHCP6- send vendor options
network: Inroduce DHCP6- send vendor options ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | OPTION_VENDOR_OPTS | option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | enterprise-number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . vendor-option-data . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | sub-opt-code | sub-option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . sub-option-data . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 31: Vendor-specific Options Format sub-opt-code The code for the sub-option. A 2-octet field. sub-option-len An unsigned integer giving the length of the sub-option-data field in this sub-option in octets. A 2-octet field. sub-option-data The data area for the sub-option. The length, in octets, is specified by sub-option-len. ```
This commit is contained in:
parent
99ccb8ff89
commit
b4ccc5de7d
@ -1765,6 +1765,22 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SendVendorOption=</varname></term>
|
||||
<listitem>
|
||||
<para>Send an arbitrary vendor option in the DHCPv6 request. Takes an enterprise identifier, DHCP option number,
|
||||
data type, and data separated with a colon
|
||||
(<literal><replaceable>enterprise identifier</replaceable>:<replaceable>option</replaceable>:<replaceable>type</replaceable>:
|
||||
<replaceable>value</replaceable></literal>). Enterprise identifier is an unsigned integer ranges 1..4294967294.
|
||||
The option number must be an integer in the range 1..254. Data type takes one of <literal>uint8</literal>,
|
||||
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, <literal>ipv6address</literal>, or
|
||||
<literal>string</literal>. 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. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ForceDHCPv6PDOtherInformation=</varname></term>
|
||||
<listitem>
|
||||
|
@ -437,13 +437,13 @@ int config_parse_dhcp_send_option(
|
||||
|
||||
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL, *old4 = NULL;
|
||||
_cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL, *old6 = NULL;
|
||||
uint32_t uint32_data, enterprise_identifier = 0;
|
||||
_cleanup_free_ char *word = NULL, *q = NULL;
|
||||
OrderedHashmap **options = data;
|
||||
uint16_t u16, uint16_data;
|
||||
union in_addr_union addr;
|
||||
DHCPOptionDataType type;
|
||||
uint8_t u8, uint8_data;
|
||||
uint16_t u16, uint16_data;
|
||||
uint32_t uint32_data;
|
||||
const void *udata;
|
||||
const char *p;
|
||||
ssize_t sz;
|
||||
@ -460,10 +460,29 @@ int config_parse_dhcp_send_option(
|
||||
}
|
||||
|
||||
p = rvalue;
|
||||
if (ltype == AF_INET6 && streq(lvalue, "SendVendorOption")) {
|
||||
r = extract_first_word(&p, &word, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r <= 0 || isempty(p)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(word, &enterprise_identifier);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCPv6 enterprise identifier data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
word = mfree(word);
|
||||
}
|
||||
|
||||
r = extract_first_word(&p, &word, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r <= 0) {
|
||||
if (r <= 0 || isempty(p)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
@ -588,7 +607,7 @@ int config_parse_dhcp_send_option(
|
||||
}
|
||||
|
||||
if (ltype == AF_INET6) {
|
||||
r = sd_dhcp6_option_new(u16, udata, sz, &opt6);
|
||||
r = sd_dhcp6_option_new(u16, udata, sz, enterprise_identifier, &opt6);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
|
||||
|
@ -756,6 +756,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 *vendor_option;
|
||||
sd_dhcp6_option *send_option;
|
||||
void *request_options;
|
||||
const DUID *duid;
|
||||
@ -854,6 +855,14 @@ int dhcp6_configure(Link *link) {
|
||||
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set vendor class: %m");
|
||||
}
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(vendor_option, link->network->dhcp6_client_send_vendor_options, i) {
|
||||
r = sd_dhcp6_client_add_vendor_option(client, vendor_option);
|
||||
if (r == -EEXIST)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set vendor option: %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");
|
||||
|
@ -198,6 +198,7 @@ DHCPv6.MUDURL, config_parse_dhcp6_mud_url,
|
||||
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.VendorClass, config_parse_dhcp_vendor_class, 0, offsetof(Network, dhcp6_vendor_class)
|
||||
DHCPv6.SendVendorOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_vendor_options)
|
||||
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
|
||||
DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign_prefix)
|
||||
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
|
||||
|
@ -749,6 +749,7 @@ static Network *network_free(Network *network) {
|
||||
ordered_hashmap_free(network->dhcp_server_send_options);
|
||||
ordered_hashmap_free(network->dhcp_server_send_vendor_options);
|
||||
ordered_hashmap_free(network->ipv6_tokens);
|
||||
ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
|
||||
|
||||
return mfree(network);
|
||||
}
|
||||
|
@ -137,6 +137,7 @@ struct Network {
|
||||
char **dhcp6_vendor_class;
|
||||
struct in6_addr dhcp6_pd_address;
|
||||
OrderedHashmap *dhcp6_client_send_options;
|
||||
OrderedHashmap *dhcp6_client_send_vendor_options;
|
||||
Set *dhcp6_request_options;
|
||||
|
||||
/* DHCP Server Support */
|
||||
|
@ -120,6 +120,7 @@ RequestOptions=
|
||||
UserClass=
|
||||
VendorClass=
|
||||
AssignAcquiredDelegatedPrefixAddress=
|
||||
SendVendorOption=
|
||||
[Route]
|
||||
Destination=
|
||||
Protocol=
|
||||
|
Loading…
x
Reference in New Issue
Block a user