mirror of
https://github.com/systemd/systemd
synced 2025-10-02 18:24:46 +02:00
Compare commits
6 Commits
e4c9246fb3
...
b49bb2866c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b49bb2866c | ||
![]() |
d9a65c5976 | ||
![]() |
73b49d433c | ||
![]() |
e7613578b4 | ||
![]() |
1e84213a43 | ||
![]() |
cf6c33bd6b |
2
NEWS
2
NEWS
@ -115,7 +115,7 @@ CHANGES WITH 248:
|
|||||||
|
|
||||||
* The existing ConditionControlGroupController= setting has been
|
* The existing ConditionControlGroupController= setting has been
|
||||||
extended with two new values "v1" and "v2". "v2" means that the
|
extended with two new values "v1" and "v2". "v2" means that the
|
||||||
unified v2 cgroup hierachy is used, and "v1" means that legacy v1
|
unified v2 cgroup hierarchy is used, and "v1" means that legacy v1
|
||||||
hierarchy or the hybrid hierarchy are used.
|
hierarchy or the hybrid hierarchy are used.
|
||||||
|
|
||||||
* The tables of system calls in seccomp filters are now automatically
|
* The tables of system calls in seccomp filters are now automatically
|
||||||
|
@ -1470,7 +1470,7 @@
|
|||||||
|
|
||||||
<para>Alternatively, two special strings <literal>v1</literal> and <literal>v2</literal> may be
|
<para>Alternatively, two special strings <literal>v1</literal> and <literal>v2</literal> may be
|
||||||
specified (without any controller names). <literal>v2</literal> will pass if the unified v2 cgroup
|
specified (without any controller names). <literal>v2</literal> will pass if the unified v2 cgroup
|
||||||
hierachy is used, and <literal>v1</literal> will pass if the legacy v1 hierarchy or the hybrid
|
hierarchy is used, and <literal>v1</literal> will pass if the legacy v1 hierarchy or the hybrid
|
||||||
hierarchy are used (see the discussion of <varname>systemd.unified_cgroup_hierarchy</varname> and
|
hierarchy are used (see the discussion of <varname>systemd.unified_cgroup_hierarchy</varname> and
|
||||||
<varname>systemd.legacy_systemd_cgroup_controller</varname> in
|
<varname>systemd.legacy_systemd_cgroup_controller</varname> in
|
||||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
@ -97,7 +97,7 @@ typedef struct DHCP6IA DHCP6IA;
|
|||||||
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
||||||
size_t optlen, const void *optval);
|
size_t optlen, const void *optval);
|
||||||
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
|
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
|
||||||
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix);
|
int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd, const DHCP6Address *hint_pd_prefix);
|
||||||
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
|
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 * const *user_class);
|
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
|
||||||
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
|
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
|
||||||
|
@ -41,14 +41,15 @@ typedef struct DHCP6PDPrefixOption {
|
|||||||
#define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd))
|
#define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd))
|
||||||
#define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta))
|
#define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta))
|
||||||
|
|
||||||
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
|
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) {
|
||||||
size_t optlen) {
|
DHCP6Option *option;
|
||||||
DHCP6Option *option = (DHCP6Option*) *buf;
|
|
||||||
|
|
||||||
assert_return(buf, -EINVAL);
|
assert_return(buf, -EINVAL);
|
||||||
assert_return(*buf, -EINVAL);
|
assert_return(*buf, -EINVAL);
|
||||||
assert_return(buflen, -EINVAL);
|
assert_return(buflen, -EINVAL);
|
||||||
|
|
||||||
|
option = (DHCP6Option*) *buf;
|
||||||
|
|
||||||
if (optlen > 0xffff || *buflen < optlen + offsetof(DHCP6Option, data))
|
if (optlen > 0xffff || *buflen < optlen + offsetof(DHCP6Option, data))
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
@ -112,10 +113,13 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
|
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
|
||||||
uint16_t len;
|
size_t ia_buflen, ia_addrlen = 0;
|
||||||
uint8_t *ia_hdr;
|
struct ia_na ia_na;
|
||||||
size_t iaid_offset, ia_buflen, ia_addrlen = 0;
|
struct ia_ta ia_ta;
|
||||||
DHCP6Address *addr;
|
DHCP6Address *addr;
|
||||||
|
uint8_t *ia_hdr;
|
||||||
|
uint16_t len;
|
||||||
|
void *p;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(buf, -EINVAL);
|
assert_return(buf, -EINVAL);
|
||||||
@ -123,15 +127,23 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
|
|||||||
assert_return(buflen, -EINVAL);
|
assert_return(buflen, -EINVAL);
|
||||||
assert_return(ia, -EINVAL);
|
assert_return(ia, -EINVAL);
|
||||||
|
|
||||||
|
/* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
|
||||||
|
|
||||||
switch (ia->type) {
|
switch (ia->type) {
|
||||||
case SD_DHCP6_OPTION_IA_NA:
|
case SD_DHCP6_OPTION_IA_NA:
|
||||||
len = DHCP6_OPTION_IA_NA_LEN;
|
len = DHCP6_OPTION_IA_NA_LEN;
|
||||||
iaid_offset = offsetof(DHCP6IA, ia_na);
|
ia_na = (struct ia_na) {
|
||||||
|
.id = ia->ia_na.id,
|
||||||
|
};
|
||||||
|
p = &ia_na;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SD_DHCP6_OPTION_IA_TA:
|
case SD_DHCP6_OPTION_IA_TA:
|
||||||
len = DHCP6_OPTION_IA_TA_LEN;
|
len = DHCP6_OPTION_IA_TA_LEN;
|
||||||
iaid_offset = offsetof(DHCP6IA, ia_ta);
|
ia_ta = (struct ia_ta) {
|
||||||
|
.id = ia->ia_ta.id,
|
||||||
|
};
|
||||||
|
p = &ia_ta;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -147,30 +159,113 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
|
|||||||
*buf += offsetof(DHCP6Option, data);
|
*buf += offsetof(DHCP6Option, data);
|
||||||
*buflen -= offsetof(DHCP6Option, data);
|
*buflen -= offsetof(DHCP6Option, data);
|
||||||
|
|
||||||
memcpy(*buf, (char*) ia + iaid_offset, len);
|
memcpy(*buf, p, len);
|
||||||
|
|
||||||
*buf += len;
|
*buf += len;
|
||||||
*buflen -= len;
|
*buflen -= len;
|
||||||
|
|
||||||
LIST_FOREACH(addresses, addr, ia->addresses) {
|
LIST_FOREACH(addresses, addr, ia->addresses) {
|
||||||
r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR,
|
struct iaaddr a = {
|
||||||
sizeof(addr->iaaddr));
|
.address = addr->iaaddr.address,
|
||||||
|
};
|
||||||
|
|
||||||
|
r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
memcpy(*buf, &addr->iaaddr, sizeof(addr->iaaddr));
|
memcpy(*buf, &a, sizeof(struct iaaddr));
|
||||||
|
|
||||||
*buf += sizeof(addr->iaaddr);
|
*buf += sizeof(struct iaaddr);
|
||||||
*buflen -= sizeof(addr->iaaddr);
|
*buflen -= sizeof(struct iaaddr);
|
||||||
|
|
||||||
ia_addrlen += offsetof(DHCP6Option, data) + sizeof(addr->iaaddr);
|
ia_addrlen += offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
|
return option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int option_append_pd_prefix(uint8_t **buf, size_t *buflen, const DHCP6Address *prefix) {
|
||||||
|
struct iapdprefix p;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(buf);
|
||||||
|
assert(*buf);
|
||||||
|
assert(buflen);
|
||||||
|
assert(prefix);
|
||||||
|
|
||||||
|
if (prefix->iapdprefix.prefixlen == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Do not append T1 and T2. */
|
||||||
|
|
||||||
|
p = (struct iapdprefix) {
|
||||||
|
.prefixlen = prefix->iapdprefix.prefixlen,
|
||||||
|
.address = prefix->iapdprefix.address,
|
||||||
|
};
|
||||||
|
|
||||||
|
r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IA_PD_PREFIX, sizeof(struct iapdprefix));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return 0;
|
memcpy(*buf, &p, sizeof(struct iapdprefix));
|
||||||
|
|
||||||
|
*buf += sizeof(struct iapdprefix);
|
||||||
|
*buflen -= sizeof(struct iapdprefix);
|
||||||
|
|
||||||
|
return offsetof(DHCP6Option, data) + sizeof(struct iapdprefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd, const DHCP6Address *hint_pd_prefix) {
|
||||||
|
struct ia_pd ia_pd;
|
||||||
|
size_t len, pd_buflen;
|
||||||
|
uint8_t *pd_hdr;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert_return(buf, -EINVAL);
|
||||||
|
assert_return(*buf, -EINVAL);
|
||||||
|
assert_return(buflen, -EINVAL);
|
||||||
|
assert_return(pd, -EINVAL);
|
||||||
|
assert_return(pd->type == SD_DHCP6_OPTION_IA_PD, -EINVAL);
|
||||||
|
|
||||||
|
/* Do not set T1 and T2. */
|
||||||
|
ia_pd = (struct ia_pd) {
|
||||||
|
.id = pd->ia_pd.id,
|
||||||
|
};
|
||||||
|
len = sizeof(struct ia_pd);
|
||||||
|
|
||||||
|
if (*buflen < offsetof(DHCP6Option, data) + len)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
pd_hdr = *buf;
|
||||||
|
pd_buflen = *buflen;
|
||||||
|
|
||||||
|
/* The header will be written at the end of this function. */
|
||||||
|
*buf += offsetof(DHCP6Option, data);
|
||||||
|
*buflen -= offsetof(DHCP6Option, data);
|
||||||
|
|
||||||
|
memcpy(*buf, &ia_pd, len);
|
||||||
|
|
||||||
|
*buf += sizeof(struct ia_pd);
|
||||||
|
*buflen -= sizeof(struct ia_pd);
|
||||||
|
|
||||||
|
DHCP6Address *prefix;
|
||||||
|
LIST_FOREACH(addresses, prefix, pd->addresses) {
|
||||||
|
r = option_append_pd_prefix(buf, buflen, prefix);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
len += r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hint_pd_prefix) {
|
||||||
|
r = option_append_pd_prefix(buf, buflen, hint_pd_prefix);
|
||||||
|
if (r < 0 && r != -EINVAL)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
len += r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return option_append_hdr(&pd_hdr, &pd_buflen, pd->type, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
|
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
|
||||||
@ -275,51 +370,6 @@ int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const
|
|||||||
return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_CLASS, total, p);
|
return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_CLASS, total, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix) {
|
|
||||||
DHCP6Option *option = (DHCP6Option *)buf;
|
|
||||||
size_t i = sizeof(*option) + sizeof(pd->ia_pd);
|
|
||||||
DHCP6PDPrefixOption *prefix_opt;
|
|
||||||
DHCP6Address *prefix;
|
|
||||||
|
|
||||||
assert_return(buf, -EINVAL);
|
|
||||||
assert_return(pd, -EINVAL);
|
|
||||||
assert_return(pd->type == SD_DHCP6_OPTION_IA_PD, -EINVAL);
|
|
||||||
|
|
||||||
if (len < i)
|
|
||||||
return -ENOBUFS;
|
|
||||||
|
|
||||||
option->code = htobe16(SD_DHCP6_OPTION_IA_PD);
|
|
||||||
|
|
||||||
memcpy(&option->data, &pd->ia_pd, sizeof(pd->ia_pd));
|
|
||||||
LIST_FOREACH(addresses, prefix, pd->addresses) {
|
|
||||||
if (len < i + sizeof(*prefix_opt))
|
|
||||||
return -ENOBUFS;
|
|
||||||
|
|
||||||
prefix_opt = (DHCP6PDPrefixOption *)&buf[i];
|
|
||||||
prefix_opt->option.code = htobe16(SD_DHCP6_OPTION_IA_PD_PREFIX);
|
|
||||||
prefix_opt->option.len = htobe16(sizeof(prefix_opt->iapdprefix));
|
|
||||||
|
|
||||||
memcpy(&prefix_opt->iapdprefix, &prefix->iapdprefix, sizeof(struct iapdprefix));
|
|
||||||
i += sizeof(*prefix_opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hint_pd_prefix && hint_pd_prefix->iapdprefix.prefixlen > 0) {
|
|
||||||
if (len < i + sizeof(*prefix_opt))
|
|
||||||
return -ENOBUFS;
|
|
||||||
|
|
||||||
prefix_opt = (DHCP6PDPrefixOption *)&buf[i];
|
|
||||||
prefix_opt->option.code = htobe16(SD_DHCP6_OPTION_IA_PD_PREFIX);
|
|
||||||
prefix_opt->option.len = htobe16(sizeof(prefix_opt->iapdprefix));
|
|
||||||
|
|
||||||
memcpy(&prefix_opt->iapdprefix, &hint_pd_prefix->iapdprefix, sizeof(struct iapdprefix));
|
|
||||||
i += sizeof(*prefix_opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
option->len = htobe16(i - sizeof(*option));
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) {
|
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) {
|
||||||
DHCP6Option *option = (DHCP6Option*) *buf;
|
DHCP6Option *option = (DHCP6Option*) *buf;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
@ -375,8 +425,7 @@ int dhcp6_option_parse_status(DHCP6Option *option, size_t len) {
|
|||||||
return be16toh(statusopt->status);
|
return be16toh(statusopt->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
|
static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
|
||||||
uint32_t *lifetime_valid) {
|
|
||||||
DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option;
|
DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option;
|
||||||
DHCP6Address *addr;
|
DHCP6Address *addr;
|
||||||
uint32_t lt_valid, lt_pref;
|
uint32_t lt_valid, lt_pref;
|
||||||
@ -389,16 +438,22 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
|
|||||||
lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred);
|
lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred);
|
||||||
|
|
||||||
if (lt_valid == 0 || lt_pref > lt_valid) {
|
if (lt_valid == 0 || lt_pref > lt_valid) {
|
||||||
log_dhcp6_client(client, "Valid lifetime of an IA address is zero or preferred lifetime %d > valid lifetime %d",
|
log_dhcp6_client(client,
|
||||||
|
"Valid lifetime of an IA address is zero or "
|
||||||
|
"preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
|
||||||
lt_pref, lt_valid);
|
lt_pref, lt_valid);
|
||||||
|
return -EINVAL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*addr_option)) {
|
if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*addr_option)) {
|
||||||
r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*addr_option));
|
r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*addr_option));
|
||||||
if (r != 0)
|
if (r < 0)
|
||||||
return r < 0 ? r: 0;
|
return r;
|
||||||
|
if (r > 0) {
|
||||||
|
log_dhcp6_client(client, "Non-zero status code '%s' for address is received",
|
||||||
|
dhcp6_message_status_to_string(r));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = new0(DHCP6Address, 1);
|
addr = new0(DHCP6Address, 1);
|
||||||
@ -410,13 +465,12 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
|
|||||||
|
|
||||||
LIST_PREPEND(addresses, ia->addresses, addr);
|
LIST_PREPEND(addresses, ia->addresses, addr);
|
||||||
|
|
||||||
*lifetime_valid = be32toh(addr->iaaddr.lifetime_valid);
|
*ret_lifetime_valid = be32toh(addr->iaaddr.lifetime_valid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
|
static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
|
||||||
uint32_t *lifetime_valid) {
|
|
||||||
DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option;
|
DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option;
|
||||||
DHCP6Address *prefix;
|
DHCP6Address *prefix;
|
||||||
uint32_t lt_valid, lt_pref;
|
uint32_t lt_valid, lt_pref;
|
||||||
@ -429,16 +483,22 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
|
|||||||
lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred);
|
lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred);
|
||||||
|
|
||||||
if (lt_valid == 0 || lt_pref > lt_valid) {
|
if (lt_valid == 0 || lt_pref > lt_valid) {
|
||||||
log_dhcp6_client(client, "Valid lifetieme of a PD prefix is zero or preferred lifetime %d > valid lifetime %d",
|
log_dhcp6_client(client,
|
||||||
|
"Valid lifetieme of a PD prefix is zero or "
|
||||||
|
"preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
|
||||||
lt_pref, lt_valid);
|
lt_pref, lt_valid);
|
||||||
|
return -EINVAL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*pdprefix_option)) {
|
if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*pdprefix_option)) {
|
||||||
r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*pdprefix_option));
|
r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*pdprefix_option));
|
||||||
if (r != 0)
|
if (r < 0)
|
||||||
return r < 0 ? r: 0;
|
return r;
|
||||||
|
if (r > 0) {
|
||||||
|
log_dhcp6_client(client, "Non-zero status code '%s' for PD prefix is received",
|
||||||
|
dhcp6_message_status_to_string(r));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix = new0(DHCP6Address, 1);
|
prefix = new0(DHCP6Address, 1);
|
||||||
@ -450,7 +510,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
|
|||||||
|
|
||||||
LIST_PREPEND(addresses, ia->addresses, prefix);
|
LIST_PREPEND(addresses, ia->addresses, prefix);
|
||||||
|
|
||||||
*lifetime_valid = be32toh(prefix->iapdprefix.lifetime_valid);
|
*ret_lifetime_valid = be32toh(prefix->iapdprefix.lifetime_valid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -482,8 +542,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
|||||||
lt_t2 = be32toh(ia->ia_na.lifetime_t2);
|
lt_t2 = be32toh(ia->ia_na.lifetime_t2);
|
||||||
|
|
||||||
if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
|
if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
|
||||||
log_dhcp6_client(client, "IA NA T1 %ds > T2 %ds",
|
log_dhcp6_client(client, "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2);
|
||||||
lt_t1, lt_t2);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,8 +560,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
|||||||
lt_t2 = be32toh(ia->ia_pd.lifetime_t2);
|
lt_t2 = be32toh(ia->ia_pd.lifetime_t2);
|
||||||
|
|
||||||
if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
|
if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
|
||||||
log_dhcp6_client(client, "IA PD T1 %ds > T2 %ds",
|
log_dhcp6_client(client, "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2);
|
||||||
lt_t1, lt_t2);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,10 +600,9 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = dhcp6_option_parse_address(option, ia, <_valid);
|
r = dhcp6_option_parse_address(option, ia, <_valid);
|
||||||
if (r < 0)
|
if (r < 0 && r != -EINVAL)
|
||||||
return r;
|
return r;
|
||||||
|
if (r >= 0 && lt_valid < lt_min)
|
||||||
if (lt_valid < lt_min)
|
|
||||||
lt_min = lt_valid;
|
lt_min = lt_valid;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -558,10 +615,9 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = dhcp6_option_parse_pdprefix(option, ia, <_valid);
|
r = dhcp6_option_parse_pdprefix(option, ia, <_valid);
|
||||||
if (r < 0)
|
if (r < 0 && r != -EINVAL)
|
||||||
return r;
|
return r;
|
||||||
|
if (r >= 0 && lt_valid < lt_min)
|
||||||
if (lt_valid < lt_min)
|
|
||||||
lt_min = lt_valid;
|
lt_min = lt_valid;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -594,26 +650,26 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
|||||||
|
|
||||||
switch(iatype) {
|
switch(iatype) {
|
||||||
case SD_DHCP6_OPTION_IA_NA:
|
case SD_DHCP6_OPTION_IA_NA:
|
||||||
if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2) {
|
if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2 && lt_min != UINT32_MAX) {
|
||||||
lt_t1 = lt_min / 2;
|
lt_t1 = lt_min / 2;
|
||||||
lt_t2 = lt_min / 10 * 8;
|
lt_t2 = lt_min / 10 * 8;
|
||||||
ia->ia_na.lifetime_t1 = htobe32(lt_t1);
|
ia->ia_na.lifetime_t1 = htobe32(lt_t1);
|
||||||
ia->ia_na.lifetime_t2 = htobe32(lt_t2);
|
ia->ia_na.lifetime_t2 = htobe32(lt_t2);
|
||||||
|
|
||||||
log_dhcp6_client(client, "Computed IA NA T1 %ds and T2 %ds as both were zero",
|
log_dhcp6_client(client, "Computed IA NA T1 %"PRIu32"sec and T2 %"PRIu32"sec as both were zero",
|
||||||
lt_t1, lt_t2);
|
lt_t1, lt_t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SD_DHCP6_OPTION_IA_PD:
|
case SD_DHCP6_OPTION_IA_PD:
|
||||||
if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2) {
|
if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2 && lt_min != UINT32_MAX) {
|
||||||
lt_t1 = lt_min / 2;
|
lt_t1 = lt_min / 2;
|
||||||
lt_t2 = lt_min / 10 * 8;
|
lt_t2 = lt_min / 10 * 8;
|
||||||
ia->ia_pd.lifetime_t1 = htobe32(lt_t1);
|
ia->ia_pd.lifetime_t1 = htobe32(lt_t1);
|
||||||
ia->ia_pd.lifetime_t2 = htobe32(lt_t2);
|
ia->ia_pd.lifetime_t2 = htobe32(lt_t2);
|
||||||
|
|
||||||
log_dhcp6_client(client, "Computed IA PD T1 %ds and T2 %ds as both were zero",
|
log_dhcp6_client(client, "Computed IA PD T1 %"PRIu32"sec and T2 %"PRIu32"sec as both were zero",
|
||||||
lt_t1, lt_t2);
|
lt_t1, lt_t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,12 +698,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
||||||
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
|
r = dhcp6_option_append_pd(&opt, &optlen, &client->ia_pd, &client->hint_pd_prefix);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
opt += r;
|
|
||||||
optlen -= r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -762,12 +759,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
|
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
|
||||||
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
|
r = dhcp6_option_append_pd(&opt, &optlen, &client->lease->pd, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
opt += r;
|
|
||||||
optlen -= r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -814,12 +808,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
||||||
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
|
r = dhcp6_option_append_pd(&opt, &optlen, &client->lease->pd, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
opt += r;
|
|
||||||
optlen -= r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -650,12 +650,12 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
|
|||||||
assert_se(optlen == 40);
|
assert_se(optlen == 40);
|
||||||
assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
|
assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
|
||||||
|
|
||||||
val = htobe32(80);
|
/* T1 and T2 should not be set. */
|
||||||
|
val = 0;
|
||||||
assert_se(!memcmp(optval + 4, &val, sizeof(val)));
|
assert_se(!memcmp(optval + 4, &val, sizeof(val)));
|
||||||
|
|
||||||
val = htobe32(120);
|
|
||||||
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
|
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
|
||||||
|
|
||||||
|
/* Then, this should refuse all addresses. */
|
||||||
assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
|
assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -694,14 +694,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
|
|||||||
found_elapsed_time);
|
found_elapsed_time);
|
||||||
|
|
||||||
sd_dhcp6_lease_reset_address_iter(lease);
|
sd_dhcp6_lease_reset_address_iter(lease);
|
||||||
assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
|
assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) == -ENOMSG);
|
||||||
<_valid) >= 0);
|
|
||||||
assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
|
|
||||||
assert_se(lt_pref == 150);
|
|
||||||
assert_se(lt_valid == 180);
|
|
||||||
|
|
||||||
assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
|
|
||||||
<_valid) == -ENOMSG);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user