</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>
_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;
}
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;
}
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);
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;
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");
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
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);
}
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 */
UserClass=
VendorClass=
AssignAcquiredDelegatedPrefixAddress=
+SendVendorOption=
[Route]
Destination=
Protocol=