summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-10-24 22:35:04 +0200
committerThomas Haller <thaller@redhat.com>2022-10-25 11:04:47 +0200
commit5afa09e966ca57b8fc3b898cc6116465d71cc53e (patch)
treecbfae5c250fefccd3a5a7e0fc658e692ff3343ac
parenta3460730f27ebba85710d7f085619dce78ff481c (diff)
downloadNetworkManager-5afa09e966ca57b8fc3b898cc6116465d71cc53e.tar.gz
systemd: update code from upstream (2022-10-25)
This is a direct dump from systemd git. $ git clean -fdx && \ git cat-file -p HEAD | sed '1,/^======$/ d' | bash - && \ git add . ====== SYSTEMD_DIR=../systemd COMMIT=4117366a283657295264723e559d7ead79a7cfd3 ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files -z :/src/libnm-systemd-core/src/ \ :/src/libnm-systemd-shared/src/ \ :/src/libnm-std-aux/unaligned.h | \ xargs -0 rm -f nm_copy_sd_shared() { mkdir -p "./src/libnm-systemd-shared/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/libnm-systemd-shared/$1" } nm_copy_sd_core() { mkdir -p "./src/libnm-systemd-core/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/libnm-systemd-core/$1" } nm_copy_sd_stdaux() { mkdir -p "./src/libnm-std-aux/" cp "$SYSTEMD_DIR/$1" "./src/libnm-std-aux/${1##*/}" } nm_copy_sd_core "src/libsystemd-network/arp-util.c" nm_copy_sd_core "src/libsystemd-network/arp-util.h" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h" nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-option.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h" nm_copy_sd_core "src/libsystemd-network/network-common.c" nm_copy_sd_core "src/libsystemd-network/network-common.h" nm_copy_sd_core "src/libsystemd-network/network-internal.h" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c" nm_copy_sd_core "src/libsystemd/sd-event/event-source.h" nm_copy_sd_core "src/libsystemd/sd-event/event-util.c" nm_copy_sd_core "src/libsystemd/sd-event/event-util.h" nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h" nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c" nm_copy_sd_core "src/systemd/_sd-common.h" nm_copy_sd_core "src/systemd/sd-dhcp6-client.h" nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h" nm_copy_sd_core "src/systemd/sd-dhcp6-option.h" nm_copy_sd_core "src/systemd/sd-event.h" nm_copy_sd_core "src/systemd/sd-id128.h" nm_copy_sd_core "src/systemd/sd-ndisc.h" nm_copy_sd_shared "src/basic/alloc-util.c" nm_copy_sd_shared "src/basic/alloc-util.h" nm_copy_sd_shared "src/basic/async.h" nm_copy_sd_shared "src/basic/cgroup-util.h" nm_copy_sd_shared "src/basic/dns-def.h" nm_copy_sd_shared "src/basic/env-file.c" nm_copy_sd_shared "src/basic/env-file.h" nm_copy_sd_shared "src/basic/env-util.c" nm_copy_sd_shared "src/basic/env-util.h" nm_copy_sd_shared "src/basic/errno-util.h" nm_copy_sd_shared "src/basic/escape.c" nm_copy_sd_shared "src/basic/escape.h" nm_copy_sd_shared "src/basic/ether-addr-util.c" nm_copy_sd_shared "src/basic/ether-addr-util.h" nm_copy_sd_shared "src/basic/extract-word.c" nm_copy_sd_shared "src/basic/extract-word.h" nm_copy_sd_shared "src/basic/fd-util.c" nm_copy_sd_shared "src/basic/fd-util.h" nm_copy_sd_shared "src/basic/fileio.c" nm_copy_sd_shared "src/basic/fileio.h" nm_copy_sd_shared "src/basic/format-util.c" nm_copy_sd_shared "src/basic/format-util.h" nm_copy_sd_shared "src/basic/fs-util.c" nm_copy_sd_shared "src/basic/fs-util.h" nm_copy_sd_shared "src/basic/glyph-util.c" nm_copy_sd_shared "src/basic/glyph-util.h" nm_copy_sd_shared "src/basic/hash-funcs.c" nm_copy_sd_shared "src/basic/hash-funcs.h" nm_copy_sd_shared "src/basic/hashmap.c" nm_copy_sd_shared "src/basic/hashmap.h" nm_copy_sd_shared "src/basic/hexdecoct.c" nm_copy_sd_shared "src/basic/hexdecoct.h" nm_copy_sd_shared "src/basic/hostname-util.c" nm_copy_sd_shared "src/basic/hostname-util.h" nm_copy_sd_shared "src/basic/in-addr-util.c" nm_copy_sd_shared "src/basic/in-addr-util.h" nm_copy_sd_shared "src/basic/inotify-util.c" nm_copy_sd_shared "src/basic/inotify-util.h" nm_copy_sd_shared "src/basic/io-util.c" nm_copy_sd_shared "src/basic/io-util.h" nm_copy_sd_shared "src/basic/list.h" nm_copy_sd_shared "src/basic/locale-util.c" nm_copy_sd_shared "src/basic/locale-util.h" nm_copy_sd_shared "src/basic/log.h" nm_copy_sd_shared "src/basic/macro.h" nm_copy_sd_shared "src/basic/memory-util.c" nm_copy_sd_shared "src/basic/memory-util.h" nm_copy_sd_shared "src/basic/mempool.c" nm_copy_sd_shared "src/basic/mempool.h" nm_copy_sd_shared "src/basic/missing_fcntl.h" nm_copy_sd_shared "src/basic/missing_random.h" nm_copy_sd_shared "src/basic/missing_socket.h" nm_copy_sd_shared "src/basic/missing_stat.h" nm_copy_sd_shared "src/basic/missing_syscall.h" nm_copy_sd_shared "src/basic/missing_type.h" nm_copy_sd_shared "src/basic/ordered-set.c" nm_copy_sd_shared "src/basic/ordered-set.h" nm_copy_sd_shared "src/basic/parse-util.c" nm_copy_sd_shared "src/basic/parse-util.h" nm_copy_sd_shared "src/basic/path-util.c" nm_copy_sd_shared "src/basic/path-util.h" nm_copy_sd_shared "src/basic/prioq.c" nm_copy_sd_shared "src/basic/prioq.h" nm_copy_sd_shared "src/basic/process-util.c" nm_copy_sd_shared "src/basic/process-util.h" nm_copy_sd_shared "src/basic/random-util.c" nm_copy_sd_shared "src/basic/random-util.h" nm_copy_sd_shared "src/basic/ratelimit.c" nm_copy_sd_shared "src/basic/ratelimit.h" nm_copy_sd_shared "src/basic/set.h" nm_copy_sd_shared "src/basic/signal-util.c" nm_copy_sd_shared "src/basic/signal-util.h" nm_copy_sd_shared "src/basic/siphash24.h" nm_copy_sd_shared "src/basic/socket-util.c" nm_copy_sd_shared "src/basic/socket-util.h" nm_copy_sd_shared "src/basic/sort-util.h" nm_copy_sd_shared "src/basic/sparse-endian.h" nm_copy_sd_shared "src/basic/stat-util.c" nm_copy_sd_shared "src/basic/stat-util.h" nm_copy_sd_shared "src/basic/stdio-util.h" nm_copy_sd_shared "src/basic/string-table.c" nm_copy_sd_shared "src/basic/string-table.h" nm_copy_sd_shared "src/basic/string-util.c" nm_copy_sd_shared "src/basic/string-util.h" nm_copy_sd_shared "src/basic/strv.c" nm_copy_sd_shared "src/basic/strv.h" nm_copy_sd_shared "src/basic/strxcpyx.c" nm_copy_sd_shared "src/basic/strxcpyx.h" nm_copy_sd_shared "src/basic/time-util.c" nm_copy_sd_shared "src/basic/time-util.h" nm_copy_sd_shared "src/basic/tmpfile-util.c" nm_copy_sd_shared "src/basic/tmpfile-util.h" nm_copy_sd_shared "src/basic/umask-util.h" nm_copy_sd_shared "src/basic/user-util.h" nm_copy_sd_shared "src/basic/utf8.c" nm_copy_sd_shared "src/basic/utf8.h" nm_copy_sd_shared "src/basic/util.c" nm_copy_sd_shared "src/basic/util.h" nm_copy_sd_shared "src/fundamental/macro-fundamental.h" nm_copy_sd_shared "src/fundamental/sha256.c" nm_copy_sd_shared "src/fundamental/sha256.h" nm_copy_sd_shared "src/fundamental/string-util-fundamental.c" nm_copy_sd_shared "src/fundamental/string-util-fundamental.h" nm_copy_sd_shared "src/shared/dns-domain.c" nm_copy_sd_shared "src/shared/dns-domain.h" nm_copy_sd_shared "src/shared/log-link.h" nm_copy_sd_shared "src/shared/web-util.c" nm_copy_sd_shared "src/shared/web-util.h" nm_copy_sd_stdaux "src/basic/unaligned.h"
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c198
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.h12
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.c796
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.h92
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/lldp-network.c70
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/lldp-network.h6
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/lldp-rx-internal.h48
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c123
-rw-r--r--src/libnm-systemd-core/src/libsystemd-network/sd-lldp-rx.c525
-rw-r--r--src/libnm-systemd-core/src/systemd/sd-lldp-rx.h109
-rw-r--r--src/libnm-systemd-core/src/systemd/sd-lldp.h123
-rw-r--r--src/libnm-systemd-shared/src/basic/errno-util.h31
-rw-r--r--src/libnm-systemd-shared/src/basic/fd-util.c15
-rw-r--r--src/libnm-systemd-shared/src/basic/fd-util.h1
-rw-r--r--src/libnm-systemd-shared/src/basic/in-addr-util.c11
-rw-r--r--src/libnm-systemd-shared/src/basic/process-util.c2
-rw-r--r--src/libnm-systemd-shared/src/basic/stdio-util.h14
-rw-r--r--src/libnm-systemd-shared/src/basic/string-util.h7
18 files changed, 190 insertions, 1993 deletions
diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c
index 5e91e86f53..62873e0111 100644
--- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c
+++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c
@@ -211,47 +211,55 @@ bool dhcp6_option_can_request(uint16_t option) {
}
}
-static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) {
- assert_return(buf, -EINVAL);
- assert_return(*buf, -EINVAL);
- assert_return(buflen, -EINVAL);
+static int option_append_hdr(uint8_t **buf, size_t *offset, uint16_t optcode, size_t optlen) {
+ assert(buf);
+ assert(*buf);
+ assert(offset);
- if (optlen > 0xffff || *buflen < optlen + offsetof(DHCP6Option, data))
+ if (optlen > 0xffff)
return -ENOBUFS;
- unaligned_write_be16(*buf + offsetof(DHCP6Option, code), optcode);
- unaligned_write_be16(*buf + offsetof(DHCP6Option, len), optlen);
+ if (optlen + offsetof(DHCP6Option, data) > SIZE_MAX - *offset)
+ return -ENOBUFS;
- *buf += offsetof(DHCP6Option, data);
- *buflen -= offsetof(DHCP6Option, data);
+ if (!GREEDY_REALLOC(*buf, *offset + optlen + offsetof(DHCP6Option, data)))
+ return -ENOMEM;
+
+ unaligned_write_be16(*buf + *offset + offsetof(DHCP6Option, code), optcode);
+ unaligned_write_be16(*buf + *offset + offsetof(DHCP6Option, len), optlen);
+ *offset += offsetof(DHCP6Option, data);
return 0;
}
-int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
- size_t optlen, const void *optval) {
+int dhcp6_option_append(
+ uint8_t **buf,
+ size_t *offset,
+ uint16_t code,
+ size_t optlen,
+ const void *optval) {
+
int r;
- assert_return(optval || optlen == 0, -EINVAL);
+ assert(optval || optlen == 0);
- r = option_append_hdr(buf, buflen, code, optlen);
+ r = option_append_hdr(buf, offset, code, optlen);
if (r < 0)
return r;
- *buf = mempcpy_safe(*buf, optval, optlen);
- *buflen -= optlen;
+ memcpy_safe(*buf + *offset, optval, optlen);
+ *offset += optlen;
return 0;
}
-int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet *vendor_options) {
+int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *offset, OrderedSet *vendor_options) {
sd_dhcp6_option *options;
int r;
assert(buf);
assert(*buf);
- assert(buflen);
- assert(vendor_options);
+ assert(offset);
ORDERED_SET_FOREACH(options, vendor_options) {
_cleanup_free_ uint8_t *p = NULL;
@@ -268,7 +276,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet
unaligned_write_be16(p + 6, options->length);
memcpy(p + 8, options->data, options->length);
- r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_OPTS, total, p);
+ r = dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_VENDOR_OPTS, total, p);
if (r < 0)
return r;
}
@@ -276,69 +284,48 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet
return 0;
}
-static int option_append_ia_address(uint8_t **buf, size_t *buflen, const struct iaaddr *address) {
- struct iaaddr a;
- int r;
-
+static int option_append_ia_address(uint8_t **buf, size_t *offset, const struct iaaddr *address) {
assert(buf);
assert(*buf);
- assert(buflen);
+ assert(offset);
assert(address);
/* Do not append T1 and T2. */
- a = (struct iaaddr) {
+ const struct iaaddr a = {
.address = address->address,
};
- r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
- if (r < 0)
- return r;
-
- *buf = mempcpy(*buf, &a, sizeof(struct iaaddr));
- *buflen -= sizeof(struct iaaddr);
-
- return offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
+ return dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr), &a);
}
-static int option_append_pd_prefix(uint8_t **buf, size_t *buflen, const struct iapdprefix *prefix) {
- struct iapdprefix p;
- int r;
-
+static int option_append_pd_prefix(uint8_t **buf, size_t *offset, const struct iapdprefix *prefix) {
assert(buf);
assert(*buf);
- assert(buflen);
+ assert(offset);
assert(prefix);
if (prefix->prefixlen == 0)
return -EINVAL;
/* Do not append T1 and T2. */
- p = (struct iapdprefix) {
+ const struct iapdprefix p = {
.prefixlen = prefix->prefixlen,
.address = prefix->address,
};
- r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IA_PD_PREFIX, sizeof(struct iapdprefix));
- if (r < 0)
- return r;
-
- *buf = mempcpy(*buf, &p, sizeof(struct iapdprefix));
- *buflen -= sizeof(struct iapdprefix);
-
- return offsetof(DHCP6Option, data) + sizeof(struct iapdprefix);
+ return dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_IA_PD_PREFIX, sizeof(struct iapdprefix), &p);
}
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
+int dhcp6_option_append_ia(uint8_t **buf, size_t *offset, const DHCP6IA *ia) {
+ _cleanup_free_ uint8_t *data = NULL;
struct ia_header header;
- size_t ia_buflen;
- uint8_t *ia_hdr;
- uint16_t len;
+ size_t len;
int r;
- assert_return(buf, -EINVAL);
- assert_return(*buf, -EINVAL);
- assert_return(buflen, -EINVAL);
- assert_return(ia, -EINVAL);
+ assert(buf);
+ assert(*buf);
+ assert(offset);
+ assert(ia);
/* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
@@ -362,43 +349,38 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
assert_not_reached();
}
- if (*buflen < offsetof(DHCP6Option, data) + len)
- return -ENOBUFS;
-
- ia_hdr = *buf;
- ia_buflen = *buflen;
-
- /* The header will be written at the end of this function. */
- *buf += offsetof(DHCP6Option, data);
- *buflen -= offsetof(DHCP6Option, data);
+ if (!GREEDY_REALLOC(data, len))
+ return -ENOMEM;
- *buf = mempcpy(*buf, &header, len);
- *buflen -= len;
+ memcpy(data, &header, len);
LIST_FOREACH(addresses, addr, ia->addresses) {
if (ia->type == SD_DHCP6_OPTION_IA_PD)
- r = option_append_pd_prefix(buf, buflen, &addr->iapdprefix);
+ r = option_append_pd_prefix(&data, &len, &addr->iapdprefix);
else
- r = option_append_ia_address(buf, buflen, &addr->iaaddr);
+ r = option_append_ia_address(&data, &len, &addr->iaaddr);
if (r < 0)
return r;
-
- len += r;
}
- return option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len);
+ return dhcp6_option_append(buf, offset, ia->type, len, data);
}
-int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
+int dhcp6_option_append_fqdn(uint8_t **buf, size_t *offset, const char *fqdn) {
uint8_t buffer[1 + DNS_WIRE_FORMAT_HOSTNAME_MAX];
int r;
- assert_return(buf && *buf && buflen && fqdn, -EINVAL);
+ assert(buf);
+ assert(*buf);
+ assert(offset);
+
+ if (isempty(fqdn))
+ return 0;
buffer[0] = DHCP6_FQDN_FLAG_S; /* Request server to perform AAAA RR DNS updates */
/* Store domain name after flags field */
- r = dns_name_to_wire_format(fqdn, buffer + 1, sizeof(buffer) - 1, false);
+ r = dns_name_to_wire_format(fqdn, buffer + 1, sizeof(buffer) - 1, false);
if (r <= 0)
return r;
@@ -411,82 +393,70 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
if (dns_name_is_single_label(fqdn))
r--;
- r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_CLIENT_FQDN, 1 + r, buffer);
-
- return r;
+ return dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_CLIENT_FQDN, 1 + r, buffer);
}
-int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class) {
+int dhcp6_option_append_user_class(uint8_t **buf, size_t *offset, char * const *user_class) {
_cleanup_free_ uint8_t *p = NULL;
- size_t total = 0, offset = 0;
+ size_t n = 0;
assert(buf);
assert(*buf);
- assert(buflen);
- assert(!strv_isempty(user_class));
+ assert(offset);
+
+ if (strv_isempty(user_class))
+ return 0;
STRV_FOREACH(s, user_class) {
size_t len = strlen(*s);
- uint8_t *q;
- if (len > 0xffff || len == 0)
+ if (len > UINT16_MAX || len == 0)
return -EINVAL;
- q = realloc(p, total + len + 2);
- if (!q)
- return -ENOMEM;
- p = q;
-
- unaligned_write_be16(&p[offset], len);
- memcpy(&p[offset + 2], *s, len);
+ if (!GREEDY_REALLOC(p, n + len + 2))
+ return -ENOMEM;
- offset += 2 + len;
- total += 2 + len;
+ unaligned_write_be16(p + n, len);
+ memcpy(p + n + 2, *s, len);
+ n += len + 2;
}
- return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_USER_CLASS, total, p);
+ return dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_USER_CLASS, n, p);
}
-int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *vendor_class) {
+int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *offset, char * const *vendor_class) {
_cleanup_free_ uint8_t *p = NULL;
- uint32_t enterprise_identifier;
- size_t total, offset;
+ size_t n = 0;
assert(buf);
assert(*buf);
- assert(buflen);
- assert(!strv_isempty(vendor_class));
+ assert(offset);
- enterprise_identifier = htobe32(SYSTEMD_PEN);
+ if (strv_isempty(vendor_class))
+ return 0;
- p = memdup(&enterprise_identifier, sizeof(enterprise_identifier));
- if (!p)
+ if (!GREEDY_REALLOC(p, sizeof(be32_t)))
return -ENOMEM;
- total = sizeof(enterprise_identifier);
- offset = total;
+ /* Enterprise Identifier */
+ unaligned_write_be32(p, SYSTEMD_PEN);
+ n += sizeof(be32_t);
STRV_FOREACH(s, vendor_class) {
size_t len = strlen(*s);
- uint8_t *q;
if (len > UINT16_MAX || len == 0)
return -EINVAL;
- q = realloc(p, total + len + 2);
- if (!q)
+ if (!GREEDY_REALLOC(p, n + len + 2))
return -ENOMEM;
- p = q;
-
- unaligned_write_be16(&p[offset], len);
- memcpy(&p[offset + 2], *s, len);
-
- offset += 2 + len;
- total += 2 + len;
+ unaligned_write_be16(p + n, len);
+ memcpy(p + n + 2, *s, len);
+ n += len + 2;
}
- return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_CLASS, total, p);
+ return dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_VENDOR_CLASS, n, p);
}
int dhcp6_option_parse(
diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.h b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.h
index 80aba7f37f..36841dd270 100644
--- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.h
+++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.h
@@ -72,13 +72,13 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DHCP6IA*, dhcp6_ia_free);
bool dhcp6_option_can_request(uint16_t option);
-int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
+int dhcp6_option_append(uint8_t **buf, size_t *offset, uint16_t code,
size_t optlen, const void *optval);
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
-int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
-int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
-int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
-int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet *vendor_options);
+int dhcp6_option_append_ia(uint8_t **buf, size_t *offset, const DHCP6IA *ia);
+int dhcp6_option_append_fqdn(uint8_t **buf, size_t *offset, const char *fqdn);
+int dhcp6_option_append_user_class(uint8_t **buf, size_t *offset, char * const *user_class);
+int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *offset, char * const *vendor_class);
+int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *offset, OrderedSet *vendor_options);
int dhcp6_option_parse(
const uint8_t *buf,
diff --git a/src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.c b/src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.c
deleted file mode 100644
index 6672409d75..0000000000
--- a/src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "alloc-util.h"
-#include "escape.h"
-#include "ether-addr-util.h"
-#include "hexdecoct.h"
-#include "in-addr-util.h"
-#include "lldp-neighbor.h"
-#include "memory-util.h"
-#include "missing_network.h"
-#include "unaligned.h"
-
-static void lldp_neighbor_id_hash_func(const LLDPNeighborID *id, struct siphash *state) {
- assert(id);
- assert(state);
-
- siphash24_compress(id->chassis_id, id->chassis_id_size, state);
- siphash24_compress(&id->chassis_id_size, sizeof(id->chassis_id_size), state);
- siphash24_compress(id->port_id, id->port_id_size, state);
- siphash24_compress(&id->port_id_size, sizeof(id->port_id_size), state);
-}
-
-int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y) {
- assert(x);
- assert(y);
-
- return memcmp_nn(x->chassis_id, x->chassis_id_size, y->chassis_id, y->chassis_id_size)
- ?: memcmp_nn(x->port_id, x->port_id_size, y->port_id, y->port_id_size);
-}
-
-DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
- lldp_neighbor_hash_ops,
- LLDPNeighborID,
- lldp_neighbor_id_hash_func,
- lldp_neighbor_id_compare_func,
- sd_lldp_neighbor,
- lldp_neighbor_unlink);
-
-int lldp_neighbor_prioq_compare_func(const void *a, const void *b) {
- const sd_lldp_neighbor *x = a, *y = b;
-
- assert(x);
- assert(y);
-
- return CMP(x->until, y->until);
-}
-
-sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) {
- if (!n)
- return NULL;
-
- assert(n->n_ref > 0 || n->lldp_rx);
- n->n_ref++;
-
- return n;
-}
-
-static sd_lldp_neighbor *lldp_neighbor_free(sd_lldp_neighbor *n) {
- if (!n)
- return NULL;
-
- free(n->id.port_id);
- free(n->id.chassis_id);
- free(n->port_description);
- free(n->system_name);
- free(n->system_description);
- free(n->mud_url);
- free(n->chassis_id_as_string);
- free(n->port_id_as_string);
- return mfree(n);
-}
-
-sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n) {
-
- /* Drops one reference from the neighbor. Note that the object is not freed unless it is already unlinked from
- * the sd_lldp object. */
-
- if (!n)
- return NULL;
-
- assert(n->n_ref > 0);
- n->n_ref--;
-
- if (n->n_ref <= 0 && !n->lldp_rx)
- lldp_neighbor_free(n);
-
- return NULL;
-}
-
-sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n) {
-
- /* Removes the neighbor object from the LLDP object, and frees it if it also has no other reference. */
-
- if (!n)
- return NULL;
-
- if (!n->lldp_rx)
- return NULL;
-
- /* Only remove the neighbor object from the hash table if it's in there, don't complain if it isn't. This is
- * because we are used as destructor call for hashmap_clear() and thus sometimes are called to de-register
- * ourselves from the hashtable and sometimes are called after we already are de-registered. */
-
- (void) hashmap_remove_value(n->lldp_rx->neighbor_by_id, &n->id, n);
-
- assert_se(prioq_remove(n->lldp_rx->neighbor_by_expiry, n, &n->prioq_idx) >= 0);
-
- n->lldp_rx = NULL;
-
- if (n->n_ref <= 0)
- lldp_neighbor_free(n);
-
- return NULL;
-}
-
-sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size) {
- sd_lldp_neighbor *n;
-
- if (raw_size > SIZE_MAX - ALIGN(sizeof(sd_lldp_neighbor)))
- return NULL;
-
- n = malloc0(ALIGN(sizeof(sd_lldp_neighbor)) + raw_size);
- if (!n)
- return NULL;
-
- n->raw_size = raw_size;
- n->n_ref = 1;
-
- return n;
-}
-
-static int parse_string(sd_lldp_rx *lldp_rx, char **s, const void *q, size_t n) {
- const char *p = q;
- char *k;
-
- assert(s);
- assert(p || n == 0);
-
- if (*s) {
- log_lldp_rx(lldp_rx, "Found duplicate string, ignoring field.");
- return 0;
- }
-
- /* Strip trailing NULs, just to be nice */
- while (n > 0 && p[n-1] == 0)
- n--;
-
- if (n <= 0) /* Ignore empty strings */
- return 0;
-
- /* Look for inner NULs */
- if (memchr(p, 0, n)) {
- log_lldp_rx(lldp_rx, "Found inner NUL in string, ignoring field.");
- return 0;
- }
-
- /* Let's escape weird chars, for security reasons */
- k = cescape_length(p, n);
- if (!k)
- return log_oom_debug();
-
- free(*s);
- *s = k;
-
- return 1;
-}
-
-int lldp_neighbor_parse(sd_lldp_neighbor *n) {
- struct ether_header h;
- const uint8_t *p;
- size_t left;
- int r;
-
- assert(n);
-
- if (n->raw_size < sizeof(struct ether_header))
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Received truncated packet, ignoring.");
-
- memcpy(&h, LLDP_NEIGHBOR_RAW(n), sizeof(h));
-
- if (h.ether_type != htobe16(ETHERTYPE_LLDP))
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Received packet with wrong type, ignoring.");
-
- if (h.ether_dhost[0] != 0x01 ||
- h.ether_dhost[1] != 0x80 ||
- h.ether_dhost[2] != 0xc2 ||
- h.ether_dhost[3] != 0x00 ||
- h.ether_dhost[4] != 0x00 ||
- !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e))
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Received packet with wrong destination address, ignoring.");
-
- memcpy(&n->source_address, h.ether_shost, sizeof(struct ether_addr));
- memcpy(&n->destination_address, h.ether_dhost, sizeof(struct ether_addr));
-
- p = (const uint8_t*) LLDP_NEIGHBOR_RAW(n) + sizeof(struct ether_header);
- left = n->raw_size - sizeof(struct ether_header);
-
- for (;;) {
- uint8_t type;
- uint16_t length;
-
- if (left < 2)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "TLV lacks header, ignoring.");
-
- type = p[0] >> 1;
- length = p[1] + (((uint16_t) (p[0] & 1)) << 8);
- p += 2, left -= 2;
-
- if (left < length)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "TLV truncated, ignoring datagram.");
-
- switch (type) {
-
- case SD_LLDP_TYPE_END:
- if (length != 0)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "End marker TLV not zero-sized, ignoring datagram.");
-
- /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0
- * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */
-
- goto end_marker;
-
- case SD_LLDP_TYPE_CHASSIS_ID:
- if (length < 2 || length > 256)
- /* includes the chassis subtype, hence one extra byte */
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Chassis ID field size out of range, ignoring datagram.");
-
- if (n->id.chassis_id)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Duplicate chassis ID field, ignoring datagram.");
-
- n->id.chassis_id = memdup(p, length);
- if (!n->id.chassis_id)
- return log_oom_debug();
-
- n->id.chassis_id_size = length;
- break;
-
- case SD_LLDP_TYPE_PORT_ID:
- if (length < 2 || length > 256)
- /* includes the port subtype, hence one extra byte */
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Port ID field size out of range, ignoring datagram.");
-
- if (n->id.port_id)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Duplicate port ID field, ignoring datagram.");
-
- n->id.port_id = memdup(p, length);
- if (!n->id.port_id)
- return log_oom_debug();
-
- n->id.port_id_size = length;
- break;
-
- case SD_LLDP_TYPE_TTL:
- if (length != 2)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "TTL field has wrong size, ignoring datagram.");
-
- if (n->has_ttl)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Duplicate TTL field, ignoring datagram.");
-
- n->ttl = unaligned_read_be16(p);
- n->has_ttl = true;
- break;
-
- case SD_LLDP_TYPE_PORT_DESCRIPTION:
- r = parse_string(n->lldp_rx, &n->port_description, p, length);
- if (r < 0)
- return r;
- break;
-
- case SD_LLDP_TYPE_SYSTEM_NAME:
- r = parse_string(n->lldp_rx, &n->system_name, p, length);
- if (r < 0)
- return r;
- break;
-
- case SD_LLDP_TYPE_SYSTEM_DESCRIPTION:
- r = parse_string(n->lldp_rx, &n->system_description, p, length);
- if (r < 0)
- return r;
- break;
-
- case SD_LLDP_TYPE_SYSTEM_CAPABILITIES:
- if (length != 4)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "System capabilities field has wrong size.");
-
- n->system_capabilities = unaligned_read_be16(p);
- n->enabled_capabilities = unaligned_read_be16(p + 2);
- n->has_capabilities = true;
- break;
-
- case SD_LLDP_TYPE_PRIVATE:
- if (length < 4)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "Found private TLV that is too short, ignoring.");
-
- /* RFC 8520: MUD URL */
- if (memcmp(p, SD_LLDP_OUI_IANA_MUD, sizeof(SD_LLDP_OUI_IANA_MUD)) == 0) {
- r = parse_string(n->lldp_rx, &n->mud_url, p + sizeof(SD_LLDP_OUI_IANA_MUD),
- length - sizeof(SD_LLDP_OUI_IANA_MUD));
- if (r < 0)
- return r;
- }
- break;
- }
-
- p += length, left -= length;
- }
-
-end_marker:
- if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl)
- return log_lldp_rx_errno(n->lldp_rx, SYNTHETIC_ERRNO(EBADMSG),
- "One or more mandatory TLV missing in datagram. Ignoring.");
-
- n->rindex = sizeof(struct ether_header);
-
- return 0;
-}
-
-void lldp_neighbor_start_ttl(sd_lldp_neighbor *n) {
- assert(n);
-
- if (n->ttl > 0) {
- usec_t base;
-
- /* Use the packet's timestamp if there is one known */
- base = triple_timestamp_by_clock(&n->timestamp, CLOCK_BOOTTIME);
- if (!timestamp_is_set(base))
- base = now(CLOCK_BOOTTIME); /* Otherwise, take the current time */
-
- n->until = usec_add(base, n->ttl * USEC_PER_SEC);
- } else
- n->until = 0;
-
- if (n->lldp_rx)
- prioq_reshuffle(n->lldp_rx->neighbor_by_expiry, n, &n->prioq_idx);
-}
-
-bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b) {
- if (a == b)
- return true;
-
- if (!a || !b)
- return false;
-
- if (a->raw_size != b->raw_size)
- return false;
-
- return memcmp(LLDP_NEIGHBOR_RAW(a), LLDP_NEIGHBOR_RAW(b), a->raw_size) == 0;
-}
-
-int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address) {
- assert_return(n, -EINVAL);
- assert_return(address, -EINVAL);
-
- *address = n->source_address;
- return 0;
-}
-
-int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address) {
- assert_return(n, -EINVAL);
- assert_return(address, -EINVAL);
-
- *address = n->destination_address;
- return 0;
-}
-
-int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
- assert_return(size, -EINVAL);
-
- *ret = LLDP_NEIGHBOR_RAW(n);
- *size = n->raw_size;
-
- return 0;
-}
-
-int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) {
- assert_return(n, -EINVAL);
- assert_return(type, -EINVAL);
- assert_return(ret, -EINVAL);
- assert_return(size, -EINVAL);
-
- assert(n->id.chassis_id_size > 0);
-
- *type = *(uint8_t*) n->id.chassis_id;
- *ret = (uint8_t*) n->id.chassis_id + 1;
- *size = n->id.chassis_id_size - 1;
-
- return 0;
-}
-
-static int format_mac_address(const void *data, size_t sz, char **ret) {
- struct ether_addr a;
- char *k;
-
- assert(data || sz <= 0);
-
- if (sz != 7)
- return 0;
-
- memcpy(&a, (uint8_t*) data + 1, sizeof(a));
-
- k = new(char, ETHER_ADDR_TO_STRING_MAX);
- if (!k)
- return -ENOMEM;
-
- *ret = ether_addr_to_string(&a, k);
- return 1;
-}
-
-static int format_network_address(const void *data, size_t sz, char **ret) {
- union in_addr_union a;
- int family, r;
-
- if (sz == 6 && ((uint8_t*) data)[1] == 1) {
- memcpy(&a.in, (uint8_t*) data + 2, sizeof(a.in));
- family = AF_INET;
- } else if (sz == 18 && ((uint8_t*) data)[1] == 2) {
- memcpy(&a.in6, (uint8_t*) data + 2, sizeof(a.in6));
- family = AF_INET6;
- } else
- return 0;
-
- r = in_addr_to_string(family, &a, ret);
- if (r < 0)
- return r;
- return 1;
-}
-
-int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, const char **ret) {
- char *k;
- int r;
-
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (n->chassis_id_as_string) {
- *ret = n->chassis_id_as_string;
- return 0;
- }
-
- assert(n->id.chassis_id_size > 0);
-
- switch (*(uint8_t*) n->id.chassis_id) {
-
- case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
- case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
- case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT:
- case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
- case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
- k = cescape_length((char*) n->id.chassis_id + 1, n->id.chassis_id_size - 1);
- if (!k)
- return -ENOMEM;
-
- goto done;
-
- case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
- r = format_mac_address(n->id.chassis_id, n->id.chassis_id_size, &k);
- if (r < 0)
- return r;
- if (r > 0)
- goto done;
-
- break;
-
- case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS:
- r = format_network_address(n->id.chassis_id, n->id.chassis_id_size, &k);
- if (r < 0)
- return r;
- if (r > 0)
- goto done;
-
- break;
- }
-
- /* Generic fallback */
- k = hexmem(n->id.chassis_id, n->id.chassis_id_size);
- if (!k)
- return -ENOMEM;
-
-done:
- *ret = n->chassis_id_as_string = k;
- return 0;
-}
-
-int sd_lldp_neighbor_get_port_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) {
- assert_return(n, -EINVAL);
- assert_return(type, -EINVAL);
- assert_return(ret, -EINVAL);
- assert_return(size, -EINVAL);
-
- assert(n->id.port_id_size > 0);
-
- *type = *(uint8_t*) n->id.port_id;
- *ret = (uint8_t*) n->id.port_id + 1;
- *size = n->id.port_id_size - 1;
-
- return 0;
-}
-
-int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const char **ret) {
- char *k;
- int r;
-
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (n->port_id_as_string) {
- *ret = n->port_id_as_string;
- return 0;
- }
-
- assert(n->id.port_id_size > 0);
-
- switch (*(uint8_t*) n->id.port_id) {
-
- case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
- case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT:
- case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME:
- case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
- k = cescape_length((char*) n->id.port_id + 1, n->id.port_id_size - 1);
- if (!k)
- return -ENOMEM;
-
- goto done;
-
- case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS:
- r = format_mac_address(n->id.port_id, n->id.port_id_size, &k);
- if (r < 0)
- return r;
- if (r > 0)
- goto done;
-
- break;
-
- case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS:
- r = format_network_address(n->id.port_id, n->id.port_id_size, &k);
- if (r < 0)
- return r;
- if (r > 0)
- goto done;
-
- break;
- }
-
- /* Generic fallback */
- k = hexmem(n->id.port_id, n->id.port_id_size);
- if (!k)
- return -ENOMEM;
-
-done:
- *ret = n->port_id_as_string = k;
- return 0;
-}
-
-int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec) {
- assert_return(n, -EINVAL);
- assert_return(ret_sec, -EINVAL);
-
- *ret_sec = n->ttl;
- return 0;
-}
-
-int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!n->system_name)
- return -ENODATA;
-
- *ret = n->system_name;
- return 0;
-}
-
-int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!n->system_description)
- return -ENODATA;
-
- *ret = n->system_description;
- return 0;
-}
-
-int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!n->port_description)
- return -ENODATA;
-
- *ret = n->port_description;
- return 0;
-}
-
-int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!n->mud_url)
- return -ENODATA;
-
- *ret = n->mud_url;
- return 0;
-}
-
-int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!n->has_capabilities)
- return -ENODATA;
-
- *ret = n->system_capabilities;
- return 0;
-}
-
-int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret) {
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!n->has_capabilities)
- return -ENODATA;
-
- *ret = n->enabled_capabilities;
- return 0;
-}
-
-int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) {
- _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
- int r;
-
- assert_return(ret, -EINVAL);
- assert_return(raw || raw_size <= 0, -EINVAL);
-
- n = lldp_neighbor_new(raw_size);
- if (!n)
- return -ENOMEM;
-
- memcpy_safe(LLDP_NEIGHBOR_RAW(n), raw, raw_size);
-
- r = lldp_neighbor_parse(n);
- if (r < 0)
- return r;
-
- *ret = TAKE_PTR(n);
-
- return r;
-}
-
-int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n) {
- assert_return(n, -EINVAL);
-
- assert(n->raw_size >= sizeof(struct ether_header));
- n->rindex = sizeof(struct ether_header);
-
- return n->rindex < n->raw_size;
-}
-
-int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n) {
- size_t length;
-
- assert_return(n, -EINVAL);
-
- if (n->rindex == n->raw_size) /* EOF */
- return -ESPIPE;
-
- if (n->rindex + 2 > n->raw_size) /* Truncated message */
- return -EBADMSG;
-
- length = LLDP_NEIGHBOR_TLV_LENGTH(n);
- if (n->rindex + 2 + length > n->raw_size)
- return -EBADMSG;
-
- n->rindex += 2 + length;
- return n->rindex < n->raw_size;
-}
-
-int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type) {
- assert_return(n, -EINVAL);
- assert_return(type, -EINVAL);
-
- if (n->rindex == n->raw_size) /* EOF */
- return -ESPIPE;
-
- if (n->rindex + 2 > n->raw_size)
- return -EBADMSG;
-
- *type = LLDP_NEIGHBOR_TLV_TYPE(n);
- return 0;
-}
-
-int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type) {
- uint8_t k;
- int r;
-
- assert_return(n, -EINVAL);
-
- r = sd_lldp_neighbor_tlv_get_type(n, &k);
- if (r < 0)
- return r;
-
- return type == k;
-}
-
-int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t *subtype) {
- const uint8_t *d;
- size_t length;
- int r;
-
- assert_return(n, -EINVAL);
- assert_return(oui, -EINVAL);
- assert_return(subtype, -EINVAL);
-
- r = sd_lldp_neighbor_tlv_is_type(n, SD_LLDP_TYPE_PRIVATE);
- if (r < 0)
- return r;
- if (r == 0)
- return -ENXIO;
-
- length = LLDP_NEIGHBOR_TLV_LENGTH(n);
- if (length < 4)
- return -EBADMSG;
-
- if (n->rindex + 2 + length > n->raw_size)
- return -EBADMSG;
-
- d = LLDP_NEIGHBOR_TLV_DATA(n);
- memcpy(oui, d, 3);
- *subtype = d[3];
-
- return 0;
-}
-
-int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t subtype) {
- uint8_t k[3], st;
- int r;
-
- r = sd_lldp_neighbor_tlv_get_oui(n, k, &st);
- if (r == -ENXIO)
- return 0;
- if (r < 0)
- return r;
-
- return memcmp(k, oui, 3) == 0 && st == subtype;
-}
-
-int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) {
- size_t length;
-
- assert_return(n, -EINVAL);
- assert_return(ret, -EINVAL);
- assert_return(size, -EINVAL);
-
- /* Note that this returns the full TLV, including the TLV header */
-
- if (n->rindex + 2 > n->raw_size)
- return -EBADMSG;
-
- length = LLDP_NEIGHBOR_TLV_LENGTH(n);
- if (n->rindex + 2 + length > n->raw_size)
- return -EBADMSG;
-
- *ret = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex;
- *size = length + 2;
-
- return 0;
-}
-
-int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret) {
- assert_return(n, -EINVAL);
- assert_return(TRIPLE_TIMESTAMP_HAS_CLOCK(clock), -EOPNOTSUPP);
- assert_return(clock_supported(clock), -EOPNOTSUPP);
- assert_return(ret, -EINVAL);
-
- if (!triple_timestamp_is_set(&n->timestamp))
- return -ENODATA;
-
- *ret = triple_timestamp_by_clock(&n->timestamp, clock);
- return 0;
-}
diff --git a/src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.h b/src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.h
deleted file mode 100644
index 016286b17d..0000000000
--- a/src/libnm-systemd-core/src/libsystemd-network/lldp-neighbor.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include <inttypes.h>
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include "sd-lldp-rx.h"
-
-#include "hash-funcs.h"
-#include "lldp-rx-internal.h"
-#include "time-util.h"
-
-typedef struct LLDPNeighborID {
- /* The spec calls this an "MSAP identifier" */
- void *chassis_id;
- size_t chassis_id_size;
-
- void *port_id;
- size_t port_id_size;
-} LLDPNeighborID;
-
-struct sd_lldp_neighbor {
- /* Neighbor objects stay around as long as they are linked into an "sd_lldp_rx" object or n_ref > 0. */
- sd_lldp_rx *lldp_rx;
- unsigned n_ref;
-
- triple_timestamp timestamp;
-
- usec_t until;
- unsigned prioq_idx;
-
- struct ether_addr source_address;
- struct ether_addr destination_address;
-
- LLDPNeighborID id;
-
- /* The raw packet size. The data is appended to the object, accessible via LLDP_NEIGHBOR_RAW() */
- size_t raw_size;
-
- /* The current read index for the iterative TLV interface */
- size_t rindex;
-
- /* And a couple of fields parsed out. */
- bool has_ttl:1;
- bool has_capabilities:1;
- bool has_port_vlan_id:1;
-
- uint16_t ttl;
-
- uint16_t system_capabilities;
- uint16_t enabled_capabilities;
-
- char *port_description;
- char *system_name;
- char *system_description;
- char *mud_url;
-
- uint16_t port_vlan_id;
-
- char *chassis_id_as_string;
- char *port_id_as_string;
-};
-
-static inline void *LLDP_NEIGHBOR_RAW(const sd_lldp_neighbor *n) {
- return (uint8_t*) n + ALIGN(sizeof(sd_lldp_neighbor));
-}
-
-static inline uint8_t LLDP_NEIGHBOR_TLV_TYPE(const sd_lldp_neighbor *n) {
- return ((uint8_t*) LLDP_NEIGHBOR_RAW(n))[n->rindex] >> 1;
-}
-
-static inline size_t LLDP_NEIGHBOR_TLV_LENGTH(const sd_lldp_neighbor *n) {
- uint8_t *p;
-
- p = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex;
- return p[1] + (((size_t) (p[0] & 1)) << 8);
-}
-
-static inline void* LLDP_NEIGHBOR_TLV_DATA(const sd_lldp_neighbor *n) {
- return ((uint8_t*) LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2;
-}
-
-extern const struct hash_ops lldp_neighbor_hash_ops;
-int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y);
-int lldp_neighbor_prioq_compare_func(const void *a, const void *b);
-
-sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n);
-sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size);
-int lldp_neighbor_parse(sd_lldp_neighbor *n);
-void lldp_neighbor_start_ttl(sd_lldp_neighbor *n);
-bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b);
diff --git a/src/libnm-systemd-core/src/libsystemd-network/lldp-network.c b/src/libnm-systemd-core/src/libsystemd-network/lldp-network.c
deleted file mode 100644
index 24edc371db..0000000000
--- a/src/libnm-systemd-core/src/libsystemd-network/lldp-network.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <linux/filter.h>
-#include <netinet/if_ether.h>
-
-#include "fd-util.h"
-#include "lldp-network.h"
-#include "missing_network.h"
-#include "socket-util.h"
-
-int lldp_network_bind_raw_socket(int ifindex) {
- static const struct sock_filter filter[] = {
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ethhdr, h_dest)), /* A <- 4 bytes of destination MAC */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0180c200, 1, 0), /* A != 01:80:c2:00 */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_dest) + 4), /* A <- remaining 2 bytes of destination MAC */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0000, 3, 0), /* A != 00:00 */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0003, 2, 0), /* A != 00:03 */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x000e, 1, 0), /* A != 00:0e */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_proto)), /* A <- protocol */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_LLDP, 1, 0), /* A != ETHERTYPE_LLDP */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept packet */
- };
- static const struct sock_fprog fprog = {
- .len = ELEMENTSOF(filter),
- .filter = (struct sock_filter*) filter,
- };
- struct packet_mreq mreq = {
- .mr_ifindex = ifindex,
- .mr_type = PACKET_MR_MULTICAST,
- .mr_alen = ETH_ALEN,
- .mr_address = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }
- };
- union sockaddr_union saddrll = {
- .ll.sll_family = AF_PACKET,
- .ll.sll_ifindex = ifindex,
- };
- _cleanup_close_ int fd = -1;
-
- assert(ifindex > 0);
-
- fd = socket(AF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK,
- htobe16(ETHERTYPE_LLDP));
- if (fd < 0)
- return -errno;
-
- if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0)
- return -errno;
-
- /* customer bridge */
- if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
- return -errno;
-
- /* non TPMR bridge */
- mreq.mr_address[ETH_ALEN - 1] = 0x03;
- if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
- return -errno;
-
- /* nearest bridge */
- mreq.mr_address[ETH_ALEN - 1] = 0x0E;
- if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
- return -errno;
-
- if (bind(fd, &saddrll.sa, sizeof(saddrll.ll)) < 0)
- return -errno;
-
- return TAKE_FD(fd);
-}
diff --git a/src/libnm-systemd-core/src/libsystemd-network/lldp-network.h b/src/libnm-systemd-core/src/libsystemd-network/lldp-network.h
deleted file mode 100644
index bc69b324c2..0000000000
--- a/src/libnm-systemd-core/src/libsystemd-network/lldp-network.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include "sd-event.h"
-
-int lldp_network_bind_raw_socket(int ifindex);
diff --git a/src/libnm-systemd-core/src/libsystemd-network/lldp-rx-internal.h b/src/libnm-systemd-core/src/libsystemd-network/lldp-rx-internal.h
deleted file mode 100644
index 83d0bc460d..0000000000
--- a/src/libnm-systemd-core/src/libsystemd-network/lldp-rx-internal.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include "sd-event.h"
-#include "sd-lldp-rx.h"
-
-#include "hashmap.h"
-#include "network-common.h"
-#include "prioq.h"
-
-struct sd_lldp_rx {
- unsigned n_ref;
-
- int ifindex;
- char *ifname;
- int fd;
-
- sd_event *event;
- int64_t event_priority;
- sd_event_source *io_event_source;
- sd_event_source *timer_event_source;
-
- Prioq *neighbor_by_expiry;
- Hashmap *neighbor_by_id;
-
- uint64_t neighbors_max;
-
- sd_lldp_rx_callback_t callback;
- void *userdata;
-
- uint16_t capability_mask;
-
- struct ether_addr filter_address;
-};
-
-const char* lldp_rx_event_to_string(sd_lldp_rx_event_t e) _const_;
-sd_lldp_rx_event_t lldp_rx_event_from_string(const char *s) _pure_;
-
-#define log_lldp_rx_errno(lldp_rx, error, fmt, ...) \
- log_interface_prefix_full_errno( \
- "LLDP Rx: ", \
- sd_lldp_rx, lldp_rx, \
- error, fmt, ##__VA_ARGS__)
-#define log_lldp_rx(lldp_rx, fmt, ...) \
- log_interface_prefix_full_errno_zerook( \
- "LLDP Rx: ", \
- sd_lldp_rx, lldp_rx, \
- 0, fmt, ##__VA_ARGS__)
diff --git a/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c b/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c
index 606e48ce6f..375f984940 100644
--- a/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c
@@ -574,8 +574,8 @@ static void client_stop(sd_dhcp6_client *client, int error) {
static int client_append_common_options_in_managed_mode(
sd_dhcp6_client *client,
- uint8_t **opt,
- size_t *optlen,
+ uint8_t **buf,
+ size_t *offset,
const DHCP6IA *ia_na,
const DHCP6IA *ia_pd) {
@@ -587,44 +587,37 @@ static int client_append_common_options_in_managed_mode(
DHCP6_STATE_REQUEST,
DHCP6_STATE_RENEW,
DHCP6_STATE_REBIND));
- assert(opt);
- assert(optlen);
+ assert(buf);
+ assert(*buf);
+ assert(offset);
if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_NA) && ia_na) {
- r = dhcp6_option_append_ia(opt, optlen, ia_na);
+ r = dhcp6_option_append_ia(buf, offset, ia_na);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD) && ia_pd) {
- r = dhcp6_option_append_ia(opt, optlen, ia_pd);
+ r = dhcp6_option_append_ia(buf, offset, ia_pd);
if (r < 0)
return r;
}
- if (client->fqdn) {
- r = dhcp6_option_append_fqdn(opt, optlen, client->fqdn);
- if (r < 0)
- return r;
- }
+ r = dhcp6_option_append_fqdn(buf, offset, client->fqdn);
+ if (r < 0)
+ return r;
- if (client->user_class) {
- r = dhcp6_option_append_user_class(opt, optlen, client->user_class);
- if (r < 0)
- return r;
- }
+ r = dhcp6_option_append_user_class(buf, offset, client->user_class);
+ if (r < 0)
+ return r;
- if (client->vendor_class) {
- r = dhcp6_option_append_vendor_class(opt, optlen, client->vendor_class);
- if (r < 0)
- return r;
- }
+ r = dhcp6_option_append_vendor_class(buf, offset, client->vendor_class);
+ if (r < 0)
+ return r;
- if (!ordered_set_isempty(client->vendor_options)) {
- r = dhcp6_option_append_vendor_option(opt, optlen, client->vendor_options);
- if (r < 0)
- return r;
- }
+ r = dhcp6_option_append_vendor_option(buf, offset, client->vendor_options);
+ if (r < 0)
+ return r;
return 0;
}
@@ -648,41 +641,42 @@ static DHCP6MessageType client_message_type_from_state(sd_dhcp6_client *client)
}
}
-static int client_append_oro(sd_dhcp6_client *client, uint8_t **opt, size_t *optlen) {
- _cleanup_free_ be16_t *buf = NULL;
+static int client_append_oro(sd_dhcp6_client *client, uint8_t **buf, size_t *offset) {
+ _cleanup_free_ be16_t *p = NULL;
be16_t *req_opts;
size_t n;
assert(client);
- assert(opt);
- assert(optlen);
+ assert(buf);
+ assert(*buf);
+ assert(offset);
switch (client->state) {
case DHCP6_STATE_INFORMATION_REQUEST:
n = client->n_req_opts;
- buf = new(be16_t, n + 2);
- if (!buf)
+ p = new(be16_t, n + 2);
+ if (!p)
return -ENOMEM;
- memcpy_safe(buf, client->req_opts, n * sizeof(be16_t));
- buf[n++] = htobe16(SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME); /* RFC 8415 section 21.23 */
- buf[n++] = htobe16(SD_DHCP6_OPTION_INF_MAX_RT); /* RFC 8415 section 21.25 */
+ memcpy_safe(p, client->req_opts, n * sizeof(be16_t));
+ p[n++] = htobe16(SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME); /* RFC 8415 section 21.23 */
+ p[n++] = htobe16(SD_DHCP6_OPTION_INF_MAX_RT); /* RFC 8415 section 21.25 */
- typesafe_qsort(buf, n, be16_compare_func);
- req_opts = buf;
+ typesafe_qsort(p, n, be16_compare_func);
+ req_opts = p;
break;
case DHCP6_STATE_SOLICITATION:
n = client->n_req_opts;
- buf = new(be16_t, n + 1);
- if (!buf)
+ p = new(be16_t, n + 1);
+ if (!p)
return -ENOMEM;
- memcpy_safe(buf, client->req_opts, n * sizeof(be16_t));
- buf[n++] = htobe16(SD_DHCP6_OPTION_SOL_MAX_RT); /* RFC 8415 section 21.24 */
+ memcpy_safe(p, client->req_opts, n * sizeof(be16_t));
+ p[n++] = htobe16(SD_DHCP6_OPTION_SOL_MAX_RT); /* RFC 8415 section 21.24 */
- typesafe_qsort(buf, n, be16_compare_func);
- req_opts = buf;
+ typesafe_qsort(p, n, be16_compare_func);
+ req_opts = p;
break;
default:
@@ -693,18 +687,18 @@ static int client_append_oro(sd_dhcp6_client *client, uint8_t **opt, size_t *opt
if (n == 0)
return 0;
- return dhcp6_option_append(opt, optlen, SD_DHCP6_OPTION_ORO, n * sizeof(be16_t), req_opts);
+ return dhcp6_option_append(buf, offset, SD_DHCP6_OPTION_ORO, n * sizeof(be16_t), req_opts);
}
int dhcp6_client_send_message(sd_dhcp6_client *client) {
- _cleanup_free_ DHCP6Message *message = NULL;
+ _cleanup_free_ uint8_t *buf = NULL;
struct in6_addr all_servers =
IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
struct sd_dhcp6_option *j;
- size_t len, optlen = 512;
- uint8_t *opt;
usec_t elapsed_usec, time_now;
be16_t elapsed_time;
+ DHCP6Message *message;
+ size_t offset;
int r;
assert(client);
@@ -714,16 +708,13 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
if (r < 0)
return r;
- len = sizeof(DHCP6Message) + optlen;
-
- message = malloc0(len);
- if (!message)
+ if (!GREEDY_REALLOC0(buf, offsetof(DHCP6Message, options)))
return -ENOMEM;
- opt = (uint8_t *)(message + 1);
-
+ message = (DHCP6Message*) buf;
message->transaction_id = client->transaction_id;
message->type = client_message_type_from_state(client);
+ offset = offsetof(DHCP6Message, options);
switch (client->state) {
case DHCP6_STATE_INFORMATION_REQUEST:
@@ -731,12 +722,12 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
case DHCP6_STATE_SOLICITATION:
if (client->rapid_commit) {
- r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
+ r = dhcp6_option_append(&buf, &offset, SD_DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
if (r < 0)
return r;
}
- r = client_append_common_options_in_managed_mode(client, &opt, &optlen,
+ r = client_append_common_options_in_managed_mode(client, &buf, &offset,
&client->ia_na, &client->ia_pd);
if (r < 0)
return r;
@@ -745,7 +736,7 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
case DHCP6_STATE_REQUEST:
case DHCP6_STATE_RENEW:
- r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_SERVERID,
+ r = dhcp6_option_append(&buf, &offset, SD_DHCP6_OPTION_SERVERID,
client->lease->serverid_len,
client->lease->serverid);
if (r < 0)
@@ -756,7 +747,7 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
assert(client->lease);
- r = client_append_common_options_in_managed_mode(client, &opt, &optlen,
+ r = client_append_common_options_in_managed_mode(client, &buf, &offset,
client->lease->ia_na, client->lease->ia_pd);
if (r < 0)
return r;
@@ -769,24 +760,24 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
}
if (client->mudurl) {
- r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_MUD_URL_V6,
+ r = dhcp6_option_append(&buf, &offset, SD_DHCP6_OPTION_MUD_URL_V6,
strlen(client->mudurl), client->mudurl);
if (r < 0)
return r;
}
- r = client_append_oro(client, &opt, &optlen);
+ r = client_append_oro(client, &buf, &offset);
if (r < 0)
return r;
- assert(client->duid_len);
- r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_CLIENTID,
+ assert(client->duid_len > 0);
+ r = dhcp6_option_append(&buf, &offset, SD_DHCP6_OPTION_CLIENTID,
client->duid_len, &client->duid);
if (r < 0)
return r;
ORDERED_HASHMAP_FOREACH(j, client->extra_options) {
- r = dhcp6_option_append(&opt, &optlen, j->option, j->length, j->data);
+ r = dhcp6_option_append(&buf, &offset, j->option, j->length, j->data);
if (r < 0)
return r;
}
@@ -796,18 +787,16 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
* been trying to complete a DHCP message exchange. */
elapsed_usec = MIN(usec_sub_unsigned(time_now, client->transaction_start) / USEC_PER_MSEC / 10, (usec_t) UINT16_MAX);
elapsed_time = htobe16(elapsed_usec);
- r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ELAPSED_TIME, sizeof(elapsed_time), &elapsed_time);
+ r = dhcp6_option_append(&buf, &offset, SD_DHCP6_OPTION_ELAPSED_TIME, sizeof(elapsed_time), &elapsed_time);
if (r < 0)
return r;
- r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message,
- len - optlen);
+ r = dhcp6_network_send_udp_socket(client->fd, &all_servers, buf, offset);
if (r < 0)
return r;
log_dhcp6_client(client, "Sent %s",
- dhcp6_message_type_to_string(message->type));
-
+ dhcp6_message_type_to_string(client_message_type_from_state(client)));
return 0;
}
diff --git a/src/libnm-systemd-core/src/libsystemd-network/sd-lldp-rx.c b/src/libnm-systemd-core/src/libsystemd-network/sd-lldp-rx.c
deleted file mode 100644
index 0479cff5f5..0000000000
--- a/src/libnm-systemd-core/src/libsystemd-network/sd-lldp-rx.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <arpa/inet.h>
-#include <linux/sockios.h>
-#include <sys/ioctl.h>
-
-#include "sd-lldp-rx.h"
-
-#include "alloc-util.h"
-#include "ether-addr-util.h"
-#include "event-util.h"
-#include "fd-util.h"
-#include "lldp-neighbor.h"
-#include "lldp-network.h"
-#include "lldp-rx-internal.h"
-#include "memory-util.h"
-#include "network-common.h"
-#include "socket-util.h"
-#include "sort-util.h"
-#include "string-table.h"
-
-#define LLDP_DEFAULT_NEIGHBORS_MAX 128U
-
-static const char * const lldp_rx_event_table[_SD_LLDP_RX_EVENT_MAX] = {
- [SD_LLDP_RX_EVENT_ADDED] = "added",
- [SD_LLDP_RX_EVENT_REMOVED] = "removed",
- [SD_LLDP_RX_EVENT_UPDATED] = "updated",
- [SD_LLDP_RX_EVENT_REFRESHED] = "refreshed",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(lldp_rx_event, sd_lldp_rx_event_t);
-
-static void lldp_rx_flush_neighbors(sd_lldp_rx *lldp_rx) {
- assert(lldp_rx);
-
- hashmap_clear(lldp_rx->neighbor_by_id);
-}
-
-static void lldp_rx_callback(sd_lldp_rx *lldp_rx, sd_lldp_rx_event_t event, sd_lldp_neighbor *n) {
- assert(lldp_rx);
- assert(event >= 0 && event < _SD_LLDP_RX_EVENT_MAX);
-
- if (!lldp_rx->callback)
- return (void) log_lldp_rx(lldp_rx, "Received '%s' event.", lldp_rx_event_to_string(event));
-
- log_lldp_rx(lldp_rx, "Invoking callback for '%s' event.", lldp_rx_event_to_string(event));
- lldp_rx->callback(lldp_rx, event, n, lldp_rx->userdata);
-}
-
-static int lldp_rx_make_space(sd_lldp_rx *lldp_rx, size_t extra) {
- usec_t t = USEC_INFINITY;
- bool changed = false;
-
- assert(lldp_rx);
-
- /* Remove all entries that are past their TTL, and more until at least the specified number of extra entries
- * are free. */
-
- for (;;) {
- _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
-
- n = prioq_peek(lldp_rx->neighbor_by_expiry);
- if (!n)
- break;
-
- sd_lldp_neighbor_ref(n);
-
- if (hashmap_size(lldp_rx->neighbor_by_id) > LESS_BY(lldp_rx->neighbors_max, extra))
- goto remove_one;
-
- if (t == USEC_INFINITY)
- t = now(CLOCK_BOOTTIME);
-
- if (n->until > t)
- break;
-
- remove_one:
- lldp_neighbor_unlink(n);
- lldp_rx_callback(lldp_rx, SD_LLDP_RX_EVENT_REMOVED, n);
- changed = true;
- }
-
- return changed;
-}
-
-static bool lldp_rx_keep_neighbor(sd_lldp_rx *lldp_rx, sd_lldp_neighbor *n) {
- assert(lldp_rx);
- assert(n);
-
- /* Don't keep data with a zero TTL */
- if (n->ttl <= 0)
- return false;
-
- /* Filter out data from the filter address */
- if (!ether_addr_is_null(&lldp_rx->filter_address) &&
- ether_addr_equal(&lldp_rx->filter_address, &n->source_address))
- return false;
-
- /* Only add if the neighbor has a capability we are interested in. Note that we also store all neighbors with
- * no caps field set. */
- if (n->has_capabilities &&
- (n->enabled_capabilities & lldp_rx->capability_mask) == 0)
- return false;
-
- /* Keep everything else */
- return true;
-}
-
-static int lldp_rx_start_timer(sd_lldp_rx *lldp_rx, sd_lldp_neighbor *neighbor);
-
-static int lldp_rx_add_neighbor(sd_lldp_rx *lldp_rx, sd_lldp_neighbor *n) {
- _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *old = NULL;
- bool keep;
- int r;
-
- assert(lldp_rx);
- assert(n);
- assert(!n->lldp_rx);
-
- keep = lldp_rx_keep_neighbor(lldp_rx, n);
-
- /* First retrieve the old entry for this MSAP */
- old = hashmap_get(lldp_rx->neighbor_by_id, &n->id);
- if (old) {
- sd_lldp_neighbor_ref(old);
-
- if (!keep) {
- lldp_neighbor_unlink(old);
- lldp_rx_callback(lldp_rx, SD_LLDP_RX_EVENT_REMOVED, old);
- return 0;
- }
-
- if (lldp_neighbor_equal(n, old)) {
- /* Is this equal, then restart the TTL counter, but don't do anything else. */
- old->timestamp = n->timestamp;
- lldp_rx_start_timer(lldp_rx, old);
- lldp_rx_callback(lldp_rx, SD_LLDP_RX_EVENT_REFRESHED, old);
- return 0;
- }
-
- /* Data changed, remove the old entry, and add a new one */
- lldp_neighbor_unlink(old);
-
- } else if (!keep)
- return 0;
-
- /* Then, make room for at least one new neighbor */
- lldp_rx_make_space(lldp_rx, 1);
-
- r = hashmap_ensure_put(&lldp_rx->neighbor_by_id, &lldp_neighbor_hash_ops, &n->id, n);
- if (r < 0)
- goto finish;
-
- r = prioq_ensure_put(&lldp_rx->neighbor_by_expiry, lldp_neighbor_prioq_compare_func, n, &n->prioq_idx);
- if (r < 0) {
- assert_se(hashmap_remove(lldp_rx->neighbor_by_id, &n->id) == n);
- goto finish;
- }
-
- n->lldp_rx = lldp_rx;
-
- lldp_rx_start_timer(lldp_rx, n);
- lldp_rx_callback(lldp_rx, old ? SD_LLDP_RX_EVENT_UPDATED : SD_LLDP_RX_EVENT_ADDED, n);
-
- return 1;
-
-finish:
- if (old)
- lldp_rx_callback(lldp_rx, SD_LLDP_RX_EVENT_REMOVED, old);
-
- return r;
-}
-
-static int lldp_rx_handle_datagram(sd_lldp_rx *lldp_rx, sd_lldp_neighbor *n) {
- int r;
-
- assert(lldp_rx);
- assert(n);
-
- r = lldp_neighbor_parse(n);
- if (r < 0)
- return r;
-
- r = lldp_rx_add_neighbor(lldp_rx, n);
- if (r < 0)
- return log_lldp_rx_errno(lldp_rx, r, "Failed to add datagram. Ignoring.");
-
- log_lldp_rx(lldp_rx, "Successfully processed LLDP datagram.");
- return 0;
-}
-
-static int lldp_rx_receive_datagram(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
- ssize_t space, length;
- sd_lldp_rx *lldp_rx = ASSERT_PTR(userdata);
- struct timespec ts;
-
- assert(fd >= 0);
-
- space = next_datagram_size_fd(fd);
- if (space < 0) {
- if (ERRNO_IS_TRANSIENT(space) || ERRNO_IS_DISCONNECT(space))
- return 0;
-
- log_lldp_rx_errno(lldp_rx, space, "Failed to determine datagram size to read, ignoring: %m");
- return 0;
- }
-
- n = lldp_neighbor_new(space);
- if (!n) {
- log_oom_debug();
- return 0;
- }
-
- length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT);
- if (length < 0) {
- if (ERRNO_IS_TRANSIENT(errno) || ERRNO_IS_DISCONNECT(errno))
- return 0;
-
- log_lldp_rx_errno(lldp_rx, errno, "Failed to read LLDP datagram, ignoring: %m");
- return 0;
- }
-
- if ((size_t) length != n->raw_size) {
- log_lldp_rx(lldp_rx, "Packet size mismatch, ignoring");
- return 0;
- }
-
- /* Try to get the timestamp of this packet if it is known */
- if (ioctl(fd, SIOCGSTAMPNS, &ts) >= 0)
- triple_timestamp_from_realtime(&n->timestamp, timespec_load(&ts));
- else
- triple_timestamp_get(&n->timestamp);
-
- (void) lldp_rx_handle_datagram(lldp_rx, n);
- return 0;
-}
-
-static void lldp_rx_reset(sd_lldp_rx *lldp_rx) {
- assert(lldp_rx);
-
- (void) event_source_disable(lldp_rx->timer_event_source);
- lldp_rx->io_event_source = sd_event_source_disable_unref(lldp_rx->io_event_source);
- lldp_rx->fd = safe_close(lldp_rx->fd);
-}
-
-int sd_lldp_rx_is_running(sd_lldp_rx *lldp_rx) {
- if (!lldp_rx)
- return false;
-
- return lldp_rx->fd >= 0;
-}
-
-int sd_lldp_rx_start(sd_lldp_rx *lldp_rx) {
- int r;
-
- assert_return(lldp_rx, -EINVAL);
- assert_return(lldp_rx->event, -EINVAL);
- assert_return(lldp_rx->ifindex > 0, -EINVAL);
-
- if (sd_lldp_rx_is_running(lldp_rx))
- return 0;
-
- assert(!lldp_rx->io_event_source);
-
- lldp_rx->fd = lldp_network_bind_raw_socket(lldp_rx->ifindex);
- if (lldp_rx->fd < 0)
- return lldp_rx->fd;
-
- r = sd_event_add_io(lldp_rx->event, &lldp_rx->io_event_source, lldp_rx->fd, EPOLLIN, lldp_rx_receive_datagram, lldp_rx);
- if (r < 0)
- goto fail;
-
- r = sd_event_source_set_priority(lldp_rx->io_event_source, lldp_rx->event_priority);
- if (r < 0)
- goto fail;
-
- (void) sd_event_source_set_description(lldp_rx->io_event_source, "lldp-rx-io");
-
- log_lldp_rx(lldp_rx, "Started LLDP client");
- return 1;
-
-fail:
- lldp_rx_reset(lldp_rx);
- return r;
-}
-
-int sd_lldp_rx_stop(sd_lldp_rx *lldp_rx) {
- if (!sd_lldp_rx_is_running(lldp_rx))
- return 0;
-
- log_lldp_rx(lldp_rx, "Stopping LLDP client");
-
- lldp_rx_reset(lldp_rx);
- lldp_rx_flush_neighbors(lldp_rx);
-
- return 1;
-}
-
-int sd_lldp_rx_attach_event(sd_lldp_rx *lldp_rx, sd_event *event, int64_t priority) {
- int r;
-
- assert_return(lldp_rx, -EINVAL);
- assert_return(!sd_lldp_rx_is_running(lldp_rx), -EBUSY);
- assert_return(!lldp_rx->event, -EBUSY);
-
- if (event)
- lldp_rx->event = sd_event_ref(event);
- else {
- r = sd_event_default(&lldp_rx->event);
- if (r < 0)
- return r;
- }
-
- lldp_rx->event_priority = priority;
-
- return 0;
-}
-
-int sd_lldp_rx_detach_event(sd_lldp_rx *lldp_rx) {
- assert_return(lldp_rx, -EINVAL);
- assert_return(!sd_lldp_rx_is_running(lldp_rx), -EBUSY);
-
- lldp_rx->io_event_source = sd_event_source_disable_unref(lldp_rx->io_event_source);
- lldp_rx->timer_event_source = sd_event_source_disable_unref(lldp_rx->timer_event_source);
- lldp_rx->event = sd_event_unref(lldp_rx->event);
- return 0;
-}
-
-sd_event* sd_lldp_rx_get_event(sd_lldp_rx *lldp_rx) {
- assert_return(lldp_rx, NULL);
-
- return lldp_rx->event;
-}
-
-int sd_lldp_rx_set_callback(sd_lldp_rx *lldp_rx, sd_lldp_rx_callback_t cb, void *userdata) {
- assert_return(lldp_rx, -EINVAL);
-
- lldp_rx->callback = cb;
- lldp_rx->userdata = userdata;
-
- return 0;
-}
-
-int sd_lldp_rx_set_ifindex(sd_lldp_rx *lldp_rx, int ifindex) {
- assert_return(lldp_rx, -EINVAL);
- assert_return(ifindex > 0, -EINVAL);
- assert_return(!sd_lldp_rx_is_running(lldp_rx), -EBUSY);
-
- lldp_rx->ifindex = ifindex;
- return 0;
-}
-
-int sd_lldp_rx_set_ifname(sd_lldp_rx *lldp_rx, const char *ifname) {
- assert_return(lldp_rx, -EINVAL);
- assert_return(ifname, -EINVAL);
-
- if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
- return -EINVAL;
-
- return free_and_strdup(&lldp_rx->ifname, ifname);
-}
-
-int sd_lldp_rx_get_ifname(sd_lldp_rx *lldp_rx, const char **ret) {
- int r;
-
- assert_return(lldp_rx, -EINVAL);
-
- r = get_ifname(lldp_rx->ifindex, &lldp_rx->ifname);
- if (r < 0)
- return r;
-
- if (ret)
- *ret = lldp_rx->ifname;
-
- return 0;
-}
-
-static sd_lldp_rx *lldp_rx_free(sd_lldp_rx *lldp_rx) {
- if (!lldp_rx)
- return NULL;
-
- lldp_rx_reset(lldp_rx);
-
- sd_lldp_rx_detach_event(lldp_rx);
-
- lldp_rx_flush_neighbors(lldp_rx);
-
- hashmap_free(lldp_rx->neighbor_by_id);
- prioq_free(lldp_rx->neighbor_by_expiry);
- free(lldp_rx->ifname);
- return mfree(lldp_rx);
-}
-
-DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_lldp_rx, sd_lldp_rx, lldp_rx_free);
-
-int sd_lldp_rx_new(sd_lldp_rx **ret) {
- _cleanup_(sd_lldp_rx_unrefp) sd_lldp_rx *lldp_rx = NULL;
-
- assert_return(ret, -EINVAL);
-
- lldp_rx = new(sd_lldp_rx, 1);
- if (!lldp_rx)
- return -ENOMEM;
-
- *lldp_rx = (sd_lldp_rx) {
- .n_ref = 1,
- .fd = -1,
- .neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX,
- .capability_mask = UINT16_MAX,
- };
-
- *ret = TAKE_PTR(lldp_rx);
- return 0;
-}
-
-static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_lldp_rx *lldp_rx = userdata;
- int r;
-
- r = lldp_rx_make_space(lldp_rx, 0);
- if (r < 0) {
- log_lldp_rx_errno(lldp_rx, r, "Failed to make space, ignoring: %m");
- return 0;
- }
-
- r = lldp_rx_start_timer(lldp_rx, NULL);
- if (r < 0) {
- log_lldp_rx_errno(lldp_rx, r, "Failed to restart timer, ignoring: %m");
- return 0;
- }
-
- return 0;
-}
-
-static int lldp_rx_start_timer(sd_lldp_rx *lldp_rx, sd_lldp_neighbor *neighbor) {
- sd_lldp_neighbor *n;
-
- assert(lldp_rx);
- assert(lldp_rx->event);
-
- if (neighbor)
- lldp_neighbor_start_ttl(neighbor);
-
- n = prioq_peek(lldp_rx->neighbor_by_expiry);
- if (!n)
- return event_source_disable(lldp_rx->timer_event_source);
-
- return event_reset_time(lldp_rx->event, &lldp_rx->timer_event_source,
- CLOCK_BOOTTIME,
- n->until, 0,
- on_timer_event, lldp_rx,
- lldp_rx->event_priority, "lldp-rx-timer", true);
-}
-
-static inline int neighbor_compare_func(sd_lldp_neighbor * const *a, sd_lldp_neighbor * const *b) {
- assert(a);
- assert(b);
- assert(*a);
- assert(*b);
-
- return lldp_neighbor_id_compare_func(&(*a)->id, &(*b)->id);
-}
-
-int sd_lldp_rx_get_neighbors(sd_lldp_rx *lldp_rx, sd_lldp_neighbor ***ret) {
- _cleanup_free_ sd_lldp_neighbor **l = NULL;
- sd_lldp_neighbor *n;
- int k = 0;
-
- assert_return(lldp_rx, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (hashmap_isempty(lldp_rx->neighbor_by_id)) { /* Special shortcut */
- *ret = NULL;
- return 0;
- }
-
- l = new0(sd_lldp_neighbor*, hashmap_size(lldp_rx->neighbor_by_id));
- if (!l)
- return -ENOMEM;
-
- HASHMAP_FOREACH(n, lldp_rx->neighbor_by_id)
- l[k++] = sd_lldp_neighbor_ref(n);
-
- assert((size_t) k == hashmap_size(lldp_rx->neighbor_by_id));
-
- /* Return things in a stable order */
- typesafe_qsort(l, k, neighbor_compare_func);
- *ret = TAKE_PTR(l);
-
- return k;
-}
-
-int sd_lldp_rx_set_neighbors_max(sd_lldp_rx *lldp_rx, uint64_t m) {
- assert_return(lldp_rx, -EINVAL);
- assert_return(m > 0, -EINVAL);
-
- lldp_rx->neighbors_max = m;
- lldp_rx_make_space(lldp_rx, 0);
-
- return 0;
-}
-
-int sd_lldp_rx_match_capabilities(sd_lldp_rx *lldp_rx, uint16_t mask) {
- assert_return(lldp_rx, -EINVAL);
- assert_return(mask != 0, -EINVAL);
-
- lldp_rx->capability_mask = mask;
-
- return 0;
-}
-
-int sd_lldp_rx_set_filter_address(sd_lldp_rx *lldp_rx, const struct ether_addr *addr) {
- assert_return(lldp_rx, -EINVAL);
-
- /* In order to deal nicely with bridges that send back our own packets, allow one address to be filtered, so
- * that our own can be filtered out here. */
-
- if (addr)
- lldp_rx->filter_address = *addr;
- else
- zero(lldp_rx->filter_address);
-
- return 0;
-}
diff --git a/src/libnm-systemd-core/src/systemd/sd-lldp-rx.h b/src/libnm-systemd-core/src/systemd/sd-lldp-rx.h
deleted file mode 100644
index 504d7f59c1..0000000000
--- a/src/libnm-systemd-core/src/systemd/sd-lldp-rx.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#ifndef foosdlldprxhfoo
-#define foosdlldprxhfoo
-
-/***
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <https://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <inttypes.h>
-#include <net/ethernet.h>
-#include <sys/types.h>
-
-#include "sd-event.h"
-#include "sd-lldp.h"
-
-#include "_sd-common.h"
-
-_SD_BEGIN_DECLARATIONS;
-
-typedef struct sd_lldp_rx sd_lldp_rx;
-typedef struct sd_lldp_neighbor sd_lldp_neighbor;
-
-__extension__ typedef enum sd_lldp_rx_event_t {
- SD_LLDP_RX_EVENT_ADDED,
- SD_LLDP_RX_EVENT_REMOVED,
- SD_LLDP_RX_EVENT_UPDATED,
- SD_LLDP_RX_EVENT_REFRESHED,
- _SD_LLDP_RX_EVENT_MAX,
- _SD_LLDP_RX_EVENT_INVALID = -EINVAL,
- _SD_ENUM_FORCE_S64(LLDP_RX_EVENT)
-} sd_lldp_rx_event_t;
-
-typedef void (*sd_lldp_rx_callback_t)(sd_lldp_rx *lldp_rx, sd_lldp_rx_event_t event, sd_lldp_neighbor *n, void *userdata);
-
-int sd_lldp_rx_new(sd_lldp_rx **ret);
-sd_lldp_rx *sd_lldp_rx_ref(sd_lldp_rx *lldp_rx);
-sd_lldp_rx *sd_lldp_rx_unref(sd_lldp_rx *lldp_rx);
-
-int sd_lldp_rx_start(sd_lldp_rx *lldp_rx);
-int sd_lldp_rx_stop(sd_lldp_rx *lldp_rx);
-int sd_lldp_rx_is_running(sd_lldp_rx *lldp_rx);
-
-int sd_lldp_rx_attach_event(sd_lldp_rx *lldp_rx, sd_event *event, int64_t priority);
-int sd_lldp_rx_detach_event(sd_lldp_rx *lldp_rx);
-sd_event *sd_lldp_rx_get_event(sd_lldp_rx *lldp_rx);
-
-int sd_lldp_rx_set_callback(sd_lldp_rx *lldp_rx, sd_lldp_rx_callback_t cb, void *userdata);
-int sd_lldp_rx_set_ifindex(sd_lldp_rx *lldp_rx, int ifindex);
-int sd_lldp_rx_set_ifname(sd_lldp_rx *lldp_rx, const char *ifname);
-int sd_lldp_rx_get_ifname(sd_lldp_rx *lldp_rx, const char **ret);
-
-/* Controls how much and what to store in the neighbors database */
-int sd_lldp_rx_set_neighbors_max(sd_lldp_rx *lldp_rx, uint64_t n);
-int sd_lldp_rx_match_capabilities(sd_lldp_rx *lldp_rx, uint16_t mask);
-int sd_lldp_rx_set_filter_address(sd_lldp_rx *lldp_rx, const struct ether_addr *address);
-
-int sd_lldp_rx_get_neighbors(sd_lldp_rx *lldp_rx, sd_lldp_neighbor ***neighbors);
-
-int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size);
-sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n);
-sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n);
-
-/* Access to LLDP frame metadata */
-int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address);
-int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address);
-int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret);
-int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size);
-
-/* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */
-int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size);
-int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, const char **ret);
-int sd_lldp_neighbor_get_port_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size);
-int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const char **ret);
-int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec);
-int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret);
-int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret);
-int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret);
-int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret);
-int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
-int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
-
-/* Low-level, iterative TLV access. This is for everything else, it iteratively goes through all available TLVs
- * (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */
-int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n);
-int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n);
-int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type);
-int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type);
-int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t *subtype);
-int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[_SD_ARRAY_STATIC 3], uint8_t subtype);
-int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size);
-
-_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_lldp_rx, sd_lldp_rx_unref);
-_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_lldp_neighbor, sd_lldp_neighbor_unref);
-
-_SD_END_DECLARATIONS;
-
-#endif
diff --git a/src/libnm-systemd-core/src/systemd/sd-lldp.h b/src/libnm-systemd-core/src/systemd/sd-lldp.h
deleted file mode 100644
index 4069c5b299..0000000000
--- a/src/libnm-systemd-core/src/systemd/sd-lldp.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#ifndef foosdlldphfoo
-#define foosdlldphfoo
-
-/***
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <https://www.gnu.org/licenses/>.
-***/
-
-#include <inttypes.h>
-
-#include "_sd-common.h"
-
-_SD_BEGIN_DECLARATIONS;
-
-/* IEEE 802.1AB-2009 Clause 8: TLV Types */
-enum {
- SD_LLDP_TYPE_END = 0,
- SD_LLDP_TYPE_CHASSIS_ID = 1,
- SD_LLDP_TYPE_PORT_ID = 2,
- SD_LLDP_TYPE_TTL = 3,
- SD_LLDP_TYPE_PORT_DESCRIPTION = 4,
- SD_LLDP_TYPE_SYSTEM_NAME = 5,
- SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
- SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
- SD_LLDP_TYPE_MGMT_ADDRESS = 8,
- SD_LLDP_TYPE_PRIVATE = 127
-};
-
-/* IEEE 802.1AB-2009 Clause 8.5.2: Chassis subtypes */
-enum {
- SD_LLDP_CHASSIS_SUBTYPE_RESERVED = 0,
- SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1,
- SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2,
- SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3,
- SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4,
- SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5,
- SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6,
- SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7
-};
-
-/* IEEE 802.1AB-2009 Clause 8.5.3: Port subtype */
-enum {
- SD_LLDP_PORT_SUBTYPE_RESERVED = 0,
- SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
- SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
- SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
- SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4,
- SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
- SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
- SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7
-};
-
-/* IEEE 802.1AB-2009 Clause 8.5.8: System capabilities */
-enum {
- SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
- SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
- SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
- SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
- SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
- SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
- SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
- SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
- SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
- SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
- SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10
-};
-
-#define SD_LLDP_SYSTEM_CAPABILITIES_ALL UINT16_MAX
-
-#define SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS \
- ((uint16_t) \
- (SD_LLDP_SYSTEM_CAPABILITIES_REPEATER | \
- SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE | \
- SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP | \
- SD_LLDP_SYSTEM_CAPABILITIES_ROUTER | \
- SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS | \
- SD_LLDP_SYSTEM_CAPABILITIES_CVLAN | \
- SD_LLDP_SYSTEM_CAPABILITIES_SVLAN | \
- SD_LLDP_SYSTEM_CAPABILITIES_TPMR))
-
-#define SD_LLDP_OUI_802_1 (const uint8_t[]) { 0x00, 0x80, 0xc2 }
-#define SD_LLDP_OUI_802_3 (const uint8_t[]) { 0x00, 0x12, 0x0f }
-
-#define _SD_LLDP_OUI_IANA 0x00, 0x00, 0x5E
-#define SD_LLDP_OUI_IANA (const uint8_t[]) { _SD_LLDP_OUI_IANA }
-
-#define SD_LLDP_OUI_IANA_SUBTYPE_MUD 0x01
-#define SD_LLDP_OUI_IANA_MUD \
- (const uint8_t[]) { _SD_LLDP_OUI_IANA, SD_LLDP_OUI_IANA_SUBTYPE_MUD }
-
-/* IEEE 802.1AB-2009 Annex E */
-enum {
- SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1,
- SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2,
- SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3,
- SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4,
- SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5,
- SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6,
- SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7
-};
-
-/* IEEE 802.1AB-2009 Annex F */
-enum {
- SD_LLDP_OUI_802_3_SUBTYPE_MAC_PHY_CONFIG_STATUS = 1,
- SD_LLDP_OUI_802_3_SUBTYPE_POWER_VIA_MDI = 2,
- SD_LLDP_OUI_802_3_SUBTYPE_LINK_AGGREGATION = 3,
- SD_LLDP_OUI_802_3_SUBTYPE_MAXIMUM_FRAME_SIZE = 4
-};
-
-_SD_END_DECLARATIONS;
-
-#endif
diff --git a/src/libnm-systemd-shared/src/basic/errno-util.h b/src/libnm-systemd-shared/src/basic/errno-util.h
index 648de50eb4..091f99c590 100644
--- a/src/libnm-systemd-shared/src/basic/errno-util.h
+++ b/src/libnm-systemd-shared/src/basic/errno-util.h
@@ -6,6 +6,21 @@
#include "macro.h"
+/* strerror(3) says that glibc uses a maximum length of 1024 bytes. */
+#define ERRNO_BUF_LEN 1024
+
+/* Note: the lifetime of the compound literal is the immediately surrounding block,
+ * see C11 §6.5.2.5, and
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks
+ *
+ * Note that we use the GNU variant of strerror_r() here. */
+#define STRERROR(errnum) strerror_r(abs(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN)
+
+/* A helper to print an error message or message for functions that return 0 on EOF.
+ * Note that we can't use ({ … }) to define a temporary variable, so errnum is
+ * evaluated twice. */
+#define STRERROR_OR_EOF(errnum) ((errnum) != 0 ? STRERROR(errnum) : "Unexpected EOF")
+
static inline void _reset_errno_(int *saved_errno) {
if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
return;
@@ -22,6 +37,10 @@ static inline void _reset_errno_(int *saved_errno) {
_saved_errno_ = -1; \
} while (false)
+#define LOCAL_ERRNO(value) \
+ PROTECT_ERRNO; \
+ errno = abs(value)
+
static inline int negative_errno(void) {
/* This helper should be used to shut up gcc if you know 'errno' is
* negative. Instead of "return -errno;", use "return negative_errno();"
@@ -54,11 +73,6 @@ static inline int RET_NERRNO(int ret) {
return ret;
}
-static inline const char *strerror_safe(int error) {
- /* 'safe' here does NOT mean thread safety. */
- return strerror(abs(error)); /* lgtm [cpp/potentially-dangerous-function] */
-}
-
static inline int errno_or_else(int fallback) {
/* To be used when invoking library calls where errno handling is not defined clearly: we return
* errno if it is set, and the specified error otherwise. The idea is that the caller initializes
@@ -153,3 +167,10 @@ static inline bool ERRNO_IS_DEVICE_ABSENT(int r) {
ENXIO,
ENOENT);
}
+
+/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and
+ * where it simply doesn't have the requested xattr the same way */
+static inline bool ERRNO_IS_XATTR_ABSENT(int r) {
+ return abs(r) == ENODATA ||
+ ERRNO_IS_NOT_SUPPORTED(r);
+}
diff --git a/src/libnm-systemd-shared/src/basic/fd-util.c b/src/libnm-systemd-shared/src/basic/fd-util.c
index 6c85a34896..cee20a9a81 100644
--- a/src/libnm-systemd-shared/src/basic/fd-util.c
+++ b/src/libnm-systemd-shared/src/basic/fd-util.c
@@ -2,7 +2,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <linux/btrfs.h>
#if WANT_LINUX_FS_H
#include <linux/fs.h>
#endif
@@ -779,20 +778,6 @@ int read_nr_open(void) {
return 1024 * 1024;
}
-/* This is here because it's fd-related and is called from sd-journal code. Other btrfs-related utilities are
- * in src/shared, but libsystemd must not link to libsystemd-shared, see docs/ARCHITECTURE.md. */
-int btrfs_defrag_fd(int fd) {
- int r;
-
- assert(fd >= 0);
-
- r = fd_verify_regular(fd);
- if (r < 0)
- return r;
-
- return RET_NERRNO(ioctl(fd, BTRFS_IOC_DEFRAG, NULL));
-}
-
int fd_get_diskseq(int fd, uint64_t *ret) {
uint64_t diskseq;
diff --git a/src/libnm-systemd-shared/src/basic/fd-util.h b/src/libnm-systemd-shared/src/basic/fd-util.h
index 8543d0d5ea..d9896e27e8 100644
--- a/src/libnm-systemd-shared/src/basic/fd-util.h
+++ b/src/libnm-systemd-shared/src/basic/fd-util.h
@@ -108,7 +108,6 @@ static inline int make_null_stdio(void) {
int fd_reopen(int fd, int flags);
int read_nr_open(void);
-int btrfs_defrag_fd(int fd);
int fd_get_diskseq(int fd, uint64_t *ret);
/* The maximum length a buffer for a /proc/self/fd/<fd> path needs */
diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.c b/src/libnm-systemd-shared/src/basic/in-addr-util.c
index cefe3f7661..05c729d34d 100644
--- a/src/libnm-systemd-shared/src/basic/in-addr-util.c
+++ b/src/libnm-systemd-shared/src/basic/in-addr-util.c
@@ -66,7 +66,7 @@ bool in4_addr_is_link_local_dynamic(const struct in_addr *a) {
bool in6_addr_is_link_local(const struct in6_addr *a) {
assert(a);
- return IN6_IS_ADDR_LINKLOCAL(a); /* lgtm [cpp/potentially-dangerous-function] */
+ return IN6_IS_ADDR_LINKLOCAL(a);
}
int in_addr_is_link_local(int family, const union in_addr_union *u) {
@@ -131,7 +131,7 @@ int in_addr_is_localhost(int family, const union in_addr_union *u) {
return in4_addr_is_localhost(&u->in);
if (family == AF_INET6)
- return IN6_IS_ADDR_LOOPBACK(&u->in6); /* lgtm [cpp/potentially-dangerous-function] */
+ return IN6_IS_ADDR_LOOPBACK(&u->in6);
return -EAFNOSUPPORT;
}
@@ -144,7 +144,7 @@ int in_addr_is_localhost_one(int family, const union in_addr_union *u) {
return be32toh(u->in.s_addr) == UINT32_C(0x7F000001);
if (family == AF_INET6)
- return IN6_IS_ADDR_LOOPBACK(&u->in6); /* lgtm [cpp/potentially-dangerous-function] */
+ return IN6_IS_ADDR_LOOPBACK(&u->in6);
return -EAFNOSUPPORT;
}
@@ -194,8 +194,7 @@ int in_addr_prefix_intersect(
assert(a);
assert(b);
- /* Checks whether there are any addresses that are in both
- * networks */
+ /* Checks whether there are any addresses that are in both networks */
m = MIN(aprefixlen, bprefixlen);
@@ -203,7 +202,7 @@ int in_addr_prefix_intersect(
uint32_t x, nm;
x = be32toh(a->in.s_addr ^ b->in.s_addr);
- nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
+ nm = m == 0 ? 0 : 0xFFFFFFFFUL << (32 - m);
return (x & nm) == 0;
}
diff --git a/src/libnm-systemd-shared/src/basic/process-util.c b/src/libnm-systemd-shared/src/basic/process-util.c
index 3dd6f4df59..fb0b38fa49 100644
--- a/src/libnm-systemd-shared/src/basic/process-util.c
+++ b/src/libnm-systemd-shared/src/basic/process-util.c
@@ -815,7 +815,7 @@ int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
if (status.si_pid == pid) {
/* This is the correct child. */
if (status.si_code == CLD_EXITED)
- return (status.si_status == 0) ? 0 : -EPROTO;
+ return status.si_status == 0 ? 0 : -EPROTO;
else
return -EPROTO;
}
diff --git a/src/libnm-systemd-shared/src/basic/stdio-util.h b/src/libnm-systemd-shared/src/basic/stdio-util.h
index 69d7062ec6..f647f125ac 100644
--- a/src/libnm-systemd-shared/src/basic/stdio-util.h
+++ b/src/libnm-systemd-shared/src/basic/stdio-util.h
@@ -9,16 +9,16 @@
#include "macro.h"
#include "memory-util.h"
-#define snprintf_ok(buf, len, fmt, ...) \
- ({ \
- char *_buf = (buf); \
- size_t _len = (len); \
- int _snpf = snprintf(_buf, _len, (fmt), __VA_ARGS__); \
- _snpf >= 0 && (size_t) _snpf < _len ? _buf : NULL; \
+#define snprintf_ok(buf, len, fmt, ...) \
+ ({ \
+ char *_buf = (buf); \
+ size_t _len = (len); \
+ int _snpf = snprintf(_buf, _len, (fmt), ##__VA_ARGS__); \
+ _snpf >= 0 && (size_t) _snpf < _len ? _buf : NULL; \
})
#define xsprintf(buf, fmt, ...) \
- assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough")
+ assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, ##__VA_ARGS__), "xsprintf: " #buf "[] must be big enough")
#define VA_FORMAT_ADVANCE(format, ap) \
do { \
diff --git a/src/libnm-systemd-shared/src/basic/string-util.h b/src/libnm-systemd-shared/src/basic/string-util.h
index 0703c848f0..46681ced99 100644
--- a/src/libnm-systemd-shared/src/basic/string-util.h
+++ b/src/libnm-systemd-shared/src/basic/string-util.h
@@ -171,9 +171,12 @@ int split_pair(const char *s, const char *sep, char **l, char **r);
int free_and_strdup(char **p, const char *s);
static inline int free_and_strdup_warn(char **p, const char *s) {
- if (free_and_strdup(p, s) < 0)
+ int r;
+
+ r = free_and_strdup(p, s);
+ if (r < 0)
return log_oom();
- return 0;
+ return r;
}
int free_and_strndup(char **p, const char *s, size_t l);