Merge pull request #15884 from ssahani/dhcpv6-vendor

DHCPv6: Introduce vendor specific
This commit is contained in:
Yu Watanabe
2020-06-01 12:25:54 +09:00
committed by GitHub
13 changed files with 136 additions and 7 deletions
+3
View File
@@ -11,12 +11,14 @@
#include "sd-event.h"
#include "list.h"
#include "hashmap.h"
#include "macro.h"
#include "sparse-endian.h"
typedef struct sd_dhcp6_option {
unsigned n_ref;
uint32_t enterprise_identifier;
uint16_t option;
void *data;
size_t length;
@@ -99,6 +101,7 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Add
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class);
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **user_class);
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
size_t *optlen, uint8_t **optvalue);
int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
+35 -1
View File
@@ -79,6 +79,39 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
return 0;
}
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options) {
sd_dhcp6_option *options;
Iterator i;
int r;
assert(buf);
assert(*buf);
assert(buflen);
assert(vendor_options);
ORDERED_HASHMAP_FOREACH(options, vendor_options, i) {
_cleanup_free_ uint8_t *p = NULL;
size_t total;
total = 4 + 2 + 2 + options->length;
p = malloc(total);
if (!p)
return -ENOMEM;
unaligned_write_be32(p, options->enterprise_identifier);
unaligned_write_be16(p + 4, options->option);
unaligned_write_be16(p + 6, options->length);
memcpy(p + 8, options->data, options->length);
r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_OPTS, total, p);
if (r < 0)
return r;
}
return 0;
}
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
uint16_t len;
uint8_t *ia_hdr;
@@ -683,7 +716,7 @@ static sd_dhcp6_option* dhcp6_option_free(sd_dhcp6_option *i) {
return mfree(i);
}
int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhcp6_option **ret) {
int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, uint32_t enterprise_identifier, sd_dhcp6_option **ret) {
assert_return(ret, -EINVAL);
assert_return(length == 0 || data, -EINVAL);
@@ -698,6 +731,7 @@ int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhc
*p = (sd_dhcp6_option) {
.n_ref = 1,
.option = option,
.enterprise_identifier = enterprise_identifier,
.length = length,
.data = TAKE_PTR(q),
};
+39
View File
@@ -81,6 +81,7 @@ struct sd_dhcp6_client {
usec_t information_request_time_usec;
usec_t information_refresh_time_usec;
OrderedHashmap *extra_options;
OrderedHashmap *vendor_options;
};
static const uint16_t default_req_opts[] = {
@@ -225,6 +226,25 @@ int sd_dhcp6_client_set_prefix_delegation_hint(
return 0;
}
int sd_dhcp6_client_add_vendor_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->vendor_options, &dhcp6_option_hash_ops);
if (r < 0)
return r;
r = ordered_hashmap_put(client->vendor_options, v, v);
if (r < 0)
return r;
sd_dhcp6_option_ref(v);
return 1;
}
static int client_ensure_duid(sd_dhcp6_client *client) {
if (client->duid_len != 0)
return 0;
@@ -622,6 +642,13 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
if (!ordered_hashmap_isempty(client->vendor_options)) {
r = dhcp6_option_append_vendor_option(&opt, &optlen,
client->vendor_options);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
if (r < 0)
@@ -680,6 +707,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
if (!ordered_hashmap_isempty(client->vendor_options)) {
r = dhcp6_option_append_vendor_option(&opt, &optlen, client->vendor_options);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
@@ -726,6 +759,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
if (!ordered_hashmap_isempty(client->vendor_options)) {
r = dhcp6_option_append_vendor_option(&opt, &optlen, client->vendor_options);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)