systemd: merge branch systemd into master

This commit is contained in:
Thomas Haller 2019-11-20 08:47:31 +01:00
commit c016165e1b
64 changed files with 644 additions and 291 deletions

View file

@ -1705,12 +1705,10 @@ shared_systemd_libnm_systemd_shared_la_SOURCES = \
shared/systemd/nm-sd-utils-shared.c \
shared/systemd/nm-sd-utils-shared.h \
shared/systemd/sd-adapt-shared/architecture.h \
shared/systemd/sd-adapt-shared/btrfs-util.h \
shared/systemd/sd-adapt-shared/build.h \
shared/systemd/sd-adapt-shared/cgroup-util.h \
shared/systemd/sd-adapt-shared/copy.h \
shared/systemd/sd-adapt-shared/def.h \
shared/systemd/sd-adapt-shared/device-nodes.h \
shared/systemd/sd-adapt-shared/dhcp-server-internal.h \
shared/systemd/sd-adapt-shared/dirent-util.h \
shared/systemd/sd-adapt-shared/errno-list.h \
shared/systemd/sd-adapt-shared/glob-util.h \
@ -1718,7 +1716,10 @@ shared_systemd_libnm_systemd_shared_la_SOURCES = \
shared/systemd/sd-adapt-shared/ioprio.h \
shared/systemd/sd-adapt-shared/locale-util.h \
shared/systemd/sd-adapt-shared/memfd-util.h \
shared/systemd/sd-adapt-shared/missing.h \
shared/systemd/sd-adapt-shared/missing_fs.h \
shared/systemd/sd-adapt-shared/missing_magic.h \
shared/systemd/sd-adapt-shared/missing_network.h \
shared/systemd/sd-adapt-shared/missing_sched.h \
shared/systemd/sd-adapt-shared/missing_syscall.h \
shared/systemd/sd-adapt-shared/missing_timerfd.h \
shared/systemd/sd-adapt-shared/mkdir.h \
@ -1726,7 +1727,6 @@ shared_systemd_libnm_systemd_shared_la_SOURCES = \
shared/systemd/sd-adapt-shared/nm-sd-adapt-shared.h \
shared/systemd/sd-adapt-shared/nm-sd-adapt-shared.h \
shared/systemd/sd-adapt-shared/nulstr-util.h \
shared/systemd/sd-adapt-shared/procfs-util.h \
shared/systemd/sd-adapt-shared/raw-clone.h \
shared/systemd/sd-adapt-shared/rlimit-util.h \
shared/systemd/sd-adapt-shared/terminal-util.h \
@ -1775,6 +1775,7 @@ shared_systemd_libnm_systemd_shared_la_SOURCES = \
shared/systemd/src/basic/mempool.c \
shared/systemd/src/basic/mempool.h \
shared/systemd/src/basic/missing_fcntl.h \
shared/systemd/src/basic/missing_random.h \
shared/systemd/src/basic/missing_socket.h \
shared/systemd/src/basic/missing_stat.h \
shared/systemd/src/basic/missing_type.h \
@ -1898,6 +1899,7 @@ src_libnm_systemd_core_la_SOURCES = \
src/systemd/src/systemd/_sd-common.h \
src/systemd/src/systemd/sd-dhcp-client.h \
src/systemd/src/systemd/sd-dhcp-lease.h \
src/systemd/src/systemd/sd-dhcp-option.h \
src/systemd/src/systemd/sd-dhcp6-client.h \
src/systemd/src/systemd/sd-dhcp6-lease.h \
src/systemd/src/systemd/sd-event.h \

View file

@ -1,8 +0,0 @@
#pragma once
/* dummy header */
#include "missing_fcntl.h"
#include "missing_socket.h"
#include "missing_stat.h"
#include "missing_type.h"

View file

@ -6,7 +6,6 @@
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "alloc-util.h"

View file

@ -8,7 +8,6 @@
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "alloc-util.h"

View file

@ -5,7 +5,6 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
@ -18,7 +17,8 @@
#include "io-util.h"
#include "macro.h"
#include "memfd-util.h"
#include "missing.h"
#include "missing_fcntl.h"
#include "missing_syscall.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"

View file

@ -10,7 +10,6 @@
#include <stdint.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@ -22,7 +21,6 @@
#include "hexdecoct.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
@ -314,6 +312,113 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
}
#endif /* NM_IGNORED */
int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) {
_cleanup_free_ char *buf = NULL;
_cleanup_close_ int fd = -1;
struct stat st;
size_t n, size;
int n_retries;
char *p;
assert(ret_contents);
/* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work
* with two sorts of virtual files. One sort uses "seq_file", and the results of
* the first read are buffered for the second read. The other sort uses "raw"
* reads which always go direct to the device. In the latter case, the content of
* the virtual file must be retrieved with a single read otherwise a second read
* might get the new value instead of finding EOF immediately. That's the reason
* why the usage of fread(3) is prohibited in this case as it always performs a
* second call to read(2) looking for EOF. See issue 13585. */
fd = open(filename, O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
/* Start size for files in /proc which usually report a file size of 0. */
size = LINE_MAX / 2;
/* Limit the number of attempts to read the number of bytes returned by fstat(). */
n_retries = 3;
for (;;) {
if (n_retries <= 0)
return -EIO;
if (fstat(fd, &st) < 0)
return -errno;
if (!S_ISREG(st.st_mode))
return -EBADF;
/* Be prepared for files from /proc which generally report a file size of 0. */
if (st.st_size > 0) {
size = st.st_size;
n_retries--;
} else
size = size * 2;
if (size > READ_FULL_BYTES_MAX)
return -E2BIG;
p = realloc(buf, size + 1);
if (!p)
return -ENOMEM;
buf = TAKE_PTR(p);
for (;;) {
ssize_t k;
/* Read one more byte so we can detect whether the content of the
* file has already changed or the guessed size for files from /proc
* wasn't large enough . */
k = read(fd, buf, size + 1);
if (k >= 0) {
n = k;
break;
}
if (errno != -EINTR)
return -errno;
}
/* Consider a short read as EOF */
if (n <= size)
break;
/* Hmm... either we read too few bytes from /proc or less likely the content
* of the file might have been changed (and is now bigger) while we were
* processing, let's try again either with a bigger guessed size or the new
* file size. */
if (lseek(fd, 0, SEEK_SET) < 0)
return -errno;
}
if (n < size) {
p = realloc(buf, n + 1);
if (!p)
return -ENOMEM;
buf = TAKE_PTR(p);
}
if (!ret_size) {
/* Safety check: if the caller doesn't want to know the size of what we
* just read it will rely on the trailing NUL byte. But if there's an
* embedded NUL byte, then we should refuse operation as otherwise
* there'd be ambiguity about what we just read. */
if (memchr(buf, 0, n))
return -EBADMSG;
} else
*ret_size = n;
buf[n] = 0;
*ret_contents = TAKE_PTR(buf);
return 0;
}
int read_full_stream_full(
FILE *f,
const char *filename,
@ -346,9 +451,9 @@ int read_full_stream_full(
if (st.st_size > READ_FULL_BYTES_MAX)
return -E2BIG;
/* Start with the right file size, but be prepared for files from /proc which generally report a file
* size of 0. Note that we increase the size to read here by one, so that the first read attempt
* already makes us notice the EOF. */
/* Start with the right file size. Note that we increase the size
* to read here by one, so that the first read attempt already
* makes us notice the EOF. */
if (st.st_size > 0)
n_next = st.st_size + 1;
@ -508,7 +613,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin
assert(pattern);
assert(field);
r = read_full_file(filename, &status, NULL);
r = read_full_virtual_file(filename, &status, NULL);
if (r < 0)
return r;

View file

@ -56,6 +56,7 @@ int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **co
static inline int read_full_file(const char *filename, char **contents, size_t *size) {
return read_full_file_full(filename, 0, contents, size);
}
int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size);
int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size);
static inline int read_full_stream(FILE *f, char **contents, size_t *size) {
return read_full_stream_full(f, NULL, 0, contents, size);

View file

@ -2,15 +2,26 @@
#include "nm-sd-adapt-shared.h"
#include <stdio.h>
#include "format-util.h"
#include "memory-util.h"
#include "stdio-util.h"
char *format_ifname(int ifindex, char buf[static IF_NAMESIZE + 1]) {
assert_cc(DECIMAL_STR_MAX(int) + 1 <= IF_NAMESIZE + 1);
char *format_ifname_full(int ifindex, char buf[static IF_NAMESIZE + 1], FormatIfnameFlag flag) {
/* Buffer is always cleared */
memzero(buf, IF_NAMESIZE + 1);
return if_indextoname(ifindex, buf);
if (if_indextoname(ifindex, buf))
return buf;
if (!FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX))
return NULL;
if (FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX_WITH_PERCENT))
snprintf(buf, IF_NAMESIZE + 1, "%%%d", ifindex);
else
snprintf(buf, IF_NAMESIZE + 1, "%d", ifindex);
return buf;
}
char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) {

View file

@ -68,7 +68,15 @@
# error Unknown ino_t size
#endif
char *format_ifname(int ifindex, char buf[static IF_NAMESIZE + 1]);
typedef enum {
FORMAT_IFNAME_IFINDEX = 1 << 0,
FORMAT_IFNAME_IFINDEX_WITH_PERCENT = (1 << 1) | FORMAT_IFNAME_IFINDEX,
} FormatIfnameFlag;
char *format_ifname_full(int ifindex, char buf[static IF_NAMESIZE + 1], FormatIfnameFlag flag);
static inline char *format_ifname(int ifindex, char buf[static IF_NAMESIZE + 1]) {
return format_ifname_full(ifindex, buf, 0);
}
typedef enum {
FORMAT_BYTES_USE_IEC = 1 << 0,

View file

@ -4,13 +4,9 @@
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <linux/falloc.h>
#include <linux/magic.h>
#include <time.h>
#include <unistd.h>
#include "alloc-util.h"
@ -20,7 +16,9 @@
#include "locale-util.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
#include "missing_fcntl.h"
#include "missing_fs.h"
#include "missing_syscall.h"
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
@ -669,6 +667,18 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
}
#if 0 /* NM_IGNORED */
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
if (inotify_add_watch(fd, pathname, mask) < 0) {
if (errno == ENOSPC)
return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname);
return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname);
}
return 0;
}
static bool unsafe_transition(const struct stat *a, const struct stat *b) {
/* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
* privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
@ -707,7 +717,7 @@ static int log_autofs_mount_point(int fd, const char *path, unsigned flags) {
n1, path);
}
int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret_path, int *ret_fd) {
_cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
_cleanup_close_ int fd = -1;
unsigned max_follow = CHASE_SYMLINKS_MAX; /* how many symlinks to follow before giving up and returning ELOOP */
@ -719,10 +729,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
assert(path);
/* Either the file may be missing, or we return an fd to the final object, but both make no sense */
if (FLAGS_SET(flags, CHASE_NONEXISTENT | CHASE_OPEN))
if ((flags & CHASE_NONEXISTENT) && ret_fd)
return -EINVAL;
if (FLAGS_SET(flags, CHASE_STEP | CHASE_OPEN))
if ((flags & CHASE_STEP) && ret_fd)
return -EINVAL;
if (isempty(path))
@ -748,17 +758,17 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
* function what to do when encountering a symlink with an absolute path as directory: prefix it by the
* specified path.
*
* There are three ways to invoke this function:
* There are five ways to invoke this function:
*
* 1. Without CHASE_STEP or CHASE_OPEN: in this case the path is resolved and the normalized path is returned
* in `ret`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0 is returned if the file
* doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is returned if the destination was
* found, -ENOENT if it wasn't.
* 1. Without CHASE_STEP or ret_fd: in this case the path is resolved and the normalized path is
* returned in `ret_path`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0
* is returned if the file doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is
* returned if the destination was found, -ENOENT if it wasn't.
*
* 2. With CHASE_OPEN: in this case the destination is opened after chasing it as O_PATH and this file
* 2. With ret_fd: in this case the destination is opened after chasing it as O_PATH and this file
* descriptor is returned as return value. This is useful to open files relative to some root
* directory. Note that the returned O_PATH file descriptors must be converted into a regular one (using
* fd_reopen() or such) before it can be used for reading/writing. CHASE_OPEN may not be combined with
* fd_reopen() or such) before it can be used for reading/writing. ret_fd may not be combined with
* CHASE_NONEXISTENT.
*
* 3. With CHASE_STEP: in this case only a single step of the normalization is executed, i.e. only the first
@ -774,21 +784,21 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
* 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization
* is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of
* the mount point is emitted.
*
*/
/* A root directory of "/" or "" is identical to none */
if (empty_or_root(original_root))
original_root = NULL;
if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) {
/* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set
if (!original_root && !ret_path && !(flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_STEP)) && ret_fd) {
/* Shortcut the ret_fd case if the caller isn't interested in the actual path and has no root set
* and doesn't care about any of the other special features we provide either. */
r = open(path, O_PATH|O_CLOEXEC|((flags & CHASE_NOFOLLOW) ? O_NOFOLLOW : 0));
if (r < 0)
return -errno;
return r;
*ret_fd = r;
return 0;
}
if (original_root) {
@ -797,7 +807,6 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return r;
if (flags & CHASE_PREFIX_ROOT) {
/* We don't support relative paths in combination with a root directory */
if (!path_is_absolute(path))
return -EINVAL;
@ -942,7 +951,6 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
if (S_ISLNK(st.st_mode) && !((flags & CHASE_NOFOLLOW) && isempty(todo))) {
char *joined;
_cleanup_free_ char *destination = NULL;
/* This is a symlink, in this case read the destination. But let's make sure we don't follow
@ -1028,15 +1036,15 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return -ENOMEM;
}
if (ret)
*ret = TAKE_PTR(done);
if (ret_path)
*ret_path = TAKE_PTR(done);
if (flags & CHASE_OPEN) {
/* Return the O_PATH fd we currently are looking to the caller. It can translate it to a proper fd by
* opening /proc/self/fd/xyz. */
if (ret_fd) {
/* Return the O_PATH fd we currently are looking to the caller. It can translate it to a
* proper fd by opening /proc/self/fd/xyz. */
assert(fd >= 0);
return TAKE_FD(fd);
*ret_fd = TAKE_FD(fd);
}
if (flags & CHASE_STEP)
@ -1045,14 +1053,14 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return exists;
chased_one:
if (ret) {
if (ret_path) {
char *c;
c = strjoin(strempty(done), todo);
if (!c)
return -ENOMEM;
*ret = c;
*ret_path = c;
}
return 0;
@ -1081,9 +1089,10 @@ int chase_symlinks_and_open(
return r;
}
path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
if (path_fd < 0)
return path_fd;
r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd);
if (r < 0)
return r;
assert(path_fd >= 0);
r = fd_reopen(path_fd, open_flags);
if (r < 0)
@ -1106,6 +1115,7 @@ int chase_symlinks_and_opendir(
_cleanup_close_ int path_fd = -1;
_cleanup_free_ char *p = NULL;
DIR *d;
int r;
if (!ret_dir)
return -EINVAL;
@ -1122,9 +1132,10 @@ int chase_symlinks_and_opendir(
return 0;
}
path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
if (path_fd < 0)
return path_fd;
r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd);
if (r < 0)
return r;
assert(path_fd >= 0);
xsprintf(procfs_path, "/proc/self/fd/%i", path_fd);
d = opendir(procfs_path);
@ -1143,10 +1154,12 @@ int chase_symlinks_and_stat(
const char *root,
unsigned chase_flags,
char **ret_path,
struct stat *ret_stat) {
struct stat *ret_stat,
int *ret_fd) {
_cleanup_close_ int path_fd = -1;
_cleanup_free_ char *p = NULL;
int r;
assert(path);
assert(ret_stat);
@ -1162,18 +1175,18 @@ int chase_symlinks_and_stat(
return 1;
}
path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
if (path_fd < 0)
return path_fd;
r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd);
if (r < 0)
return r;
assert(path_fd >= 0);
if (fstat(path_fd, ret_stat) < 0)
return -errno;
if (ret_path)
*ret_path = TAKE_PTR(p);
if (chase_flags & CHASE_OPEN)
return TAKE_FD(path_fd);
if (ret_fd)
*ret_fd = TAKE_FD(path_fd);
return 1;
}

View file

@ -72,29 +72,28 @@ union inotify_event_buffer {
};
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask);
enum {
CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */
CHASE_NONEXISTENT = 1 << 1, /* It's OK if the path doesn't actually exist. */
CHASE_NO_AUTOFS = 1 << 2, /* Return -EREMOTE if autofs mount point found */
CHASE_SAFE = 1 << 3, /* Return EPERM if we ever traverse from unprivileged to privileged files or directories */
CHASE_OPEN = 1 << 4, /* Return an O_PATH object to the final component */
CHASE_TRAIL_SLASH = 1 << 5, /* Any trailing slash will be preserved */
CHASE_STEP = 1 << 6, /* Just execute a single step of the normalization */
CHASE_NOFOLLOW = 1 << 7, /* Do not follow the path's right-most compontent. With CHASE_OPEN, when
* the path's right-most component refers to symlink, return O_PATH fd of
* the symlink. */
CHASE_WARN = 1 << 8, /* Emit an appropriate warning when an error is encountered */
CHASE_TRAIL_SLASH = 1 << 4, /* Any trailing slash will be preserved */
CHASE_STEP = 1 << 5, /* Just execute a single step of the normalization */
CHASE_NOFOLLOW = 1 << 6, /* Do not follow the path's right-most compontent. With ret_fd, when the path's
* right-most component refers to symlink, return O_PATH fd of the symlink. */
CHASE_WARN = 1 << 7, /* Emit an appropriate warning when an error is encountered */
};
/* How many iterations to execute before returning -ELOOP */
#define CHASE_SYMLINKS_MAX 32
int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret_path, int *ret_fd);
int chase_symlinks_and_open(const char *path, const char *root, unsigned chase_flags, int open_flags, char **ret_path);
int chase_symlinks_and_opendir(const char *path, const char *root, unsigned chase_flags, char **ret_path, DIR **ret_dir);
int chase_symlinks_and_stat(const char *path, const char *root, unsigned chase_flags, char **ret_path, struct stat *ret_stat);
int chase_symlinks_and_stat(const char *path, const char *root, unsigned chase_flags, char **ret_path, struct stat *ret_stat, int *ret_fd);
/* Useful for usage with _cleanup_(), removes a directory and frees the pointer */
static inline void rmdir_and_free(char *p) {

View file

@ -55,11 +55,7 @@ void path_hash_func(const char *q, struct siphash *state) {
}
}
int path_compare_func(const char *a, const char *b) {
return path_compare(a, b);
}
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare_func);
DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare);
#endif /* NM_IGNORED */
void trivial_hash_func(const void *p, struct siphash *state) {

View file

@ -79,7 +79,6 @@ extern const struct hash_ops string_hash_ops;
extern const struct hash_ops string_hash_ops_free_free;
void path_hash_func(const char *p, struct siphash *state);
int path_compare_func(const char *a, const char *b) _pure_;
extern const struct hash_ops path_hash_ops;
/* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings

View file

@ -5,7 +5,6 @@
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "alloc-util.h"
#include "fileio.h"
@ -13,7 +12,7 @@
#include "macro.h"
#include "memory-util.h"
#include "mempool.h"
#include "missing.h"
#include "missing_syscall.h"
#include "process-util.h"
#include "random-util.h"
#include "set.h"

View file

@ -5,7 +5,6 @@
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/utsname.h>
#include <unistd.h>

View file

@ -6,7 +6,6 @@
#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "io-util.h"

View file

@ -316,17 +316,18 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
extern void __coverity_panic__(void);
static inline int __coverity_check__(int condition) {
static inline void __coverity_check__(int condition) {
if (!condition)
__coverity_panic__();
}
static inline int __coverity_check_and_return__(int condition) {
return condition;
}
#define assert_message_se(expr, message) \
do { \
if (__coverity_check__(!(expr))) \
__coverity_panic__(); \
} while (false)
#define assert_message_se(expr, message) __coverity_check__(!!(expr))
#define assert_log(expr, message) __coverity_check__(!!(expr))
#define assert_log(expr, message) __coverity_check_and_return__(!!(expr))
#else /* ! __COVERITY__ */

View file

@ -11,6 +11,7 @@
size_t page_size(void) _pure_;
#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
#define PAGE_ALIGN_DOWN(l) (l & ~(page_size() - 1))
/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
static inline void memcpy_safe(void *dst, const void *src, size_t n) {

View file

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#if USE_SYS_RANDOM_H
# include <sys/random.h>
#else
# include <linux/random.h>
#endif
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK 0x0001
#endif
#ifndef GRND_RANDOM
#define GRND_RANDOM 0x0002
#endif

View file

@ -5,11 +5,9 @@
#include <errno.h>
#include <inttypes.h>
#include <linux/oom.h>
#include <locale.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include "alloc-util.h"
@ -17,7 +15,7 @@
#include "extract-word.h"
#include "locale-util.h"
#include "macro.h"
#include "missing.h"
#include "missing_network.h"
#include "parse-util.h"
#include "process-util.h"
#include "stat-util.h"

View file

@ -6,8 +6,6 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
/* When we include libgen.h because we need dirname() we immediately
@ -22,7 +20,6 @@
#include "glob-util.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
#include "nulstr-util.h"
#include "parse-util.h"
#include "path-util.h"
@ -276,7 +273,7 @@ char **path_strv_resolve(char **l, const char *root) {
} else
t = *s;
r = chase_symlinks(t, root, 0, &u);
r = chase_symlinks(t, root, 0, &u, NULL);
if (r == -ENOENT) {
if (root) {
u = TAKE_PTR(orig);
@ -658,7 +655,9 @@ int find_binary(const char *name, char **ret) {
return 0;
}
last_error = -errno;
/* PATH entries which we don't have access to are ignored, as per tradition. */
if (errno != EACCES)
last_error = -errno;
}
return last_error;

View file

@ -12,42 +12,38 @@
#if 0 /* NM_IGNORED */
#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
#define PATH_SPLIT_BIN_SBIN(x) x "bin:" x "sbin"
#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
#define PATH_NORMAL_SBIN_BIN(x) x "bin"
#define PATH_NORMAL_BIN_SBIN(x) x "bin"
#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
#if HAVE_SPLIT_BIN
# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
# define PATH_BIN_SBIN(x) PATH_SPLIT_BIN_SBIN(x)
# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
#else
# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
# define PATH_BIN_SBIN(x) PATH_NORMAL_BIN_SBIN(x)
# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
#endif
#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
#define DEFAULT_USER_PATH_NORMAL PATH_BIN_SBIN("/usr/local/") ":" PATH_BIN_SBIN("/usr/")
#define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/")
#define DEFAULT_USER_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_BIN_SBIN("/")
#define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/")
#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
#if HAVE_SPLIT_USR
# define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
# define DEFAULT_USER_PATH DEFAULT_USER_PATH_SPLIT_USR
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR
#else
# define DEFAULT_PATH DEFAULT_PATH_NORMAL
# define DEFAULT_USER_PATH DEFAULT_USER_PATH_NORMAL
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR
#endif
#endif /* NM_IGNORED */
#ifndef DEFAULT_USER_PATH
# define DEFAULT_USER_PATH DEFAULT_PATH
#endif
bool is_path(const char *p) _pure_;
int path_split_and_make_absolute(const char *p, char ***ret);
bool path_is_absolute(const char *p) _pure_;

View file

@ -6,11 +6,9 @@
#include <errno.h>
#include <limits.h>
#include <linux/oom.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/personality.h>
@ -37,7 +35,8 @@
#include "log.h"
#include "macro.h"
#include "memory-util.h"
#include "missing.h"
#include "missing_sched.h"
#include "missing_syscall.h"
#include "namespace-util.h"
#include "process-util.h"
#include "raw-clone.h"

View file

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <alloca.h>
#include <errno.h>
#include <sched.h>
#include <signal.h>

View file

@ -19,17 +19,12 @@
# include <sys/auxv.h>
#endif
#if USE_SYS_RANDOM_H
# include <sys/random.h>
#else
# include <linux/random.h>
#endif
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "io-util.h"
#include "missing.h"
#include "missing_random.h"
#include "missing_syscall.h"
#include "parse-util.h"
#include "random-util.h"
#include "siphash24.h"

View file

@ -102,8 +102,8 @@ static inline void *set_steal_first(Set *s) {
/* no set_steal_first_key */
/* no set_first_key */
static inline void *set_first(Set *s) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(s), false, NULL);
static inline void *set_first(const Set *s) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE((Set *) s), false, NULL);
}
/* no set_next */

View file

@ -13,7 +13,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "alloc-util.h"
@ -25,7 +25,7 @@
#include "log.h"
#include "macro.h"
#include "memory-util.h"
#include "missing.h"
#include "missing_socket.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"

View file

@ -2,12 +2,9 @@
#include "nm-sd-adapt-shared.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/magic.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <unistd.h>
@ -17,7 +14,8 @@
#include "fd-util.h"
#include "fs-util.h"
#include "macro.h"
#include "missing.h"
#include "missing_fs.h"
#include "missing_magic.h"
#include "parse-util.h"
#include "stat-util.h"
#include "string-util.h"
@ -340,7 +338,7 @@ int device_path_make_canonical(mode_t mode, dev_t devno, char **ret) {
if (r < 0)
return r;
return chase_symlinks(p, NULL, 0, ret);
return chase_symlinks(p, NULL, 0, ret, NULL);
}
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devno) {

View file

@ -5,7 +5,6 @@
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "macro.h"

View file

@ -7,7 +7,6 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc-util.h"
#include "escape.h"
@ -750,7 +749,7 @@ static void advance_offsets(
}
char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
const char *i, *begin = NULL;
const char *begin = NULL;
enum {
STATE_OTHER,
STATE_ESCAPE,
@ -758,7 +757,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
STATE_CSO,
} state = STATE_OTHER;
char *obuf = NULL;
size_t osz = 0, isz, shift[2] = {};
size_t osz = 0, isz, shift[2] = {}, n_carriage_returns = 0;
FILE *f;
assert(ibuf);
@ -769,6 +768,8 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
* 1. Replaces TABs by 8 spaces
* 2. Strips ANSI color sequences (a subset of CSI), i.e. ESC '[' 'm' sequences
* 3. Strips ANSI operating system sequences (CSO), i.e. ESC ']' BEL sequences
* 4. Strip trailing \r characters (since they would "move the cursor", but have no
* other effect).
*
* Everything else will be left as it is. In particular other ANSI sequences are left as they are, as
* are any other special characters. Truncated ANSI sequences are left-as is too. This call is
@ -784,14 +785,24 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
if (!f)
return NULL;
for (i = *ibuf; i < *ibuf + isz + 1; i++) {
for (const char *i = *ibuf; i < *ibuf + isz + 1; i++) {
switch (state) {
case STATE_OTHER:
if (i >= *ibuf + isz) /* EOT */
break;
else if (*i == '\x1B')
if (*i == '\r') {
n_carriage_returns++;
break;
} else if (*i == '\n')
/* Ignore carriage returns before new line */
n_carriage_returns = 0;
for (; n_carriage_returns > 0; n_carriage_returns--)
fputc('\r', f);
if (*i == '\x1B')
state = STATE_ESCAPE;
else if (*i == '\t') {
fputs(" ", f);
@ -802,6 +813,8 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
break;
case STATE_ESCAPE:
assert(n_carriage_returns == 0);
if (i >= *ibuf + isz) { /* EOT */
fputc('\x1B', f);
advance_offsets(i - *ibuf, highlight, shift, 1);
@ -822,6 +835,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
break;
case STATE_CSI:
assert(n_carriage_returns == 0);
if (i >= *ibuf + isz || /* EOT … */
!strchr("01234567890;m", *i)) { /* … or invalid chars in sequence */
@ -836,6 +850,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
break;
case STATE_CSO:
assert(n_carriage_returns == 0);
if (i >= *ibuf + isz || /* EOT … */
(*i != '\a' && (uint8_t) *i < 32U) || (uint8_t) *i > 126U) { /* … or invalid chars in sequence */
@ -855,7 +870,6 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
fclose(f);
return mfree(obuf);
}
fclose(f);
free_and_replace(*ibuf, obuf);

View file

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <alloca.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
@ -45,6 +44,22 @@ static inline const char *strna(const char *s) {
return s ?: "n/a";
}
static inline const char* yes_no(bool b) {
return b ? "yes" : "no";
}
static inline const char* true_false(bool b) {
return b ? "true" : "false";
}
static inline const char* one_zero(bool b) {
return b ? "1" : "0";
}
static inline const char* enable_disable(bool b) {
return b ? "enable" : "disable";
}
static inline bool isempty(const char *p) {
return !p || !p[0];
}

View file

@ -7,7 +7,6 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc-util.h"
#include "escape.h"

View file

@ -6,9 +6,7 @@
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/timerfd.h>
#include <sys/timex.h>
@ -839,8 +837,12 @@ int parse_timestamp(const char *t, usec_t *usec) {
}
if (r == 0) {
bool with_tz = true;
char *colon_tz;
if (setenv("TZ", tz, 1) != 0) {
/* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */
colon_tz = strjoina(":", tz);
if (setenv("TZ", colon_tz, 1) != 0) {
shared->return_value = negative_errno();
_exit(EXIT_FAILURE);
}
@ -1265,6 +1267,7 @@ int get_timezones(char ***ret) {
}
strv_sort(zones);
strv_uniq(zones);
} else if (errno != ENOENT)
return -errno;
@ -1285,6 +1288,10 @@ bool timezone_is_valid(const char *name, int log_level) {
if (isempty(name))
return false;
/* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */
if (streq(name, "UTC"))
return true;
if (name[0] == '/')
return false;
@ -1391,13 +1398,22 @@ bool clock_supported(clockid_t clock) {
}
#if 0 /* NM_IGNORED */
int get_timezone(char **tz) {
int get_timezone(char **ret) {
_cleanup_free_ char *t = NULL;
const char *e;
char *z;
int r;
r = readlink_malloc("/etc/localtime", &t);
if (r == -ENOENT) {
/* If the symlink does not exist, assume "UTC", like glibc does*/
z = strdup("UTC");
if (!z)
return -ENOMEM;
*ret = z;
return 0;
}
if (r < 0)
return r; /* returns EINVAL if not a symlink */
@ -1412,7 +1428,7 @@ int get_timezone(char **tz) {
if (!z)
return -ENOMEM;
*tz = z;
*ret = z;
return 0;
}

View file

@ -2,7 +2,6 @@
#include "nm-sd-adapt-shared.h"
#include <stdio.h>
#include <sys/mman.h>
#include "alloc-util.h"

View file

@ -28,7 +28,6 @@
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "alloc-util.h"
#include "gunicode.h"

View file

@ -2,50 +2,23 @@
#include "nm-sd-adapt-shared.h"
#include <alloca.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/statfs.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>
#include "alloc-util.h"
#include "btrfs-util.h"
#include "build.h"
#include "def.h"
#include "device-nodes.h"
#include "dirent-util.h"
#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "hashmap.h"
#include "hostname-util.h"
#include "log.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "procfs-util.h"
#include "set.h"
#include "signal-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
#include "umask-util.h"
#include "user-util.h"
#include "util.h"
#include "virt.h"

View file

@ -5,22 +5,6 @@
#include "macro.h"
static inline const char* yes_no(bool b) {
return b ? "yes" : "no";
}
static inline const char* true_false(bool b) {
return b ? "true" : "false";
}
static inline const char* one_zero(bool b) {
return b ? "1" : "0";
}
static inline const char* enable_disable(bool b) {
return b ? "enable" : "disable";
}
extern int saved_argc;
extern char **saved_argv;

View file

@ -14,7 +14,6 @@
#include <endian.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include "alloc-util.h"

View file

@ -15,11 +15,21 @@
#include "dhcp-protocol.h"
#include "socket-util.h"
typedef struct sd_dhcp_option {
unsigned n_ref;
uint8_t option;
void *data;
size_t length;
} sd_dhcp_option;
extern const struct hash_ops dhcp_option_hash_ops;
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid, const uint8_t *mac_addr,
size_t mac_addr_len, uint16_t arp_type,
uint16_t port);
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port);
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type);
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
@ -41,7 +51,7 @@ uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
uint16_t source, be32_t destination_addr,
uint16_t destination, uint16_t len);
uint16_t destination, uint16_t len, int ip_service_type);
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);

View file

@ -11,7 +11,6 @@
#include <net/if_arp.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/filter.h>
#include <linux/if_infiniband.h>
#include <linux/if_packet.h>
@ -148,7 +147,7 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
bcast_addr, &eth_mac, arp_type, dhcp_hlen, port);
}
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type) {
union sockaddr_union src = {
.in.sin_family = AF_INET,
.in.sin_port = htobe16(port),
@ -161,7 +160,11 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
if (s < 0)
return -errno;
r = setsockopt_int(s, IPPROTO_IP, IP_TOS, IPTOS_CLASS_CS6);
if (ip_service_type >= 0)
r = setsockopt_int(s, IPPROTO_IP, IP_TOS, ip_service_type);
else
r = setsockopt_int(s, IPPROTO_IP, IP_TOS, IPTOS_CLASS_CS6);
if (r < 0)
return r;

View file

@ -8,10 +8,10 @@
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "alloc-util.h"
#include "dhcp-internal.h"
#include "dhcp-server-internal.h"
#include "memory-util.h"
#include "strv.h"
#include "utf8.h"
@ -79,6 +79,32 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
*offset += 3 + optlen;
break;
case SD_DHCP_OPTION_VENDOR_SPECIFIC: {
OrderedHashmap *s = (OrderedHashmap *) optval;
struct sd_dhcp_option *p;
size_t l = 0;
Iterator i;
ORDERED_HASHMAP_FOREACH(p, s, i)
l += p->length + 2;
if (*offset + l + 2 > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = l;
*offset += 2;
ORDERED_HASHMAP_FOREACH(p, s, i) {
options[*offset] = p->option;
options[*offset + 1] = p->length;
memcpy(&options[*offset + 2], p->data, p->length);
*offset += 2 + p->length;
}
break;
}
default:
if (*offset + 2 + optlen > size)
return -ENOBUFS;
@ -291,3 +317,43 @@ int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t c
return message_type;
}
static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) {
if (!i)
return NULL;
free(i->data);
return mfree(i);
}
int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret) {
assert_return(ret, -EINVAL);
assert_return(length == 0 || data, -EINVAL);
_cleanup_free_ void *q = memdup(data, length);
if (!q)
return -ENOMEM;
sd_dhcp_option *p = new(sd_dhcp_option, 1);
if (!p)
return -ENOMEM;
*p = (sd_dhcp_option) {
.n_ref = 1,
.option = option,
.length = length,
.data = TAKE_PTR(q),
};
*ret = TAKE_PTR(p);
return 0;
}
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
dhcp_option_hash_ops,
void,
trivial_hash_func,
trivial_compare_func,
sd_dhcp_option,
sd_dhcp_option_unref);

View file

@ -77,12 +77,15 @@ uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len) {
void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
uint16_t source_port, be32_t destination_addr,
uint16_t destination_port, uint16_t len) {
uint16_t destination_port, uint16_t len, int ip_service_type) {
packet->ip.version = IPVERSION;
packet->ip.ihl = DHCP_IP_SIZE / 4;
packet->ip.tot_len = htobe16(len);
packet->ip.tos = IPTOS_CLASS_CS6;
if (ip_service_type >= 0)
packet->ip.tos = ip_service_type;
else
packet->ip.tos = IPTOS_CLASS_CS6;
packet->ip.protocol = IPPROTO_UDP;
packet->ip.saddr = source_addr;

View file

@ -85,7 +85,7 @@ typedef struct DHCP6IA DHCP6IA;
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
size_t optlen, const void *optval);
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd);
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix);
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
size_t *optlen, uint8_t **optvalue);

View file

@ -10,7 +10,6 @@
#include <netinet/ip6.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/if_packet.h>

View file

@ -7,7 +7,6 @@
#include <errno.h>
#include <netinet/in.h>
#include <string.h>
#include "sd-dhcp6-client.h"
@ -170,9 +169,10 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
return r;
}
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd) {
int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix) {
DHCP6Option *option = (DHCP6Option *)buf;
size_t i = sizeof(*option) + sizeof(pd->ia_pd);
DHCP6PDPrefixOption *prefix_opt;
DHCP6Address *prefix;
assert_return(buf, -EINVAL);
@ -185,10 +185,7 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd) {
option->code = htobe16(SD_DHCP6_OPTION_IA_PD);
memcpy(&option->data, &pd->ia_pd, sizeof(pd->ia_pd));
LIST_FOREACH(addresses, prefix, pd->addresses) {
DHCP6PDPrefixOption *prefix_opt;
if (len < i + sizeof(*prefix_opt))
return -ENOBUFS;
@ -196,9 +193,19 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd) {
prefix_opt->option.code = htobe16(SD_DHCP6_OPTION_IA_PD_PREFIX);
prefix_opt->option.len = htobe16(sizeof(prefix_opt->iapdprefix));
memcpy(&prefix_opt->iapdprefix, &prefix->iapdprefix,
sizeof(struct iapdprefix));
memcpy(&prefix_opt->iapdprefix, &prefix->iapdprefix, sizeof(struct iapdprefix));
i += sizeof(*prefix_opt);
}
if (hint_pd_prefix && hint_pd_prefix->iapdprefix.prefixlen > 0) {
if (len < i + sizeof(*prefix_opt))
return -ENOBUFS;
prefix_opt = (DHCP6PDPrefixOption *)&buf[i];
prefix_opt->option.code = htobe16(SD_DHCP6_OPTION_IA_PD_PREFIX);
prefix_opt->option.len = htobe16(sizeof(prefix_opt->iapdprefix));
memcpy(&prefix_opt->iapdprefix, &hint_pd_prefix->iapdprefix, sizeof(struct iapdprefix));
i += sizeof(*prefix_opt);
}

View file

@ -10,7 +10,7 @@
#include "lldp-internal.h"
#include "lldp-neighbor.h"
#include "memory-util.h"
#include "missing.h"
#include "missing_network.h"
#include "unaligned.h"
static void lldp_neighbor_id_hash_func(const LLDPNeighborID *id, struct siphash *state) {

View file

@ -7,7 +7,7 @@
#include "fd-util.h"
#include "lldp-network.h"
#include "missing.h"
#include "missing_network.h"
#include "socket-util.h"
int lldp_network_bind_raw_socket(int ifindex) {

View file

@ -22,6 +22,7 @@
#include "parse-util.h"
#include "siphash24.h"
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "utf8.h"
@ -139,15 +140,38 @@ static int net_condition_test_property(char * const *match_property, sd_device *
return true;
}
static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = {
[NL80211_IFTYPE_ADHOC] = "ad-hoc",
[NL80211_IFTYPE_STATION] = "station",
[NL80211_IFTYPE_AP] = "ap",
[NL80211_IFTYPE_AP_VLAN] = "ap-vlan",
[NL80211_IFTYPE_WDS] = "wds",
[NL80211_IFTYPE_MONITOR] = "monitor",
[NL80211_IFTYPE_MESH_POINT] = "mesh-point",
[NL80211_IFTYPE_P2P_CLIENT] = "p2p-client",
[NL80211_IFTYPE_P2P_GO] = "p2p-go",
[NL80211_IFTYPE_P2P_DEVICE] = "p2p-device",
[NL80211_IFTYPE_OCB] = "ocb",
[NL80211_IFTYPE_NAN] = "nan",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype);
bool net_match_config(Set *match_mac,
char * const *match_paths,
char * const *match_drivers,
char * const *match_types,
char * const *match_names,
char * const *match_property,
char * const *match_wifi_iftype,
char * const *match_ssid,
Set *match_bssid,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name) {
const char *dev_name,
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid) {
const char *dev_path = NULL, *dev_driver = NULL, *dev_type = NULL, *mac_str;
@ -181,6 +205,15 @@ bool net_match_config(Set *match_mac,
if (!net_condition_test_property(match_property, device))
return false;
if (!net_condition_test_strv(match_wifi_iftype, wifi_iftype_to_string(wifi_iftype)))
return false;
if (!net_condition_test_strv(match_ssid, ssid))
return false;
if (match_bssid && (!bssid || !set_contains(match_bssid, bssid)))
return false;
return true;
}

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <linux/nl80211.h>
#include <stdbool.h>
#include "sd-device.h"
@ -21,9 +22,15 @@ bool net_match_config(Set *match_mac,
char * const *match_type,
char * const *match_name,
char * const *match_property,
char * const *match_wifi_iftype,
char * const *match_ssid,
Set *match_bssid,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name);
const char *dev_name,
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid);
CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);

View file

@ -10,7 +10,6 @@
#include <net/if_arp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/if_infiniband.h>
@ -92,6 +91,7 @@ struct sd_dhcp_client {
usec_t start_time;
uint64_t attempt;
uint64_t max_attempts;
OrderedHashmap *options;
usec_t request_sent;
sd_event_source *timeout_t1;
sd_event_source *timeout_t2;
@ -100,6 +100,7 @@ struct sd_dhcp_client {
void *userdata;
sd_dhcp_lease *lease;
usec_t start_delay;
int ip_service_type;
};
static const uint8_t default_req_opts[] = {
@ -234,6 +235,7 @@ int sd_dhcp_client_set_mac(
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
int r;
assert_return(client, -EINVAL);
assert_return(addr, -EINVAL);
@ -261,8 +263,11 @@ int sd_dhcp_client_set_mac(
client->mac_addr_len = addr_len;
client->arp_type = arp_type;
if (need_restart && client->state != DHCP_STATE_STOPPED)
sd_dhcp_client_start(client);
if (need_restart && client->state != DHCP_STATE_STOPPED) {
r = sd_dhcp_client_start(client);
if (r < 0)
return log_dhcp_client_errno(client, r, "Failed to restart DHCPv4 client: %m");
}
return 0;
}
@ -298,6 +303,7 @@ int sd_dhcp_client_set_client_id(
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false;
int r;
assert_return(client, -EINVAL);
assert_return(data, -EINVAL);
@ -331,8 +337,11 @@ int sd_dhcp_client_set_client_id(
memcpy(&client->client_id.raw.data, data, data_len);
client->client_id_len = data_len + sizeof (client->client_id.type);
if (need_restart && client->state != DHCP_STATE_STOPPED)
sd_dhcp_client_start(client);
if (need_restart && client->state != DHCP_STATE_STOPPED) {
r = sd_dhcp_client_start(client);
if (r < 0)
return log_dhcp_client_errno(client, r, "Failed to restart DHCPv4 client: %m");
}
return 0;
}
@ -363,7 +372,7 @@ static int dhcp_client_set_iaid_duid_internal(
if (duid) {
r = dhcp_validate_duid_len(duid_type, duid_len, true);
if (r < 0)
return r;
return log_dhcp_client_errno(client, r, "Failed to validate length of DUID: %m");
}
zero(client->client_id);
@ -378,7 +387,7 @@ static int dhcp_client_set_iaid_duid_internal(
true,
&client->client_id.ns.iaid);
if (r < 0)
return r;
return log_dhcp_client_errno(client, r, "Failed to set IAID: %m");
}
}
@ -390,32 +399,32 @@ static int dhcp_client_set_iaid_duid_internal(
switch (duid_type) {
case DUID_TYPE_LLT:
if (client->mac_addr_len == 0)
return -EOPNOTSUPP;
return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to set DUID-LLT, MAC address is not set.");
r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
if (r < 0)
return r;
return log_dhcp_client_errno(client, r, "Failed to set DUID-LLT: %m");
break;
case DUID_TYPE_EN:
r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
if (r < 0)
return r;
return log_dhcp_client_errno(client, r, "Failed to set DUID-EN: %m");
break;
case DUID_TYPE_LL:
if (client->mac_addr_len == 0)
return -EOPNOTSUPP;
return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to set DUID-LL, MAC address is not set.");
r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
if (r < 0)
return r;
return log_dhcp_client_errno(client, r, "Failed to set DUID-LL: %m");
break;
case DUID_TYPE_UUID:
r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len);
if (r < 0)
return r;
return log_dhcp_client_errno(client, r, "Failed to set DUID-UUID: %m");
break;
default:
return -EINVAL;
return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Invalid DUID type");
}
client->client_id_len = sizeof(client->client_id.type) + len +
@ -424,7 +433,9 @@ static int dhcp_client_set_iaid_duid_internal(
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
log_dhcp_client(client, "Configured %sDUID, restarting.", iaid_append ? "IAID+" : "");
client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
sd_dhcp_client_start(client);
r = sd_dhcp_client_start(client);
if (r < 0)
return log_dhcp_client_errno(client, r, "Failed to restart DHCPv4 client: %m");
}
return 0;
@ -534,6 +545,24 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt
return 0;
}
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
int r;
assert_return(client, -EINVAL);
assert_return(v, -EINVAL);
r = ordered_hashmap_ensure_allocated(&client->options, &dhcp_option_hash_ops);
if (r < 0)
return r;
r = ordered_hashmap_put(client->options, UINT_TO_PTR(v->option), v);
if (r < 0)
return r;
sd_dhcp_option_ref(v);
return 0;
}
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
assert_return(client, -EINVAL);
@ -546,6 +575,14 @@ int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
return 0;
}
int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
assert_return(client, -EINVAL);
client->ip_service_type = type;
return 0;
}
static int client_notify(sd_dhcp_client *client, int event) {
assert(client);
@ -778,7 +815,7 @@ static int dhcp_client_send_raw(
size_t len) {
dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
INADDR_BROADCAST, DHCP_PORT_SERVER, len);
INADDR_BROADCAST, DHCP_PORT_SERVER, len, client->ip_service_type);
return dhcp_network_send_raw_socket(client->fd, &client->link,
packet, len);
@ -787,6 +824,8 @@ static int dhcp_client_send_raw(
static int client_send_discover(sd_dhcp_client *client) {
_cleanup_free_ DHCPPacket *discover = NULL;
size_t optoffset, optlen;
sd_dhcp_option *j;
Iterator i;
int r;
assert(client);
@ -803,7 +842,9 @@ static int client_send_discover(sd_dhcp_client *client) {
address be assigned, and may include the IP address lease time
option to suggest the lease time it would like.
*/
if (client->last_addr != INADDR_ANY) {
/* RFC7844 section 3:
SHOULD NOT contain any other option. */
if (!client->anonymize && client->last_addr != INADDR_ANY) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
4, &client->last_addr);
@ -848,6 +889,13 @@ static int client_send_discover(sd_dhcp_client *client) {
return r;
}
ORDERED_HASHMAP_FOREACH(j, client->options, i) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
j->option, j->length, j->data);
if (r < 0)
return r;
}
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
@ -866,41 +914,6 @@ static int client_send_discover(sd_dhcp_client *client) {
return 0;
}
static int client_send_release(sd_dhcp_client *client) {
_cleanup_free_ DHCPPacket *release = NULL;
size_t optoffset, optlen;
int r;
assert(client);
assert(!IN_SET(client->state, DHCP_STATE_STOPPED));
r = client_message_init(client, &release, DHCP_RELEASE,
&optlen, &optoffset);
if (r < 0)
return r;
/* Fill up release IP and MAC */
release->dhcp.ciaddr = client->lease->address;
memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
r = dhcp_network_send_udp_socket(client->fd,
client->lease->server_address,
DHCP_PORT_SERVER,
&release->dhcp,
sizeof(DHCPMessage) + optoffset);
if (r < 0)
return r;
log_dhcp_client(client, "RELEASE");
return 0;
}
static int client_send_request(sd_dhcp_client *client) {
_cleanup_free_ DHCPPacket *request = NULL;
size_t optoffset, optlen;
@ -1666,7 +1679,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
goto error;
}
r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
if (r < 0) {
log_dhcp_client(client, "could not bind UDP socket");
goto error;
@ -1925,8 +1938,35 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
int sd_dhcp_client_send_release(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
assert_return(client->state != DHCP_STATE_STOPPED, -ESTALE);
assert_return(client->lease, -EUNATCH);
client_send_release(client);
_cleanup_free_ DHCPPacket *release = NULL;
size_t optoffset, optlen;
int r;
r = client_message_init(client, &release, DHCP_RELEASE, &optlen, &optoffset);
if (r < 0)
return r;
/* Fill up release IP and MAC */
release->dhcp.ciaddr = client->lease->address;
memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
r = dhcp_network_send_udp_socket(client->fd,
client->lease->server_address,
DHCP_PORT_SERVER,
&release->dhcp,
sizeof(DHCPMessage) + optoffset);
if (r < 0)
return r;
log_dhcp_client(client, "RELEASE");
return 0;
}
@ -1976,7 +2016,8 @@ sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
}
static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
assert(client);
if (!client)
return NULL;
log_dhcp_client(client, "FREE");
@ -1995,17 +2036,16 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
free(client->hostname);
free(client->vendor_class_identifier);
client->user_class = strv_free(client->user_class);
ordered_hashmap_free(client->options);
return mfree(client);
}
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
_cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
assert_return(ret, -EINVAL);
client = new(sd_dhcp_client, 1);
_cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = new(sd_dhcp_client, 1);
if (!client)
return -ENOMEM;
@ -2018,6 +2058,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
.port = DHCP_PORT_CLIENT,
.anonymize = !!anonymize,
.max_attempts = (uint64_t) -1,
.ip_service_type = -1,
};
/* NOTE: this could be moved to a function. */
if (anonymize) {

View file

@ -7,9 +7,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

View file

@ -6,7 +6,6 @@
#include "nm-sd-adapt-core.h"
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/if_arp.h>
#include <linux/if_infiniband.h>
@ -48,6 +47,7 @@ struct sd_dhcp6_client {
sd_event *event;
int event_priority;
int ifindex;
DHCP6Address hint_pd_prefix;
struct in6_addr local_address;
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
size_t mac_addr_len;
@ -189,6 +189,22 @@ int sd_dhcp6_client_set_mac(
return 0;
}
int sd_dhcp6_client_set_prefix_delegation_hint(
sd_dhcp6_client *client,
uint8_t prefixlen,
const struct in6_addr *pd_address) {
assert_return(client, -EINVAL);
assert_return(pd_address, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
client->hint_pd_prefix.iapdprefix.address = *pd_address;
client->hint_pd_prefix.iapdprefix.prefixlen = prefixlen;
return 0;
}
static int client_ensure_duid(sd_dhcp6_client *client) {
if (client->duid_len != 0)
return 0;
@ -218,7 +234,7 @@ static int dhcp6_client_set_duid_internal(
if (r < 0) {
r = dhcp_validate_duid_len(duid_type, duid_len, false);
if (r < 0)
return r;
return log_dhcp6_client_errno(client, r, "Failed to validate length of DUID: %m");
log_dhcp6_client(client, "Setting DUID of type %u with unexpected content", duid_type);
}
@ -230,32 +246,32 @@ static int dhcp6_client_set_duid_internal(
switch (duid_type) {
case DUID_TYPE_LLT:
if (client->mac_addr_len == 0)
return -EOPNOTSUPP;
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to set DUID-LLT, MAC address is not set.");
r = dhcp_identifier_set_duid_llt(&client->duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
if (r < 0)
return r;
return log_dhcp6_client_errno(client, r, "Failed to set DUID-LLT: %m");
break;
case DUID_TYPE_EN:
r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
if (r < 0)
return r;
return log_dhcp6_client_errno(client, r, "Failed to set DUID-EN: %m");
break;
case DUID_TYPE_LL:
if (client->mac_addr_len == 0)
return -EOPNOTSUPP;
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to set DUID-LL, MAC address is not set.");
r = dhcp_identifier_set_duid_ll(&client->duid, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
if (r < 0)
return r;
return log_dhcp6_client_errno(client, r, "Failed to set DUID-LL: %m");
break;
case DUID_TYPE_UUID:
r = dhcp_identifier_set_duid_uuid(&client->duid, &client->duid_len);
if (r < 0)
return r;
return log_dhcp6_client_errno(client, r, "Failed to set DUID-UUID: %m");
break;
default:
return -EINVAL;
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Invalid DUID type");
}
#else /* NM_IGNORED */
g_return_val_if_reached (-EINVAL);
@ -498,7 +514,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd);
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
if (r < 0)
return r;
@ -536,7 +552,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd);
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
return r;
@ -562,7 +578,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd);
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
return r;
@ -1543,6 +1559,8 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
.request = DHCP6_REQUEST_IA_NA,
.fd = -1,
.req_opts_len = ELEMENTSOF(default_req_opts),
.hint_pd_prefix.iapdprefix.lifetime_preferred = (be32_t) -1,
.hint_pd_prefix.iapdprefix.lifetime_valid = (be32_t) -1,
.req_opts = TAKE_PTR(req_opts),
};

View file

@ -10,7 +10,6 @@
#include <netinet/if_ether.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sd-ipv4acd.h"

View file

@ -9,7 +9,6 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sd-id128.h"
#include "sd-ipv4acd.h"

View file

@ -18,7 +18,7 @@
#include "list.h"
#include "macro.h"
#include "memory-util.h"
#include "missing.h"
#include "missing_syscall.h"
#include "prioq.h"
#include "process-util.h"
#include "set.h"
@ -773,11 +773,13 @@ static void source_disconnect(sd_event_source *s) {
event = s->event;
s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
s->event = NULL;
LIST_REMOVE(sources, event->sources, s);
event->n_sources--;
/* Note that we don't invalidate the type here, since we still need it in order to close the fd or
* pidfd associated with this event source, which we'll do only on source_free(). */
if (!s->floating)
sd_event_unref(event);
}
@ -2556,7 +2558,7 @@ static int process_child(sd_event *e) {
* benefit in leaving it queued */
assert(s->child.options & (WSTOPPED|WCONTINUED));
waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|(s->child.options & (WSTOPPED|WCONTINUED)));
(void) waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|(s->child.options & (WSTOPPED|WCONTINUED)));
}
r = source_set_pending(s, true);

View file

@ -15,7 +15,7 @@
#include "io-util.h"
#include "khash.h"
#include "macro.h"
#include "missing.h"
#include "missing_syscall.h"
#include "random-util.h"
#include "user-util.h"
#include "util.h"

View file

@ -26,6 +26,7 @@
#include <stdbool.h>
#include "sd-dhcp-lease.h"
#include "sd-dhcp-option.h"
#include "sd-event.h"
#include "_sd-common.h"
@ -174,6 +175,11 @@ int sd_dhcp_client_set_user_class(
int sd_dhcp_client_get_lease(
sd_dhcp_client *client,
sd_dhcp_lease **ret);
int sd_dhcp_client_set_service_type(
sd_dhcp_client *client,
int type);
int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v);
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);

View file

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosddhcpoptionhfoo
#define foosddhcpoptionhfoo
/***
Copyright © 2013 Intel Corporation. All rights reserved.
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 <http://www.gnu.org/licenses/>.
***/
#include <inttypes.h>
#include <sys/types.h>
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
typedef struct sd_dhcp_option sd_dhcp_option;
int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret);
sd_dhcp_option *sd_dhcp_option_ref(sd_dhcp_option *ra);
sd_dhcp_option *sd_dhcp_option_unref(sd_dhcp_option *ra);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref);
_SD_END_DECLARATIONS;
#endif

View file

@ -120,6 +120,10 @@ int sd_dhcp6_client_get_information_request(
int sd_dhcp6_client_set_request_option(
sd_dhcp6_client *client,
uint16_t option);
int sd_dhcp6_client_set_prefix_delegation_hint(
sd_dhcp6_client *client,
uint8_t prefixlen,
const struct in6_addr *pd_address);
int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client,
int *delegation);
int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client,