mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
DHCP client: make SendOption work for DHCPv6 too.
This commit is contained in:
parent
2d5996c175
commit
e7d5fe17db
@ -1748,6 +1748,14 @@
|
||||
Defaults to false.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SendOption=</varname></term>
|
||||
<listitem>
|
||||
<para>As in the <literal>[DHCPv4]</literal> section, however because DHCPv6 uses 16-bit fields to store
|
||||
option numbers, the option number is an integer in the range 1..65536.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
@ -1985,7 +1993,7 @@
|
||||
<para>Send a raw option with value via DHCPv4 server. Takes a DHCP option number, data type
|
||||
and data (<literal><replaceable>option</replaceable>:<replaceable>type</replaceable>:<replaceable>value</replaceable></literal>).
|
||||
The option number is an integer in the range 1..254. The type takes one of <literal>uint8</literal>,
|
||||
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, or
|
||||
<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,
|
||||
|
@ -19,6 +19,7 @@ typedef enum DHCPRawOption {
|
||||
DHCP_RAW_OPTION_DATA_UINT32,
|
||||
DHCP_RAW_OPTION_DATA_STRING,
|
||||
DHCP_RAW_OPTION_DATA_IPV4ADDRESS,
|
||||
DHCP_RAW_OPTION_DATA_IPV6ADDRESS,
|
||||
_DHCP_RAW_OPTION_DATA_MAX,
|
||||
_DHCP_RAW_OPTION_DATA_INVALID,
|
||||
} DHCPRawOption;
|
||||
|
@ -14,6 +14,16 @@
|
||||
#include "macro.h"
|
||||
#include "sparse-endian.h"
|
||||
|
||||
typedef struct sd_dhcp6_option {
|
||||
unsigned n_ref;
|
||||
|
||||
uint16_t option;
|
||||
void *data;
|
||||
size_t length;
|
||||
} sd_dhcp6_option;
|
||||
|
||||
extern const struct hash_ops dhcp6_option_hash_ops;
|
||||
|
||||
/* Common option header */
|
||||
typedef struct DHCP6Option {
|
||||
be16_t code;
|
||||
|
@ -597,3 +597,43 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static sd_dhcp6_option* dhcp6_option_free(sd_dhcp6_option *i) {
|
||||
if (!i)
|
||||
return NULL;
|
||||
|
||||
free(i->data);
|
||||
return mfree(i);
|
||||
}
|
||||
|
||||
int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhcp6_option **ret) {
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(length == 0 || data, -EINVAL);
|
||||
|
||||
_cleanup_free_ void *q = memdup(data, length);
|
||||
if (!q)
|
||||
return -ENOMEM;
|
||||
|
||||
sd_dhcp6_option *p = new(sd_dhcp6_option, 1);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
*p = (sd_dhcp6_option) {
|
||||
.n_ref = 1,
|
||||
.option = option,
|
||||
.length = length,
|
||||
.data = TAKE_PTR(q),
|
||||
};
|
||||
|
||||
*ret = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_option, sd_dhcp6_option, dhcp6_option_free);
|
||||
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
dhcp6_option_hash_ops,
|
||||
void,
|
||||
trivial_hash_func,
|
||||
trivial_compare_func,
|
||||
sd_dhcp6_option,
|
||||
sd_dhcp6_option_unref);
|
||||
|
@ -78,6 +78,7 @@ struct sd_dhcp6_client {
|
||||
size_t duid_len;
|
||||
usec_t information_request_time_usec;
|
||||
usec_t information_refresh_time_usec;
|
||||
OrderedHashmap *extra_options;
|
||||
};
|
||||
|
||||
static const uint16_t default_req_opts[] = {
|
||||
@ -447,6 +448,24 @@ int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp6_client_add_option(sd_dhcp6_client *client, sd_dhcp6_option *v) {
|
||||
int r;
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(v, -EINVAL);
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(&client->extra_options, &dhcp6_option_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_put(client->extra_options, UINT_TO_PTR(v->option), v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
sd_dhcp6_option_ref(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_notify(sd_dhcp6_client *client, int event) {
|
||||
assert(client);
|
||||
|
||||
@ -492,7 +511,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
||||
_cleanup_free_ DHCP6Message *message = NULL;
|
||||
struct in6_addr all_servers =
|
||||
IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
|
||||
struct sd_dhcp6_option *j;
|
||||
size_t len, optlen = 512;
|
||||
Iterator i;
|
||||
uint8_t *opt;
|
||||
int r;
|
||||
usec_t elapsed_usec;
|
||||
@ -672,6 +693,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(j, client->extra_options, i) {
|
||||
r = dhcp6_option_append(&opt, &optlen, j->option, j->length, j->data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message,
|
||||
len - optlen);
|
||||
if (r < 0)
|
||||
@ -1584,6 +1611,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
|
||||
free(client->req_opts);
|
||||
free(client->fqdn);
|
||||
free(client->mudurl);
|
||||
ordered_hashmap_free(client->extra_options);
|
||||
return mfree(client);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include "dhcp-internal.h"
|
||||
#include "dhcp6-internal.h"
|
||||
#include "escape.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-dhcp-common.h"
|
||||
@ -320,13 +321,14 @@ int config_parse_dhcp_send_option(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
|
||||
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL, *old4 = NULL;
|
||||
_cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL, *old6 = NULL;
|
||||
_cleanup_free_ char *word = NULL, *q = NULL;
|
||||
OrderedHashmap **options = data;
|
||||
union in_addr_union addr;
|
||||
DHCPOptionDataType type;
|
||||
uint8_t u, uint8_data;
|
||||
uint16_t uint16_data;
|
||||
uint8_t u8, uint8_data;
|
||||
uint16_t u16, uint16_data;
|
||||
uint32_t uint32_data;
|
||||
const void *udata;
|
||||
const char *p;
|
||||
@ -353,16 +355,30 @@ int config_parse_dhcp_send_option(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou8(word, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (u < 1 || u >= 255) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
if (ltype == AF_INET6) {
|
||||
r = safe_atou16(word, &u16);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (u16 < 1 || u16 >= 65535) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid DHCP option, valid range is 1-65535, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
r = safe_atou8(word, &u8);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Invalid DHCP option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (u8 < 1 || u8 >= 255) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
word = mfree(word);
|
||||
@ -387,7 +403,7 @@ int config_parse_dhcp_send_option(
|
||||
r = safe_atou8(p, &uint8_data);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p);
|
||||
"Failed to parse DHCP uint8 data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -399,7 +415,7 @@ int config_parse_dhcp_send_option(
|
||||
r = safe_atou16(p, &uint16_data);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p);
|
||||
"Failed to parse DHCP uint16 data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -411,7 +427,7 @@ int config_parse_dhcp_send_option(
|
||||
r = safe_atou32(p, &uint32_data);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p);
|
||||
"Failed to parse DHCP uint32 data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -424,7 +440,7 @@ int config_parse_dhcp_send_option(
|
||||
r = in_addr_from_string(AF_INET, p, &addr);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p);
|
||||
"Failed to parse DHCP ipv4address data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -432,11 +448,23 @@ int config_parse_dhcp_send_option(
|
||||
sz = sizeof(addr.in.s_addr);
|
||||
break;
|
||||
}
|
||||
case DHCP_OPTION_DATA_IPV6ADDRESS: {
|
||||
r = in_addr_from_string(AF_INET6, p, &addr);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCP ipv6address data, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
udata = &addr.in6;
|
||||
sz = sizeof(addr.in6.s6_addr);
|
||||
break;
|
||||
}
|
||||
case DHCP_OPTION_DATA_STRING:
|
||||
sz = cunescape(p, UNESCAPE_ACCEPT_NUL, &q);
|
||||
if (sz < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, sz,
|
||||
"Failed to decode DHCPv4 option data, ignoring assignment: %s", p);
|
||||
"Failed to decode DHCP option data, ignoring assignment: %s", p);
|
||||
}
|
||||
|
||||
udata = q;
|
||||
@ -445,27 +473,49 @@ int config_parse_dhcp_send_option(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = sd_dhcp_option_new(u, udata, sz, &opt);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
if (ltype == AF_INET6) {
|
||||
r = sd_dhcp6_option_new(u16, udata, sz, &opt6);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(options, &dhcp6_option_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Overwrite existing option */
|
||||
old6 = ordered_hashmap_get(*options, UINT_TO_PTR(u16));
|
||||
r = ordered_hashmap_replace(*options, UINT_TO_PTR(u16), opt6);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
TAKE_PTR(opt6);
|
||||
} else {
|
||||
r = sd_dhcp_option_new(u8, udata, sz, &opt4);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Overwrite existing option */
|
||||
old4 = ordered_hashmap_get(*options, UINT_TO_PTR(u8));
|
||||
r = ordered_hashmap_replace(*options, UINT_TO_PTR(u8), opt4);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
TAKE_PTR(opt4);
|
||||
}
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Overwrite existing option */
|
||||
old = ordered_hashmap_remove(*options, UINT_TO_PTR(u));
|
||||
r = ordered_hashmap_put(*options, UINT_TO_PTR(u), opt);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(opt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -486,6 +536,7 @@ static const char * const dhcp_option_data_type_table[_DHCP_OPTION_DATA_MAX] = {
|
||||
[DHCP_OPTION_DATA_UINT32] = "uint32",
|
||||
[DHCP_OPTION_DATA_STRING] = "string",
|
||||
[DHCP_OPTION_DATA_IPV4ADDRESS] = "ipv4address",
|
||||
[DHCP_OPTION_DATA_IPV6ADDRESS] = "ipv6address",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(dhcp_option_data_type, DHCPOptionDataType);
|
||||
|
@ -21,6 +21,7 @@ typedef enum DHCPOptionDataType {
|
||||
DHCP_OPTION_DATA_UINT32,
|
||||
DHCP_OPTION_DATA_STRING,
|
||||
DHCP_OPTION_DATA_IPV4ADDRESS,
|
||||
DHCP_OPTION_DATA_IPV6ADDRESS,
|
||||
_DHCP_OPTION_DATA_MAX,
|
||||
_DHCP_OPTION_DATA_INVALID,
|
||||
} DHCPOptionDataType;
|
||||
|
@ -620,7 +620,9 @@ 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 *send_option;
|
||||
const DUID *duid;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -662,6 +664,14 @@ int dhcp6_configure(Link *link) {
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set DUID: %m");
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp6_client_send_options, i) {
|
||||
r = sd_dhcp6_client_add_option(client, send_option);
|
||||
if (r == -EEXIST)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set option: %m");
|
||||
}
|
||||
|
||||
r = dhcp6_set_hostname(client, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -185,7 +185,7 @@ DHCPv4.SendRelease, config_parse_bool,
|
||||
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
|
||||
DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
|
||||
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, ip_service_type)
|
||||
DHCPv4.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_options)
|
||||
DHCPv4.SendOption, config_parse_dhcp_send_option, AF_INET, offsetof(Network, dhcp_client_send_options)
|
||||
DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options)
|
||||
DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu)
|
||||
DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
|
||||
@ -195,6 +195,7 @@ DHCPv6.MUDURL, config_parse_dhcp6_mud_url,
|
||||
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)
|
||||
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
|
||||
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
|
||||
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
|
||||
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
|
||||
|
@ -133,6 +133,7 @@ struct Network {
|
||||
uint8_t dhcp6_pd_length;
|
||||
char *dhcp6_mudurl;
|
||||
struct in6_addr dhcp6_pd_address;
|
||||
OrderedHashmap *dhcp6_client_send_options;
|
||||
|
||||
/* DHCP Server Support */
|
||||
bool dhcp_server;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "sd-dhcp6-lease.h"
|
||||
#include "sd-dhcp6-option.h"
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "_sd-common.h"
|
||||
@ -142,6 +143,8 @@ int sd_dhcp6_client_get_lease(
|
||||
sd_dhcp6_client *client,
|
||||
sd_dhcp6_lease **ret);
|
||||
|
||||
int sd_dhcp6_client_add_option(sd_dhcp6_client *client, sd_dhcp6_option *v);
|
||||
|
||||
int sd_dhcp6_client_stop(sd_dhcp6_client *client);
|
||||
int sd_dhcp6_client_start(sd_dhcp6_client *client);
|
||||
int sd_dhcp6_client_is_running(sd_dhcp6_client *client);
|
||||
|
37
src/systemd/sd-dhcp6-option.h
Normal file
37
src/systemd/sd-dhcp6-option.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#ifndef foosddhcp6optionhfoo
|
||||
#define foosddhcp6optionhfoo
|
||||
|
||||
/***
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "_sd-common.h"
|
||||
|
||||
_SD_BEGIN_DECLARATIONS;
|
||||
|
||||
typedef struct sd_dhcp6_option sd_dhcp6_option;
|
||||
|
||||
int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhcp6_option **ret);
|
||||
sd_dhcp6_option *sd_dhcp6_option_ref(sd_dhcp6_option *ra);
|
||||
sd_dhcp6_option *sd_dhcp6_option_unref(sd_dhcp6_option *ra);
|
||||
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp6_option, sd_dhcp6_option_unref);
|
||||
|
||||
_SD_END_DECLARATIONS;
|
||||
|
||||
#endif
|
@ -112,6 +112,7 @@ ForceDHCPv6PDOtherInformation=
|
||||
PrefixDelegationHint=
|
||||
WithoutRA=
|
||||
MUDURL=
|
||||
SendOption=
|
||||
[Route]
|
||||
Destination=
|
||||
Protocol=
|
||||
|
Loading…
Reference in New Issue
Block a user