mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-05 09:17:44 +03:00
networkd: add private options to lease struct
This stores private-zone DHCP options inside of their respective DHCP lease. These options aren't used by networkd (what would it do with them?), but saving them will allow other programs to query the values. To improve performance, the options are stored in ascending order by tag.
This commit is contained in:
parent
85e22bfc3f
commit
7e753d9d28
@ -27,6 +27,7 @@
|
||||
|
||||
#include "refcnt.h"
|
||||
#include "util.h"
|
||||
#include "list.h"
|
||||
|
||||
#include "dhcp-protocol.h"
|
||||
|
||||
@ -38,6 +39,14 @@ struct sd_dhcp_route {
|
||||
unsigned char dst_prefixlen;
|
||||
};
|
||||
|
||||
struct sd_dhcp_raw_option {
|
||||
LIST_FIELDS(struct sd_dhcp_raw_option, options);
|
||||
|
||||
uint8_t tag;
|
||||
uint8_t length;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct sd_dhcp_lease {
|
||||
RefCount n_ref;
|
||||
|
||||
@ -74,11 +83,14 @@ struct sd_dhcp_lease {
|
||||
size_t client_id_len;
|
||||
uint8_t *vendor_specific;
|
||||
size_t vendor_specific_len;
|
||||
LIST_HEAD(struct sd_dhcp_raw_option, private_options);
|
||||
};
|
||||
|
||||
int dhcp_lease_new(sd_dhcp_lease **ret);
|
||||
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
|
||||
void *user_data);
|
||||
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag,
|
||||
const uint8_t *data, uint8_t len);
|
||||
|
||||
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
|
||||
|
||||
|
@ -203,6 +203,14 @@ sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
|
||||
|
||||
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
|
||||
if (lease && REFCNT_DEC(lease->n_ref) == 0) {
|
||||
while (lease->private_options) {
|
||||
struct sd_dhcp_raw_option *option = lease->private_options;
|
||||
|
||||
LIST_REMOVE(options, lease->private_options, option);
|
||||
|
||||
free(option->data);
|
||||
free(option);
|
||||
}
|
||||
free(lease->hostname);
|
||||
free(lease->domainname);
|
||||
free(lease->dns);
|
||||
@ -607,11 +615,49 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (code < DHCP_OPTION_PRIVATE_BASE || code > DHCP_OPTION_PRIVATE_LAST)
|
||||
break;
|
||||
|
||||
r = dhcp_lease_insert_private_option(lease, code, option, len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag,
|
||||
const uint8_t *data, uint8_t len) {
|
||||
struct sd_dhcp_raw_option *cur, *option;
|
||||
|
||||
LIST_FOREACH(options, cur, lease->private_options) {
|
||||
if (tag < cur->tag)
|
||||
break;
|
||||
else if (tag == cur->tag) {
|
||||
log_error("Ignoring duplicate option, tagged %d.", tag);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
option = new(struct sd_dhcp_raw_option, 1);
|
||||
if (!option)
|
||||
return -ENOMEM;
|
||||
|
||||
option->tag = tag;
|
||||
option->length = len;
|
||||
option->data = memdup(data, len);
|
||||
if (!option->data) {
|
||||
free(option);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
LIST_INSERT_BEFORE(options, lease->private_options, cur, option);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp_lease_new(sd_dhcp_lease **ret) {
|
||||
sd_dhcp_lease *lease;
|
||||
|
||||
@ -621,6 +667,7 @@ int dhcp_lease_new(sd_dhcp_lease **ret) {
|
||||
|
||||
lease->router = INADDR_ANY;
|
||||
lease->n_ref = REFCNT_INIT;
|
||||
LIST_HEAD_INIT(lease->private_options);
|
||||
|
||||
*ret = lease;
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user