1
0
mirror of https://github.com/systemd/systemd synced 2025-10-02 18:24:46 +02:00

Compare commits

..

No commits in common. "b49bb2866ccffdef23dc326288149c1a6f28b8fd" and "e4c9246fb32e40937d41c7161b405f29521f783b" have entirely different histories.

6 changed files with 118 additions and 158 deletions

2
NEWS
View File

@ -115,7 +115,7 @@ CHANGES WITH 248:
* The existing ConditionControlGroupController= setting has been
extended with two new values "v1" and "v2". "v2" means that the
unified v2 cgroup hierarchy is used, and "v1" means that legacy v1
unified v2 cgroup hierachy is used, and "v1" means that legacy v1
hierarchy or the hybrid hierarchy are used.
* The tables of system calls in seccomp filters are now automatically

View File

@ -1470,7 +1470,7 @@
<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
hierarchy is used, and <literal>v1</literal> will pass if the legacy v1 hierarchy or the hybrid
hierachy 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
<varname>systemd.legacy_systemd_cgroup_controller</varname> in
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>

View File

@ -97,7 +97,7 @@ typedef struct DHCP6IA DHCP6IA;
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
size_t optlen, const void *optval);
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd, const DHCP6Address *hint_pd_prefix);
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix);
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_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);

View File

@ -41,15 +41,14 @@ typedef struct DHCP6PDPrefixOption {
#define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd))
#define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta))
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) {
DHCP6Option *option;
static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
size_t optlen) {
DHCP6Option *option = (DHCP6Option*) *buf;
assert_return(buf, -EINVAL);
assert_return(*buf, -EINVAL);
assert_return(buflen, -EINVAL);
option = (DHCP6Option*) *buf;
if (optlen > 0xffff || *buflen < optlen + offsetof(DHCP6Option, data))
return -ENOBUFS;
@ -113,13 +112,10 @@ 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) {
size_t ia_buflen, ia_addrlen = 0;
struct ia_na ia_na;
struct ia_ta ia_ta;
DHCP6Address *addr;
uint8_t *ia_hdr;
uint16_t len;
void *p;
uint8_t *ia_hdr;
size_t iaid_offset, ia_buflen, ia_addrlen = 0;
DHCP6Address *addr;
int r;
assert_return(buf, -EINVAL);
@ -127,23 +123,15 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
assert_return(buflen, -EINVAL);
assert_return(ia, -EINVAL);
/* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
switch (ia->type) {
case SD_DHCP6_OPTION_IA_NA:
len = DHCP6_OPTION_IA_NA_LEN;
ia_na = (struct ia_na) {
.id = ia->ia_na.id,
};
p = &ia_na;
iaid_offset = offsetof(DHCP6IA, ia_na);
break;
case SD_DHCP6_OPTION_IA_TA:
len = DHCP6_OPTION_IA_TA_LEN;
ia_ta = (struct ia_ta) {
.id = ia->ia_ta.id,
};
p = &ia_ta;
iaid_offset = offsetof(DHCP6IA, ia_ta);
break;
default:
@ -159,113 +147,30 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
*buf += offsetof(DHCP6Option, data);
*buflen -= offsetof(DHCP6Option, data);
memcpy(*buf, p, len);
memcpy(*buf, (char*) ia + iaid_offset, len);
*buf += len;
*buflen -= len;
LIST_FOREACH(addresses, addr, ia->addresses) {
struct iaaddr a = {
.address = addr->iaaddr.address,
};
r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR,
sizeof(addr->iaaddr));
if (r < 0)
return r;
memcpy(*buf, &a, sizeof(struct iaaddr));
memcpy(*buf, &addr->iaaddr, sizeof(addr->iaaddr));
*buf += sizeof(struct iaaddr);
*buflen -= sizeof(struct iaaddr);
*buf += sizeof(addr->iaaddr);
*buflen -= sizeof(addr->iaaddr);
ia_addrlen += offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
ia_addrlen += offsetof(DHCP6Option, data) + sizeof(addr->iaaddr);
}
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));
r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
if (r < 0)
return r;
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);
return 0;
}
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
@ -370,6 +275,51 @@ 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);
}
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) {
DHCP6Option *option = (DHCP6Option*) *buf;
uint16_t len;
@ -425,7 +375,8 @@ int dhcp6_option_parse_status(DHCP6Option *option, size_t len) {
return be16toh(statusopt->status);
}
static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
uint32_t *lifetime_valid) {
DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option;
DHCP6Address *addr;
uint32_t lt_valid, lt_pref;
@ -438,22 +389,16 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t
lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred);
if (lt_valid == 0 || lt_pref > lt_valid) {
log_dhcp6_client(client,
"Valid lifetime of an IA address is zero or "
"preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
log_dhcp6_client(client, "Valid lifetime of an IA address is zero or preferred lifetime %d > valid lifetime %d",
lt_pref, lt_valid);
return -EINVAL;
return 0;
}
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));
if (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;
}
if (r != 0)
return r < 0 ? r: 0;
}
addr = new0(DHCP6Address, 1);
@ -465,12 +410,13 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t
LIST_PREPEND(addresses, ia->addresses, addr);
*ret_lifetime_valid = be32toh(addr->iaaddr.lifetime_valid);
*lifetime_valid = be32toh(addr->iaaddr.lifetime_valid);
return 0;
}
static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) {
static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
uint32_t *lifetime_valid) {
DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option;
DHCP6Address *prefix;
uint32_t lt_valid, lt_pref;
@ -483,22 +429,16 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_
lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred);
if (lt_valid == 0 || lt_pref > lt_valid) {
log_dhcp6_client(client,
"Valid lifetieme of a PD prefix is zero or "
"preferred lifetime %"PRIu32" > valid lifetime %"PRIu32,
log_dhcp6_client(client, "Valid lifetieme of a PD prefix is zero or preferred lifetime %d > valid lifetime %d",
lt_pref, lt_valid);
return -EINVAL;
return 0;
}
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));
if (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;
}
if (r != 0)
return r < 0 ? r: 0;
}
prefix = new0(DHCP6Address, 1);
@ -510,7 +450,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_
LIST_PREPEND(addresses, ia->addresses, prefix);
*ret_lifetime_valid = be32toh(prefix->iapdprefix.lifetime_valid);
*lifetime_valid = be32toh(prefix->iapdprefix.lifetime_valid);
return 0;
}
@ -542,7 +482,8 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
lt_t2 = be32toh(ia->ia_na.lifetime_t2);
if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
log_dhcp6_client(client, "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2);
log_dhcp6_client(client, "IA NA T1 %ds > T2 %ds",
lt_t1, lt_t2);
return -EINVAL;
}
@ -560,7 +501,8 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
lt_t2 = be32toh(ia->ia_pd.lifetime_t2);
if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
log_dhcp6_client(client, "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2);
log_dhcp6_client(client, "IA PD T1 %ds > T2 %ds",
lt_t1, lt_t2);
return -EINVAL;
}
@ -600,9 +542,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
}
r = dhcp6_option_parse_address(option, ia, &lt_valid);
if (r < 0 && r != -EINVAL)
if (r < 0)
return r;
if (r >= 0 && lt_valid < lt_min)
if (lt_valid < lt_min)
lt_min = lt_valid;
break;
@ -615,9 +558,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
}
r = dhcp6_option_parse_pdprefix(option, ia, &lt_valid);
if (r < 0 && r != -EINVAL)
if (r < 0)
return r;
if (r >= 0 && lt_valid < lt_min)
if (lt_valid < lt_min)
lt_min = lt_valid;
break;
@ -650,26 +594,26 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
switch(iatype) {
case SD_DHCP6_OPTION_IA_NA:
if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2 && lt_min != UINT32_MAX) {
if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2) {
lt_t1 = lt_min / 2;
lt_t2 = lt_min / 10 * 8;
ia->ia_na.lifetime_t1 = htobe32(lt_t1);
ia->ia_na.lifetime_t2 = htobe32(lt_t2);
log_dhcp6_client(client, "Computed IA NA T1 %"PRIu32"sec and T2 %"PRIu32"sec as both were zero",
log_dhcp6_client(client, "Computed IA NA T1 %ds and T2 %ds as both were zero",
lt_t1, lt_t2);
}
break;
case SD_DHCP6_OPTION_IA_PD:
if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2 && lt_min != UINT32_MAX) {
if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2) {
lt_t1 = lt_min / 2;
lt_t2 = lt_min / 10 * 8;
ia->ia_pd.lifetime_t1 = htobe32(lt_t1);
ia->ia_pd.lifetime_t2 = htobe32(lt_t2);
log_dhcp6_client(client, "Computed IA PD T1 %"PRIu32"sec and T2 %"PRIu32"sec as both were zero",
log_dhcp6_client(client, "Computed IA PD T1 %ds and T2 %ds as both were zero",
lt_t1, lt_t2);
}

View File

@ -698,9 +698,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
}
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)
return r;
opt += r;
optlen -= r;
}
break;
@ -759,9 +762,12 @@ 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) {
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)
return r;
opt += r;
optlen -= r;
}
break;
@ -808,9 +814,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
}
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)
return r;
opt += r;
optlen -= r;
}
break;

View File

@ -650,12 +650,12 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
assert_se(optlen == 40);
assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
/* T1 and T2 should not be set. */
val = 0;
val = htobe32(80);
assert_se(!memcmp(optval + 4, &val, sizeof(val)));
val = htobe32(120);
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);
break;
@ -694,7 +694,14 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
found_elapsed_time);
sd_dhcp6_lease_reset_address_iter(lease);
assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) == -ENOMSG);
assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
&lt_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, &lt_pref,
&lt_valid) == -ENOMSG);
return 0;
}