1
0
mirror of https://github.com/systemd/systemd synced 2025-12-26 10:54:45 +01:00

Compare commits

..

No commits in common. "f8bff7805ea1252c2421d07a92bf5b19f4f16aa7" and "dee00c1939c6194404c15a80650d0c04bb01b0db" have entirely different histories.

45 changed files with 1042 additions and 1264 deletions

View File

@ -200,24 +200,22 @@
</para>
<para>If the address string is a string in the format
<literal><replaceable>v.w.x.y</replaceable>:<replaceable>z</replaceable></literal>, it is interpeted
as IPv4 address <replaceable>v.w.x.y</replaceable> and port <replaceable>z</replaceable>.</para>
v.w.x.y:z, it is read as IPv4 specifier for listening on an
address v.w.x.y on a port z.</para>
<para>If the address string is a string in the format [x]:y,
it is read as IPv6 address x on a port y. Note that this might
make the service available via IPv4, too, depending on the
<varname>BindIPv6Only=</varname> setting (see below).
</para>
<para>If the address string is a string in the format
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable></literal>, it is interpreted as
IPv6 address <replaceable>x</replaceable> and port <replaceable>y</replaceable>. An optional
interface scope (interface name or number) may be specifed after a <literal>%</literal> symbol:
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable>%<replaceable>dev</replaceable></literal>.
Interface scopes are only useful with link-local addresses, because the kernel ignores them in other
cases. Note that if an address is specified as IPv6, it might still make the service available via
IPv4 too, depending on the <varname>BindIPv6Only=</varname> setting (see below).</para>
<para>If the address string is a string in the format
<literal>vsock:<replaceable>x</replaceable>:<replaceable>y</replaceable></literal>, it is read as CID
<replaceable>x</replaceable> on a port <replaceable>y</replaceable> address in the
<constant>AF_VSOCK</constant> family. The CID is a unique 32-bit integer identifier in
<constant>AF_VSOCK</constant> analogous to an IP address. Specifying the CID is optional, and may be
set to the empty string.</para>
<literal>vsock:x:y</literal>, it is read as CID <literal>x</literal> on
a port <literal>y</literal> address in the
<constant>AF_VSOCK</constant> family. The CID is a unique 32-bit
integer identifier in <constant>AF_VSOCK</constant> analogous to an IP
address. Specifying the CID is optional, and may be set to the empty
string.</para>
<para>Note that <constant>SOCK_SEQPACKET</constant> (i.e.
<varname>ListenSequentialPacket=</varname>) is only available

View File

@ -1654,10 +1654,7 @@ int btrfs_subvol_snapshot_fd_full(
} else if (r < 0)
return r;
r = copy_directory_fd_full(
old_fd, new_path,
COPY_MERGE|COPY_REFLINK|COPY_SAME_MOUNT|COPY_HARDLINKS|(FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGINT) ? COPY_SIGINT : 0),
progress_path, progress_bytes, userdata);
r = copy_directory_fd_full(old_fd, new_path, COPY_MERGE|COPY_REFLINK|COPY_SAME_MOUNT|(FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGINT) ? COPY_SIGINT : 0), progress_path, progress_bytes, userdata);
if (r < 0)
goto fallback_fail;

View File

@ -22,10 +22,8 @@
#include "missing_syscall.h"
#include "mountpoint-util.h"
#include "nulstr-util.h"
#include "rm-rf.h"
#include "selinux-util.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
@ -396,188 +394,6 @@ static int fd_copy_symlink(
return 0;
}
/* Encapsulates the database we store potential hardlink targets in */
typedef struct HardlinkContext {
int dir_fd; /* An fd to the directory we use as lookup table. Never AT_FDCWD. Lazily created, when
* we add the first entry. */
/* These two fields are used to create the hardlink repository directory above — via
* mkdirat(parent_fd, subdir) and are kept so that we can automatically remove the directory again
* when we are done. */
int parent_fd; /* Possibly AT_FDCWD */
char *subdir;
} HardlinkContext;
static int hardlink_context_setup(
HardlinkContext *c,
int dt,
const char *to,
CopyFlags copy_flags) {
_cleanup_close_ int dt_copy = -1;
int r;
assert(c);
assert(c->dir_fd < 0 && c->dir_fd != AT_FDCWD);
assert(c->parent_fd < 0);
assert(!c->subdir);
/* If hardlink recreation is requested we have to maintain a database of inodes that are potential
* hardlink sources. Given that generally disk sizes have to be assumed to be larger than what fits
* into physical RAM we cannot maintain that database in dynamic memory alone. Here we opt to
* maintain it on disk, to simplify things: inside the destination directory we'll maintain a
* temporary directory consisting of hardlinks of every inode we copied that might be subject of
* hardlinks. We can then use that as hardlink source later on. Yes, this means additional disk IO
* but thankfully Linux is optimized for this kind of thing. If this ever becomes a performance
* bottleneck we can certainly place an in-memory hash table in front of this, but for the beginning,
* let's keep things simple, and just use the disk as lookup table for inodes.
*
* Note that this should have zero performace impact as long as .n_link of all files copied remains
* <= 0, because in that case we will not actually allocate the hardlink inode lookup table directory
* on disk (we do so lazily, when the first candidate with .n_link > 1 is seen). This means, in the
* common case where hardlinks are not used at all or only for few files the fact that we store the
* table on disk shouldn't matter perfomance-wise. */
if (!FLAGS_SET(copy_flags, COPY_HARDLINKS))
return 0;
if (dt == AT_FDCWD)
dt_copy = AT_FDCWD;
else if (dt < 0)
return -EBADF;
else {
dt_copy = fcntl(dt, F_DUPFD_CLOEXEC, 3);
if (dt_copy < 0)
return -errno;
}
r = tempfn_random_child(to, "hardlink", &c->subdir);
if (r < 0)
return r;
c->parent_fd = TAKE_FD(dt_copy);
/* We don't actually create the directory we keep the table in here, that's done on-demand when the
* first entry is added, using hardlink_context_realize() below. */
return 1;
}
static int hardlink_context_realize(HardlinkContext *c) {
int r;
if (!c)
return 0;
if (c->dir_fd >= 0) /* Already realized */
return 1;
if (c->parent_fd < 0 && c->parent_fd != AT_FDCWD) /* Not configured */
return 0;
assert(c->subdir);
if (mkdirat(c->parent_fd, c->subdir, 0700) < 0)
return -errno;
c->dir_fd = openat(c->parent_fd, c->subdir, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (c->dir_fd < 0) {
r = -errno;
unlinkat(c->parent_fd, c->subdir, AT_REMOVEDIR);
return r;
}
return 1;
}
static void hardlink_context_destroy(HardlinkContext *c) {
int r;
assert(c);
/* Automatically remove the hardlink lookup table directory again after we are done. This is used via
* _cleanup_() so that we really delete this, even on failure. */
if (c->dir_fd >= 0) {
r = rm_rf_children(TAKE_FD(c->dir_fd), REMOVE_PHYSICAL, NULL); /* consumes dir_fd in all cases, even on failure */
if (r < 0)
log_debug_errno(r, "Failed to remove hardlink store (%s) contents, ignoring: %m", c->subdir);
assert(c->parent_fd >= 0 || c->parent_fd == AT_FDCWD);
assert(c->subdir);
if (unlinkat(c->parent_fd, c->subdir, AT_REMOVEDIR) < 0)
log_debug_errno(errno, "Failed to remove hardlink store (%s) directory, ignoring: %m", c->subdir);
}
assert_cc(AT_FDCWD < 0);
c->parent_fd = safe_close(c->parent_fd);
c->subdir = mfree(c->subdir);
}
static int try_hardlink(
HardlinkContext *c,
const struct stat *st,
int dt,
const char *to) {
char dev_ino[DECIMAL_STR_MAX(dev_t)*2 + DECIMAL_STR_MAX(uint64_t) + 4];
assert(st);
assert(dt >= 0 || dt == AT_FDCWD);
assert(to);
if (!c) /* No temporary hardlink directory, don't bother */
return 0;
if (st->st_nlink <= 1) /* Source not hardlinked, don't bother */
return 0;
if (c->dir_fd < 0) /* not yet realized, hence empty */
return 0;
xsprintf(dev_ino, "%u:%u:%" PRIu64, major(st->st_dev), minor(st->st_dev), (uint64_t) st->st_ino);
if (linkat(c->dir_fd, dev_ino, dt, to, 0) < 0) {
if (errno != ENOENT) /* doesn't exist in store yet */
log_debug_errno(errno, "Failed to hardlink %s to %s, ignoring: %m", dev_ino, to);
return 0;
}
return 1;
}
static int memorize_hardlink(
HardlinkContext *c,
const struct stat *st,
int dt,
const char *to) {
char dev_ino[DECIMAL_STR_MAX(dev_t)*2 + DECIMAL_STR_MAX(uint64_t) + 4];
int r;
assert(st);
assert(dt >= 0 || dt == AT_FDCWD);
assert(to);
if (!c) /* No temporary hardlink directory, don't bother */
return 0;
if (st->st_nlink <= 1) /* Source not hardlinked, don't bother */
return 0;
r = hardlink_context_realize(c); /* Create the hardlink store lazily */
if (r < 0)
return r;
xsprintf(dev_ino, "%u:%u:%" PRIu64, major(st->st_dev), minor(st->st_dev), (uint64_t) st->st_ino);
if (linkat(dt, to, c->dir_fd, dev_ino, 0) < 0) {
log_debug_errno(errno, "Failed to hardlink %s to %s, ignoring: %m", to, dev_ino);
return 0;
}
return 1;
}
static int fd_copy_regular(
int df,
const char *from,
@ -587,7 +403,6 @@ static int fd_copy_regular(
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
HardlinkContext *hardlink_context,
copy_progress_bytes_t progress,
void *userdata) {
@ -599,12 +414,6 @@ static int fd_copy_regular(
assert(st);
assert(to);
r = try_hardlink(hardlink_context, st, dt, to);
if (r < 0)
return r;
if (r > 0) /* worked! */
return 0;
fdf = openat(df, from, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
if (fdf < 0)
return -errno;
@ -647,7 +456,6 @@ static int fd_copy_regular(
(void) unlinkat(dt, to, 0);
}
(void) memorize_hardlink(hardlink_context, st, dt, to);
return r;
}
@ -659,20 +467,13 @@ static int fd_copy_fifo(
const char *to,
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
HardlinkContext *hardlink_context) {
CopyFlags copy_flags) {
int r;
assert(from);
assert(st);
assert(to);
r = try_hardlink(hardlink_context, st, dt, to);
if (r < 0)
return r;
if (r > 0) /* worked! */
return 0;
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dt, to, S_IFIFO);
if (r < 0)
@ -693,7 +494,6 @@ static int fd_copy_fifo(
if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
r = -errno;
(void) memorize_hardlink(hardlink_context, st, dt, to);
return r;
}
@ -705,20 +505,13 @@ static int fd_copy_node(
const char *to,
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
HardlinkContext *hardlink_context) {
CopyFlags copy_flags) {
int r;
assert(from);
assert(st);
assert(to);
r = try_hardlink(hardlink_context, st, dt, to);
if (r < 0)
return r;
if (r > 0) /* worked! */
return 0;
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dt, to, st->st_mode & S_IFMT);
if (r < 0)
@ -739,7 +532,6 @@ static int fd_copy_node(
if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
r = -errno;
(void) memorize_hardlink(hardlink_context, st, dt, to);
return r;
}
@ -754,17 +546,11 @@ static int fd_copy_directory(
uid_t override_uid,
gid_t override_gid,
CopyFlags copy_flags,
HardlinkContext *hardlink_context,
const char *display_path,
copy_progress_path_t progress_path,
copy_progress_bytes_t progress_bytes,
void *userdata) {
_cleanup_(hardlink_context_destroy) HardlinkContext our_hardlink_context = {
.dir_fd = -1,
.parent_fd = -1,
};
_cleanup_close_ int fdf = -1, fdt = -1;
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
@ -784,16 +570,6 @@ static int fd_copy_directory(
if (fdf < 0)
return -errno;
if (!hardlink_context) {
/* If recreating hardlinks is requested let's set up a context for that now. */
r = hardlink_context_setup(&our_hardlink_context, dt, to, copy_flags);
if (r < 0)
return r;
if (r > 0) /* It's enabled and allocated, let's now use the same context for all recursive
* invocations from here down */
hardlink_context = &our_hardlink_context;
}
d = take_fdopendir(&fdf);
if (!d)
return -errno;
@ -892,15 +668,15 @@ static int fd_copy_directory(
continue;
}
q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, depth_left-1, override_uid, override_gid, copy_flags, hardlink_context, child_display_path, progress_path, progress_bytes, userdata);
q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, depth_left-1, override_uid, override_gid, copy_flags, child_display_path, progress_path, progress_bytes, userdata);
} else if (S_ISREG(buf.st_mode))
q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, hardlink_context, progress_bytes, userdata);
q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, progress_bytes, userdata);
else if (S_ISLNK(buf.st_mode))
q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISFIFO(buf.st_mode))
q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, hardlink_context);
q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) || S_ISSOCK(buf.st_mode))
q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, hardlink_context);
q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else
q = -EOPNOTSUPP;
@ -954,15 +730,15 @@ int copy_tree_at_full(
return -errno;
if (S_ISREG(st.st_mode))
return fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL, progress_bytes, userdata);
return fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, progress_bytes, userdata);
else if (S_ISDIR(st.st_mode))
return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, progress_path, progress_bytes, userdata);
else if (S_ISLNK(st.st_mode))
return fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else if (S_ISFIFO(st.st_mode))
return fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
return fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode))
return fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
return fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
else
return -EOPNOTSUPP;
}
@ -986,7 +762,7 @@ int copy_directory_fd_full(
if (!S_ISDIR(st.st_mode))
return -ENOTDIR;
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, progress_path, progress_bytes, userdata);
}
int copy_directory_full(
@ -1008,7 +784,7 @@ int copy_directory_full(
if (!S_ISDIR(st.st_mode))
return -ENOTDIR;
return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, progress_path, progress_bytes, userdata);
}
int copy_file_fd_full(

View File

@ -17,7 +17,6 @@ typedef enum CopyFlags {
COPY_CRTIME = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
COPY_SIGINT = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
COPY_MAC_CREATE = 1 << 7, /* Create files with the correct MAC label (currently SELinux only) */
COPY_HARDLINKS = 1 << 8, /* Try to reproduce hard links */
} CopyFlags;
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);

View File

@ -68,7 +68,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
if (a->sockaddr.in.sin_port == 0)
return -EINVAL;
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM))
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
return -EINVAL;
return 0;
@ -80,7 +80,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
if (a->sockaddr.in6.sin6_port == 0)
return -EINVAL;
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM))
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
return -EINVAL;
return 0;
@ -114,7 +114,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
}
}
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
return -EINVAL;
return 0;
@ -124,7 +124,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
if (a->size != sizeof(struct sockaddr_nl))
return -EINVAL;
if (!IN_SET(a->type, 0, SOCK_RAW, SOCK_DGRAM))
if (!IN_SET(a->type, SOCK_RAW, SOCK_DGRAM))
return -EINVAL;
return 0;
@ -133,7 +133,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
if (a->size != sizeof(struct sockaddr_vm))
return -EINVAL;
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM))
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
return -EINVAL;
return 0;
@ -399,23 +399,19 @@ int sockaddr_pretty(
if (r < 0)
return -ENOMEM;
} else {
char a[INET6_ADDRSTRLEN], ifname[IF_NAMESIZE + 1];
char a[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
if (sa->in6.sin6_scope_id != 0)
format_ifname_full(sa->in6.sin6_scope_id, ifname, FORMAT_IFNAME_IFINDEX);
if (include_port) {
r = asprintf(&p,
"[%s]:%u%s%s",
"[%s]:%u",
a,
be16toh(sa->in6.sin6_port),
sa->in6.sin6_scope_id != 0 ? "%" : "",
sa->in6.sin6_scope_id != 0 ? ifname : "");
be16toh(sa->in6.sin6_port));
if (r < 0)
return -ENOMEM;
} else {
p = sa->in6.sin6_scope_id != 0 ? strjoin(a, "%", ifname) : strdup(a);
p = strdup(a);
if (!p)
return -ENOMEM;
}
@ -690,19 +686,17 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
bool ifname_valid_full(const char *p, bool alternative) {
bool numeric = true;
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
* but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
* also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
assert(!(flags & ~_IFNAME_VALID_ALL));
if (isempty(p))
return false;
if (flags & IFNAME_VALID_ALTERNATIVE) {
if (alternative) {
if (strlen(p) >= ALTIFNAMSIZ)
return false;
} else {
@ -713,28 +707,23 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
if (dot_or_dot_dot(p))
return false;
for (const char *t = p; *t; t++) {
if ((unsigned char) *t >= 127U)
while (*p) {
if ((unsigned char) *p >= 127U)
return false;
if ((unsigned char) *t <= 32U)
if ((unsigned char) *p <= 32U)
return false;
if (IN_SET(*t, ':', '/'))
if (IN_SET(*p, ':', '/'))
return false;
numeric = numeric && (*t >= '0' && *t <= '9');
numeric = numeric && (*p >= '0' && *p <= '9');
p++;
}
if (numeric) {
if (!(flags & IFNAME_VALID_NUMERIC))
if (numeric)
return false;
/* Verify that the number is well-formatted and in range. */
if (parse_ifindex(p) < 0)
return false;
}
return true;
}
@ -1118,10 +1107,12 @@ int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) {
* reference paths in the abstract namespace that include NUL bytes in the name. */
l = strlen(path);
if (l < 2)
if (l == 0)
return -EINVAL;
if (!IN_SET(path[0], '/', '@'))
return -EINVAL;
if (path[1] == 0)
return -EINVAL;
/* Don't allow paths larger than the space in sockaddr_un. Note that we are a tiny bit more restrictive than
* the kernel is: we insist on NUL termination (both for abstract namespace and regular file system socket

View File

@ -130,14 +130,9 @@ static inline int fd_inc_rcvbuf(int fd, size_t n) {
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
typedef enum {
IFNAME_VALID_ALTERNATIVE = 1 << 0,
IFNAME_VALID_NUMERIC = 1 << 1,
_IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC,
} IfnameValidFlags;
bool ifname_valid_full(const char *p, IfnameValidFlags flags);
bool ifname_valid_full(const char *p, bool alternative);
static inline bool ifname_valid(const char *p) {
return ifname_valid_full(p, 0);
return ifname_valid_full(p, false);
}
bool address_label_valid(const char *p);

File diff suppressed because it is too large Load Diff

View File

@ -627,7 +627,7 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
}
/* Try to copy as directory? */
r = copy_directory_fd(source_fd, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT|COPY_HARDLINKS);
r = copy_directory_fd(source_fd, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT);
if (r >= 0)
return 0;
if (r != -ENOTDIR)
@ -699,9 +699,9 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
if (errno != ENOENT)
return log_error_errno(errno, "Failed to open destination '%s': %m", arg_target);
r = copy_tree_at(source_fd, ".", dfd, basename(arg_target), UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
r = copy_tree_at(source_fd, ".", dfd, basename(arg_target), UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_SIGINT);
} else
r = copy_tree_at(source_fd, ".", target_fd, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
r = copy_tree_at(source_fd, ".", target_fd, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_SIGINT);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s' to '%s' in image '%s': %m", arg_source, arg_target, arg_image);

View File

@ -45,7 +45,7 @@ int config_parse_default_file_system_type(
assert(s);
if (!isempty(rvalue) && !supported_fstype(rvalue)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Unsupported file system, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Unsupported file system, ignoring: %s", rvalue);
return 0;
}

View File

@ -2551,7 +2551,7 @@ int config_parse_line_max(
r = parse_size(rvalue, 1024, &v);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse LineMax= value, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse LineMax= value, ignoring: %s", rvalue);
return 0;
}
@ -2606,7 +2606,7 @@ int config_parse_compress(
if (r < 0) {
r = parse_size(rvalue, 1024, &compress->threshold_bytes);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r,
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse Compress= value, ignoring: %s", rvalue);
else
compress->enabled = true;

View File

@ -466,14 +466,12 @@ int config_parse_n_autovts(
r = safe_atou(rvalue, &o);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse number of autovts, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse number of autovts, ignoring: %s", rvalue);
return 0;
}
if (o > 15) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"A maximum of 15 autovts are supported, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "A maximum of 15 autovts are supported, ignoring: %s", rvalue);
return 0;
}

View File

@ -919,7 +919,7 @@ int config_parse_tmpfs_size(
if (r >= 0 && (k <= 0 || (uint64_t) (size_t) k != k))
r = -ERANGE;
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse size value '%s', ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value '%s', ignoring: %m", rvalue);
return 0;
}

View File

@ -1066,7 +1066,7 @@ finish:
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *src, *dest, *host_path, *container_path, *host_basename, *container_basename, *container_dirname;
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS;
CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE;
_cleanup_close_ int hostfd = -1;
Machine *m = userdata;
bool copy_from;

View File

@ -847,16 +847,13 @@ int config_parse_macsec_key_id(
return log_oom();
r = unhexmem(rvalue, strlen(rvalue), &p, &l);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse KeyId=%s, ignoring assignment: %m", rvalue);
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse KeyId \"%s\": %m", rvalue);
return 0;
}
if (l > MACSEC_KEYID_LEN) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Specified KeyId= is larger then the allowed maximum (%zu > %u), ignoring: %s",
"Specified KeyId is larger then the allowed maximum (%zu > %u), ignoring: %s",
l, MACSEC_KEYID_LEN, rvalue);
return 0;
}

View File

@ -220,8 +220,8 @@ WireGuard.PrivateKey, config_parse_wireguard_private_key,
WireGuard.PrivateKeyFile, config_parse_wireguard_private_key_file, 0, 0
WireGuardPeer.AllowedIPs, config_parse_wireguard_allowed_ips, 0, 0
WireGuardPeer.Endpoint, config_parse_wireguard_endpoint, 0, 0
WireGuardPeer.PublicKey, config_parse_wireguard_peer_key, 0, 0
WireGuardPeer.PresharedKey, config_parse_wireguard_peer_key, 0, 0
WireGuardPeer.PublicKey, config_parse_wireguard_public_key, 0, 0
WireGuardPeer.PresharedKey, config_parse_wireguard_preshared_key, 0, 0
WireGuardPeer.PresharedKeyFile, config_parse_wireguard_preshared_key_file, 0, 0
WireGuardPeer.PersistentKeepalive, config_parse_wireguard_keepalive, 0, 0
Xfrm.InterfaceId, config_parse_uint32, 0, offsetof(Xfrm, if_id)

View File

@ -492,8 +492,6 @@ static int wireguard_decode_key_and_warn(
(void) warn_file_is_world_accessible(filename, NULL, unit, line);
r = unbase64mem_full(rvalue, strlen(rvalue), true, &key, &len);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to decode wireguard key provided by %s=, ignoring assignment: %m", lvalue);
@ -528,7 +526,8 @@ int config_parse_wireguard_private_key(
w = WIREGUARD(data);
assert(w);
return wireguard_decode_key_and_warn(rvalue, w->private_key, unit, filename, line, lvalue);
(void) wireguard_decode_key_and_warn(rvalue, w->private_key, unit, filename, line, lvalue);
return 0;
}
int config_parse_wireguard_private_key_file(
@ -565,7 +564,7 @@ int config_parse_wireguard_private_key_file(
return free_and_replace(w->private_key_file, path);
}
int config_parse_wireguard_peer_key(
int config_parse_wireguard_preshared_key(
const char *unit,
const char *filename,
unsigned line,
@ -577,7 +576,7 @@ int config_parse_wireguard_peer_key(
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
WireguardPeer *peer;
Wireguard *w;
int r;
@ -589,13 +588,7 @@ int config_parse_wireguard_peer_key(
if (r < 0)
return log_oom();
r = wireguard_decode_key_and_warn(rvalue,
streq(lvalue, "PublicKey") ? peer->public_key : peer->preshared_key,
unit, filename, line, lvalue);
if (r < 0)
return r;
TAKE_PTR(peer);
(void) wireguard_decode_key_and_warn(rvalue, peer->preshared_key, unit, filename, line, lvalue);
return 0;
}
@ -642,6 +635,38 @@ int config_parse_wireguard_preshared_key_file(
return 0;
}
int config_parse_wireguard_public_key(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
Wireguard *w;
int r;
assert(data);
w = WIREGUARD(data);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0)
return log_oom();
r = wireguard_decode_key_and_warn(rvalue, peer->public_key, unit, filename, line, lvalue);
if (r < 0)
return 0;
TAKE_PTR(peer);
return 0;
}
int config_parse_wireguard_allowed_ips(
const char *unit,
const char *filename,
@ -796,7 +821,7 @@ int config_parse_wireguard_keepalive(
void *data,
void *userdata) {
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
WireguardPeer *peer;
uint16_t keepalive = 0;
Wireguard *w;
int r;
@ -824,8 +849,6 @@ int config_parse_wireguard_keepalive(
}
peer->persistent_keepalive_interval = keepalive;
TAKE_PTR(peer);
return 0;
}

View File

@ -61,8 +61,10 @@ extern const NetDevVTable wireguard_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_allowed_ips);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_endpoint);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_listen_port);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_peer_key);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_public_key);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key_file);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_preshared_key);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_preshared_key_file);
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_keepalive);

View File

@ -691,7 +691,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
switch (type) {
case RTM_NEWNEIGH:
if (neighbor)
log_link_debug(link, "Received remembered neighbor: %s->%s",
log_link_debug(link, "Remembering neighbor: %s->%s",
strnull(addr_str), strnull(lladdr_str));
else {
/* A neighbor appeared that we did not request */
@ -1082,6 +1082,9 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
assert_not_reached("Received rule message with unsupported address family");
}
if (tmp->from_prefixlen == 0 && tmp->to_prefixlen == 0)
return 0;
r = sd_rtnl_message_routing_policy_rule_get_flags(message, &flags);
if (r < 0) {
log_warning_errno(r, "rtnl: received rule message without valid flag, ignoring: %m");
@ -1178,12 +1181,9 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
switch (type) {
case RTM_NEWRULE:
if (rule)
log_debug("Received remembered routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32,
tmp->priority, strna(from), tmp->from_prefixlen, strna(to), tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
else {
log_debug("Remembering foreign routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32,
tmp->priority, strna(from), tmp->from_prefixlen, strna(to), tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
if (!rule) {
log_debug("Remembering foreign routing policy rule: %s/%u -> %s/%u, iif: %s, oif: %s, table: %u",
from, tmp->from_prefixlen, to, tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
r = routing_policy_rule_add_foreign(m, tmp, &rule);
if (r < 0) {
log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
@ -1192,13 +1192,10 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
}
break;
case RTM_DELRULE:
if (rule) {
log_debug("Forgetting routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32,
tmp->priority, strna(from), tmp->from_prefixlen, strna(to), tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
log_debug("Forgetting routing policy rule: %s/%u -> %s/%u, iif: %s, oif: %s, table: %u",
from, tmp->from_prefixlen, to, tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
routing_policy_rule_free(rule);
} else
log_debug("Kernel removed a routing policy rule we don't remember: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32", ignoring.",
tmp->priority, strna(from), tmp->from_prefixlen, strna(to), tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
break;
default:
@ -1301,24 +1298,19 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
switch (type) {
case RTM_NEWNEXTHOP:
if (nexthop)
log_link_debug(link, "Received remembered nexthop: %s, oif: %d, id: %d", strna(gateway), tmp->oif, tmp->id);
else {
log_link_debug(link, "Remembering foreign nexthop: %s, oif: %d, id: %d", strna(gateway), tmp->oif, tmp->id);
if (!nexthop) {
log_debug("Remembering foreign nexthop: %s, oif: %d, id: %d", gateway, tmp->oif, tmp->id);
r = nexthop_add_foreign(link, tmp, &nexthop);
if (r < 0) {
log_link_warning_errno(link, r, "Could not remember foreign nexthop, ignoring: %m");
log_warning_errno(r, "Could not remember foreign nexthop, ignoring: %m");
return 0;
}
}
break;
case RTM_DELNEXTHOP:
if (nexthop) {
log_link_debug(link, "Forgetting nexthop: %s, oif: %d, id: %d", strna(gateway), tmp->oif, tmp->id);
log_debug("Forgetting foreign nexthop: %s, oif: %d, id: %d", gateway, tmp->oif, tmp->id);
nexthop_free(nexthop);
} else
log_link_debug(link, "Kernel removed a nexthop we don't remember: %s, oif: %d, id: %d, ignoring.",
strna(gateway), tmp->oif, tmp->id);
break;
default:

View File

@ -39,7 +39,7 @@ Match.Type, config_parse_match_strv,
Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match_wlan_iftype)
Match.SSID, config_parse_match_strv, 0, offsetof(Network, match_ssid)
Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match_bssid)
Match.Name, config_parse_match_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(Network, match_name)
Match.Name, config_parse_match_ifnames, 1, offsetof(Network, match_name)
Match.Property, config_parse_match_property, 0, offsetof(Network, match_property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions)

View File

@ -333,48 +333,37 @@ static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_messa
return 1;
}
int routing_policy_rule_remove(RoutingPolicyRule *rule, Link *link, link_netlink_message_handler_t callback) {
int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, link_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
assert(rule);
assert(routing_policy_rule);
assert(link);
assert(link->manager);
assert(link->manager->rtnl);
assert(link->ifindex > 0);
assert(IN_SET(rule->family, AF_INET, AF_INET6));
assert(IN_SET(routing_policy_rule->family, AF_INET, AF_INET6));
if (DEBUG_LOGGING) {
_cleanup_free_ char *from = NULL, *to = NULL;
(void) in_addr_to_string(rule->family, &rule->from, &from);
(void) in_addr_to_string(rule->family, &rule->to, &to);
log_link_debug(link,
"Removing routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32,
rule->priority, strna(from), rule->from_prefixlen, strna(to), rule->to_prefixlen, strna(rule->iif), strna(rule->oif), rule->table);
}
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_DELRULE, rule->family);
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_DELRULE, routing_policy_rule->family);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate RTM_DELRULE message: %m");
if (in_addr_is_null(rule->family, &rule->from) == 0) {
r = netlink_message_append_in_addr_union(m, FRA_SRC, rule->family, &rule->from);
if (in_addr_is_null(routing_policy_rule->family, &routing_policy_rule->from) == 0) {
r = netlink_message_append_in_addr_union(m, FRA_SRC, routing_policy_rule->family, &routing_policy_rule->from);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_SRC attribute: %m");
r = sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(m, rule->from_prefixlen);
r = sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(m, routing_policy_rule->from_prefixlen);
if (r < 0)
return log_link_error_errno(link, r, "Could not set source prefix length: %m");
}
if (in_addr_is_null(rule->family, &rule->to) == 0) {
r = netlink_message_append_in_addr_union(m, FRA_DST, rule->family, &rule->to);
if (in_addr_is_null(routing_policy_rule->family, &routing_policy_rule->to) == 0) {
r = netlink_message_append_in_addr_union(m, FRA_DST, routing_policy_rule->family, &routing_policy_rule->to);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_DST attribute: %m");
r = sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(m, rule->to_prefixlen);
r = sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(m, routing_policy_rule->to_prefixlen);
if (r < 0)
return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
}
@ -484,8 +473,8 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
(void) in_addr_to_string(rule->family, &rule->to, &to);
log_link_debug(link,
"Configuring routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32,
rule->priority, strna(from), rule->from_prefixlen, strna(to), rule->to_prefixlen, strna(rule->iif), strna(rule->oif), rule->table);
"Configuring routing policy rule: %s/%u -> %s/%u, iif: %s, oif: %s, table: %u",
from, rule->from_prefixlen, to, rule->to_prefixlen, strna(rule->iif), strna(rule->oif), rule->table);
}
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULE, rule->family);
@ -540,16 +529,18 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
r = sd_netlink_message_append_u32(m, FRA_FWMARK, rule->fwmark);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_FWMARK attribute: %m");
}
if (rule->fwmask > 0) {
r = sd_netlink_message_append_u32(m, FRA_FWMASK, rule->fwmask);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_FWMASK attribute: %m");
}
if (rule->iif) {
r = sd_netlink_message_append_string(m, FRA_IIFNAME, rule->iif);
r = sd_netlink_message_append_string(m, FRA_IFNAME, rule->iif);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_IIFNAME attribute: %m");
return log_link_error_errno(link, r, "Could not append FRA_IFNAME attribute: %m");
}
if (rule->oif) {
@ -653,39 +644,31 @@ int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
return 0;
}
static int parse_fwmark_fwmask(const char *s, uint32_t *ret_fwmark, uint32_t *ret_fwmask) {
_cleanup_free_ char *fwmark_str = NULL;
uint32_t fwmark, fwmask = 0;
const char *slash;
static int parse_fwmark_fwmask(const char *s, uint32_t *fwmark, uint32_t *fwmask) {
_cleanup_free_ char *f = NULL;
char *p;
int r;
assert(s);
assert(ret_fwmark);
assert(ret_fwmask);
slash = strchr(s, '/');
if (slash) {
fwmark_str = strndup(s, slash - s);
if (!fwmark_str)
f = strdup(s);
if (!f)
return -ENOMEM;
}
r = safe_atou32(fwmark_str ?: s, &fwmark);
p = strchr(f, '/');
if (p)
*p++ = '\0';
r = safe_atou32(f, fwmark);
if (r < 0)
return r;
return log_error_errno(r, "Failed to parse RPDB rule firewall mark, ignoring: %s", f);
if (fwmark > 0) {
if (slash) {
r = safe_atou32(slash + 1, &fwmask);
if (p) {
r = safe_atou32(p, fwmask);
if (r < 0)
return r;
} else
fwmask = UINT32_MAX;
return log_error_errno(r, "Failed to parse RPDB rule mask, ignoring: %s", f);
}
*ret_fwmark = fwmark;
*ret_fwmask = fwmask;
return 0;
}
@ -1240,11 +1223,9 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
}
if (rule->fwmark != 0) {
fprintf(f, "%sfwmark=%"PRIu32,
fprintf(f, "%sfwmark=%"PRIu32"/%"PRIu32,
space ? " " : "",
rule->fwmark);
if (rule->fwmask != UINT32_MAX)
fprintf(f, "/%"PRIu32, rule->fwmask);
rule->fwmark, rule->fwmask);
space = true;
}

View File

@ -62,8 +62,8 @@ void routing_policy_rule_free(RoutingPolicyRule *rule);
DEFINE_NETWORK_SECTION_FUNCTIONS(RoutingPolicyRule, routing_policy_rule_free);
int routing_policy_rule_section_verify(RoutingPolicyRule *rule);
int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netlink_message_handler_t callback);
int routing_policy_rule_remove(RoutingPolicyRule *rule, Link *link, link_netlink_message_handler_t callback);
int routing_policy_rule_configure(RoutingPolicyRule *address, Link *link, link_netlink_message_handler_t callback);
int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, link_netlink_message_handler_t callback);
int routing_policy_rule_add_foreign(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret);
int routing_policy_rule_get(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret);

View File

@ -67,7 +67,7 @@ int main(int argc, char **argv) {
test_rule_serialization("ignored values",
"RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32"
" \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20",
"RULE=family=AF_INET from=1.2.3.4/32 to=2.3.4.5/32 tos=5 fwmark=1 invert_rule=no table=20");
"RULE=family=AF_INET from=1.2.3.4/32 to=2.3.4.5/32 tos=5 fwmark=1/0 invert_rule=no table=20");
test_rule_serialization("ipv6",
"RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=yes table=6", NULL);

View File

@ -233,10 +233,14 @@ int config_parse_expose_port(
assert(rvalue);
r = expose_port_parse(&s->expose_ports, rvalue);
if (r == -EEXIST)
log_syntax(unit, LOG_WARNING, filename, line, r, "Duplicate port specification, ignoring: %s", rvalue);
else if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse host port %s: %m", rvalue);
if (r == -EEXIST) {
log_syntax(unit, LOG_ERR, filename, line, r, "Duplicate port specification, ignoring: %s", rvalue);
return 0;
}
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse host port %s: %m", rvalue);
return 0;
}
return 0;
}
@ -264,10 +268,8 @@ int config_parse_capability(
_cleanup_free_ char *word = NULL;
r = extract_first_word(&rvalue, &word, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to extract capability string, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract capability string, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
@ -278,7 +280,7 @@ int config_parse_capability(
else {
r = capability_from_name(word);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse capability, ignoring: %s", word);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse capability, ignoring: %s", word);
continue;
}
@ -313,8 +315,10 @@ int config_parse_pivot_root(
assert(rvalue);
r = pivot_root_parse(&settings->pivot_root_new, &settings->pivot_root_old, rvalue);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid pivot root mount specification %s: %m", rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid pivot root mount specification %s: %m", rvalue);
return 0;
}
return 0;
}
@ -339,8 +343,10 @@ int config_parse_bind(
assert(rvalue);
r = bind_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid bind mount specification %s: %m", rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid bind mount specification %s: %m", rvalue);
return 0;
}
return 0;
}
@ -365,8 +371,10 @@ int config_parse_tmpfs(
assert(rvalue);
r = tmpfs_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid temporary file system specification %s: %m", rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid temporary file system specification %s: %m", rvalue);
return 0;
}
return 0;
}
@ -391,8 +399,10 @@ int config_parse_inaccessible(
assert(rvalue);
r = inaccessible_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid inaccessible file system specification %s: %m", rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid inaccessible file system specification %s: %m", rvalue);
return 0;
}
return 0;
}
@ -418,7 +428,7 @@ int config_parse_overlay(
r = overlay_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid overlay file system specification %s, ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid overlay file system specification %s, ignoring: %m", rvalue);
return 0;
}
@ -443,8 +453,10 @@ int config_parse_veth_extra(
assert(rvalue);
r = veth_extra_parse(&settings->network_veth_extra, rvalue);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid extra virtual Ethernet link specification %s: %m", rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid extra virtual Ethernet link specification %s: %m", rvalue);
return 0;
}
return 0;
}
@ -470,11 +482,13 @@ int config_parse_network_zone(
j = strjoin("vz-", rvalue);
if (!ifname_valid(j)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid network zone name, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid network zone name, ignoring: %s", rvalue);
return 0;
}
return free_and_replace(settings->network_zone, j);
free_and_replace(settings->network_zone, j);
return 0;
}
int config_parse_boot(
@ -498,11 +512,11 @@ int config_parse_boot(
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse Boot= parameter %s, ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Boot= parameter %s, ignoring: %m", rvalue);
return 0;
}
if (r) {
if (r > 0) {
if (settings->start_mode == START_PID2)
goto conflict;
@ -518,7 +532,7 @@ int config_parse_boot(
return 0;
conflict:
log_syntax(unit, LOG_WARNING, filename, line, 0, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
return 0;
}
@ -543,11 +557,11 @@ int config_parse_pid2(
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse ProcessTwo= parameter %s, ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse ProcessTwo= parameter %s, ignoring: %m", rvalue);
return 0;
}
if (r) {
if (r > 0) {
if (settings->start_mode == START_BOOT)
goto conflict;
@ -563,7 +577,7 @@ int config_parse_pid2(
return 0;
conflict:
log_syntax(unit, LOG_WARNING, filename, line, 0, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
return 0;
}
@ -615,7 +629,7 @@ int config_parse_private_users(
r = safe_atou32(range, &rn);
if (r < 0 || rn <= 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "UID/GID range invalid, ignoring: %s", range);
log_syntax(unit, LOG_ERR, filename, line, r, "UID/GID range invalid, ignoring: %s", range);
return 0;
}
} else {
@ -625,7 +639,7 @@ int config_parse_private_users(
r = parse_uid(shift, &sh);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "UID/GID shift invalid, ignoring: %s", range);
log_syntax(unit, LOG_ERR, filename, line, r, "UID/GID shift invalid, ignoring: %s", range);
return 0;
}
@ -666,12 +680,11 @@ int config_parse_syscall_filter(
r = extract_first_word(&items, &word, NULL, 0);
if (r == 0)
return 0;
break;
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse SystemCallFilter= parameter %s, ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse SystemCallFilter= parameter %s, ignoring: %m", rvalue);
return 0;
}
@ -682,6 +695,8 @@ int config_parse_syscall_filter(
if (r < 0)
return log_oom();
}
return 0;
}
int config_parse_hostname(
@ -702,7 +717,7 @@ int config_parse_hostname(
assert(s);
if (!hostname_is_valid(rvalue, false)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue);
return 0;
}
@ -737,11 +752,11 @@ int config_parse_oom_score_adjust(
r = parse_oom_score_adjust(rvalue, &oa);
if (r == -ERANGE) {
log_syntax(unit, LOG_WARNING, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue);
return 0;
}
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
return 0;
}
@ -848,8 +863,10 @@ int config_parse_link_journal(
assert(settings);
r = parse_link_journal(rvalue, &settings->link_journal, &settings->link_journal_try);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse link journal mode, ignoring: %s", rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse link journal mode, ignoring: %s", rvalue);
return 0;
}
return 0;
}

View File

@ -947,7 +947,7 @@ static int config_parse_label(
r = specifier_printf(rvalue, specifier_table, NULL, &resolved);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
return 0;
}
@ -2609,17 +2609,9 @@ static int do_copy_files(Partition *p, const char *fs) {
if (pfd < 0)
return log_error_errno(pfd, "Failed to open parent directory of target: %m");
r = copy_tree_at(
sfd, ".",
pfd, basename(*target),
UID_INVALID, GID_INVALID,
COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
r = copy_tree_at(sfd, ".", pfd, basename(*target), UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT);
} else
r = copy_tree_at(
sfd, ".",
tfd, ".",
UID_INVALID, GID_INVALID,
COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS);
r = copy_tree_at(sfd, ".", tfd, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE|COPY_REPLACE|COPY_SIGINT);
if (r < 0)
return log_error_errno(r, "Failed to copy %s%s to %s: %m", strempty(arg_root), *source, *target);
} else {

View File

@ -1754,6 +1754,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
_cleanup_(dnssd_service_freep) DnssdService *service = NULL;
_cleanup_(sd_bus_track_unrefp) sd_bus_track *bus_track = NULL;
_cleanup_free_ char *path = NULL;
_cleanup_free_ char *instance_name = NULL;
Manager *m = userdata;
DnssdService *s = NULL;
const char *name;
@ -1794,10 +1795,6 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
if (!dnssd_srv_type_is_valid(type))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service type '%s' is invalid", type);
r = dnssd_render_instance_name(name_template, NULL);
if (r < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service name '%s' is invalid", name_template);
service->name = strdup(name);
if (!service->name)
return log_oom();
@ -1810,6 +1807,10 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
if (!service->type)
return log_oom();
r = dnssd_render_instance_name(service, &instance_name);
if (r < 0)
return r;
r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "a{say}");
if (r < 0)
return r;

View File

@ -35,6 +35,9 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons
if (r < 0)
return r;
if (IN_SET(port, 53, 853))
port = 0;
/* Silently filter out 0.0.0.0 and 127.0.0.53 (our own stub DNS listener) */
if (!dns_server_address_valid(family, &address))
return 0;
@ -47,8 +50,12 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons
/* Filter out duplicates */
s = dns_server_find(manager_get_first_dns_server(m, type), family, &address, port, ifindex, server_name);
if (s) {
/* Drop the marker. This is used to find the servers that ceased to exist, see
* manager_mark_dns_servers() and manager_flush_marked_dns_servers(). */
/*
* Drop the marker. This is used to find the servers
* that ceased to exist, see
* manager_mark_dns_servers() and
* manager_flush_marked_dns_servers().
*/
dns_server_move_back_and_unmark(s);
return 0;
}
@ -161,8 +168,7 @@ int config_parse_dns_servers(
/* Otherwise, add to the list */
r = manager_parse_dns_server_string_and_warn(m, ltype, rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse DNS server string '%s', ignoring.", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
return 0;
}
}
@ -204,8 +210,7 @@ int config_parse_search_domains(
/* Otherwise, add to the list */
r = manager_parse_search_domains_and_warn(m, rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse search domains string '%s', ignoring.", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse search domains string '%s'. Ignoring.", rvalue);
return 0;
}
}
@ -217,19 +222,21 @@ int config_parse_search_domains(
return 0;
}
int config_parse_dnssd_service_name(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
static const Specifier specifier_table[] = {
{ 'm', specifier_machine_id, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{}
};
DnssdService *s = userdata;
_cleanup_free_ char *name = NULL;
int r;
assert(filename);
@ -238,38 +245,27 @@ int config_parse_dnssd_service_name(
assert(s);
if (isempty(rvalue)) {
s->name_template = mfree(s->name_template);
return 0;
}
r = dnssd_render_instance_name(rvalue, NULL);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid service instance name template '%s', ignoring: %m", rvalue);
return 0;
log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name can't be empty. Ignoring.");
return -EINVAL;
}
r = free_and_strdup(&s->name_template, rvalue);
if (r < 0)
return log_oom();
r = specifier_printf(s->name_template, specifier_table, NULL, &name);
if (r < 0)
return log_debug_errno(r, "Failed to replace specifiers: %m");
if (!dns_service_name_is_valid(name)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name template renders to invalid name '%s'. Ignoring.", name);
return -EINVAL;
}
return 0;
}
int config_parse_dnssd_service_type(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int config_parse_dnssd_service_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
DnssdService *s = userdata;
int r;
@ -279,13 +275,13 @@ int config_parse_dnssd_service_type(
assert(s);
if (isempty(rvalue)) {
s->type = mfree(s->type);
return 0;
log_syntax(unit, LOG_ERR, filename, line, 0, "Service type can't be empty. Ignoring.");
return -EINVAL;
}
if (!dnssd_srv_type_is_valid(rvalue)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Service type is invalid. Ignoring.");
return 0;
log_syntax(unit, LOG_ERR, filename, line, 0, "Service type is invalid. Ignoring.");
return -EINVAL;
}
r = free_and_strdup(&s->type, rvalue);
@ -295,18 +291,7 @@ int config_parse_dnssd_service_type(
return 0;
}
int config_parse_dnssd_txt(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
_cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
DnssdService *s = userdata;
DnsTxtItem *last = NULL;
@ -327,7 +312,9 @@ int config_parse_dnssd_txt(
return log_oom();
for (;;) {
_cleanup_free_ char *word = NULL, *key = NULL, *value = NULL;
_cleanup_free_ char *word = NULL;
_cleanup_free_ char *key = NULL;
_cleanup_free_ char *value = NULL;
_cleanup_free_ void *decoded = NULL;
size_t length = 0;
DnsTxtItem *i;
@ -339,10 +326,8 @@ int config_parse_dnssd_txt(
break;
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
return 0;
}
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
r = split_pair(word, "=", &key, &value);
if (r == -ENOMEM)
@ -351,8 +336,8 @@ int config_parse_dnssd_txt(
key = TAKE_PTR(word);
if (!ascii_is_valid(key)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid key, ignoring: %s", key);
continue;
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", key);
return -EINVAL;
}
switch (ltype) {
@ -362,11 +347,9 @@ int config_parse_dnssd_txt(
r = unbase64mem(value, strlen(value), &decoded, &length);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid base64 encoding, ignoring: %s", value);
continue;
}
}
r = dnssd_txt_item_new_from_data(key, decoded, length, &i);
@ -390,7 +373,7 @@ int config_parse_dnssd_txt(
if (!LIST_IS_EMPTY(txt_data->txt)) {
LIST_PREPEND(items, s->txt_data_items, txt_data);
TAKE_PTR(txt_data);
txt_data = NULL;
}
return 0;
@ -440,7 +423,7 @@ int config_parse_dns_stub_listener_extra(
}
}
r = in_addr_port_ifindex_name_from_string_auto(p, &stub->family, &stub->address, &stub->port, NULL, NULL);
r = in_addr_port_from_string_auto(p, &stub->family, &stub->address, &stub->port);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse address in %s=%s, ignoring assignment: %m",

View File

@ -15,7 +15,7 @@
* IP and UDP header sizes */
#define ADVERTISE_DATAGRAM_SIZE_MAX (65536U-14U-20U-8U)
static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int type);
static int manager_dns_stub_udp_fd_extra(Manager *m, DnsStubListenerExtra *l);
static void dns_stub_listener_extra_hash_func(const DnsStubListenerExtra *a, struct siphash *state) {
assert(a);
@ -217,7 +217,7 @@ static int dns_stub_send(
* is because otherwise the kernel will choose it automatically based on the routing table and will
* thus pick 127.0.0.1 rather than 127.0.0.53. */
r = manager_send(m,
manager_dns_stub_fd_extra(m, l, SOCK_DGRAM),
manager_dns_stub_udp_fd_extra(m, l),
l ? p->ifindex : LOOPBACK_IFINDEX, /* force loopback iface if this is the main listener stub */
p->family, &p->sender, p->sender_port, &p->destination,
reply);
@ -477,6 +477,151 @@ static int on_dns_stub_packet_extra(sd_event_source *s, int fd, uint32_t revents
return on_dns_stub_packet_internal(s, fd, revents, l->manager, l);
}
static int set_dns_stub_common_socket_options(int fd, int family) {
int r;
assert(fd >= 0);
assert(IN_SET(family, AF_INET, AF_INET6));
r = setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, true);
if (r < 0)
return r;
if (family == AF_INET) {
r = setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, true);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, true);
if (r < 0)
return r;
} else {
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, true);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, true);
if (r < 0)
return r;
}
return 0;
}
static int manager_dns_stub_udp_fd(Manager *m) {
union sockaddr_union sa = {
.in.sin_family = AF_INET,
.in.sin_port = htobe16(53),
.in.sin_addr.s_addr = htobe32(INADDR_DNS_STUB),
};
_cleanup_close_ int fd = -1;
int r;
if (m->dns_stub_udp_event_source)
return sd_event_source_get_io_fd(m->dns_stub_udp_event_source);
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0)
return -errno;
r = set_dns_stub_common_socket_options(fd, AF_INET);
if (r < 0)
return r;
/* Make sure no traffic from outside the local host can leak to onto this socket */
r = socket_bind_to_ifindex(fd, LOOPBACK_IFINDEX);
if (r < 0)
return r;
if (bind(fd, &sa.sa, sizeof(sa.in)) < 0)
return -errno;
r = sd_event_add_io(m->event, &m->dns_stub_udp_event_source, fd, EPOLLIN, on_dns_stub_packet, m);
if (r < 0)
return r;
r = sd_event_source_set_io_fd_own(m->dns_stub_udp_event_source, true);
if (r < 0)
return r;
(void) sd_event_source_set_description(m->dns_stub_udp_event_source, "dns-stub-udp");
return TAKE_FD(fd);
}
static int manager_dns_stub_udp_fd_extra(Manager *m, DnsStubListenerExtra *l) {
_cleanup_free_ char *pretty = NULL;
_cleanup_close_ int fd = -1;
union sockaddr_union sa;
int r;
assert(m);
if (!l)
return manager_dns_stub_udp_fd(m);
if (l->udp_event_source)
return 0;
if (l->family == AF_INET)
sa = (union sockaddr_union) {
.in.sin_family = l->family,
.in.sin_port = htobe16(l->port != 0 ? l->port : 53U),
.in.sin_addr = l->address.in,
};
else
sa = (union sockaddr_union) {
.in6.sin6_family = l->family,
.in6.sin6_port = htobe16(l->port != 0 ? l->port : 53U),
.in6.sin6_addr = l->address.in6,
};
fd = socket(l->family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0) {
r = -errno;
goto fail;
}
if (l->family == AF_INET) {
r = setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, true);
if (r < 0)
goto fail;
}
r = set_dns_stub_common_socket_options(fd, l->family);
if (r < 0)
goto fail;
if (bind(fd, &sa.sa, SOCKADDR_LEN(sa)) < 0) {
r = -errno;
goto fail;
}
r = sd_event_add_io(m->event, &l->udp_event_source, fd, EPOLLIN, on_dns_stub_packet_extra, l);
if (r < 0)
goto fail;
r = sd_event_source_set_io_fd_own(l->udp_event_source, true);
if (r < 0)
goto fail;
(void) sd_event_source_set_description(l->udp_event_source, "dns-stub-udp-extra");
if (DEBUG_LOGGING) {
(void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty);
log_debug("Listening on UDP socket %s.", strnull(pretty));
}
return TAKE_FD(fd);
fail:
assert(r < 0);
(void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty);
if (r == -EADDRINUSE)
return log_warning_errno(r, "Another process is already listening on UDP socket %s: %m", strnull(pretty));
return log_warning_errno(r, "Failed to listen on UDP socket %s: %m", strnull(pretty));
}
static int on_dns_stub_stream_packet(DnsStream *s) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
@ -533,38 +678,7 @@ static int on_dns_stub_stream_extra(sd_event_source *s, int fd, uint32_t revents
return on_dns_stub_stream_internal(s, fd, revents, l->manager, l);
}
static int set_dns_stub_common_socket_options(int fd, int family) {
int r;
assert(fd >= 0);
assert(IN_SET(family, AF_INET, AF_INET6));
r = setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, true);
if (r < 0)
return r;
if (family == AF_INET) {
r = setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, true);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, true);
if (r < 0)
return r;
} else {
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, true);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, true);
if (r < 0)
return r;
}
return 0;
}
static int manager_dns_stub_fd(Manager *m, int type) {
static int manager_dns_stub_tcp_fd(Manager *m) {
union sockaddr_union sa = {
.in.sin_family = AF_INET,
.in.sin_addr.s_addr = htobe32(INADDR_DNS_STUB),
@ -573,13 +687,10 @@ static int manager_dns_stub_fd(Manager *m, int type) {
_cleanup_close_ int fd = -1;
int r;
assert(IN_SET(type, SOCK_DGRAM, SOCK_STREAM));
if (m->dns_stub_tcp_event_source)
return sd_event_source_get_io_fd(m->dns_stub_tcp_event_source);
sd_event_source **event_source = type == SOCK_DGRAM ? &m->dns_stub_udp_event_source : &m->dns_stub_tcp_event_source;
if (*event_source)
return sd_event_source_get_io_fd(*event_source);
fd = socket(AF_INET, type | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0)
return -errno;
@ -587,53 +698,42 @@ static int manager_dns_stub_fd(Manager *m, int type) {
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IP, IP_TTL, 1);
if (r < 0)
return r;
/* Make sure no traffic from outside the local host can leak to onto this socket */
r = socket_bind_to_ifindex(fd, LOOPBACK_IFINDEX);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IP, IP_TTL, 1);
if (r < 0)
return r;
if (bind(fd, &sa.sa, sizeof(sa.in)) < 0)
return -errno;
if (type == SOCK_STREAM &&
listen(fd, SOMAXCONN) < 0)
if (listen(fd, SOMAXCONN) < 0)
return -errno;
r = sd_event_add_io(m->event, event_source, fd, EPOLLIN,
type == SOCK_DGRAM ? on_dns_stub_packet : on_dns_stub_stream,
m);
r = sd_event_add_io(m->event, &m->dns_stub_tcp_event_source, fd, EPOLLIN, on_dns_stub_stream, m);
if (r < 0)
return r;
r = sd_event_source_set_io_fd_own(*event_source, true);
r = sd_event_source_set_io_fd_own(m->dns_stub_tcp_event_source, true);
if (r < 0)
return r;
(void) sd_event_source_set_description(*event_source,
type == SOCK_DGRAM ? "dns-stub-udp" : "dns-stub-tcp");
(void) sd_event_source_set_description(m->dns_stub_tcp_event_source, "dns-stub-tcp");
return TAKE_FD(fd);
}
static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int type) {
static int manager_dns_stub_tcp_fd_extra(Manager *m, DnsStubListenerExtra *l) {
_cleanup_free_ char *pretty = NULL;
_cleanup_close_ int fd = -1;
union sockaddr_union sa;
int r;
assert(m);
assert(IN_SET(type, SOCK_DGRAM, SOCK_STREAM));
if (!l)
return manager_dns_stub_fd(m, type);
sd_event_source **event_source = type == SOCK_DGRAM ? &l->udp_event_source : &l->tcp_event_source;
if (*event_source)
return sd_event_source_get_io_fd(*event_source);
if (l->tcp_event_source)
return sd_event_source_get_io_fd(l->tcp_event_source);;
if (l->family == AF_INET)
sa = (union sockaddr_union) {
@ -648,7 +748,7 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
.in6.sin6_addr = l->address.in6,
};
fd = socket(l->family, type | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
fd = socket(l->family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0) {
r = -errno;
goto fail;
@ -658,8 +758,8 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
if (r < 0)
goto fail;
/* Do not set IP_TTL for extra DNS stub listners, as the address may not be local and in that case
* people may want ttl > 1. */
/* Do not set IP_TTL for extra DNS stub listners, as the address may not be local and in that
* case people may want ttl > 1. */
if (l->family == AF_INET)
r = setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, true);
@ -673,30 +773,24 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
goto fail;
}
if (type == SOCK_STREAM &&
listen(fd, SOMAXCONN) < 0) {
if (listen(fd, SOMAXCONN) < 0) {
r = -errno;
goto fail;
}
r = sd_event_add_io(m->event, event_source, fd, EPOLLIN,
type == SOCK_DGRAM ? on_dns_stub_packet_extra : on_dns_stub_stream_extra,
l);
r = sd_event_add_io(m->event, &l->tcp_event_source, fd, EPOLLIN, on_dns_stub_stream_extra, l);
if (r < 0)
goto fail;
r = sd_event_source_set_io_fd_own(*event_source, true);
r = sd_event_source_set_io_fd_own(l->tcp_event_source, true);
if (r < 0)
goto fail;
(void) sd_event_source_set_description(*event_source,
type == SOCK_DGRAM ? "dns-stub-udp-extra" : "dns-stub-tcp-extra");
(void) sd_event_source_set_description(l->tcp_event_source, "dns-stub-tcp-extra");
if (DEBUG_LOGGING) {
(void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty);
log_debug("Listening on %s socket %s.",
type == SOCK_DGRAM ? "UDP" : "TCP",
strnull(pretty));
log_debug("Listening on TCP socket %s.", strnull(pretty));
}
return TAKE_FD(fd);
@ -704,11 +798,9 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
fail:
assert(r < 0);
(void) in_addr_port_to_string(l->family, &l->address, l->port, &pretty);
return log_warning_errno(r,
r == -EADDRINUSE ? "Another process is already listening on %s socket %s: %m" :
"Failed to listen on %s socket %s: %m",
type == SOCK_DGRAM ? "UDP" : "TCP",
strnull(pretty));
if (r == -EADDRINUSE)
return log_warning_errno(r, "Another process is already listening on TCP socket %s: %m", strnull(pretty));
return log_warning_errno(r, "Failed to listen on TCP socket %s: %m", strnull(pretty));
}
int manager_dns_stub_start(Manager *m) {
@ -726,21 +818,23 @@ int manager_dns_stub_start(Manager *m) {
"UDP/TCP");
if (FLAGS_SET(m->dns_stub_listener_mode, DNS_STUB_LISTENER_UDP))
r = manager_dns_stub_fd(m, SOCK_DGRAM);
r = manager_dns_stub_udp_fd(m);
if (r >= 0 &&
FLAGS_SET(m->dns_stub_listener_mode, DNS_STUB_LISTENER_TCP)) {
t = "TCP";
r = manager_dns_stub_fd(m, SOCK_STREAM);
r = manager_dns_stub_tcp_fd(m);
}
if (IN_SET(r, -EADDRINUSE, -EPERM)) {
if (r == -EADDRINUSE)
log_warning_errno(r,
"Another process is already listening on %s socket 127.0.0.53:53.\n"
"Turning off local DNS stub support.", t);
else
log_warning_errno(r,
r == -EADDRINUSE ? "Another process is already listening on %s socket 127.0.0.53:53.\n"
"Turning off local DNS stub support." :
"Failed to listen on %s socket 127.0.0.53:53: %m.\n"
"Turning off local DNS stub support.",
t);
"Turning off local DNS stub support.", t);
manager_dns_stub_stop(m);
} else if (r < 0)
return log_error_errno(r, "Failed to listen on %s socket 127.0.0.53:53: %m", t);
@ -752,9 +846,9 @@ int manager_dns_stub_start(Manager *m) {
ORDERED_SET_FOREACH(l, m->dns_extra_stub_listeners) {
if (FLAGS_SET(l->mode, DNS_STUB_LISTENER_UDP))
(void) manager_dns_stub_fd_extra(m, l, SOCK_DGRAM);
(void) manager_dns_stub_udp_fd_extra(m, l);
if (FLAGS_SET(l->mode, DNS_STUB_LISTENER_TCP))
(void) manager_dns_stub_fd_extra(m, l, SOCK_STREAM);
(void) manager_dns_stub_tcp_fd_extra(m, l);
}
}

View File

@ -155,7 +155,7 @@ static int specifier_dnssd_host_name(char specifier, const void *data, const voi
return 0;
}
int dnssd_render_instance_name(const char *name_template, char **ret_name) {
int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
static const Specifier specifier_table[] = {
{ 'm', specifier_machine_id, NULL },
{ 'b', specifier_boot_id, NULL },
@ -171,16 +171,18 @@ int dnssd_render_instance_name(const char *name_template, char **ret_name) {
_cleanup_free_ char *name = NULL;
int r;
assert(name_template);
assert(s);
assert(s->name_template);
r = specifier_printf(name_template, specifier_table, NULL, &name);
r = specifier_printf(s->name_template, specifier_table, s, &name);
if (r < 0)
return r;
return log_debug_errno(r, "Failed to replace specifiers: %m");
if (!dns_service_name_is_valid(name))
return -EINVAL;
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Service instance name '%s' is invalid.",
name);
if (ret_name)
*ret_name = TAKE_PTR(name);
return 0;
@ -225,7 +227,7 @@ int dnssd_update_rrs(DnssdService *s) {
LIST_FOREACH(items, txt_data, s->txt_data_items)
txt_data->rr = dns_resource_record_unref(txt_data->rr);
r = dnssd_render_instance_name(s->name_template, &n);
r = dnssd_render_instance_name(s, &n);
if (r < 0)
return r;

View File

@ -51,7 +51,7 @@ DnssdTxtData *dnssd_txtdata_free_all(DnssdTxtData *txt_data);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdService*, dnssd_service_free);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnssdTxtData*, dnssd_txtdata_free);
int dnssd_render_instance_name(const char *name_template, char **ret_name);
int dnssd_render_instance_name(DnssdService *s, char **ret_name);
int dnssd_load(Manager *manager);
int dnssd_txt_item_new_from_string(const char *key, const char *value, DnsTxtItem **ret_item);
int dnssd_txt_item_new_from_data(const char *key, const void *value, const size_t size, DnsTxtItem **ret_item);

View File

@ -183,12 +183,14 @@ static int parse_line(
k = strlen(l);
assert(k > 0);
if (l[k-1] != ']')
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EBADMSG), "Invalid section header '%s'", l);
if (l[k-1] != ']') {
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid section header '%s'", l);
return -EBADMSG;
}
n = strndup(l+1, k-2);
if (!n)
return log_oom();
return -ENOMEM;
if (sections && !nulstr_contains(sections, n)) {
bool ignore = flags & CONFIG_PARSE_RELAXED;

View File

@ -938,13 +938,12 @@ int config_parse_channel(const char *unit,
r = safe_atou32(rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse channel value for %s=, ignoring: %s", lvalue, rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse channel value, ignoring: %s", rvalue);
return 0;
}
if (k < 1) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s= value, ignoring: %s", lvalue, rvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid %s value, ignoring: %s", lvalue, rvalue);
return 0;
}
@ -999,24 +998,24 @@ int config_parse_advertise(const char *unit,
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to split advertise modes '%s', ignoring assignment: %m", rvalue);
return 0;
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to split advertise modes '%s', ignoring: %m", rvalue);
break;
}
if (r == 0)
return 0;
break;
mode = ethtool_link_mode_bit_from_string(w);
/* We reuse the kernel provided enum which does not contain negative value. So, the cast
* below is mandatory. Otherwise, the check below always passes and access an invalid address. */
if ((int) mode < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Failed to parse advertise mode, ignoring: %s", w);
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse advertise mode, ignoring: %s", w);
continue;
}
advertise[mode / 32] |= 1UL << (mode % 32);
}
return 0;
}
int config_parse_nic_buffer_size(const char *unit,
@ -1041,13 +1040,12 @@ int config_parse_nic_buffer_size(const char *unit,
r = safe_atou32(rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse interface buffer value, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse interface buffer value, ignoring: %s", rvalue);
return 0;
}
if (k < 1) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s= value, ignoring: %s", lvalue, rvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid %s value, ignoring: %s", lvalue, rvalue);
return 0;
}

View File

@ -62,23 +62,75 @@ int socket_address_parse(SocketAddress *a, const char *s) {
assert(a);
assert(s);
if (IN_SET(*s, '/', '@')) {
/* AF_UNIX socket */
struct sockaddr_un un;
*a = (SocketAddress) {
.type = SOCK_STREAM,
};
r = sockaddr_un_set_path(&un, s);
if (*s == '[') {
uint16_t port;
/* IPv6 in [x:.....:z]:p notation */
e = strchr(s+1, ']');
if (!e)
return -EINVAL;
n = strndup(s+1, e-s-1);
if (!n)
return -ENOMEM;
errno = 0;
if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
return errno_or_else(EINVAL);
e++;
if (*e != ':')
return -EINVAL;
e++;
r = parse_ip_port(e, &port);
if (r < 0)
return r;
*a = (SocketAddress) {
.sockaddr.un = un,
.size = r,
};
a->sockaddr.in6.sin6_family = AF_INET6;
a->sockaddr.in6.sin6_port = htobe16(port);
a->size = sizeof(struct sockaddr_in6);
} else if (*s == '/') {
/* AF_UNIX socket */
size_t l;
l = strlen(s);
if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when
* parsing (the kernel itself is less strict here in what it
* accepts) */
return -EINVAL;
a->sockaddr.un.sun_family = AF_UNIX;
memcpy(a->sockaddr.un.sun_path, s, l);
a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
} else if (*s == '@') {
/* Abstract AF_UNIX socket */
size_t l;
l = strlen(s+1);
if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminated sockets here
* when parsing, even though abstract namespace sockets
* explicitly allow embedded NUL bytes and don't consider
* them special. But it's simply annoying to debug such
* sockets. */
return -EINVAL;
a->sockaddr.un.sun_family = AF_UNIX;
memcpy(a->sockaddr.un.sun_path+1, s+1, l);
a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
} else if (startswith(s, "vsock:")) {
/* AF_VSOCK socket in vsock:cid:port notation */
const char *cid_start = s + STRLEN("vsock:");
unsigned port, cid;
unsigned port;
e = strchr(cid_start, ':');
if (!e)
@ -92,82 +144,72 @@ int socket_address_parse(SocketAddress *a, const char *s) {
if (!n)
return -ENOMEM;
if (isempty(n))
cid = VMADDR_CID_ANY;
else {
r = safe_atou(n, &cid);
if (!isempty(n)) {
r = safe_atou(n, &a->sockaddr.vm.svm_cid);
if (r < 0)
return r;
}
} else
a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
*a = (SocketAddress) {
.sockaddr.vm = {
.svm_cid = cid,
.svm_family = AF_VSOCK,
.svm_port = port,
},
.size = sizeof(struct sockaddr_vm),
};
a->sockaddr.vm.svm_family = AF_VSOCK;
a->sockaddr.vm.svm_port = port;
a->size = sizeof(struct sockaddr_vm);
} else {
uint16_t port;
r = parse_ip_port(s, &port);
if (r == -ERANGE)
return r; /* Valid port syntax, but the numerical value is wrong for a port. */
if (r >= 0) {
/* Just a port */
if (socket_ipv6_is_supported())
*a = (SocketAddress) {
.sockaddr.in6 = {
.sin6_family = AF_INET6,
.sin6_port = htobe16(port),
.sin6_addr = in6addr_any,
},
.size = sizeof(struct sockaddr_in6),
};
else
*a = (SocketAddress) {
.sockaddr.in = {
.sin_family = AF_INET,
.sin_port = htobe16(port),
.sin_addr.s_addr = INADDR_ANY,
},
.size = sizeof(struct sockaddr_in),
};
} else {
union in_addr_union address;
int family, ifindex;
r = in_addr_port_ifindex_name_from_string_auto(s, &family, &address, &port, &ifindex, NULL);
e = strchr(s, ':');
if (e) {
r = parse_ip_port(e + 1, &port);
if (r < 0)
return r;
if (port == 0) /* No port, no go. */
return -EINVAL;
n = strndup(s, e-s);
if (!n)
return -ENOMEM;
if (family == AF_INET)
*a = (SocketAddress) {
.sockaddr.in = {
.sin_family = AF_INET,
.sin_addr = address.in,
.sin_port = htobe16(port),
},
.size = sizeof(struct sockaddr_in),
};
else if (family == AF_INET6)
*a = (SocketAddress) {
.sockaddr.in6 = {
.sin6_family = AF_INET6,
.sin6_addr = address.in6,
.sin6_port = htobe16(port),
.sin6_scope_id = ifindex,
},
.size = sizeof(struct sockaddr_in6),
};
else
assert_not_reached("Family quarrel");
/* IPv4 in w.x.y.z:p notation? */
r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
if (r < 0)
return -errno;
if (r > 0) {
/* Gotcha, it's a traditional IPv4 address */
a->sockaddr.in.sin_family = AF_INET;
a->sockaddr.in.sin_port = htobe16(port);
a->size = sizeof(struct sockaddr_in);
} else {
int idx;
/* Uh, our last resort, an interface name */
idx = resolve_ifname(NULL, n);
if (idx < 0)
return idx;
a->sockaddr.in6.sin6_family = AF_INET6;
a->sockaddr.in6.sin6_port = htobe16(port);
a->sockaddr.in6.sin6_scope_id = idx;
a->sockaddr.in6.sin6_addr = in6addr_any;
a->size = sizeof(struct sockaddr_in6);
}
} else {
/* Just a port */
r = parse_ip_port(s, &port);
if (r < 0)
return r;
if (socket_ipv6_is_supported()) {
a->sockaddr.in6.sin6_family = AF_INET6;
a->sockaddr.in6.sin6_port = htobe16(port);
a->sockaddr.in6.sin6_addr = in6addr_any;
a->size = sizeof(struct sockaddr_in6);
} else {
a->sockaddr.in.sin_family = AF_INET;
a->sockaddr.in.sin_port = htobe16(port);
a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
a->size = sizeof(struct sockaddr_in);
}
}
}
@ -201,6 +243,10 @@ int socket_address_parse_netlink(SocketAddress *a, const char *s) {
assert(a);
assert(s);
*a = (SocketAddress) {
.type = SOCK_RAW,
};
r = extract_first_word(&s, &word, NULL, 0);
if (r < 0)
return r;
@ -217,13 +263,12 @@ int socket_address_parse_netlink(SocketAddress *a, const char *s) {
return r;
}
*a = (SocketAddress) {
.type = SOCK_RAW,
.sockaddr.nl.nl_family = AF_NETLINK,
.sockaddr.nl.nl_groups = group,
.protocol = family,
.size = sizeof(struct sockaddr_nl),
};
a->sockaddr.nl.nl_family = AF_NETLINK;
a->sockaddr.nl.nl_groups = group;
a->type = SOCK_RAW;
a->size = sizeof(struct sockaddr_nl);
a->protocol = family;
return 0;
}
@ -300,14 +345,10 @@ int in_addr_port_ifindex_name_from_string_auto(
/* This accepts the following:
* 192.168.0.1:53#example.com
* [2001:4860:4860::8888]:53%eth0#example.com
*
* If ret_port is NULL, then the port cannot be specified.
* If ret_ifindex is NULL, then the interface index cannot be specified.
* If ret_server_name is NULL, then server_name cannot be specified.
*
* ret_family is always AF_INET or AF_INET6.
*/
* [2001:4860:4860::8888]:53%eth0#example.com */
/* if ret_port is NULL, then strings with port cannot be specified.
* Also, if ret_server_name is NULL, then server_name cannot be specified. */
m = strchr(s, '#');
if (m) {
@ -328,19 +369,15 @@ int in_addr_port_ifindex_name_from_string_auto(
m = strchr(s, '%');
if (m) {
if (!ret_ifindex)
return -EINVAL;
if (isempty(m + 1))
return -EINVAL;
if (!ifname_valid_full(m + 1, IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC))
return -EINVAL; /* We want to return -EINVAL for syntactically invalid names,
* and -ENODEV for valid but nonexistent interfaces. */
if (ret_ifindex) {
/* If we shall return the interface index, try to parse it */
ifindex = resolve_interface(NULL, m + 1);
if (ifindex < 0)
return ifindex;
}
s = buf2 = strndup(s, m - s);
if (!buf2)
@ -418,6 +455,36 @@ int in_addr_port_ifindex_name_from_string_auto(
return r;
}
int in_addr_port_from_string_auto(
const char *s,
int *ret_family,
union in_addr_union *ret_address,
uint16_t *ret_port) {
union in_addr_union addr;
int family, ifindex, r;
uint16_t port;
assert(s);
r = in_addr_port_ifindex_name_from_string_auto(s, &family, &addr, &port, &ifindex, NULL);
if (r < 0)
return r;
/* This does not accept interface specified. */
if (ifindex != 0)
return -EINVAL;
if (ret_family)
*ret_family = family;
if (ret_address)
*ret_address = addr;
if (ret_port)
*ret_port = port;
return r;
}
struct in_addr_full *in_addr_full_free(struct in_addr_full *a) {
if (!a)
return NULL;

View File

@ -33,6 +33,7 @@ static inline int in_addr_ifindex_name_from_string_auto(const char *s, int *fami
static inline int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex) {
return in_addr_ifindex_name_from_string_auto(s, family, ret, ifindex, NULL);
}
int in_addr_port_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret_address, uint16_t *ret_port);
struct in_addr_full {
int family;

View File

@ -86,13 +86,11 @@ int config_parse_vlanid(
r = parse_vlanid(rvalue, id);
if (r == -ERANGE) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"VLAN identifier outside of valid range 0…4094, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "VLAN identifier outside of valid range 0…4094, ignoring: %s", rvalue);
return 0;
}
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse VLAN identifier value, ignoring: %s", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VLAN identifier value, ignoring: %s", rvalue);
return 0;
}

View File

@ -81,12 +81,10 @@ static void test_copy_tree(void) {
char original_dir[] = "/tmp/test-copy_tree/";
char copy_dir[] = "/tmp/test-copy_tree-copy/";
char **files = STRV_MAKE("file", "dir1/file", "dir1/dir2/file", "dir1/dir2/dir3/dir4/dir5/file");
char **symlinks = STRV_MAKE("link", "file",
char **links = STRV_MAKE("link", "file",
"link2", "dir1/file");
char **hardlinks = STRV_MAKE("hlink", "file",
"hlink2", "dir1/file");
const char *unixsockp;
char **p, **ll;
char **p, **link;
struct stat st;
int xattr_worked = -1; /* xattr support is optional in temporary directories, hence use it if we can,
* but don't fail if we can't */
@ -112,30 +110,20 @@ static void test_copy_tree(void) {
xattr_worked = k >= 0;
}
STRV_FOREACH_PAIR(ll, p, symlinks) {
STRV_FOREACH_PAIR(link, p, links) {
_cleanup_free_ char *f, *l;
assert_se(f = path_join(original_dir, *p));
assert_se(l = path_join(original_dir, *ll));
assert_se(l = path_join(original_dir, *link));
assert_se(mkdir_parents(l, 0755) >= 0);
assert_se(symlink(f, l) == 0);
}
STRV_FOREACH_PAIR(ll, p, hardlinks) {
_cleanup_free_ char *f, *l;
assert_se(f = path_join(original_dir, *p));
assert_se(l = path_join(original_dir, *ll));
assert_se(mkdir_parents(l, 0755) >= 0);
assert_se(link(f, l) == 0);
}
unixsockp = strjoina(original_dir, "unixsock");
assert_se(mknod(unixsockp, S_IFSOCK|0644, 0) >= 0);
assert_se(copy_tree(original_dir, copy_dir, UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS) == 0);
assert_se(copy_tree(original_dir, copy_dir, UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE) == 0);
STRV_FOREACH(p, files) {
_cleanup_free_ char *buf, *f, *c = NULL;
@ -159,30 +147,16 @@ static void test_copy_tree(void) {
}
}
STRV_FOREACH_PAIR(ll, p, symlinks) {
STRV_FOREACH_PAIR(link, p, links) {
_cleanup_free_ char *target, *f, *l;
assert_se(f = strjoin(original_dir, *p));
assert_se(l = strjoin(copy_dir, *ll));
assert_se(l = strjoin(copy_dir, *link));
assert_se(chase_symlinks(l, NULL, 0, &target, NULL) == 1);
assert_se(path_equal(f, target));
}
STRV_FOREACH_PAIR(ll, p, hardlinks) {
_cleanup_free_ char *f, *l;
struct stat a, b;
assert_se(f = strjoin(copy_dir, *p));
assert_se(l = strjoin(copy_dir, *ll));
assert_se(lstat(f, &a) >= 0);
assert_se(lstat(l, &b) >= 0);
assert_se(a.st_ino == b.st_ino);
assert_se(a.st_dev == b.st_dev);
}
unixsockp = strjoina(copy_dir, "unixsock");
assert_se(stat(unixsockp, &st) >= 0);
assert_se(S_ISSOCK(st.st_mode));

View File

@ -58,8 +58,6 @@ static void test_in_addr_prefix_from_string_one(
}
static void test_in_addr_prefix_from_string(void) {
log_info("/* %s */", __func__);
test_in_addr_prefix_from_string_one("", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
test_in_addr_prefix_from_string_one("/", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
test_in_addr_prefix_from_string_one("/8", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
@ -92,7 +90,7 @@ static void test_in_addr_prefix_to_string_valid(int family, const char *p) {
union in_addr_union u;
unsigned char l;
log_info("%s: %s", __func__, p);
log_info("/* %s */", p);
assert_se(in_addr_prefix_from_string(p, family, &u, &l) >= 0);
assert_se(in_addr_prefix_to_string(family, &u, l, &str) >= 0);
@ -104,7 +102,7 @@ static void test_in_addr_prefix_to_string_unoptimized(int family, const char *p)
union in_addr_union u1, u2;
unsigned char len1, len2;
log_info("%s: %s", __func__, p);
log_info("/* %s */", p);
assert_se(in_addr_prefix_from_string(p, family, &u1, &len1) >= 0);
assert_se(in_addr_prefix_to_string(family, &u1, len1, &str1) >= 0);
@ -117,8 +115,6 @@ static void test_in_addr_prefix_to_string_unoptimized(int family, const char *p)
}
static void test_in_addr_prefix_to_string(void) {
log_info("/* %s */", __func__);
test_in_addr_prefix_to_string_valid(AF_INET, "0.0.0.0/32");
test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/0");
test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/24");
@ -141,8 +137,6 @@ static void test_in_addr_random_prefix(void) {
_cleanup_free_ char *str = NULL;
union in_addr_union a;
log_info("/* %s */", __func__);
assert_se(in_addr_from_string(AF_INET, "192.168.10.1", &a) >= 0);
assert_se(in_addr_random_prefix(AF_INET, &a, 31, 32) >= 0);

View File

@ -12,20 +12,11 @@ static void test_socket_address_parse_one(const char *in, int ret, int family, c
int r;
r = socket_address_parse(&a, in);
if (r >= 0) {
r = socket_address_print(&a, &out);
if (r < 0)
log_error_errno(r, "Printing failed for \"%s\": %m", in);
assert(r >= 0);
assert_se(a.type == 0);
}
if (r >= 0)
assert_se(socket_address_print(&a, &out) >= 0);
log_info("\"%s\" → %s %d → \"%s\" (expect %d / \"%s\")",
in,
r >= 0 ? "" : "", r,
empty_to_dash(out),
ret,
ret >= 0 ? expected ?: in : "-");
log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in,
r >= 0 ? "" : "", empty_to_dash(out), r >= 0 ? expected ?: in : "-");
assert_se(r == ret);
if (r >= 0) {
assert_se(a.sockaddr.sa.sa_family == family);
@ -59,24 +50,14 @@ static void test_socket_address_parse(void) {
test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL);
test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]%lo:1234", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]%lo:0", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]%lo", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]%lo%lo:1234", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]% lo:1234", -EINVAL, 0, NULL);
test_socket_address_parse_one("8888", 0, default_family, "[::]:8888");
test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6,
"[2001:db8:0:85a3::ac1f:8001]:8888");
test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
test_socket_address_parse_one("[::1]:1234%lo", 0, AF_INET6, NULL);
test_socket_address_parse_one("[::1]:0%lo", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]%lo", -EINVAL, 0, NULL);
test_socket_address_parse_one("[::1]:1234%lo%lo", -ENODEV, 0, NULL);
test_socket_address_parse_one("[::1]:1234%xxxxasdf", -ENODEV, 0, NULL);
test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
test_socket_address_parse_one("/", -EINVAL, 0, NULL);
test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL);
{
@ -217,13 +198,9 @@ static void test_socket_address_is(void) {
log_info("/* %s */", __func__);
assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
assert_se( socket_address_is(&a, "192.168.1.1:8888", 0 /* unspecified yet */));
assert_se(!socket_address_is(&a, "route", 0));
assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
assert_se(!socket_address_is(&a, "route", SOCK_STREAM));
assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW));
assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
a.type = SOCK_STREAM;
assert_se( socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
}
static void test_socket_address_is_netlink(void) {
@ -307,83 +284,66 @@ static void test_in_addr_ifindex_name_from_string_auto(void) {
test_in_addr_ifindex_name_from_string_auto_one("fe80::18%19#another.test.com", "another.test.com");
}
static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str, int family, uint16_t port, int ifindex,
const char *server_name, const char *str_repr) {
static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str, int family, uint16_t port, int ifindex, const char *server_name) {
_cleanup_free_ char *name = NULL, *x = NULL;
union in_addr_union a;
uint16_t p;
int f, i;
char *fake;
log_info("%s: %s", __func__, str);
{
_cleanup_free_ char *name = NULL, *x = NULL;
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, &name) == 0);
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, &name) >= 0);
assert_se(family == f);
assert_se(port == p);
assert_se(ifindex == i);
assert_se(streq_ptr(server_name, name));
assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, name, &x) >= 0);
assert_se(streq(str_repr ?: str, x));
}
if (port > 0)
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, NULL, &i, &fake) == -EINVAL);
else {
_cleanup_free_ char *name = NULL, *x = NULL;
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, NULL, &i, &name) == 0);
assert_se(family == f);
assert_se(ifindex == i);
assert_se(streq_ptr(server_name, name));
assert_se(in_addr_port_ifindex_name_to_string(f, &a, 0, i, name, &x) >= 0);
assert_se(streq(str_repr ?: str, x));
}
if (ifindex > 0)
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, NULL, &fake) == -EINVAL);
else {
_cleanup_free_ char *name = NULL, *x = NULL;
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, NULL, &name) == 0);
assert_se(family == f);
assert_se(port == p);
assert_se(streq_ptr(server_name, name));
assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, 0, name, &x) >= 0);
assert_se(streq(str_repr ?: str, x));
}
if (server_name)
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, NULL) == -EINVAL);
else {
_cleanup_free_ char *x = NULL;
assert_se(in_addr_port_ifindex_name_from_string_auto(str, &f, &a, &p, &i, NULL) == 0);
assert_se(family == f);
assert_se(port == p);
assert_se(ifindex == i);
assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, NULL, &x) >= 0);
assert_se(streq(str_repr ?: str, x));
}
assert_se(streq(str, x));
}
static void test_in_addr_port_ifindex_name_from_string_auto(void) {
log_info("/* %s */", __func__);
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1", AF_INET, 0, 0, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1#test.com", AF_INET, 0, 0, "test.com", NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53", AF_INET, 53, 0, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53#example.com", AF_INET, 53, 0, "example.com", NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18", AF_INET6, 0, 0, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18#hoge.com", AF_INET6, 0, 0, "hoge.com", NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19", AF_INET6, 0, 19, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%lo", AF_INET6, 0, 1, NULL, "fe80::18%1");
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53", AF_INET6, 53, 0, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo", AF_INET6, 53, 1, NULL, "[fe80::18]:53%1");
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19#hoge.com", AF_INET6, 0, 19, "hoge.com", NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53#hoge.com", AF_INET6, 53, 0, "hoge.com", NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19#hoge.com", AF_INET6, 53, 19, "hoge.com", NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo", AF_INET6, 53, 1, NULL, "[fe80::18]:53%1");
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo#hoge.com", AF_INET6, 53, 1, "hoge.com", "[fe80::18]:53%1#hoge.com");
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1", AF_INET, 0, 0, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1#test.com", AF_INET, 0, 0, "test.com");
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53", AF_INET, 53, 0, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53#example.com", AF_INET, 53, 0, "example.com");
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18", AF_INET6, 0, 0, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18#hoge.com", AF_INET6, 0, 0, "hoge.com");
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19", AF_INET6, 0, 19, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53", AF_INET6, 53, 0, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19#hoge.com", AF_INET6, 0, 19, "hoge.com");
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53#hoge.com", AF_INET6, 53, 0, "hoge.com");
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL);
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19#hoge.com", AF_INET6, 53, 19, "hoge.com");
}
static void test_in_addr_port_from_string_auto_one(const char *str, int family, const char *address_string, uint16_t port) {
union in_addr_union a, b;
uint16_t p;
int f;
assert_se(in_addr_port_from_string_auto(str, &f, &a, &p) >= 0);
assert_se(family == f);
assert_se(port == p);
assert_se(in_addr_from_string(family, address_string, &b) >= 0);
assert_se(in_addr_equal(family, &a, &b) == 1);
}
static void test_in_addr_port_from_string_auto(void) {
log_info("/* %s */", __func__);
assert_se(in_addr_port_from_string_auto("192.168.0.1#test.com", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("192.168.0.1:53#example.com", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("fe80::18#hoge.com", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("fe80::18%19", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("fe80::18%19#hoge.com", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("[fe80::18]:53#hoge.com", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("[fe80::18]:53%19", NULL, NULL, NULL) < 0);
assert_se(in_addr_port_from_string_auto("[fe80::18]:53%19#hoge.com", NULL, NULL, NULL) < 0);
test_in_addr_port_from_string_auto_one("192.168.0.1", AF_INET, "192.168.0.1", 0);
test_in_addr_port_from_string_auto_one("192.168.0.1:53", AF_INET, "192.168.0.1", 53);
test_in_addr_port_from_string_auto_one("fe80::18", AF_INET6, "fe80::18", 0);
test_in_addr_port_from_string_auto_one("[fe80::18]:53", AF_INET6, "fe80::18", 53);
}
int main(int argc, char *argv[]) {
@ -400,6 +360,7 @@ int main(int argc, char *argv[]) {
test_in_addr_ifindex_from_string_auto();
test_in_addr_ifindex_name_from_string_auto();
test_in_addr_port_ifindex_name_from_string_auto();
test_in_addr_port_from_string_auto();
return 0;
}

View File

@ -44,13 +44,9 @@ static void test_ifname_valid(void) {
assert(ifname_valid("foo.bar"));
assert(!ifname_valid("x:y"));
assert( ifname_valid_full("xxxxxxxxxxxxxxx", 0));
assert(!ifname_valid_full("xxxxxxxxxxxxxxxx", 0));
assert( ifname_valid_full("xxxxxxxxxxxxxxxx", IFNAME_VALID_ALTERNATIVE));
assert( ifname_valid_full("xxxxxxxxxxxxxxxx", IFNAME_VALID_ALTERNATIVE));
assert(!ifname_valid_full("999", IFNAME_VALID_ALTERNATIVE));
assert( ifname_valid_full("999", IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC));
assert(!ifname_valid_full("0", IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC));
assert(ifname_valid("xxxxxxxxxxxxxxx"));
assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true));
}
static void test_socket_print_unix_one(const char *in, size_t len_in, const char *expected) {
@ -508,11 +504,17 @@ int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG);
test_ifname_valid();
test_socket_print_unix();
test_sockaddr_equal();
test_sockaddr_un_len();
test_in_addr_is_multicast();
test_getpeercred_getpeergroups();
test_passfd_read();
test_passfd_contents_read();
test_receive_nopassfd();

View File

@ -89,8 +89,7 @@ int config_parse_servers(
else {
r = manager_parse_server_string(m, ltype, rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse NTP server string '%s', ignoring: %m", rvalue);
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NTP server string '%s'. Ignoring.", rvalue);
return 0;
}
}

View File

@ -1543,7 +1543,7 @@ static int copy_files(Item *i) {
dfd, bn,
i->uid_set ? i->uid : UID_INVALID,
i->gid_set ? i->gid : GID_INVALID,
COPY_REFLINK | COPY_MERGE_EMPTY | COPY_MAC_CREATE | COPY_HARDLINKS);
COPY_REFLINK | COPY_MERGE_EMPTY | COPY_MAC_CREATE);
if (r < 0) {
struct stat a, b;

View File

@ -7,7 +7,6 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include "ethtool-util.h"
#include "link-config.h"
#include "network-internal.h"
#include "socket-util.h"
%}
struct ConfigPerfItem;
%null_strings
@ -37,7 +36,7 @@ Link.MACAddressPolicy, config_parse_mac_address_policy, 0,
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(link_config, alternative_names)
Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(link_config, alternative_names_policy)
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)

View File

@ -118,7 +118,8 @@ int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command
if (!builtins[cmd])
return -EOPNOTSUPP;
r = strv_split_full(&argv, command, NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_RETAIN_ESCAPE);
r = strv_split_full(&argv, command, NULL,
EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_RETAIN_ESCAPE);
if (r < 0)
return r;

View File

@ -166,7 +166,7 @@ static int xdg_config_parse_string(
/* XDG does not allow duplicate definitions. */
if (*out) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Key %s was defined multiple times, ignoring.", lvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Key %s was defined multiple times, ignoring.", lvalue);
return 0;
}
@ -238,7 +238,7 @@ static int xdg_config_parse_strv(
/* XDG does not allow duplicate definitions. */
if (*ret_sv) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Key %s was already defined, ignoring.", lvalue);
log_syntax(unit, LOG_ERR, filename, line, 0, "Key %s was already defined, ignoring.", lvalue);
return 0;
}
@ -256,7 +256,7 @@ static int xdg_config_parse_strv(
/* Move forward, and ensure it is a valid escape. */
end++;
if (!strchr("sntr\\;", *end)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Undefined escape sequence \\%c.", *end);
log_syntax(unit, LOG_ERR, filename, line, 0, "Undefined escape sequence \\%c.", *end);
return 0;
}
continue;

View File

@ -1,33 +0,0 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
# fwmark
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10111
FirewallMark=1011
# oif
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10112
OutgoingInterface=test1
# iif
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10113
IncomingInterface=test1
# source
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10114
From=192.168.8.254

View File

@ -1735,11 +1735,9 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-vrf.network',
'26-link-local-addressing-ipv6.network',
'routing-policy-rule-dummy98.network',
'routing-policy-rule-test1.network',
'routing-policy-rule-reconfigure.network',
]
'routing-policy-rule-test1.network']
routing_policy_rule_tables = ['7', '8', '9', '1011']
routing_policy_rule_tables = ['7', '8', '9']
routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
def setUp(self):
@ -1972,6 +1970,32 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'iif test1')
self.assertRegex(output, 'lookup 8')
output = check_output('ip -6 rule list iif test1 priority 101')
print(output)
self.assertRegex(output, '101:')
self.assertRegex(output, 'from all')
self.assertRegex(output, 'iif test1')
self.assertRegex(output, 'lookup 9')
run('ip rule delete iif test1 priority 111')
output = check_output('ip rule list iif test1 priority 111')
print(output)
self.assertEqual(output, '')
run(*networkctl_cmd, 'reconfigure', 'test1', env=env)
self.wait_online(['test1:degraded'])
output = check_output('ip rule list iif test1 priority 111')
print(output)
self.assertRegex(output, '111:')
self.assertRegex(output, 'from 192.168.100.18')
self.assertRegex(output, r'tos (0x08|throughput)\s')
self.assertRegex(output, 'iif test1')
self.assertRegex(output, 'oif test1')
self.assertRegex(output, 'lookup 7')
def test_routing_policy_rule_issue_11280(self):
copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev',
'routing-policy-rule-dummy98.network', '12-dummy.netdev')
@ -1992,39 +2016,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
stop_networkd(remove_state_files=False)
def test_routing_policy_rule_reconfigure(self):
copy_unit_to_networkd_unit_path('routing-policy-rule-reconfigure.network', '11-dummy.netdev')
start_networkd()
self.wait_online(['test1:degraded'])
output = check_output('ip rule list table 1011')
print(output)
self.assertRegex(output, '10111: from all fwmark 0x3f3 lookup 1011')
self.assertRegex(output, '10112: from all oif test1 lookup 1011')
self.assertRegex(output, '10113: from all iif test1 lookup 1011')
self.assertRegex(output, '10114: from 192.168.8.254 lookup 1011')
run('ip rule delete priority 10111')
run('ip rule delete priority 10112')
run('ip rule delete priority 10113')
run('ip rule delete priority 10114')
run('ip rule delete priority 10115')
output = check_output('ip rule list table 1011')
print(output)
self.assertEqual(output, '')
run(*networkctl_cmd, 'reconfigure', 'test1', env=env)
self.wait_online(['test1:degraded'])
output = check_output('ip rule list table 1011')
print(output)
self.assertRegex(output, '10111: from all fwmark 0x3f3 lookup 1011')
self.assertRegex(output, '10112: from all oif test1 lookup 1011')
self.assertRegex(output, '10113: from all iif test1 lookup 1011')
self.assertRegex(output, '10114: from 192.168.8.254 lookup 1011')
@expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
def test_routing_policy_rule_port_range(self):
copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')