summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-11-23 09:12:56 +0100
committerThomas Haller <thaller@redhat.com>2018-11-23 10:53:12 +0100
commit48d64de1776660eb06fde77078507d25b0d5b40a (patch)
tree28cf9603bcfd394ddd27c5a306bbcb502fda5edf
parent5437448a6404376f2e8fdadff329682bfe9c992e (diff)
downloadNetworkManager-48d64de1776660eb06fde77078507d25b0d5b40a.tar.gz
systemd: update code from upstream (2018-11-23)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=91540eaa5c636f4073955f025c4e72b1bbb4f2e9 ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files :/src/systemd/src/ \ :/shared/nm-utils/unaligned.h | \ xargs -d '\n' rm -f nm_copy_sd() { mkdir -p "./src/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/systemd/$1" } nm_copy_sd_shared() { mkdir -p "./shared/nm-utils/" cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}" } nm_copy_sd "src/basic/alloc-util.c" nm_copy_sd "src/basic/alloc-util.h" nm_copy_sd "src/basic/async.h" nm_copy_sd "src/basic/env-util.c" nm_copy_sd "src/basic/env-util.h" nm_copy_sd "src/basic/escape.c" nm_copy_sd "src/basic/escape.h" nm_copy_sd "src/basic/ether-addr-util.c" nm_copy_sd "src/basic/ether-addr-util.h" nm_copy_sd "src/basic/extract-word.c" nm_copy_sd "src/basic/extract-word.h" nm_copy_sd "src/basic/fileio.c" nm_copy_sd "src/basic/fileio.h" nm_copy_sd "src/basic/fd-util.c" nm_copy_sd "src/basic/fd-util.h" nm_copy_sd "src/basic/fs-util.c" nm_copy_sd "src/basic/fs-util.h" nm_copy_sd "src/basic/hash-funcs.c" nm_copy_sd "src/basic/hash-funcs.h" nm_copy_sd "src/basic/hashmap.c" nm_copy_sd "src/basic/hashmap.h" nm_copy_sd "src/basic/hexdecoct.c" nm_copy_sd "src/basic/hexdecoct.h" nm_copy_sd "src/basic/hostname-util.c" nm_copy_sd "src/basic/hostname-util.h" nm_copy_sd "src/basic/in-addr-util.c" nm_copy_sd "src/basic/in-addr-util.h" nm_copy_sd "src/basic/io-util.c" nm_copy_sd "src/basic/io-util.h" nm_copy_sd "src/basic/list.h" nm_copy_sd "src/basic/log.h" nm_copy_sd "src/basic/macro.h" nm_copy_sd "src/basic/mempool.h" nm_copy_sd "src/basic/mempool.c" nm_copy_sd "src/basic/parse-util.c" nm_copy_sd "src/basic/parse-util.h" nm_copy_sd "src/basic/path-util.c" nm_copy_sd "src/basic/path-util.h" nm_copy_sd "src/basic/prioq.h" nm_copy_sd "src/basic/prioq.c" nm_copy_sd "src/basic/process-util.h" nm_copy_sd "src/basic/process-util.c" nm_copy_sd "src/basic/random-util.c" nm_copy_sd "src/basic/random-util.h" nm_copy_sd "src/basic/refcnt.h" nm_copy_sd "src/basic/set.h" nm_copy_sd "src/basic/signal-util.h" nm_copy_sd "src/basic/siphash24.h" nm_copy_sd "src/basic/socket-util.c" nm_copy_sd "src/basic/socket-util.h" nm_copy_sd "src/basic/sparse-endian.h" nm_copy_sd "src/basic/stat-util.c" nm_copy_sd "src/basic/stat-util.h" nm_copy_sd "src/basic/stdio-util.h" nm_copy_sd "src/basic/string-table.c" nm_copy_sd "src/basic/string-table.h" nm_copy_sd "src/basic/string-util.c" nm_copy_sd "src/basic/string-util.h" nm_copy_sd "src/basic/strv.c" nm_copy_sd "src/basic/strv.h" nm_copy_sd "src/basic/time-util.c" nm_copy_sd "src/basic/time-util.h" nm_copy_sd "src/basic/umask-util.h" nm_copy_sd_shared "src/basic/unaligned.h" nm_copy_sd "src/basic/utf8.c" nm_copy_sd "src/basic/utf8.h" nm_copy_sd "src/basic/util.c" nm_copy_sd "src/basic/util.h" nm_copy_sd "src/libsystemd-network/arp-util.c" nm_copy_sd "src/libsystemd-network/arp-util.h" nm_copy_sd "src/libsystemd-network/dhcp6-internal.h" nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h" nm_copy_sd "src/libsystemd-network/dhcp6-network.c" nm_copy_sd "src/libsystemd-network/dhcp6-option.c" nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h" nm_copy_sd "src/libsystemd-network/dhcp-identifier.c" nm_copy_sd "src/libsystemd-network/dhcp-identifier.h" nm_copy_sd "src/libsystemd-network/dhcp-internal.h" nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h" nm_copy_sd "src/libsystemd-network/dhcp-network.c" nm_copy_sd "src/libsystemd-network/dhcp-option.c" nm_copy_sd "src/libsystemd-network/dhcp-packet.c" nm_copy_sd "src/libsystemd-network/dhcp-protocol.h" nm_copy_sd "src/libsystemd-network/lldp-internal.h" nm_copy_sd "src/libsystemd-network/lldp-neighbor.c" nm_copy_sd "src/libsystemd-network/lldp-neighbor.h" nm_copy_sd "src/libsystemd-network/lldp-network.c" nm_copy_sd "src/libsystemd-network/lldp-network.h" nm_copy_sd "src/libsystemd-network/network-internal.c" nm_copy_sd "src/libsystemd-network/network-internal.h" nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c" nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c" nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c" nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c" nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c" nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c" nm_copy_sd "src/libsystemd-network/sd-lldp.c" nm_copy_sd "src/libsystemd/sd-event/event-source.h" nm_copy_sd "src/libsystemd/sd-event/event-util.c" nm_copy_sd "src/libsystemd/sd-event/event-util.h" nm_copy_sd "src/libsystemd/sd-event/sd-event.c" nm_copy_sd "src/libsystemd/sd-id128/id128-util.c" nm_copy_sd "src/libsystemd/sd-id128/id128-util.h" nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c" nm_copy_sd "src/shared/dns-domain.c" nm_copy_sd "src/shared/dns-domain.h" nm_copy_sd "src/systemd/_sd-common.h" nm_copy_sd "src/systemd/sd-dhcp6-client.h" nm_copy_sd "src/systemd/sd-dhcp6-lease.h" nm_copy_sd "src/systemd/sd-dhcp-client.h" nm_copy_sd "src/systemd/sd-dhcp-lease.h" nm_copy_sd "src/systemd/sd-event.h" nm_copy_sd "src/systemd/sd-ndisc.h" nm_copy_sd "src/systemd/sd-id128.h" nm_copy_sd "src/systemd/sd-ipv4acd.h" nm_copy_sd "src/systemd/sd-ipv4ll.h" nm_copy_sd "src/systemd/sd-lldp.h"
-rw-r--r--shared/nm-utils/unaligned.h24
-rw-r--r--src/systemd/src/basic/escape.c1
-rw-r--r--src/systemd/src/basic/fileio.c59
-rw-r--r--src/systemd/src/basic/fileio.h12
-rw-r--r--src/systemd/src/basic/hostname-util.c1
-rw-r--r--src/systemd/src/basic/in-addr-util.c49
-rw-r--r--src/systemd/src/basic/in-addr-util.h20
-rw-r--r--src/systemd/src/basic/log.h16
-rw-r--r--src/systemd/src/basic/macro.h44
-rw-r--r--src/systemd/src/basic/process-util.c62
-rw-r--r--src/systemd/src/basic/process-util.h2
-rw-r--r--src/systemd/src/basic/random-util.c189
-rw-r--r--src/systemd/src/basic/random-util.h16
-rw-r--r--src/systemd/src/basic/sparse-endian.h4
-rw-r--r--src/systemd/src/basic/stat-util.c44
-rw-r--r--src/systemd/src/basic/stdio-util.h4
-rw-r--r--src/systemd/src/basic/strv.c4
-rw-r--r--src/systemd/src/basic/strv.h3
-rw-r--r--src/systemd/src/basic/time-util.c214
-rw-r--r--src/systemd/src/basic/util.c28
-rw-r--r--src/systemd/src/basic/util.h7
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.c28
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-identifier.h2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-packet.c82
-rw-r--r--src/systemd/src/libsystemd-network/lldp-internal.h3
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.c9
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c184
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-lease.c5
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c160
-rw-r--r--src/systemd/src/libsystemd-network/sd-ipv4acd.c38
-rw-r--r--src/systemd/src/libsystemd-network/sd-lldp.c70
-rw-r--r--src/systemd/src/libsystemd/sd-event/event-util.c99
-rw-r--r--src/systemd/src/libsystemd/sd-event/event-util.h13
-rw-r--r--src/systemd/src/libsystemd/sd-event/sd-event.c232
-rw-r--r--src/systemd/src/libsystemd/sd-id128/sd-id128.c4
-rw-r--r--src/systemd/src/systemd/_sd-common.h8
-rw-r--r--src/systemd/src/systemd/sd-event.h2
-rw-r--r--src/systemd/src/systemd/sd-lldp.h10
-rw-r--r--src/systemd/src/systemd/sd-ndisc.h6
39 files changed, 924 insertions, 834 deletions
diff --git a/shared/nm-utils/unaligned.h b/shared/nm-utils/unaligned.h
index e62188d1a7..00c17f8769 100644
--- a/shared/nm-utils/unaligned.h
+++ b/shared/nm-utils/unaligned.h
@@ -7,37 +7,37 @@
/* BE */
static inline uint16_t unaligned_read_be16(const void *_u) {
- const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
+ const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
return be16toh(u->x);
}
static inline uint32_t unaligned_read_be32(const void *_u) {
- const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
+ const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
return be32toh(u->x);
}
static inline uint64_t unaligned_read_be64(const void *_u) {
- const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
+ const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
return be64toh(u->x);
}
static inline void unaligned_write_be16(void *_u, uint16_t a) {
- struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
+ struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
u->x = be16toh(a);
}
static inline void unaligned_write_be32(void *_u, uint32_t a) {
- struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
+ struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
u->x = be32toh(a);
}
static inline void unaligned_write_be64(void *_u, uint64_t a) {
- struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
+ struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
u->x = be64toh(a);
}
@@ -45,37 +45,37 @@ static inline void unaligned_write_be64(void *_u, uint64_t a) {
/* LE */
static inline uint16_t unaligned_read_le16(const void *_u) {
- const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
+ const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
return le16toh(u->x);
}
static inline uint32_t unaligned_read_le32(const void *_u) {
- const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
+ const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
return le32toh(u->x);
}
static inline uint64_t unaligned_read_le64(const void *_u) {
- const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
+ const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
return le64toh(u->x);
}
static inline void unaligned_write_le16(void *_u, uint16_t a) {
- struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
+ struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
u->x = le16toh(a);
}
static inline void unaligned_write_le32(void *_u, uint32_t a) {
- struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
+ struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
u->x = le32toh(a);
}
static inline void unaligned_write_le64(void *_u, uint64_t a) {
- struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
+ struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
u->x = le64toh(a);
}
diff --git a/src/systemd/src/basic/escape.c b/src/systemd/src/basic/escape.c
index 5004763d97..5f715156fb 100644
--- a/src/systemd/src/basic/escape.c
+++ b/src/systemd/src/basic/escape.c
@@ -106,7 +106,6 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
int r = 1;
assert(p);
- assert(*p);
assert(ret);
/* Unescapes C style. Returns the unescaped character in ret.
diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c
index f14afa5dce..5e771a0aae 100644
--- a/src/systemd/src/basic/fileio.c
+++ b/src/systemd/src/basic/fileio.c
@@ -15,7 +15,6 @@
#include "alloc-util.h"
#include "ctype.h"
-#include "def.h"
#include "env-util.h"
#include "escape.h"
#include "fd-util.h"
@@ -160,7 +159,7 @@ int write_string_file_ts(
/* We manually build our own version of fopen(..., "we") that
* works without O_CREAT */
- fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
+ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY | ((flags & WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0));
if (fd < 0) {
r = -errno;
goto fail;
@@ -368,7 +367,6 @@ int read_full_file(const char *fn, char **contents, size_t *size) {
static int parse_env_file_internal(
FILE *f,
const char *fname,
- const char *newline,
int (*push) (const char *filename, unsigned line,
const char *key, char *value, void *userdata, int *n_pushed),
void *userdata,
@@ -394,8 +392,6 @@ static int parse_env_file_internal(
COMMENT_ESCAPE
} state = PRE_KEY;
- assert(newline);
-
if (f)
r = read_full_stream(f, &contents, NULL);
else
@@ -423,7 +419,7 @@ static int parse_env_file_internal(
break;
case KEY:
- if (strchr(newline, c)) {
+ if (strchr(NEWLINE, c)) {
state = PRE_KEY;
line++;
n_key = 0;
@@ -445,7 +441,7 @@ static int parse_env_file_internal(
break;
case PRE_VALUE:
- if (strchr(newline, c)) {
+ if (strchr(NEWLINE, c)) {
state = PRE_KEY;
line++;
key[n_key] = 0;
@@ -483,7 +479,7 @@ static int parse_env_file_internal(
break;
case VALUE:
- if (strchr(newline, c)) {
+ if (strchr(NEWLINE, c)) {
state = PRE_KEY;
line++;
@@ -528,7 +524,7 @@ static int parse_env_file_internal(
case VALUE_ESCAPE:
state = VALUE;
- if (!strchr(newline, c)) {
+ if (!strchr(NEWLINE, c)) {
/* Escaped newlines we eat up entirely */
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
return -ENOMEM;
@@ -554,7 +550,7 @@ static int parse_env_file_internal(
case SINGLE_QUOTE_VALUE_ESCAPE:
state = SINGLE_QUOTE_VALUE;
- if (!strchr(newline, c)) {
+ if (!strchr(NEWLINE, c)) {
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
return -ENOMEM;
@@ -579,7 +575,7 @@ static int parse_env_file_internal(
case DOUBLE_QUOTE_VALUE_ESCAPE:
state = DOUBLE_QUOTE_VALUE;
- if (!strchr(newline, c)) {
+ if (!strchr(NEWLINE, c)) {
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
return -ENOMEM;
@@ -590,7 +586,7 @@ static int parse_env_file_internal(
case COMMENT:
if (c == '\\')
state = COMMENT_ESCAPE;
- else if (strchr(newline, c)) {
+ else if (strchr(NEWLINE, c)) {
state = PRE_KEY;
line++;
}
@@ -642,16 +638,18 @@ static int check_utf8ness_and_warn(
_cleanup_free_ char *p = NULL;
p = utf8_escape_invalid(key);
- log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p);
- return -EINVAL;
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "%s:%u: invalid UTF-8 in key '%s', ignoring.",
+ strna(filename), line, p);
}
if (value && !utf8_is_valid(value)) {
_cleanup_free_ char *p = NULL;
p = utf8_escape_invalid(value);
- log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p);
- return -EINVAL;
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
+ strna(filename), line, key, p);
}
return 0;
@@ -699,17 +697,13 @@ static int parse_env_file_push(
int parse_env_filev(
FILE *f,
const char *fname,
- const char *newline,
va_list ap) {
int r, n_pushed = 0;
va_list aq;
- if (!newline)
- newline = NEWLINE;
-
va_copy(aq, ap);
- r = parse_env_file_internal(f, fname, newline, parse_env_file_push, &aq, &n_pushed);
+ r = parse_env_file_internal(f, fname, parse_env_file_push, &aq, &n_pushed);
va_end(aq);
if (r < 0)
return r;
@@ -717,17 +711,16 @@ int parse_env_filev(
return n_pushed;
}
-int parse_env_file(
+int parse_env_file_sentinel(
FILE *f,
const char *fname,
- const char *newline,
...) {
va_list ap;
int r;
- va_start(ap, newline);
- r = parse_env_filev(f, fname, newline, ap);
+ va_start(ap, fname);
+ r = parse_env_filev(f, fname, ap);
va_end(ap);
return r;
@@ -763,14 +756,11 @@ static int load_env_file_push(
return 0;
}
-int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
+int load_env_file(FILE *f, const char *fname, char ***rl) {
char **m = NULL;
int r;
- if (!newline)
- newline = NEWLINE;
-
- r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL);
+ r = parse_env_file_internal(f, fname, load_env_file_push, &m, NULL);
if (r < 0) {
strv_free(m);
return r;
@@ -812,14 +802,11 @@ static int load_env_file_push_pairs(
return 0;
}
-int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) {
+int load_env_file_pairs(FILE *f, const char *fname, char ***rl) {
char **m = NULL;
int r;
- if (!newline)
- newline = NEWLINE;
-
- r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL);
+ r = parse_env_file_internal(f, fname, load_env_file_push_pairs, &m, NULL);
if (r < 0) {
strv_free(m);
return r;
@@ -872,7 +859,7 @@ int merge_env_file(
* plus "extended" substitutions, unlike other exported parsing functions.
*/
- return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
+ return parse_env_file_internal(f, fname, merge_env_file_push, env, NULL);
}
static void write_env_var(FILE *f, const char *v) {
diff --git a/src/systemd/src/basic/fileio.h b/src/systemd/src/basic/fileio.h
index 102d33d75f..dae115e3bb 100644
--- a/src/systemd/src/basic/fileio.h
+++ b/src/systemd/src/basic/fileio.h
@@ -10,6 +10,8 @@
#include "macro.h"
#include "time-util.h"
+#define LONG_LINE_MAX (1U*1024U*1024U)
+
typedef enum {
WRITE_STRING_FILE_CREATE = 1 << 0,
WRITE_STRING_FILE_ATOMIC = 1 << 1,
@@ -17,6 +19,7 @@ typedef enum {
WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1 << 3,
WRITE_STRING_FILE_SYNC = 1 << 4,
WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 5,
+ WRITE_STRING_FILE_NOFOLLOW = 1 << 6,
/* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
@@ -41,10 +44,11 @@ int read_full_stream(FILE *f, char **contents, size_t *size);
int verify_file(const char *fn, const char *blob, bool accept_extra_nl);
-int parse_env_filev(FILE *f, const char *fname, const char *separator, va_list ap);
-int parse_env_file(FILE *f, const char *fname, const char *separator, ...) _sentinel_;
-int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
-int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
+int parse_env_filev(FILE *f, const char *fname, va_list ap);
+int parse_env_file_sentinel(FILE *f, const char *fname, ...) _sentinel_;
+#define parse_env_file(f, fname, ...) parse_env_file_sentinel(f, fname, __VA_ARGS__, NULL)
+int load_env_file(FILE *f, const char *fname, char ***l);
+int load_env_file_pairs(FILE *f, const char *fname, char ***l);
int merge_env_file(char ***env, FILE *f, const char *fname);
diff --git a/src/systemd/src/basic/hostname-util.c b/src/systemd/src/basic/hostname-util.c
index 09fabe077b..3a3479910d 100644
--- a/src/systemd/src/basic/hostname-util.c
+++ b/src/systemd/src/basic/hostname-util.c
@@ -8,7 +8,6 @@
#include <unistd.h>
#include "alloc-util.h"
-#include "def.h"
#include "fd-util.h"
#include "fileio.h"
#include "hostname-util.h"
diff --git a/src/systemd/src/basic/in-addr-util.c b/src/systemd/src/basic/in-addr-util.c
index d83658eaa7..6a00de2ef0 100644
--- a/src/systemd/src/basic/in-addr-util.c
+++ b/src/systemd/src/basic/in-addr-util.c
@@ -314,6 +314,7 @@ int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union
}
int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex) {
+ _cleanup_free_ char *buf = NULL;
const char *suffix;
int r, ifi = 0;
@@ -341,7 +342,11 @@ int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_u
}
}
- s = strndupa(s, suffix - s);
+ buf = strndup(s, suffix - s);
+ if (!buf)
+ return -ENOMEM;
+
+ s = buf;
}
r = in_addr_from_string_auto(s, family, ret);
@@ -490,12 +495,14 @@ int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret) {
return 0;
}
-int in_addr_prefix_from_string(
+int in_addr_prefix_from_string_internal(
const char *p,
+ bool use_default_prefixlen,
int family,
union in_addr_union *ret_prefix,
unsigned char *ret_prefixlen) {
+ _cleanup_free_ char *str = NULL;
union in_addr_union buffer;
const char *e, *l;
unsigned char k;
@@ -507,9 +514,13 @@ int in_addr_prefix_from_string(
return -EAFNOSUPPORT;
e = strchr(p, '/');
- if (e)
- l = strndupa(p, e - p);
- else
+ if (e) {
+ str = strndup(p, e - p);
+ if (!str)
+ return -ENOMEM;
+
+ l = str;
+ } else
l = p;
r = in_addr_from_string(family, l, &buffer);
@@ -520,6 +531,13 @@ int in_addr_prefix_from_string(
r = in_addr_parse_prefixlen(family, e+1, &k);
if (r < 0)
return r;
+ } else if (use_default_prefixlen) {
+ if (family == AF_INET) {
+ r = in4_addr_default_prefixlen(&buffer.in, &k);
+ if (r < 0)
+ return r;
+ } else
+ k = 0;
} else
k = FAMILY_ADDRESS_SIZE(family) * 8;
@@ -531,12 +549,14 @@ int in_addr_prefix_from_string(
return 0;
}
-int in_addr_prefix_from_string_auto(
+int in_addr_prefix_from_string_auto_internal(
const char *p,
+ bool use_default_prefixlen,
int *ret_family,
union in_addr_union *ret_prefix,
unsigned char *ret_prefixlen) {
+ _cleanup_free_ char *str = NULL;
union in_addr_union buffer;
const char *e, *l;
unsigned char k;
@@ -545,9 +565,13 @@ int in_addr_prefix_from_string_auto(
assert(p);
e = strchr(p, '/');
- if (e)
- l = strndupa(p, e - p);
- else
+ if (e) {
+ str = strndup(p, e - p);
+ if (!str)
+ return -ENOMEM;
+
+ l = str;
+ } else
l = p;
r = in_addr_from_string_auto(l, &family, &buffer);
@@ -558,6 +582,13 @@ int in_addr_prefix_from_string_auto(
r = in_addr_parse_prefixlen(family, e+1, &k);
if (r < 0)
return r;
+ } else if (use_default_prefixlen) {
+ if (family == AF_INET) {
+ r = in4_addr_default_prefixlen(&buffer.in, &k);
+ if (r < 0)
+ return r;
+ } else
+ k = 0;
} else
k = FAMILY_ADDRESS_SIZE(family) * 8;
diff --git a/src/systemd/src/basic/in-addr-util.h b/src/systemd/src/basic/in-addr-util.h
index e4be30dc0d..2f64c31f96 100644
--- a/src/systemd/src/basic/in-addr-util.h
+++ b/src/systemd/src/basic/in-addr-util.h
@@ -45,15 +45,29 @@ int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mas
int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen);
int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address);
int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret);
-int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
-int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
+int in_addr_prefix_from_string_internal(const char *p, bool use_default_prefixlen, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
+int in_addr_prefix_from_string_auto_internal(const char *p, bool use_default_prefixlen, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
+static inline int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
+ return in_addr_prefix_from_string_internal(p, false, family, ret_prefix, ret_prefixlen);
+}
+static inline int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
+ return in_addr_prefix_from_string_auto_internal(p, false, ret_family, ret_prefix, ret_prefixlen);
+}
+static inline int in_addr_default_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
+ return in_addr_prefix_from_string_internal(p, true, family, ret_prefix, ret_prefixlen);
+}
+static inline int in_addr_default_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
+ return in_addr_prefix_from_string_auto_internal(p, true, ret_family, ret_prefix, ret_prefixlen);
+}
static inline size_t FAMILY_ADDRESS_SIZE(int family) {
assert(IN_SET(family, AF_INET, AF_INET6));
return family == AF_INET6 ? 16 : 4;
}
-#define IN_ADDR_NULL ((union in_addr_union) {})
+/* Workaround for clang, explicitly specify the maximum-size element here.
+ * See also oss-fuzz#11344. */
+#define IN_ADDR_NULL ((union in_addr_union) { .in6 = {} })
void in_addr_data_hash_func(const void *p, struct siphash *state);
int in_addr_data_compare_func(const void *a, const void *b);
diff --git a/src/systemd/src/basic/log.h b/src/systemd/src/basic/log.h
index e1f5fd30cd..17438d7ff7 100644
--- a/src/systemd/src/basic/log.h
+++ b/src/systemd/src/basic/log.h
@@ -36,10 +36,12 @@ typedef enum LogTarget{
_LOG_TARGET_INVALID = -1
} LogTarget;
-#define LOG_REALM_PLUS_LEVEL(realm, level) \
- ((realm) << 10 | (level))
-#define LOG_REALM_REMOVE_LEVEL(realm_level) \
- ((realm_level >> 10))
+/* Note to readers: << and >> have lower precedence than & and | */
+#define LOG_REALM_PLUS_LEVEL(realm, level) ((realm) << 10 | (level))
+#define LOG_REALM_REMOVE_LEVEL(realm_level) ((realm_level) >> 10)
+#define SYNTHETIC_ERRNO(num) (1 << 30 | (num))
+#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1)
+#define ERRNO_VALUE(val) (abs(val) & 255)
void log_set_target(LogTarget target);
void log_set_max_level_realm(LogRealm realm, int level);
@@ -201,10 +203,10 @@ void log_assert_failed_return_realm(
#define log_full_errno_realm(realm, level, error, ...) \
({ \
int _level = (level), _e = (error), _realm = (realm); \
- (log_get_max_level_realm(_realm) >= LOG_PRI(_level)) \
+ (log_get_max_level_realm(_realm) >= LOG_PRI(_level)) \
? log_internal_realm(LOG_REALM_PLUS_LEVEL(_realm, _level), _e, \
__FILE__, __LINE__, __func__, __VA_ARGS__) \
- : -abs(_e); \
+ : -ERRNO_VALUE(_e); \
})
#define log_full_errno(level, error, ...) \
@@ -318,3 +320,5 @@ int log_syntax_invalid_utf8_internal(
})
#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG)
+
+void log_setup_service(void);
diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h
index ae88fa5b93..0a258cc614 100644
--- a/src/systemd/src/basic/macro.h
+++ b/src/systemd/src/basic/macro.h
@@ -8,30 +8,30 @@
#include <sys/sysmacros.h>
#include <sys/types.h>
-#define _printf_(a, b) __attribute__ ((format (printf, a, b)))
+#define _printf_(a, b) __attribute__ ((__format__(printf, a, b)))
#ifdef __clang__
# define _alloc_(...)
#else
-# define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+# define _alloc_(...) __attribute__ ((__alloc_size__(__VA_ARGS__)))
#endif
-#define _sentinel_ __attribute__ ((sentinel))
-#define _unused_ __attribute__ ((unused))
-#define _destructor_ __attribute__ ((destructor))
-#define _pure_ __attribute__ ((pure))
-#define _const_ __attribute__ ((const))
-#define _deprecated_ __attribute__ ((deprecated))
-#define _packed_ __attribute__ ((packed))
-#define _malloc_ __attribute__ ((malloc))
-#define _weak_ __attribute__ ((weak))
+#define _sentinel_ __attribute__ ((__sentinel__))
+#define _unused_ __attribute__ ((__unused__))
+#define _destructor_ __attribute__ ((__destructor__))
+#define _pure_ __attribute__ ((__pure__))
+#define _const_ __attribute__ ((__const__))
+#define _deprecated_ __attribute__ ((__deprecated__))
+#define _packed_ __attribute__ ((__packed__))
+#define _malloc_ __attribute__ ((__malloc__))
+#define _weak_ __attribute__ ((__weak__))
#define _likely_(x) (__builtin_expect(!!(x), 1))
#define _unlikely_(x) (__builtin_expect(!!(x), 0))
-#define _public_ __attribute__ ((visibility("default")))
-#define _hidden_ __attribute__ ((visibility("hidden")))
-#define _weakref_(x) __attribute__((weakref(#x)))
-#define _alignas_(x) __attribute__((aligned(__alignof(x))))
-#define _cleanup_(x) __attribute__((cleanup(x)))
+#define _public_ __attribute__ ((__visibility__("default")))
+#define _hidden_ __attribute__ ((__visibility__("hidden")))
+#define _weakref_(x) __attribute__((__weakref__(#x)))
+#define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
+#define _cleanup_(x) __attribute__((__cleanup__(x)))
#if __GNUC__ >= 7
-#define _fallthrough_ __attribute__((fallthrough))
+#define _fallthrough_ __attribute__((__fallthrough__))
#else
#define _fallthrough_
#endif
@@ -41,7 +41,7 @@
#if __STDC_VERSION__ >= 201112L
#define _noreturn_ _Noreturn
#else
-#define _noreturn_ __attribute__((noreturn))
+#define _noreturn_ __attribute__((__noreturn__))
#endif
#endif
@@ -334,6 +334,12 @@ static inline int __coverity_check__(int condition) {
} \
} while (false)
+#define return_with_errno(r, err) \
+ do { \
+ errno = abs(err); \
+ return r; \
+ } while (false)
+
#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
#define PTR_TO_UINT(p) ((unsigned) ((uintptr_t) (p)))
@@ -383,7 +389,7 @@ static inline int __coverity_check__(int condition) {
#define SET_FLAG(v, flag, b) \
(v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
#define FLAGS_SET(v, flags) \
- (((v) & (flags)) == (flags))
+ ((~(v) & (flags)) == 0)
#define CASE_F(X) case X:
#define CASE_F_1(CASE, X) CASE_F(X)
diff --git a/src/systemd/src/basic/process-util.c b/src/systemd/src/basic/process-util.c
index b2aab853e2..d1a34338f6 100644
--- a/src/systemd/src/basic/process-util.c
+++ b/src/systemd/src/basic/process-util.c
@@ -25,7 +25,6 @@
#include "alloc-util.h"
#include "architecture.h"
-#include "def.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
@@ -832,7 +831,7 @@ int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
void sigkill_wait(pid_t pid) {
assert(pid > 1);
- if (kill(pid, SIGKILL) > 0)
+ if (kill(pid, SIGKILL) >= 0)
(void) wait_for_terminate(pid, NULL);
}
@@ -850,7 +849,7 @@ void sigkill_waitp(pid_t *pid) {
void sigterm_wait(pid_t pid) {
assert(pid > 1);
- if (kill_and_sigcont(pid, SIGTERM) > 0)
+ if (kill_and_sigcont(pid, SIGTERM) >= 0)
(void) wait_for_terminate(pid, NULL);
}
@@ -1228,8 +1227,7 @@ int must_be_root(void) {
if (geteuid() == 0)
return 0;
- log_error("Need to be root.");
- return -EPERM;
+ return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
}
int safe_fork_full(
@@ -1409,6 +1407,60 @@ int safe_fork_full(
return 0;
}
+int namespace_fork(
+ const char *outer_name,
+ const char *inner_name,
+ const int except_fds[],
+ size_t n_except_fds,
+ ForkFlags flags,
+ int pidns_fd,
+ int mntns_fd,
+ int netns_fd,
+ int userns_fd,
+ int root_fd,
+ pid_t *ret_pid) {
+
+ int r;
+
+ /* This is much like safe_fork(), but forks twice, and joins the specified namespaces in the middle
+ * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
+ * /proc/self/fd works correctly. */
+
+ r = safe_fork_full(outer_name, except_fds, n_except_fds, (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ pid_t pid;
+
+ /* Child */
+
+ r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd);
+ if (r < 0) {
+ log_full_errno(FLAGS_SET(flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG, r, "Failed to join namespace: %m");
+ _exit(EXIT_FAILURE);
+ }
+
+ /* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */
+ r = safe_fork_full(inner_name, except_fds, n_except_fds, flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NULL_STDIO), &pid);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+ if (r == 0) {
+ /* Child */
+ if (ret_pid)
+ *ret_pid = pid;
+ return 0;
+ }
+
+ r = wait_for_terminate_and_check(inner_name, pid, FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(r);
+ }
+
+ return 1;
+}
+
int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
bool stdout_is_tty, stderr_is_tty;
size_t n, i;
diff --git a/src/systemd/src/basic/process-util.h b/src/systemd/src/basic/process-util.h
index ca4e4401a9..af47513fab 100644
--- a/src/systemd/src/basic/process-util.h
+++ b/src/systemd/src/basic/process-util.h
@@ -159,6 +159,8 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
return safe_fork_full(name, NULL, 0, flags, ret_pid);
}
+int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
+
int fork_agent(const char *name, const int except[], size_t n_except, pid_t *pid, const char *path, ...) _sentinel_;
int set_oom_score_adjust(int value);
diff --git a/src/systemd/src/basic/random-util.c b/src/systemd/src/basic/random-util.c
index aa04cc2318..4a36ad5119 100644
--- a/src/systemd/src/basic/random-util.c
+++ b/src/systemd/src/basic/random-util.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#ifdef __x86_64__
+#if defined(__i386__) || defined(__x86_64__)
#include <cpuid.h>
#endif
@@ -30,10 +30,13 @@
#include "random-util.h"
#include "time-util.h"
+#if HAS_FEATURE_MEMORY_SANITIZER
+#include <sanitizer/msan_interface.h>
+#endif
-int rdrand64(uint64_t *ret) {
+int rdrand(unsigned long *ret) {
-#ifdef __x86_64__
+#if defined(__i386__) || defined(__x86_64__)
static int have_rdrand = -1;
unsigned char err;
@@ -56,6 +59,11 @@ int rdrand64(uint64_t *ret) {
"setc %1"
: "=r" (*ret),
"=qm" (err));
+
+#if HAS_FEATURE_MEMORY_SANITIZER
+ __msan_unpoison(&err, sizeof(err));
+#endif
+
if (!err)
return -EAGAIN;
@@ -65,85 +73,132 @@ int rdrand64(uint64_t *ret) {
#endif
}
-int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
+int genuine_random_bytes(void *p, size_t n, RandomFlags flags) {
static int have_syscall = -1;
-
_cleanup_close_ int fd = -1;
- size_t already_done = 0;
+ bool got_some = false;
int r;
- /* Gathers some randomness from the kernel. This call will never block. If
- * high_quality_required, it will always return some data from the kernel,
- * regardless of whether the random pool is fully initialized or not.
- * Otherwise, it will return success if at least some random bytes were
- * successfully acquired, and an error if the kernel has no entropy whatsover
- * for us. */
+ /* Gathers some randomness from the kernel (or the CPU if the RANDOM_ALLOW_RDRAND flag is set). This call won't
+ * block, unless the RANDOM_BLOCK flag is set. If RANDOM_DONT_DRAIN is set, an error is returned if the random
+ * pool is not initialized. Otherwise it will always return some data from the kernel, regardless of whether
+ * the random pool is fully initialized or not. */
+
+ if (n == 0)
+ return 0;
+
+ if (FLAGS_SET(flags, RANDOM_ALLOW_RDRAND))
+ /* Try x86-64' RDRAND intrinsic if we have it. We only use it if high quality randomness is not
+ * required, as we don't trust it (who does?). Note that we only do a single iteration of RDRAND here,
+ * even though the Intel docs suggest calling this in a tight loop of 10 invocations or so. That's
+ * because we don't really care about the quality here. We generally prefer using RDRAND if the caller
+ * allows us too, since this way we won't drain the kernel randomness pool if we don't need it, as the
+ * pool's entropy is scarce. */
+ for (;;) {
+ unsigned long u;
+ size_t m;
+
+ if (rdrand(&u) < 0) {
+ if (got_some && FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) {
+ /* Fill in the remaining bytes using pseudo-random values */
+ pseudo_random_bytes(p, n);
+ return 0;
+ }
+
+ /* OK, this didn't work, let's go to getrandom() + /dev/urandom instead */
+ break;
+ }
+
+ m = MIN(sizeof(u), n);
+ memcpy(p, &u, m);
+
+ p = (uint8_t*) p + m;
+ n -= m;
+
+ if (n == 0)
+ return 0; /* Yay, success! */
+
+ got_some = true;
+ }
/* Use the getrandom() syscall unless we know we don't have it. */
if (have_syscall != 0 && !HAS_FEATURE_MEMORY_SANITIZER) {
- r = getrandom(p, n, GRND_NONBLOCK);
- if (r > 0) {
- have_syscall = true;
- if ((size_t) r == n)
- return 0;
- if (!high_quality_required) {
- /* Fill in the remaining bytes using pseudorandom values */
- pseudorandom_bytes((uint8_t*) p + r, n - r);
- return 0;
- }
- already_done = r;
- } else if (errno == ENOSYS)
- /* We lack the syscall, continue with reading from /dev/urandom. */
- have_syscall = false;
- else if (errno == EAGAIN) {
- /* The kernel has no entropy whatsoever. Let's remember to
- * use the syscall the next time again though.
- *
- * If high_quality_required is false, return an error so that
- * random_bytes() can produce some pseudorandom
- * bytes. Otherwise, fall back to /dev/urandom, which we know
- * is empty, but the kernel will produce some bytes for us on
- * a best-effort basis. */
- have_syscall = true;
-
- if (!high_quality_required) {
- uint64_t u;
- size_t k;
-
- /* Try x86-64' RDRAND intrinsic if we have it. We only use it if high quality
- * randomness is not required, as we don't trust it (who does?). Note that we only do a
- * single iteration of RDRAND here, even though the Intel docs suggest calling this in
- * a tight loop of 10 invocatins or so. That's because we don't really care about the
- * quality here. */
-
- if (rdrand64(&u) < 0)
+ for (;;) {
+ r = getrandom(p, n, FLAGS_SET(flags, RANDOM_BLOCK) ? 0 : GRND_NONBLOCK);
+ if (r > 0) {
+ have_syscall = true;
+
+ if ((size_t) r == n)
+ return 0; /* Yay, success! */
+
+ assert((size_t) r < n);
+ p = (uint8_t*) p + r;
+ n -= r;
+
+ if (FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) {
+ /* Fill in the remaining bytes using pseudo-random values */
+ pseudo_random_bytes(p, n);
+ return 0;
+ }
+
+ got_some = true;
+
+ /* Hmm, we didn't get enough good data but the caller insists on good data? Then try again */
+ if (FLAGS_SET(flags, RANDOM_BLOCK))
+ continue;
+
+ /* Fill in the rest with /dev/urandom */
+ break;
+
+ } else if (r == 0) {
+ have_syscall = true;
+ return -EIO;
+
+ } else if (errno == ENOSYS) {
+ /* We lack the syscall, continue with reading from /dev/urandom. */
+ have_syscall = false;
+ break;
+
+ } else if (errno == EAGAIN) {
+ /* The kernel has no entropy whatsoever. Let's remember to use the syscall the next
+ * time again though.
+ *
+ * If RANDOM_DONT_DRAIN is set, return an error so that random_bytes() can produce some
+ * pseudo-random bytes instead. Otherwise, fall back to /dev/urandom, which we know is empty,
+ * but the kernel will produce some bytes for us on a best-effort basis. */
+ have_syscall = true;
+
+ if (got_some && FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) {
+ /* Fill in the remaining bytes using pseudorandom values */
+ pseudo_random_bytes(p, n);
+ return 0;
+ }
+
+ if (FLAGS_SET(flags, RANDOM_DONT_DRAIN))
return -ENODATA;
- k = MIN(n, sizeof(u));
- memcpy(p, &u, k);
-
- /* We only get 64bit out of RDRAND, the rest let's fill up with pseudo-random crap. */
- pseudorandom_bytes((uint8_t*) p + k, n - k);
- return 0;
- }
- } else
- return -errno;
+ /* Use /dev/urandom instead */
+ break;
+ } else
+ return -errno;
+ }
}
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return errno == ENOENT ? -ENOSYS : -errno;
- return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true);
+ return loop_read_exact(fd, p, n, true);
}
void initialize_srand(void) {
static bool srand_called = false;
unsigned x;
#if HAVE_SYS_AUXV_H
- void *auxv;
+ const void *auxv;
#endif
+ unsigned long k;
if (srand_called)
return;
@@ -153,7 +208,7 @@ void initialize_srand(void) {
* try to make use of that to seed the pseudo-random generator. It's
* better than nothing... */
- auxv = (void*) getauxval(AT_RANDOM);
+ auxv = (const void*) getauxval(AT_RANDOM);
if (auxv) {
assert_cc(sizeof(x) <= 16);
memcpy(&x, auxv, sizeof(x));
@@ -164,6 +219,9 @@ void initialize_srand(void) {
x ^= (unsigned) now(CLOCK_REALTIME);
x ^= (unsigned) gettid();
+ if (rdrand(&k) >= 0)
+ x ^= (unsigned) k;
+
srand(x);
srand_called = true;
}
@@ -176,7 +234,7 @@ void initialize_srand(void) {
# define RAND_STEP 1
#endif
-void pseudorandom_bytes(void *p, size_t n) {
+void pseudo_random_bytes(void *p, size_t n) {
uint8_t *q;
initialize_srand();
@@ -199,13 +257,10 @@ void pseudorandom_bytes(void *p, size_t n) {
}
void random_bytes(void *p, size_t n) {
- int r;
- r = acquire_random_bytes(p, n, false);
- if (r >= 0)
+ if (genuine_random_bytes(p, n, RANDOM_EXTEND_WITH_PSEUDO|RANDOM_DONT_DRAIN|RANDOM_ALLOW_RDRAND) >= 0)
return;
- /* If some idiot made /dev/urandom unavailable to us, or the
- * kernel has no entropy, use a PRNG instead. */
- return pseudorandom_bytes(p, n);
+ /* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */
+ pseudo_random_bytes(p, n);
}
diff --git a/src/systemd/src/basic/random-util.h b/src/systemd/src/basic/random-util.h
index affcc9ac1d..3e8c288d3d 100644
--- a/src/systemd/src/basic/random-util.h
+++ b/src/systemd/src/basic/random-util.h
@@ -5,9 +5,17 @@
#include <stddef.h>
#include <stdint.h>
-int acquire_random_bytes(void *p, size_t n, bool high_quality_required);
-void pseudorandom_bytes(void *p, size_t n);
-void random_bytes(void *p, size_t n);
+typedef enum RandomFlags {
+ RANDOM_EXTEND_WITH_PSEUDO = 1 << 0, /* If we can't get enough genuine randomness, but some, fill up the rest with pseudo-randomness */
+ RANDOM_BLOCK = 1 << 1, /* Rather block than return crap randomness (only if the kernel supports that) */
+ RANDOM_DONT_DRAIN = 1 << 2, /* If we can't get any randomness at all, return early with -EAGAIN */
+ RANDOM_ALLOW_RDRAND = 1 << 3, /* Allow usage of the CPU RNG */
+} RandomFlags;
+
+int genuine_random_bytes(void *p, size_t n, RandomFlags flags); /* returns "genuine" randomness, optionally filled upwith pseudo random, if not enough is available */
+void pseudo_random_bytes(void *p, size_t n); /* returns only pseudo-randommess (but possibly seeded from something better) */
+void random_bytes(void *p, size_t n); /* returns genuine randomness if cheaply available, and pseudo randomness if not. */
+
void initialize_srand(void);
static inline uint64_t random_u64(void) {
@@ -22,4 +30,4 @@ static inline uint32_t random_u32(void) {
return u;
}
-int rdrand64(uint64_t *ret);
+int rdrand(unsigned long *ret);
diff --git a/src/systemd/src/basic/sparse-endian.h b/src/systemd/src/basic/sparse-endian.h
index 8540ccd0ba..9583dda9e5 100644
--- a/src/systemd/src/basic/sparse-endian.h
+++ b/src/systemd/src/basic/sparse-endian.h
@@ -27,8 +27,8 @@
#include <stdint.h>
#ifdef __CHECKER__
-#define __sd_bitwise __attribute__((bitwise))
-#define __sd_force __attribute__((force))
+#define __sd_bitwise __attribute__((__bitwise__))
+#define __sd_force __attribute__((__force__))
#else
#define __sd_bitwise
#define __sd_force
diff --git a/src/systemd/src/basic/stat-util.c b/src/systemd/src/basic/stat-util.c
index 762777e94f..3bef0dfe44 100644
--- a/src/systemd/src/basic/stat-util.c
+++ b/src/systemd/src/basic/stat-util.c
@@ -47,10 +47,8 @@ int is_dir(const char* path, bool follow) {
int is_dir_fd(int fd) {
struct stat st;
- int r;
- r = fstat(fd, &st);
- if (r < 0)
+ if (fstat(fd, &st) < 0)
return -errno;
return !!S_ISDIR(st.st_mode);
@@ -215,15 +213,47 @@ int fd_is_network_fs(int fd) {
}
int fd_is_network_ns(int fd) {
+ struct statfs s;
int r;
- r = fd_is_fs_type(fd, NSFS_MAGIC);
- if (r <= 0)
- return r;
+ /* Checks whether the specified file descriptor refers to a network namespace. On old kernels there's no nice
+ * way to detect that, hence on those we'll return a recognizable error (EUCLEAN), so that callers can handle
+ * this somewhat nicely.
+ *
+ * This function returns > 0 if the fd definitely refers to a network namespace, 0 if it definitely does not
+ * refer to a network namespace, -EUCLEAN if we can't determine, and other negative error codes on error. */
+
+ if (fstatfs(fd, &s) < 0)
+ return -errno;
+
+ if (!is_fs_type(&s, NSFS_MAGIC)) {
+ /* On really old kernels, there was no "nsfs", and network namespace sockets belonged to procfs
+ * instead. Handle that in a somewhat smart way. */
+
+ if (is_fs_type(&s, PROC_SUPER_MAGIC)) {
+ struct statfs t;
+
+ /* OK, so it is procfs. Let's see if our own network namespace is procfs, too. If so, then the
+ * passed fd might refer to a network namespace, but we can't know for sure. In that case,
+ * return a recognizable error. */
+
+ if (statfs("/proc/self/ns/net", &t) < 0)
+ return -errno;
+
+ if (s.f_type == t.f_type)
+ return -EUCLEAN; /* It's possible, we simply don't know */
+ }
+
+ return 0; /* No! */
+ }
r = ioctl(fd, NS_GET_NSTYPE);
- if (r < 0)
+ if (r < 0) {
+ if (errno == ENOTTY) /* Old kernels didn't know this ioctl, let's also return a recognizable error in that case */
+ return -EUCLEAN;
+
return -errno;
+ }
return r == CLONE_NEWNET;
}
diff --git a/src/systemd/src/basic/stdio-util.h b/src/systemd/src/basic/stdio-util.h
index 73c03274c7..dc67b6e761 100644
--- a/src/systemd/src/basic/stdio-util.h
+++ b/src/systemd/src/basic/stdio-util.h
@@ -7,6 +7,7 @@
#include <sys/types.h>
#include "macro.h"
+#include "util.h"
#define snprintf_ok(buf, len, fmt, ...) \
((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len))
@@ -18,6 +19,9 @@
do { \
int _argtypes[128]; \
size_t _i, _k; \
+ /* See https://github.com/google/sanitizers/issues/992 */ \
+ if (HAS_FEATURE_MEMORY_SANITIZER) \
+ zero(_argtypes); \
_k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
assert(_k < ELEMENTSOF(_argtypes)); \
for (_i = 0; _i < _k; _i++) { \
diff --git a/src/systemd/src/basic/strv.c b/src/systemd/src/basic/strv.c
index 1bab723e88..3a62f25ded 100644
--- a/src/systemd/src/basic/strv.c
+++ b/src/systemd/src/basic/strv.c
@@ -169,7 +169,7 @@ char **strv_new_ap(const char *x, va_list ap) {
return TAKE_PTR(a);
}
-char **strv_new(const char *x, ...) {
+char **strv_new_internal(const char *x, ...) {
char **r;
va_list ap;
@@ -658,7 +658,7 @@ char **strv_split_nulstr(const char *s) {
}
if (!r)
- return strv_new(NULL, NULL);
+ return strv_new(NULL);
return r;
}
diff --git a/src/systemd/src/basic/strv.h b/src/systemd/src/basic/strv.h
index e9e6063f58..5f1803d87d 100644
--- a/src/systemd/src/basic/strv.h
+++ b/src/systemd/src/basic/strv.h
@@ -54,8 +54,9 @@ bool strv_equal(char **a, char **b);
#define strv_contains(l, s) (!!strv_find((l), (s)))
-char **strv_new(const char *x, ...) _sentinel_;
+char **strv_new_internal(const char *x, ...) _sentinel_;
char **strv_new_ap(const char *x, va_list ap);
+#define strv_new(...) strv_new_internal(__VA_ARGS__, NULL)
#define STRV_IGNORE ((const char *) -1)
diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c
index e351684219..30ad83d0a7 100644
--- a/src/systemd/src/basic/time-util.c
+++ b/src/systemd/src/basic/time-util.c
@@ -14,7 +14,6 @@
#include <unistd.h>
#include "alloc-util.h"
-#include "def.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
@@ -868,7 +867,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
return tmp.return_value;
}
-static char* extract_multiplier(char *p, usec_t *multiplier) {
+static const char* extract_multiplier(const char *p, usec_t *multiplier) {
static const struct {
const char *suffix;
usec_t usec;
@@ -942,8 +941,7 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
for (;;) {
usec_t multiplier = default_unit, k;
- long long l, z = 0;
- unsigned n = 0;
+ long long l;
char *e;
p += strspn(p, WHITESPACE);
@@ -966,46 +964,47 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
return -ERANGE;
if (*e == '.') {
- char *b = e + 1;
-
- /* Don't allow "0.-0", "3.+1" or "3. 1" */
- if (IN_SET(*b, '-', '+') || isspace(*b))
- return -EINVAL;
-
- errno = 0;
- z = strtoll(b, &e, 10);
- if (errno > 0)
- return -errno;
- if (z < 0)
- return -ERANGE;
- if (e == b)
- return -EINVAL;
-
- n = e - b;
-
+ p = e + 1;
+ p += strspn(p, DIGITS);
} else if (e == p)
return -EINVAL;
+ else
+ p = e;
- e += strspn(e, WHITESPACE);
- p = extract_multiplier(e, &multiplier);
+ s = extract_multiplier(p + strspn(p, WHITESPACE), &multiplier);
+ if (s == p && *s != '\0')
+ /* Don't allow '12.34.56', but accept '12.34 .56' or '12.34s.56'*/
+ return -EINVAL;
- something = true;
+ p = s;
+ if ((usec_t) l >= USEC_INFINITY / multiplier)
+ return -ERANGE;
- k = ((usec_t) -1) / multiplier;
- if ((usec_t) l + 1 >= k || (usec_t) z >= k)
+ k = (usec_t) l * multiplier;
+ if (k >= USEC_INFINITY - r)
return -ERANGE;
- k = (usec_t) z * multiplier;
+ r += k;
- for (; n > 0; n--)
- k /= 10;
+ something = true;
- k += (usec_t) l * multiplier;
- if (k >= ((usec_t) -1) - r)
- return -ERANGE;
+ if (*e == '.') {
+ usec_t m = multiplier / 10;
+ const char *b;
- r += k;
+ for (b = e + 1; *b >= '0' && *b <= '9'; b++, m /= 10) {
+ k = (usec_t) (*b - '0') * m;
+ if (k >= USEC_INFINITY - r)
+ return -ERANGE;
+
+ r += k;
+ }
+
+ /* Don't allow "0.-0", "3.+1", "3. 1", "3.sec" or "3.hoge"*/
+ if (b == e + 1)
+ return -EINVAL;
+ }
}
*usec = r;
@@ -1032,44 +1031,60 @@ int parse_sec_fix_0(const char *t, usec_t *ret) {
return r;
}
-int parse_nsec(const char *t, nsec_t *nsec) {
+static const char* extract_nsec_multiplier(const char *p, nsec_t *multiplier) {
static const struct {
const char *suffix;
nsec_t nsec;
} table[] = {
- { "seconds", NSEC_PER_SEC },
- { "second", NSEC_PER_SEC },
- { "sec", NSEC_PER_SEC },
- { "s", NSEC_PER_SEC },
+ { "seconds", NSEC_PER_SEC },
+ { "second", NSEC_PER_SEC },
+ { "sec", NSEC_PER_SEC },
+ { "s", NSEC_PER_SEC },
{ "minutes", NSEC_PER_MINUTE },
- { "minute", NSEC_PER_MINUTE },
- { "min", NSEC_PER_MINUTE },
- { "months", NSEC_PER_MONTH },
- { "month", NSEC_PER_MONTH },
- { "msec", NSEC_PER_MSEC },
- { "ms", NSEC_PER_MSEC },
- { "m", NSEC_PER_MINUTE },
- { "hours", NSEC_PER_HOUR },
- { "hour", NSEC_PER_HOUR },
- { "hr", NSEC_PER_HOUR },
- { "h", NSEC_PER_HOUR },
- { "days", NSEC_PER_DAY },
- { "day", NSEC_PER_DAY },
- { "d", NSEC_PER_DAY },
- { "weeks", NSEC_PER_WEEK },
- { "week", NSEC_PER_WEEK },
- { "w", NSEC_PER_WEEK },
- { "years", NSEC_PER_YEAR },
- { "year", NSEC_PER_YEAR },
- { "y", NSEC_PER_YEAR },
- { "usec", NSEC_PER_USEC },
- { "us", NSEC_PER_USEC },
- { "µs", NSEC_PER_USEC },
- { "nsec", 1ULL },
- { "ns", 1ULL },
- { "", 1ULL }, /* default is nsec */
+ { "minute", NSEC_PER_MINUTE },
+ { "min", NSEC_PER_MINUTE },
+ { "months", NSEC_PER_MONTH },
+ { "month", NSEC_PER_MONTH },
+ { "M", NSEC_PER_MONTH },
+ { "msec", NSEC_PER_MSEC },
+ { "ms", NSEC_PER_MSEC },
+ { "m", NSEC_PER_MINUTE },
+ { "hours", NSEC_PER_HOUR },
+ { "hour", NSEC_PER_HOUR },
+ { "hr", NSEC_PER_HOUR },
+ { "h", NSEC_PER_HOUR },
+ { "days", NSEC_PER_DAY },
+ { "day", NSEC_PER_DAY },
+ { "d", NSEC_PER_DAY },
+ { "weeks", NSEC_PER_WEEK },
+ { "week", NSEC_PER_WEEK },
+ { "w", NSEC_PER_WEEK },
+ { "years", NSEC_PER_YEAR },
+ { "year", NSEC_PER_YEAR },
+ { "y", NSEC_PER_YEAR },
+ { "usec", NSEC_PER_USEC },
+ { "us", NSEC_PER_USEC },
+ { "µs", NSEC_PER_USEC },
+ { "nsec", 1ULL },
+ { "ns", 1ULL },
+ { "", 1ULL }, /* default is nsec */
};
+ size_t i;
+
+ for (i = 0; i < ELEMENTSOF(table); i++) {
+ char *e;
+
+ e = startswith(p, table[i].suffix);
+ if (e) {
+ *multiplier = table[i].nsec;
+ return e;
+ }
+ }
+
+ return p;
+}
+int parse_nsec(const char *t, nsec_t *nsec) {
const char *p, *s;
nsec_t r = 0;
bool something = false;
@@ -1091,8 +1106,8 @@ int parse_nsec(const char *t, nsec_t *nsec) {
}
for (;;) {
- long long l, z = 0;
- size_t n = 0, i;
+ nsec_t multiplier = 1, k;
+ long long l;
char *e;
p += strspn(p, WHITESPACE);
@@ -1104,7 +1119,7 @@ int parse_nsec(const char *t, nsec_t *nsec) {
break;
}
- if (*p == '-')
+ if (*p == '-') /* Don't allow "-0" */
return -ERANGE;
errno = 0;
@@ -1115,54 +1130,47 @@ int parse_nsec(const char *t, nsec_t *nsec) {
return -ERANGE;
if (*e == '.') {
- char *b = e + 1;
-
- if (IN_SET(*b, '-', '+') || isspace(*b))
- return -EINVAL;
-
- errno = 0;
- z = strtoll(b, &e, 10);
- if (errno > 0)
- return -errno;
- if (z < 0)
- return -ERANGE;
- if (e == b)
- return -EINVAL;
-
- n = e - b;
-
+ p = e + 1;
+ p += strspn(p, DIGITS);
} else if (e == p)
return -EINVAL;
+ else
+ p = e;
- e += strspn(e, WHITESPACE);
+ s = extract_nsec_multiplier(p + strspn(p, WHITESPACE), &multiplier);
+ if (s == p && *s != '\0')
+ /* Don't allow '12.34.56', but accept '12.34 .56' or '12.34s.56'*/
+ return -EINVAL;
- for (i = 0; i < ELEMENTSOF(table); i++)
- if (startswith(e, table[i].suffix)) {
- nsec_t k;
+ p = s;
- k = ((nsec_t) -1) / table[i].nsec;
- if ((nsec_t) l + 1 >= k || (nsec_t) z >= k)
- return -ERANGE;
+ if ((nsec_t) l >= NSEC_INFINITY / multiplier)
+ return -ERANGE;
+
+ k = (nsec_t) l * multiplier;
+ if (k >= NSEC_INFINITY - r)
+ return -ERANGE;
- k = (nsec_t) z * table[i].nsec;
+ r += k;
+
+ something = true;
- for (; n > 0; n--)
- k /= 10;
+ if (*e == '.') {
+ nsec_t m = multiplier / 10;
+ const char *b;
- k += (nsec_t) l * table[i].nsec;
- if (k >= ((nsec_t) -1) - r)
+ for (b = e + 1; *b >= '0' && *b <= '9'; b++, m /= 10) {
+ k = (nsec_t) (*b - '0') * m;
+ if (k >= NSEC_INFINITY - r)
return -ERANGE;
r += k;
- p = e + strlen(table[i].suffix);
-
- something = true;
- break;
}
- if (i >= ELEMENTSOF(table))
- return -EINVAL;
-
+ /* Don't allow "0.-0", "3.+1", "3. 1", "3.sec" or "3.hoge"*/
+ if (b == e + 1)
+ return -EINVAL;
+ }
}
*nsec = r;
@@ -1190,7 +1198,7 @@ int get_timezones(char ***ret) {
assert(ret);
- zones = strv_new("UTC", NULL);
+ zones = strv_new("UTC");
if (!zones)
return -ENOMEM;
diff --git a/src/systemd/src/basic/util.c b/src/systemd/src/basic/util.c
index 0da963f4af..00052c5e1d 100644
--- a/src/systemd/src/basic/util.c
+++ b/src/systemd/src/basic/util.c
@@ -165,6 +165,28 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
return NULL;
}
+bool memeqzero(const void *data, size_t length) {
+ /* Does the buffer consist entirely of NULs?
+ * Copied from https://github.com/systemd/casync/, copied in turn from
+ * https://github.com/rustyrussell/ccan/blob/master/ccan/mem/mem.c#L92,
+ * which is licensed CC-0.
+ */
+
+ const uint8_t *p = data;
+ size_t i;
+
+ /* Check first 16 bytes manually */
+ for (i = 0; i < 16; i++, length--) {
+ if (length == 0)
+ return true;
+ if (p[i])
+ return false;
+ }
+
+ /* Now we know first 16 bytes are NUL, memcmp with self. */
+ return memcmp(data, p + i, length) == 0;
+}
+
int on_ac_power(void) {
bool found_offline = false, found_online = false;
_cleanup_closedir_ DIR *d = NULL;
@@ -248,7 +270,9 @@ int container_get_leader(const char *machine, pid_t *pid) {
return -EINVAL;
p = strjoina("/run/systemd/machines/", machine);
- r = parse_env_file(NULL, p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
+ r = parse_env_file(NULL, p,
+ "LEADER", &s,
+ "CLASS", &class);
if (r == -ENOENT)
return -EHOSTDOWN;
if (r < 0)
@@ -606,7 +630,7 @@ void disable_coredumps(void) {
if (detect_container() > 0)
return;
- r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+ r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", WRITE_STRING_FILE_DISABLE_BUFFER);
if (r < 0)
log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
}
diff --git a/src/systemd/src/basic/util.h b/src/systemd/src/basic/util.h
index 8cba4ed726..2f3d1eeab8 100644
--- a/src/systemd/src/basic/util.h
+++ b/src/systemd/src/basic/util.h
@@ -159,6 +159,10 @@ int on_ac_power(void);
#define zero(x) (memzero(&(x), sizeof(x)))
+bool memeqzero(const void *data, size_t length);
+
+#define eqzero(x) memeqzero(x, sizeof(x))
+
static inline void *mempset(void *s, int c, size_t n) {
memset(s, c, n);
return (uint8_t*)s + n;
@@ -168,7 +172,8 @@ static inline void _reset_errno_(int *saved_errno) {
errno = *saved_errno;
}
-#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
+#define PROTECT_ERRNO \
+ _cleanup_(_reset_errno_) __attribute__((__unused__)) int _saved_errno_ = errno
static inline int negative_errno(void) {
/* This helper should be used to shut up gcc if you know 'errno' is
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c
index 77c584ee60..c768adeb6d 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.c
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c
@@ -148,24 +148,30 @@ int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len) {
return 0;
}
-int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id) {
+int dhcp_identifier_set_iaid(
+ int ifindex,
+ const uint8_t *mac,
+ size_t mac_len,
+ bool legacy_unstable_byteorder,
+ void *_id) {
/* name is a pointer to memory in the sd_device struct, so must
* have the same scope */
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
const char *name = NULL;
uint64_t id;
+ uint32_t id32;
if (detect_container() <= 0) {
/* not in a container, udev will be around */
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
- int initialized, r;
+ int r;
sprintf(ifindex_str, "n%d", ifindex);
if (sd_device_new_from_device_id(&device, ifindex_str) >= 0) {
- r = sd_device_get_is_initialized(device, &initialized);
+ r = sd_device_get_is_initialized(device);
if (r < 0)
return r;
- if (!initialized)
+ if (r == 0)
/* not yet ready */
return -EBUSY;
@@ -179,10 +185,18 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
/* fall back to MAC address if no predictable name available */
id = siphash24(mac, mac_len, HASH_KEY.bytes);
- id = htole64(id);
+ id32 = (id & 0xffffffff) ^ (id >> 32);
- /* fold into 32 bits */
- unaligned_write_be32(_id, (id & 0xffffffff) ^ (id >> 32));
+ if (legacy_unstable_byteorder)
+ /* for historical reasons (a bug), the bits were swapped and thus
+ * the result was endianness dependant. Preserve that behavior. */
+ id32 = __bswap_32(id32);
+ else
+ /* the fixed behavior returns a stable byte order. Since LE is expected
+ * to be more common, swap the bytes on LE to give the same as legacy
+ * behavior. */
+ id32 = be32toh(id32);
+ unaligned_write_ne32(_id, id32);
return 0;
}
diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.h b/src/systemd/src/libsystemd-network/dhcp-identifier.h
index 64315d3a3b..a544f38ab8 100644
--- a/src/systemd/src/libsystemd-network/dhcp-identifier.h
+++ b/src/systemd/src/libsystemd-network/dhcp-identifier.h
@@ -57,4 +57,4 @@ int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *add
int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len);
-int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
+int dhcp_identifier_set_iaid(int ifindex, const uint8_t *mac, size_t mac_len, bool legacy_unstable_byteorder, void *_id);
diff --git a/src/systemd/src/libsystemd-network/dhcp-packet.c b/src/systemd/src/libsystemd-network/dhcp-packet.c
index d29cd06cb1..ad5f8e267a 100644
--- a/src/systemd/src/libsystemd-network/dhcp-packet.c
+++ b/src/systemd/src/libsystemd-network/dhcp-packet.c
@@ -106,70 +106,62 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui
/* IP */
- if (packet->ip.version != IPVERSION) {
- log_debug("ignoring packet: not IPv4");
- return -EINVAL;
- }
+ if (packet->ip.version != IPVERSION)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: not IPv4");
- if (packet->ip.ihl < 5) {
- log_debug("ignoring packet: IPv4 IHL (%u words) invalid",
- packet->ip.ihl);
- return -EINVAL;
- }
+ if (packet->ip.ihl < 5)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: IPv4 IHL (%u words) invalid",
+ packet->ip.ihl);
hdrlen = packet->ip.ihl * 4;
- if (hdrlen < 20) {
- log_debug("ignoring packet: IPv4 IHL (%zu bytes) "
- "smaller than minimum (20 bytes)", hdrlen);
- return -EINVAL;
- }
-
- if (len < hdrlen) {
- log_debug("ignoring packet: packet (%zu bytes) "
- "smaller than expected (%zu) by IP header", len,
- hdrlen);
- return -EINVAL;
- }
+ if (hdrlen < 20)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: IPv4 IHL (%zu bytes) "
+ "smaller than minimum (20 bytes)",
+ hdrlen);
+
+ if (len < hdrlen)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: packet (%zu bytes) "
+ "smaller than expected (%zu) by IP header",
+ len, hdrlen);
/* UDP */
- if (packet->ip.protocol != IPPROTO_UDP) {
- log_debug("ignoring packet: not UDP");
- return -EINVAL;
- }
+ if (packet->ip.protocol != IPPROTO_UDP)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: not UDP");
- if (len < hdrlen + be16toh(packet->udp.len)) {
- log_debug("ignoring packet: packet (%zu bytes) "
- "smaller than expected (%zu) by UDP header", len,
- hdrlen + be16toh(packet->udp.len));
- return -EINVAL;
- }
+ if (len < hdrlen + be16toh(packet->udp.len))
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: packet (%zu bytes) "
+ "smaller than expected (%zu) by UDP header",
+ len, hdrlen + be16toh(packet->udp.len));
- if (be16toh(packet->udp.dest) != port) {
- log_debug("ignoring packet: to port %u, which "
- "is not the DHCP client port (%u)",
- be16toh(packet->udp.dest), port);
- return -EINVAL;
- }
+ if (be16toh(packet->udp.dest) != port)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: to port %u, which "
+ "is not the DHCP client port (%u)",
+ be16toh(packet->udp.dest), port);
/* checksums - computing these is relatively expensive, so only do it
if all the other checks have passed
*/
- if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen)) {
- log_debug("ignoring packet: invalid IP checksum");
- return -EINVAL;
- }
+ if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen))
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: invalid IP checksum");
if (checksum && packet->udp.check) {
packet->ip.check = packet->udp.len;
packet->ip.ttl = 0;
if (dhcp_packet_checksum((uint8_t*)&packet->ip.ttl,
- be16toh(packet->udp.len) + 12)) {
- log_debug("ignoring packet: invalid UDP checksum");
- return -EINVAL;
- }
+ be16toh(packet->udp.len) + 12))
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "ignoring packet: invalid UDP checksum");
}
return 0;
diff --git a/src/systemd/src/libsystemd-network/lldp-internal.h b/src/systemd/src/libsystemd-network/lldp-internal.h
index 328d51f8ea..88b54933c3 100644
--- a/src/systemd/src/libsystemd-network/lldp-internal.h
+++ b/src/systemd/src/libsystemd-network/lldp-internal.h
@@ -34,3 +34,6 @@ struct sd_lldp {
#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__)
+
+const char* lldp_event_to_string(sd_lldp_event e) _const_;
+sd_lldp_event lldp_event_from_string(const char *s) _pure_;
diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c
index 949798a1d3..d35e3e2ce1 100644
--- a/src/systemd/src/libsystemd-network/network-internal.c
+++ b/src/systemd/src/libsystemd-network/network-internal.c
@@ -255,11 +255,10 @@ int config_parse_ifalias(const char *unit,
return 0;
}
- free(*s);
- if (*n)
- *s = TAKE_PTR(n);
+ if (isempty(n))
+ *s = mfree(*s);
else
- *s = NULL;
+ free_and_replace(*s, n);
return 0;
}
@@ -294,7 +293,7 @@ int config_parse_hwaddr(const char *unit,
return 0;
}
- *hwaddr = TAKE_PTR(n);
+ free_and_replace(*hwaddr, n);
return 0;
}
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index dde2d0ceb0..df9428518f 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -21,6 +21,7 @@
#include "dhcp-lease-internal.h"
#include "dhcp-protocol.h"
#include "dns-domain.h"
+#include "event-util.h"
#include "hostname-util.h"
#include "random-util.h"
#include "string-util.h"
@@ -371,6 +372,7 @@ static int dhcp_client_set_iaid_duid_internal(
if (iaid == 0) {
r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
client->mac_addr_len,
+ true,
&client->client_id.ns.iaid);
if (r < 0)
return r;
@@ -545,11 +547,10 @@ static int client_initialize(sd_dhcp_client *client) {
client->fd = asynchronous_close(client->fd);
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
- client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
- client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
- client->timeout_expire = sd_event_source_unref(client->timeout_expire);
+ (void) event_source_disable(client->timeout_resend);
+ (void) event_source_disable(client->timeout_t1);
+ (void) event_source_disable(client->timeout_t2);
+ (void) event_source_disable(client->timeout_expire);
client->attempt = 1;
@@ -650,7 +651,8 @@ static int client_message_init(
client->client_id.type = 255;
- r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
+ r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
+ true, &client->client_id.ns.iaid);
if (r < 0)
return r;
@@ -1063,22 +1065,11 @@ static int client_timeout_resend(
next_timeout += (random_u32() & 0x1fffff);
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
- r = sd_event_add_time(client->event,
- &client->timeout_resend,
- clock_boottime_or_monotonic(),
- next_timeout, 10 * USEC_PER_MSEC,
- client_timeout_resend, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
+ r = event_reset_time(client->event, &client->timeout_resend,
+ clock_boottime_or_monotonic(),
+ next_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_resend, client,
+ client->event_priority, "dhcp4-resend-timer", true);
if (r < 0)
goto error;
@@ -1175,31 +1166,16 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
assert(client);
assert(client->event);
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
if (client->start_delay) {
assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
usec += client->start_delay;
}
- r = sd_event_add_time(client->event,
- &client->timeout_resend,
- clock_boottime_or_monotonic(),
- usec, 0,
- client_timeout_resend, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
- if (r < 0)
- goto error;
-
-error:
+ r = event_reset_time(client->event, &client->timeout_resend,
+ clock_boottime_or_monotonic(),
+ usec, 0,
+ client_timeout_resend, client,
+ client->event_priority, "dhcp4-resend-timer", true);
if (r < 0)
client_stop(client, r);
@@ -1457,13 +1433,14 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
assert(client->lease);
assert(client->lease->lifetime);
- client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
- client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
- client->timeout_expire = sd_event_source_unref(client->timeout_expire);
-
/* don't set timers for infinite leases */
- if (client->lease->lifetime == 0xffffffff)
+ if (client->lease->lifetime == 0xffffffff) {
+ (void) event_source_disable(client->timeout_t1);
+ (void) event_source_disable(client->timeout_t2);
+ (void) event_source_disable(client->timeout_expire);
+
return 0;
+ }
r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
if (r < 0)
@@ -1515,19 +1492,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
}
/* arm lifetime timeout */
- r = sd_event_add_time(client->event, &client->timeout_expire,
- clock_boottime_or_monotonic(),
- lifetime_timeout, 10 * USEC_PER_MSEC,
- client_timeout_expire, client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_expire,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
+ r = event_reset_time(client->event, &client->timeout_expire,
+ clock_boottime_or_monotonic(),
+ lifetime_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_expire, client,
+ client->event_priority, "dhcp4-lifetime", true);
if (r < 0)
return r;
@@ -1539,21 +1508,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
return 0;
/* arm T2 timeout */
- r = sd_event_add_time(client->event,
- &client->timeout_t2,
- clock_boottime_or_monotonic(),
- t2_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_t2, client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_t2,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
+ r = event_reset_time(client->event, &client->timeout_t2,
+ clock_boottime_or_monotonic(),
+ t2_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_t2, client,
+ client->event_priority, "dhcp4-t2-timeout", true);
if (r < 0)
return r;
@@ -1565,20 +1524,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
return 0;
/* arm T1 timeout */
- r = sd_event_add_time(client->event,
- &client->timeout_t1,
- clock_boottime_or_monotonic(),
- t1_timeout, 10 * USEC_PER_MSEC,
- client_timeout_t1, client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_t1,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
+ r = event_reset_time(client->event, &client->timeout_t1,
+ clock_boottime_or_monotonic(),
+ t1_timeout, 10 * USEC_PER_MSEC,
+ client_timeout_t1, client,
+ client->event_priority, "dhcp4-t1-timer", true);
if (r < 0)
return r;
@@ -1603,26 +1553,14 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
r = client_handle_offer(client, message, len);
if (r >= 0) {
- client->timeout_resend =
- sd_event_source_unref(client->timeout_resend);
-
client->state = DHCP_STATE_REQUESTING;
client->attempt = 1;
- r = sd_event_add_time(client->event,
- &client->timeout_resend,
- clock_boottime_or_monotonic(),
- 0, 0,
- client_timeout_resend, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
+ r = event_reset_time(client->event, &client->timeout_resend,
+ clock_boottime_or_monotonic(),
+ 0, 0,
+ client_timeout_resend, client,
+ client->event_priority, "dhcp4-resend-timer", true);
if (r < 0)
goto error;
} else if (r == -ENOMSG)
@@ -1639,8 +1577,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
r = client_handle_ack(client, message, len);
if (r >= 0) {
client->start_delay = 0;
- client->timeout_resend =
- sd_event_source_unref(client->timeout_resend);
+ (void) event_source_disable(client->timeout_resend);
client->receive_message =
sd_event_source_unref(client->receive_message);
client->fd = asynchronous_close(client->fd);
@@ -1680,9 +1617,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
} else if (r == -EADDRNOTAVAIL) {
/* got a NAK, let's restart the client */
- client->timeout_resend =
- sd_event_source_unref(client->timeout_resend);
-
client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
r = client_initialize(client);
@@ -1958,9 +1892,12 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
log_dhcp_client(client, "FREE");
- client_initialize(client);
+ client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+ client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+ client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+ client->timeout_expire = sd_event_source_unref(client->timeout_expire);
- client->receive_message = sd_event_source_unref(client->receive_message);
+ client_initialize(client);
sd_dhcp_client_detach_event(client);
@@ -1980,19 +1917,20 @@ int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
assert_return(ret, -EINVAL);
- client = new0(sd_dhcp_client, 1);
+ client = new(sd_dhcp_client, 1);
if (!client)
return -ENOMEM;
- client->n_ref = 1;
- client->state = DHCP_STATE_INIT;
- client->ifindex = -1;
- client->fd = -1;
- client->attempt = 1;
- client->mtu = DHCP_DEFAULT_MIN_SIZE;
- client->port = DHCP_PORT_CLIENT;
-
- client->anonymize = !!anonymize;
+ *client = (sd_dhcp_client) {
+ .n_ref = 1,
+ .state = DHCP_STATE_INIT,
+ .ifindex = -1,
+ .fd = -1,
+ .attempt = 1,
+ .mtu = DHCP_DEFAULT_MIN_SIZE,
+ .port = DHCP_PORT_CLIENT,
+ .anonymize = !!anonymize,
+ };
/* NOTE: this could be moved to a function. */
if (anonymize) {
client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
index 863818d6da..a90c01d7db 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
@@ -1016,7 +1016,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
if (r < 0)
return r;
- r = parse_env_file(NULL, lease_file, NEWLINE,
+ r = parse_env_file(NULL, lease_file,
"ADDRESS", &address,
"ROUTER", &router,
"NETMASK", &netmask,
@@ -1067,8 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"OPTION_251", &options[27],
"OPTION_252", &options[28],
"OPTION_253", &options[29],
- "OPTION_254", &options[30],
- NULL);
+ "OPTION_254", &options[30]);
if (r < 0)
return r;
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 2ddfead4b0..c81c0f0955 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -16,6 +16,7 @@
#include "dhcp6-lease-internal.h"
#include "dhcp6-protocol.h"
#include "dns-domain.h"
+#include "event-util.h"
#include "fd-util.h"
#include "hostname-util.h"
#include "in-addr-util.h"
@@ -408,12 +409,11 @@ static int client_reset(sd_dhcp6_client *client) {
client->retransmit_time = 0;
client->retransmit_count = 0;
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
- client->timeout_resend_expire =
- sd_event_source_unref(client->timeout_resend_expire);
- client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
- client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+ (void) event_source_disable(client->timeout_resend);
+ (void) event_source_disable(client->timeout_resend_expire);
+ (void) event_source_disable(client->timeout_t1);
+ (void) event_source_disable(client->timeout_t2);
client->state = DHCP6_STATE_STOPPED;
@@ -600,8 +600,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
assert(client);
assert(client->lease);
- client->timeout_t2 =
- sd_event_source_unref(client->timeout_t2);
+ (void) event_source_disable(client->timeout_t2);
log_dhcp6_client(client, "Timeout T2");
@@ -617,8 +616,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
assert(client);
assert(client->lease);
- client->timeout_t1 =
- sd_event_source_unref(client->timeout_t1);
+ (void) event_source_disable(client->timeout_t1);
log_dhcp6_client(client, "Timeout T1");
@@ -666,7 +664,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
assert(client);
assert(client->event);
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+ (void) event_source_disable(client->timeout_resend);
switch (client->state) {
case DHCP6_STATE_INFORMATION_REQUEST:
@@ -708,7 +706,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
init_retransmit_time = DHCP6_REB_TIMEOUT;
max_retransmit_time = DHCP6_REB_MAX_RT;
- if (!client->timeout_resend_expire) {
+ if (event_source_is_enabled(client->timeout_resend_expire) <= 0) {
r = dhcp6_lease_ia_rebind_expire(&client->lease->ia,
&expire);
if (r < 0) {
@@ -757,43 +755,24 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
log_dhcp6_client(client, "Next retransmission in %s",
format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->retransmit_time, USEC_PER_SEC));
- r = sd_event_add_time(client->event, &client->timeout_resend,
- clock_boottime_or_monotonic(),
- time_now + client->retransmit_time,
- 10 * USEC_PER_MSEC, client_timeout_resend,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timer");
+ r = event_reset_time(client->event, &client->timeout_resend,
+ clock_boottime_or_monotonic(),
+ time_now + client->retransmit_time, 10 * USEC_PER_MSEC,
+ client_timeout_resend, client,
+ client->event_priority, "dhcp6-resend-timer", true);
if (r < 0)
goto error;
- if (max_retransmit_duration && !client->timeout_resend_expire) {
+ if (max_retransmit_duration && event_source_is_enabled(client->timeout_resend_expire) <= 0) {
log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs",
max_retransmit_duration / USEC_PER_SEC);
- r = sd_event_add_time(client->event,
- &client->timeout_resend_expire,
- clock_boottime_or_monotonic(),
- time_now + max_retransmit_duration,
- USEC_PER_SEC,
- client_timeout_resend_expire, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend_expire,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend_expire, "dhcp6-resend-expire-timer");
+ r = event_reset_time(client->event, &client->timeout_resend_expire,
+ clock_boottime_or_monotonic(),
+ time_now + max_retransmit_duration, USEC_PER_SEC,
+ client_timeout_resend_expire, client,
+ client->event_priority, "dhcp6-resend-expire-timer", true);
if (r < 0)
goto error;
}
@@ -807,14 +786,14 @@ error:
static int client_ensure_iaid(sd_dhcp6_client *client) {
int r;
- be32_t iaid;
+ uint32_t iaid;
assert(client);
if (client->ia_na.ia_na.id)
return 0;
- r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &iaid);
+ r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, true, &iaid);
if (r < 0)
return r;
@@ -1263,9 +1242,8 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
assert_return(client->ifindex > 0, -EINVAL);
assert_return(client->state != state, -EINVAL);
- client->timeout_resend_expire =
- sd_event_source_unref(client->timeout_resend_expire);
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+ (void) event_source_disable(client->timeout_resend_expire);
+ (void) event_source_disable(client->timeout_resend);
client->retransmit_time = 0;
client->retransmit_count = 0;
@@ -1332,20 +1310,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
log_dhcp6_client(client, "T1 expires in %s",
format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
- r = sd_event_add_time(client->event,
- &client->timeout_t1,
- clock_boottime_or_monotonic(), time_now + timeout,
- 10 * USEC_PER_SEC, client_timeout_t1,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_t1,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_t1, "dhcp6-t1-timeout");
+ r = event_reset_time(client->event, &client->timeout_t1,
+ clock_boottime_or_monotonic(),
+ time_now + timeout, 10 * USEC_PER_SEC,
+ client_timeout_t1, client,
+ client->event_priority, "dhcp6-t1-timeout", true);
if (r < 0)
goto error;
@@ -1354,20 +1323,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
log_dhcp6_client(client, "T2 expires in %s",
format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
- r = sd_event_add_time(client->event,
- &client->timeout_t2,
- clock_boottime_or_monotonic(), time_now + timeout,
- 10 * USEC_PER_SEC, client_timeout_t2,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_t2,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_t2, "dhcp6-t2-timeout");
+ r = event_reset_time(client->event, &client->timeout_t2,
+ clock_boottime_or_monotonic(),
+ time_now + timeout, 10 * USEC_PER_SEC,
+ client_timeout_t2, client,
+ client->event_priority, "dhcp6-t2-timeout", true);
if (r < 0)
goto error;
@@ -1379,18 +1339,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
client->transaction_id = random_u32() & htobe32(0x00ffffff);
client->transaction_start = time_now;
- r = sd_event_add_time(client->event, &client->timeout_resend,
- clock_boottime_or_monotonic(), 0, 0, client_timeout_resend,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout");
+ r = event_reset_time(client->event, &client->timeout_resend,
+ clock_boottime_or_monotonic(),
+ 0, 0,
+ client_timeout_resend, client,
+ client->event_priority, "dhcp6-resend-timeout", true);
if (r < 0)
goto error;
@@ -1503,6 +1456,11 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
assert(client);
+ client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+ client->timeout_resend_expire = sd_event_source_unref(client->timeout_resend_expire);
+ client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+ client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+
client_reset(client);
client->fd = safe_close(client->fd);
@@ -1518,28 +1476,32 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_client, sd_dhcp6_client, dhcp6_client_fre
int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
_cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
+ _cleanup_free_ be16_t *req_opts = NULL;
size_t t;
assert_return(ret, -EINVAL);
- client = new0(sd_dhcp6_client, 1);
- if (!client)
+ req_opts = new(be16_t, ELEMENTSOF(default_req_opts));
+ if (!req_opts)
return -ENOMEM;
- client->n_ref = 1;
- client->ia_na.type = SD_DHCP6_OPTION_IA_NA;
- client->ia_pd.type = SD_DHCP6_OPTION_IA_PD;
- client->ifindex = -1;
- client->request = DHCP6_REQUEST_IA_NA;
- client->fd = -1;
+ for (t = 0; t < ELEMENTSOF(default_req_opts); t++)
+ req_opts[t] = htobe16(default_req_opts[t]);
- client->req_opts_len = ELEMENTSOF(default_req_opts);
- client->req_opts = new0(be16_t, client->req_opts_len);
- if (!client->req_opts)
+ client = new(sd_dhcp6_client, 1);
+ if (!client)
return -ENOMEM;
- for (t = 0; t < client->req_opts_len; t++)
- client->req_opts[t] = htobe16(default_req_opts[t]);
+ *client = (sd_dhcp6_client) {
+ .n_ref = 1,
+ .ia_na.type = SD_DHCP6_OPTION_IA_NA,
+ .ia_pd.type = SD_DHCP6_OPTION_IA_PD,
+ .ifindex = -1,
+ .request = DHCP6_REQUEST_IA_NA,
+ .fd = -1,
+ .req_opts_len = ELEMENTSOF(default_req_opts),
+ .req_opts = TAKE_PTR(req_opts),
+ };
*ret = TAKE_PTR(client);
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
index 6c12b5144e..59359aec79 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
@@ -14,6 +14,7 @@
#include "alloc-util.h"
#include "arp-util.h"
#include "ether-addr-util.h"
+#include "event-util.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "list.h"
@@ -89,7 +90,7 @@ static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_count
static void ipv4acd_reset(sd_ipv4acd *acd) {
assert(acd);
- acd->timer_event_source = sd_event_source_unref(acd->timer_event_source);
+ (void) event_source_disable(acd->timer_event_source);
acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source);
acd->fd = safe_close(acd->fd);
@@ -100,6 +101,8 @@ static void ipv4acd_reset(sd_ipv4acd *acd) {
static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) {
assert(acd);
+ acd->timer_event_source = sd_event_source_unref(acd->timer_event_source);
+
ipv4acd_reset(acd);
sd_ipv4acd_detach_event(acd);
@@ -113,14 +116,16 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) {
assert_return(ret, -EINVAL);
- acd = new0(sd_ipv4acd, 1);
+ acd = new(sd_ipv4acd, 1);
if (!acd)
return -ENOMEM;
- acd->n_ref = 1;
- acd->state = IPV4ACD_STATE_INIT;
- acd->ifindex = -1;
- acd->fd = -1;
+ *acd = (sd_ipv4acd) {
+ .n_ref = 1,
+ .state = IPV4ACD_STATE_INIT,
+ .ifindex = -1,
+ .fd = -1,
+ };
*ret = TAKE_PTR(acd);
@@ -151,9 +156,7 @@ int sd_ipv4acd_stop(sd_ipv4acd *acd) {
static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata);
static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) {
- _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL;
usec_t next_timeout, time_now;
- int r;
assert(acd);
@@ -164,20 +167,11 @@ static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_u
assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
- r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(timer, acd->event_priority);
- if (r < 0)
- return r;
-
- (void) sd_event_source_set_description(timer, "ipv4acd-timer");
-
- sd_event_source_unref(acd->timer_event_source);
- acd->timer_event_source = TAKE_PTR(timer);
-
- return 0;
+ return event_reset_time(acd->event, &acd->timer_event_source,
+ clock_boottime_or_monotonic(),
+ time_now + next_timeout, 0,
+ ipv4acd_on_timeout, acd,
+ acd->event_priority, "ipv4acd-timer", true);
}
static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) {
diff --git a/src/systemd/src/libsystemd-network/sd-lldp.c b/src/systemd/src/libsystemd-network/sd-lldp.c
index f72ef204b9..4e3ee53cd7 100644
--- a/src/systemd/src/libsystemd-network/sd-lldp.c
+++ b/src/systemd/src/libsystemd-network/sd-lldp.c
@@ -6,15 +6,26 @@
#include "sd-lldp.h"
#include "alloc-util.h"
+#include "ether-addr-util.h"
+#include "event-util.h"
#include "fd-util.h"
#include "lldp-internal.h"
#include "lldp-neighbor.h"
#include "lldp-network.h"
#include "socket-util.h"
-#include "ether-addr-util.h"
+#include "string-table.h"
#define LLDP_DEFAULT_NEIGHBORS_MAX 128U
+static const char * const lldp_event_table[_SD_LLDP_EVENT_MAX] = {
+ [SD_LLDP_EVENT_ADDED] = "added",
+ [SD_LLDP_EVENT_REMOVED] = "removed",
+ [SD_LLDP_EVENT_UPDATED] = "updated",
+ [SD_LLDP_EVENT_REFRESHED] = "refreshed",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(lldp_event, sd_lldp_event);
+
static void lldp_flush_neighbors(sd_lldp *lldp) {
sd_lldp_neighbor *n;
@@ -26,12 +37,14 @@ static void lldp_flush_neighbors(sd_lldp *lldp) {
static void lldp_callback(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n) {
assert(lldp);
+ assert(event >= 0 && event < _SD_LLDP_EVENT_MAX);
- log_lldp("Invoking callback for '%c'.", event);
-
- if (!lldp->callback)
+ if (!lldp->callback) {
+ log_lldp("Received '%s' event.", lldp_event_to_string(event));
return;
+ }
+ log_lldp("Invoking callback for '%s' event.", lldp_event_to_string(event));
lldp->callback(lldp, event, n, lldp->userdata);
}
@@ -223,7 +236,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v
static void lldp_reset(sd_lldp *lldp) {
assert(lldp);
- lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source);
+ (void) event_source_disable(lldp->timer_event_source);
lldp->io_event_source = sd_event_source_unref(lldp->io_event_source);
lldp->fd = safe_close(lldp->fd);
}
@@ -332,6 +345,8 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) {
static sd_lldp* lldp_free(sd_lldp *lldp) {
assert(lldp);
+ lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source);
+
lldp_reset(lldp);
sd_lldp_detach_event(lldp);
lldp_flush_neighbors(lldp);
@@ -349,14 +364,16 @@ _public_ int sd_lldp_new(sd_lldp **ret) {
assert_return(ret, -EINVAL);
- lldp = new0(sd_lldp, 1);
+ lldp = new(sd_lldp, 1);
if (!lldp)
return -ENOMEM;
- lldp->n_ref = 1;
- lldp->fd = -1;
- lldp->neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX;
- lldp->capability_mask = (uint16_t) -1;
+ *lldp = (sd_lldp) {
+ .n_ref = 1,
+ .fd = -1,
+ .neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX,
+ .capability_mask = (uint16_t) -1,
+ };
lldp->neighbor_by_id = hashmap_new(&lldp_neighbor_id_hash_ops);
if (!lldp->neighbor_by_id)
@@ -392,7 +409,6 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
sd_lldp_neighbor *n;
- int r;
assert(lldp);
@@ -400,35 +416,17 @@ static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
lldp_neighbor_start_ttl(neighbor);
n = prioq_peek(lldp->neighbor_by_expiry);
- if (!n) {
-
- if (lldp->timer_event_source)
- return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_OFF);
-
- return 0;
- }
-
- if (lldp->timer_event_source) {
- r = sd_event_source_set_time(lldp->timer_event_source, n->until);
- if (r < 0)
- return r;
-
- return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_ONESHOT);
- }
+ if (!n)
+ return event_source_disable(lldp->timer_event_source);
if (!lldp->event)
return 0;
- r = sd_event_add_time(lldp->event, &lldp->timer_event_source, clock_boottime_or_monotonic(), n->until, 0, on_timer_event, lldp);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(lldp->timer_event_source, lldp->event_priority);
- if (r < 0)
- return r;
-
- (void) sd_event_source_set_description(lldp->timer_event_source, "lldp-timer");
- return 0;
+ return event_reset_time(lldp->event, &lldp->timer_event_source,
+ clock_boottime_or_monotonic(),
+ n->until, 0,
+ on_timer_event, lldp,
+ lldp->event_priority, "lldp-timer", true);
}
_public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
diff --git a/src/systemd/src/libsystemd/sd-event/event-util.c b/src/systemd/src/libsystemd/sd-event/event-util.c
new file mode 100644
index 0000000000..43e73d55e1
--- /dev/null
+++ b/src/systemd/src/libsystemd/sd-event/event-util.c
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+
+#include "event-source.h"
+#include "event-util.h"
+#include "log.h"
+#include "string-util.h"
+
+int event_reset_time(
+ sd_event *e,
+ sd_event_source **s,
+ clockid_t clock,
+ uint64_t usec,
+ uint64_t accuracy,
+ sd_event_time_handler_t callback,
+ void *userdata,
+ int64_t priority,
+ const char *description,
+ bool force_reset) {
+
+ bool created = false;
+ int enabled, r;
+ clockid_t c;
+
+ assert(e);
+ assert(s);
+
+ if (*s) {
+ if (!force_reset) {
+ r = sd_event_source_get_enabled(*s, &enabled);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to query whether event source \"%s\" is enabled or not: %m",
+ strna((*s)->description ?: description));
+
+ if (enabled != SD_EVENT_OFF)
+ return 0;
+ }
+
+ r = sd_event_source_get_time_clock(*s, &c);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to get clock id of event source \"%s\": %m", strna((*s)->description ?: description));
+
+ if (c != clock)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "sd-event: Current clock id %i of event source \"%s\" is different from specified one %i.",
+ (int)c,
+ strna((*s)->description ? : description),
+ (int)clock);
+
+ r = sd_event_source_set_time(*s, usec);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to set time for event source \"%s\": %m", strna((*s)->description ?: description));
+
+ r = sd_event_source_set_time_accuracy(*s, accuracy);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to set accuracy for event source \"%s\": %m", strna((*s)->description ?: description));
+
+ /* callback function is not updated, as we do not have sd_event_source_set_time_callback(). */
+
+ (void) sd_event_source_set_userdata(*s, userdata);
+
+ r = sd_event_source_set_enabled(*s, SD_EVENT_ONESHOT);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to enable event source \"%s\": %m", strna((*s)->description ?: description));
+ } else {
+ r = sd_event_add_time(e, s, clock, usec, accuracy, callback, userdata);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to create timer event \"%s\": %m", strna(description));
+
+ created = true;
+ }
+
+ r = sd_event_source_set_priority(*s, priority);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to set priority for event source \"%s\": %m", strna((*s)->description ?: description));
+
+ if (description) {
+ r = sd_event_source_set_description(*s, description);
+ if (r < 0)
+ return log_debug_errno(r, "sd-event: Failed to set description for event source \"%s\": %m", description);
+ }
+
+ return created;
+}
+
+int event_source_disable(sd_event_source *s) {
+ if (!s)
+ return 0;
+
+ return sd_event_source_set_enabled(s, SD_EVENT_OFF);
+}
+
+int event_source_is_enabled(sd_event_source *s) {
+ if (!s)
+ return false;
+
+ return sd_event_source_get_enabled(s, NULL);
+}
diff --git a/src/systemd/src/libsystemd/sd-event/event-util.h b/src/systemd/src/libsystemd/sd-event/event-util.h
new file mode 100644
index 0000000000..00180955f9
--- /dev/null
+++ b/src/systemd/src/libsystemd/sd-event/event-util.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "sd-event.h"
+
+int event_reset_time(sd_event *e, sd_event_source **s,
+ clockid_t clock, uint64_t usec, uint64_t accuracy,
+ sd_event_time_handler_t callback, void *userdata,
+ int64_t priority, const char *description, bool force_reset);
+int event_source_disable(sd_event_source *s);
+int event_source_is_enabled(sd_event_source *s);
diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c
index f44e6b4cca..f0c58a589a 100644
--- a/src/systemd/src/libsystemd/sd-event/sd-event.c
+++ b/src/systemd/src/libsystemd/sd-event/sd-event.c
@@ -9,6 +9,7 @@
#include "sd-id128.h"
#include "alloc-util.h"
+#include "event-source.h"
#include "fd-util.h"
#include "fs-util.h"
#include "hashmap.h"
@@ -26,24 +27,6 @@
#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
-typedef enum EventSourceType {
- SOURCE_IO,
- SOURCE_TIME_REALTIME,
- SOURCE_TIME_BOOTTIME,
- SOURCE_TIME_MONOTONIC,
- SOURCE_TIME_REALTIME_ALARM,
- SOURCE_TIME_BOOTTIME_ALARM,
- SOURCE_SIGNAL,
- SOURCE_CHILD,
- SOURCE_DEFER,
- SOURCE_POST,
- SOURCE_EXIT,
- SOURCE_WATCHDOG,
- SOURCE_INOTIFY,
- _SOURCE_EVENT_SOURCE_TYPE_MAX,
- _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
-} EventSourceType;
-
static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
[SOURCE_IO] = "io",
[SOURCE_TIME_REALTIME] = "realtime",
@@ -62,183 +45,8 @@ static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX]
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int);
-/* All objects we use in epoll events start with this value, so that
- * we know how to dispatch it */
-typedef enum WakeupType {
- WAKEUP_NONE,
- WAKEUP_EVENT_SOURCE,
- WAKEUP_CLOCK_DATA,
- WAKEUP_SIGNAL_DATA,
- WAKEUP_INOTIFY_DATA,
- _WAKEUP_TYPE_MAX,
- _WAKEUP_TYPE_INVALID = -1,
-} WakeupType;
-
#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
-struct inode_data;
-
-struct sd_event_source {
- WakeupType wakeup;
-
- unsigned n_ref;
-
- sd_event *event;
- void *userdata;
- sd_event_handler_t prepare;
-
- char *description;
-
- EventSourceType type:5;
- signed int enabled:3;
- bool pending:1;
- bool dispatching:1;
- bool floating:1;
-
- int64_t priority;
- unsigned pending_index;
- unsigned prepare_index;
- uint64_t pending_iteration;
- uint64_t prepare_iteration;
-
- sd_event_destroy_t destroy_callback;
-
- LIST_FIELDS(sd_event_source, sources);
-
- union {
- struct {
- sd_event_io_handler_t callback;
- int fd;
- uint32_t events;
- uint32_t revents;
- bool registered:1;
- bool owned:1;
- } io;
- struct {
- sd_event_time_handler_t callback;
- usec_t next, accuracy;
- unsigned earliest_index;
- unsigned latest_index;
- } time;
- struct {
- sd_event_signal_handler_t callback;
- struct signalfd_siginfo siginfo;
- int sig;
- } signal;
- struct {
- sd_event_child_handler_t callback;
- siginfo_t siginfo;
- pid_t pid;
- int options;
- } child;
- struct {
- sd_event_handler_t callback;
- } defer;
- struct {
- sd_event_handler_t callback;
- } post;
- struct {
- sd_event_handler_t callback;
- unsigned prioq_index;
- } exit;
- struct {
- sd_event_inotify_handler_t callback;
- uint32_t mask;
- struct inode_data *inode_data;
- LIST_FIELDS(sd_event_source, by_inode_data);
- } inotify;
- };
-};
-
-struct clock_data {
- WakeupType wakeup;
- int fd;
-
- /* For all clocks we maintain two priority queues each, one
- * ordered for the earliest times the events may be
- * dispatched, and one ordered by the latest times they must
- * have been dispatched. The range between the top entries in
- * the two prioqs is the time window we can freely schedule
- * wakeups in */
-
- Prioq *earliest;
- Prioq *latest;
- usec_t next;
-
- bool needs_rearm:1;
-};
-
-struct signal_data {
- WakeupType wakeup;
-
- /* For each priority we maintain one signal fd, so that we
- * only have to dequeue a single event per priority at a
- * time. */
-
- int fd;
- int64_t priority;
- sigset_t sigset;
- sd_event_source *current;
-};
-
-/* A structure listing all event sources currently watching a specific inode */
-struct inode_data {
- /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */
- ino_t ino;
- dev_t dev;
-
- /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can
- * rearrange the priority still until then, as we need the original inode to change the priority as we need to
- * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the
- * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of
- * the sd-event object, so that it is efficient to close everything, before entering the next event loop
- * iteration. */
- int fd;
-
- /* The inotify "watch descriptor" */
- int wd;
-
- /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has
- * most recently been set on the watch descriptor. */
- uint32_t combined_mask;
-
- /* All event sources subscribed to this inode */
- LIST_HEAD(sd_event_source, event_sources);
-
- /* The inotify object we watch this inode with */
- struct inotify_data *inotify_data;
-
- /* A linked list of all inode data objects with fds to close (see above) */
- LIST_FIELDS(struct inode_data, to_close);
-};
-
-/* A structure encapsulating an inotify fd */
-struct inotify_data {
- WakeupType wakeup;
-
- /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at
- * a time */
-
- int fd;
- int64_t priority;
-
- Hashmap *inodes; /* The inode_data structures keyed by dev+ino */
- Hashmap *wd; /* The inode_data structures keyed by the watch descriptor for each */
-
- /* The buffer we read inotify events into */
- union inotify_event_buffer buffer;
- size_t buffer_filled; /* fill level of the buffer */
-
- /* How many event sources are currently marked pending for this inotify. We won't read new events off the
- * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing
- * the events locally if they can't be coalesced). */
- unsigned n_pending;
-
- /* A linked list of all inotify objects with data already read, that still need processing. We keep this list
- * to make it efficient to figure out what inotify objects to process data on next. */
- LIST_FIELDS(struct inotify_data, buffered);
-};
-
struct sd_event {
unsigned n_ref;
@@ -1887,9 +1695,11 @@ _public_ int sd_event_source_set_description(sd_event_source *s, const char *des
_public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
assert_return(s, -EINVAL);
assert_return(description, -EINVAL);
- assert_return(s->description, -ENXIO);
assert_return(!event_pid_changed(s->event), -ECHILD);
+ if (!s->description)
+ return -ENXIO;
+
*description = s->description;
return 0;
}
@@ -2141,11 +1951,11 @@ fail:
_public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
assert_return(s, -EINVAL);
- assert_return(m, -EINVAL);
assert_return(!event_pid_changed(s->event), -ECHILD);
- *m = s->enabled;
- return 0;
+ if (m)
+ *m = s->enabled;
+ return s->enabled != SD_EVENT_OFF;
}
_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
@@ -3702,3 +3512,31 @@ _public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_d
return !!s->destroy_callback;
}
+
+_public_ int sd_event_source_get_floating(sd_event_source *s) {
+ assert_return(s, -EINVAL);
+
+ return s->floating;
+}
+
+_public_ int sd_event_source_set_floating(sd_event_source *s, int b) {
+ assert_return(s, -EINVAL);
+
+ if (s->floating == !!b)
+ return 0;
+
+ if (!s->event) /* Already disconnected */
+ return -ESTALE;
+
+ s->floating = b;
+
+ if (b) {
+ sd_event_source_ref(s);
+ sd_event_unref(s->event);
+ } else {
+ sd_event_ref(s->event);
+ sd_event_source_unref(s);
+ }
+
+ return 1;
+}
diff --git a/src/systemd/src/libsystemd/sd-id128/sd-id128.c b/src/systemd/src/libsystemd/sd-id128/sd-id128.c
index b7cca832d8..3593a71c02 100644
--- a/src/systemd/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/systemd/src/libsystemd/sd-id128/sd-id128.c
@@ -272,7 +272,9 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
assert_return(ret, -EINVAL);
- r = acquire_random_bytes(&t, sizeof t, true);
+ /* We allow usage if x86-64 RDRAND here. It might not be trusted enough for keeping secrets, but it should be
+ * fine for UUIDS. */
+ r = genuine_random_bytes(&t, sizeof t, RANDOM_ALLOW_RDRAND);
if (r < 0)
return r;
diff --git a/src/systemd/src/systemd/_sd-common.h b/src/systemd/src/systemd/_sd-common.h
index 4742b2e742..b026b5c551 100644
--- a/src/systemd/src/systemd/_sd-common.h
+++ b/src/systemd/src/systemd/_sd-common.h
@@ -25,22 +25,22 @@
#ifndef _sd_printf_
# if __GNUC__ >= 4
-# define _sd_printf_(a,b) __attribute__ ((format (printf, a, b)))
+# define _sd_printf_(a,b) __attribute__ ((__format__(printf, a, b)))
# else
# define _sd_printf_(a,b)
# endif
#endif
#ifndef _sd_sentinel_
-# define _sd_sentinel_ __attribute__((sentinel))
+# define _sd_sentinel_ __attribute__((__sentinel__))
#endif
#ifndef _sd_packed_
-# define _sd_packed_ __attribute__((packed))
+# define _sd_packed_ __attribute__((__packed__))
#endif
#ifndef _sd_pure_
-# define _sd_pure_ __attribute__((pure))
+# define _sd_pure_ __attribute__((__pure__))
#endif
#ifndef _SD_STRINGIFY
diff --git a/src/systemd/src/systemd/sd-event.h b/src/systemd/src/systemd/sd-event.h
index c38eb84beb..b15cade20a 100644
--- a/src/systemd/src/systemd/sd-event.h
+++ b/src/systemd/src/systemd/sd-event.h
@@ -143,6 +143,8 @@ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid);
int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret);
int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback);
int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret);
+int sd_event_source_get_floating(sd_event_source *s);
+int sd_event_source_set_floating(sd_event_source *s, int b);
/* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref);
diff --git a/src/systemd/src/systemd/sd-lldp.h b/src/systemd/src/systemd/sd-lldp.h
index d650794cc0..a3e5cd6be6 100644
--- a/src/systemd/src/systemd/sd-lldp.h
+++ b/src/systemd/src/systemd/sd-lldp.h
@@ -109,10 +109,12 @@ typedef struct sd_lldp sd_lldp;
typedef struct sd_lldp_neighbor sd_lldp_neighbor;
typedef enum sd_lldp_event {
- SD_LLDP_EVENT_ADDED = 'a',
- SD_LLDP_EVENT_REMOVED = 'r',
- SD_LLDP_EVENT_UPDATED = 'u',
- SD_LLDP_EVENT_REFRESHED = 'f',
+ SD_LLDP_EVENT_ADDED,
+ SD_LLDP_EVENT_REMOVED,
+ SD_LLDP_EVENT_UPDATED,
+ SD_LLDP_EVENT_REFRESHED,
+ _SD_LLDP_EVENT_MAX,
+ _SD_LLDP_EVENT_INVALID = -1,
} sd_lldp_event;
typedef void (*sd_lldp_callback_t)(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata);
diff --git a/src/systemd/src/systemd/sd-ndisc.h b/src/systemd/src/systemd/sd-ndisc.h
index 6b6249ca03..d1bee343a2 100644
--- a/src/systemd/src/systemd/sd-ndisc.h
+++ b/src/systemd/src/systemd/sd-ndisc.h
@@ -55,8 +55,10 @@ typedef struct sd_ndisc sd_ndisc;
typedef struct sd_ndisc_router sd_ndisc_router;
typedef enum sd_ndisc_event {
- SD_NDISC_EVENT_TIMEOUT = 't',
- SD_NDISC_EVENT_ROUTER = 'r',
+ SD_NDISC_EVENT_TIMEOUT,
+ SD_NDISC_EVENT_ROUTER,
+ _SD_NDISC_EVENT_MAX,
+ _SD_NDISC_EVENT_INVALID = -1,
} sd_ndisc_event;
typedef void (*sd_ndisc_callback_t)(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata);