mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
systemd: merge branch systemd into master
This commit is contained in:
commit
c016165e1b
12
Makefile.am
12
Makefile.am
|
@ -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 \
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/* dummy header */
|
||||
|
||||
#include "missing_fcntl.h"
|
||||
#include "missing_socket.h"
|
||||
#include "missing_stat.h"
|
||||
#include "missing_type.h"
|
|
@ -6,7 +6,6 @@
|
|||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "io-util.h"
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
16
shared/systemd/src/basic/missing_random.h
Normal file
16
shared/systemd/src/basic/missing_random.h
Normal 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
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <alloca.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "macro.h"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "escape.h"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "nm-sd-adapt-shared.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "gunicode.h"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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, ð_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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <netinet/if_ether.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sd-ipv4acd.h"
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sd-id128.h"
|
||||
#include "sd-ipv4acd.h"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
38
src/systemd/src/systemd/sd-dhcp-option.h
Normal file
38
src/systemd/src/systemd/sd-dhcp-option.h
Normal 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
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue