Features:
+* when importing an fs tree with machined, optionally apply userns-rec-chown
+
+* when importing an fs tree with machined, complain if image is not an OS
+
* when we fork off generators and such, lower LIMIT_NOFILE soft limit to 1K
+* Maybe introduce a helper safe_exec() or so, which is to execve() which
+ safe_fork() is to fork(). And then make revert the RLIMIT_NOFILE soft limit
+ to 1K implicitly, unless explicitly opted-out.
+
* rework seccomp/nnp logic that that even if User= is used in combination with
a seccomp option we don't have to set NNP. For that, change uid first whil
keeping CAP_SYS_ADMIN, then apply seccomp, the drop cap.
applicable to SIT tunnels.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>ISATAP=</varname></term>
+ <listitem>
+ <para>Takes a boolean. If set, configures the tunnel as Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) tunnel.
+ Only applicable to SIT tunnels. When unset, the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>SerializeTunneledPackets=</varname></term>
<listitem>
Defaults to unset.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>InvertRule=</varname></term>
+ <listitem>
+ <para>A boolean. Specifies wheather the rule to be inverted. Defaults to false.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>MulticastToUnicast=</varname></term>
+ <listitem>
+ <para>Takes a boolean. Multicast to unicast works on top of the multicast snooping feature of
+ the bridge. Which means unicast copies are only delivered to hosts which are interested in it.
+ When unset, the kernel's default will be used.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>HairPin=</varname></term>
<listitem>
if (!joined)
return log_oom();
- r = safe_fork("(activate)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &child_pid);
+ r = safe_fork("(activate)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &child_pid);
if (r < 0)
return r;
if (r == 0) {
if (f) {
PROTECT_ERRNO;
- assert_se(fclose_nointr(f) != EBADF);
+ assert_se(fclose_nointr(f) != -EBADF);
}
return NULL;
#pragma once
#include <assert.h>
+#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
memfd-util.h
mempool.c
mempool.h
+ missing_audit.h
missing_btrfs.h
missing_btrfs_tree.h
missing_capability.h
missing_ethtool.h
+ missing_fcntl.h
missing_fib_rules.h
missing_fou.h
+ missing_fs.h
missing_if_bridge.h
missing_if_link.h
missing_if_tunnel.h
missing_input.h
missing_keyctl.h
missing_magic.h
+ missing_mman.h
missing_network.h
missing_prctl.h
+ missing_random.h
+ missing_resource.h
+ missing_sched.h
missing_securebits.h
+ missing_socket.h
missing_stat.h
+ missing_stdlib.h
missing_syscall.h
+ missing_timerfd.h
missing_type.h
missing_vxcan.h
mkdir-label.c
refcnt.h
replace-var.c
replace-var.h
+ rlimit-util.c
+ rlimit-util.h
rm-rf.c
rm-rf.h
selinux-util.c
/* Missing glibc definitions to access certain kernel APIs */
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <linux/audit.h>
-#include <linux/falloc.h>
-#include <linux/oom.h>
-#include <net/ethernet.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-#if HAVE_AUDIT
-#include <libaudit.h>
-#endif
-
-#ifdef ARCH_MIPS
-#include <asm/sgidefs.h>
-#endif
-
-#if HAVE_LINUX_VM_SOCKETS_H
-#include <linux/vm_sockets.h>
-#else
-#define VMADDR_CID_ANY -1U
-struct sockaddr_vm {
- unsigned short svm_family;
- unsigned short svm_reserved1;
- unsigned int svm_port;
- unsigned int svm_cid;
- unsigned char svm_zero[sizeof(struct sockaddr) -
- sizeof(unsigned short) -
- sizeof(unsigned short) -
- sizeof(unsigned int) -
- sizeof(unsigned int)];
-};
-#endif /* !HAVE_LINUX_VM_SOCKETS_H */
-
-#ifndef RLIMIT_RTTIME
-#define RLIMIT_RTTIME 15
-#endif
-
-/* If RLIMIT_RTTIME is not defined, then we cannot use RLIMIT_NLIMITS as is */
-#define _RLIMIT_MAX (RLIMIT_RTTIME+1 > RLIMIT_NLIMITS ? RLIMIT_RTTIME+1 : RLIMIT_NLIMITS)
-
-#ifndef F_LINUX_SPECIFIC_BASE
-#define F_LINUX_SPECIFIC_BASE 1024
-#endif
-
-#ifndef F_SETPIPE_SZ
-#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
-#endif
-
-#ifndef F_GETPIPE_SZ
-#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
-#endif
-
-#ifndef F_ADD_SEALS
-#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
-#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
-
-#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
-#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
-#define F_SEAL_GROW 0x0004 /* prevent file from growing */
-#define F_SEAL_WRITE 0x0008 /* prevent writes */
-#endif
-
-#ifndef F_OFD_GETLK
-#define F_OFD_GETLK 36
-#define F_OFD_SETLK 37
-#define F_OFD_SETLKW 38
-#endif
-
-#ifndef MFD_ALLOW_SEALING
-#define MFD_ALLOW_SEALING 0x0002U
-#endif
-
-#ifndef MFD_CLOEXEC
-#define MFD_CLOEXEC 0x0001U
-#endif
-
-#ifndef IP_FREEBIND
-#define IP_FREEBIND 15
-#endif
-
-#ifndef OOM_SCORE_ADJ_MIN
-#define OOM_SCORE_ADJ_MIN (-1000)
-#endif
-
-#ifndef OOM_SCORE_ADJ_MAX
-#define OOM_SCORE_ADJ_MAX 1000
-#endif
-
-#ifndef AUDIT_SERVICE_START
-#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
-#endif
-
-#ifndef AUDIT_SERVICE_STOP
-#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
-#endif
-
-#ifndef TIOCVHANGUP
-#define TIOCVHANGUP 0x5437
-#endif
-
-#ifndef IP_TRANSPARENT
-#define IP_TRANSPARENT 19
-#endif
-
-#ifndef SOL_NETLINK
-#define SOL_NETLINK 270
-#endif
-
-#ifndef NETLINK_LIST_MEMBERSHIPS
-#define NETLINK_LIST_MEMBERSHIPS 9
-#endif
-
-#ifndef SOL_SCTP
-#define SOL_SCTP 132
-#endif
-
-#ifndef GRND_NONBLOCK
-#define GRND_NONBLOCK 0x0001
-#endif
-
-#ifndef GRND_RANDOM
-#define GRND_RANDOM 0x0002
-#endif
-
-#ifndef FS_NOCOW_FL
-#define FS_NOCOW_FL 0x00800000
-#endif
-
-#ifndef CLONE_NEWCGROUP
-#define CLONE_NEWCGROUP 0x02000000
-#endif
-
-#ifndef MS_MOVE
-#define MS_MOVE 8192
-#endif
-
-#ifndef MS_REC
-#define MS_REC 16384
-#endif
-
-#ifndef MS_PRIVATE
-#define MS_PRIVATE (1<<18)
-#endif
-
-#ifndef MS_REC
-#define MS_REC (1<<19)
-#endif
-
-#ifndef MS_SHARED
-#define MS_SHARED (1<<20)
-#endif
-
-#ifndef MS_RELATIME
-#define MS_RELATIME (1<<21)
-#endif
-
-#ifndef MS_KERNMOUNT
-#define MS_KERNMOUNT (1<<22)
-#endif
-
-#ifndef MS_I_VERSION
-#define MS_I_VERSION (1<<23)
-#endif
-
-#ifndef MS_STRICTATIME
-#define MS_STRICTATIME (1<<24)
-#endif
-
-#ifndef MS_LAZYTIME
-#define MS_LAZYTIME (1<<25)
-#endif
-
-#ifndef SCM_SECURITY
-#define SCM_SECURITY 0x03
-#endif
-
-#ifndef DM_DEFERRED_REMOVE
-#define DM_DEFERRED_REMOVE (1 << 17)
-#endif
-
-#ifndef MAX_HANDLE_SZ
-#define MAX_HANDLE_SZ 128
-#endif
-
-#if ! HAVE_SECURE_GETENV
-# if HAVE___SECURE_GETENV
-# define secure_getenv __secure_getenv
-# else
-# error "neither secure_getenv nor __secure_getenv are available"
-# endif
-#endif
-
-#ifndef CIFS_MAGIC_NUMBER
-# define CIFS_MAGIC_NUMBER 0xFF534D42
-#endif
-
-#ifndef TFD_TIMER_CANCEL_ON_SET
-# define TFD_TIMER_CANCEL_ON_SET (1 << 1)
-#endif
-
-#ifndef SO_REUSEPORT
-# define SO_REUSEPORT 15
-#endif
-
-#ifndef SO_PEERGROUPS
-# define SO_PEERGROUPS 59
-#endif
-
-#ifndef DRM_IOCTL_SET_MASTER
-# define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
-#endif
-
-#ifndef DRM_IOCTL_DROP_MASTER
-# define DRM_IOCTL_DROP_MASTER _IO('d', 0x1f)
-#endif
-
-/* The precise definition of __O_TMPFILE is arch specific; use the
- * values defined by the kernel (note: some are hexa, some are octal,
- * duplicated as-is from the kernel definitions):
- * - alpha, parisc, sparc: each has a specific value;
- * - others: they use the "generic" value.
- */
-
-#ifndef __O_TMPFILE
-#if defined(__alpha__)
-#define __O_TMPFILE 0100000000
-#elif defined(__parisc__) || defined(__hppa__)
-#define __O_TMPFILE 0400000000
-#elif defined(__sparc__) || defined(__sparc64__)
-#define __O_TMPFILE 0x2000000
-#else
-#define __O_TMPFILE 020000000
-#endif
-#endif
-
-/* a horrid kludge trying to make sure that this will fail on old kernels */
-#ifndef O_TMPFILE
-#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#endif
-
-#ifndef BPF_XOR
-#define BPF_XOR 0xa0
-#endif
-
-/* Note that LOOPBACK_IFINDEX is currently not exported by the
- * kernel/glibc, but hardcoded internally by the kernel. However, as
- * it is exported to userspace indirectly via rtnetlink and the
- * ioctls, and made use of widely we define it here too, in a way that
- * is compatible with the kernel's internal definition. */
-#ifndef LOOPBACK_IFINDEX
-#define LOOPBACK_IFINDEX 1
-#endif
-
-#ifndef MAX_AUDIT_MESSAGE_LENGTH
-#define MAX_AUDIT_MESSAGE_LENGTH 8970
-#endif
-
-#ifndef AUDIT_NLGRP_MAX
-#define AUDIT_NLGRP_READLOG 1
-#endif
-
-#ifndef RENAME_NOREPLACE
-#define RENAME_NOREPLACE (1 << 0)
-#endif
-
-#ifndef KCMP_FILE
-#define KCMP_FILE 0
-#endif
-
-#ifndef ETHERTYPE_LLDP
-#define ETHERTYPE_LLDP 0x88cc
-#endif
-
-#ifndef SOL_ALG
-#define SOL_ALG 279
-#endif
-
-#ifndef AF_VSOCK
-#define AF_VSOCK 40
-#endif
-
-#ifndef EXT4_IOC_RESIZE_FS
-# define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
-#endif
-
-#ifndef NS_GET_NSTYPE
-#define NS_GET_NSTYPE _IO(0xb7, 0x3)
-#endif
-
-#ifndef FALLOC_FL_KEEP_SIZE
-#define FALLOC_FL_KEEP_SIZE 0x01
-#endif
-
-#ifndef FALLOC_FL_PUNCH_HOLE
-#define FALLOC_FL_PUNCH_HOLE 0x02
-#endif
-
-#ifndef PF_KTHREAD
-#define PF_KTHREAD 0x00200000
-#endif
-
-/* The maximum thread/process name length including trailing NUL byte. This mimics the kernel definition of the same
- * name, which we need in userspace at various places but is not defined in userspace currently, neither under this
- * name nor any other. */
-#ifndef TASK_COMM_LEN
-#define TASK_COMM_LEN 16
-#endif
-
+#include "missing_audit.h"
#include "missing_btrfs_tree.h"
#include "missing_capability.h"
+#include "missing_fcntl.h"
+#include "missing_fs.h"
#include "missing_input.h"
#include "missing_magic.h"
+#include "missing_mman.h"
#include "missing_network.h"
#include "missing_prctl.h"
+#include "missing_random.h"
+#include "missing_resource.h"
+#include "missing_sched.h"
+#include "missing_socket.h"
+#include "missing_stdlib.h"
+#include "missing_timerfd.h"
#include "missing_type.h"
#include "missing_syscall.h"
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <linux/audit.h>
+
+#if HAVE_AUDIT
+#include <libaudit.h>
+#endif
+
+#ifndef AUDIT_SERVICE_START
+#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
+#endif
+
+#ifndef AUDIT_SERVICE_STOP
+#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
+#endif
+
+#ifndef MAX_AUDIT_MESSAGE_LENGTH
+#define MAX_AUDIT_MESSAGE_LENGTH 8970
+#endif
+
+#ifndef AUDIT_NLGRP_MAX
+#define AUDIT_NLGRP_READLOG 1
+#endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <fcntl.h>
+
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+
+#ifndef F_SETPIPE_SZ
+#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
+#endif
+
+#ifndef F_GETPIPE_SZ
+#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
+#endif
+
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
+
+#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
+#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
+#define F_SEAL_GROW 0x0004 /* prevent file from growing */
+#define F_SEAL_WRITE 0x0008 /* prevent writes */
+#endif
+
+#ifndef F_OFD_GETLK
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
+#endif
+
+#ifndef MAX_HANDLE_SZ
+#define MAX_HANDLE_SZ 128
+#endif
+
+/* The precise definition of __O_TMPFILE is arch specific; use the
+ * values defined by the kernel (note: some are hexa, some are octal,
+ * duplicated as-is from the kernel definitions):
+ * - alpha, parisc, sparc: each has a specific value;
+ * - others: they use the "generic" value.
+ */
+
+#ifndef __O_TMPFILE
+#if defined(__alpha__)
+#define __O_TMPFILE 0100000000
+#elif defined(__parisc__) || defined(__hppa__)
+#define __O_TMPFILE 0400000000
+#elif defined(__sparc__) || defined(__sparc64__)
+#define __O_TMPFILE 0x2000000
+#else
+#define __O_TMPFILE 020000000
+#endif
+#endif
+
+/* a horrid kludge trying to make sure that this will fail on old kernels */
+#ifndef O_TMPFILE
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+#endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+/* linux/fs.h */
+#ifndef RENAME_NOREPLACE /* 0a7c3937a1f23f8cb5fc77ae01661e9968a51d0c (3.15) */
+#define RENAME_NOREPLACE (1 << 0)
+#endif
+
+/* linux/fs.h or sys/mount.h */
+#ifndef MS_MOVE
+#define MS_MOVE 8192
+#endif
+
+#ifndef MS_REC
+#define MS_REC 16384
+#endif
+
+#ifndef MS_PRIVATE
+#define MS_PRIVATE (1<<18)
+#endif
+
+#ifndef MS_SLAVE
+#define MS_SLAVE (1<<19)
+#endif
+
+#ifndef MS_SHARED
+#define MS_SHARED (1<<20)
+#endif
+
+#ifndef MS_RELATIME
+#define MS_RELATIME (1<<21)
+#endif
+
+#ifndef MS_KERNMOUNT
+#define MS_KERNMOUNT (1<<22)
+#endif
+
+#ifndef MS_I_VERSION
+#define MS_I_VERSION (1<<23)
+#endif
+
+#ifndef MS_STRICTATIME
+#define MS_STRICTATIME (1<<24)
+#endif
+
+#ifndef MS_LAZYTIME
+#define MS_LAZYTIME (1<<25)
+#endif
+
+/* Not exposed yet. Defined at fs/ext4/ext4.h */
+#ifndef EXT4_IOC_RESIZE_FS
+#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
+#endif
+
+/* Not exposed yet. Defined at fs/cifs/cifsglob.h */
+#ifndef CIFS_MAGIC_NUMBER
+#define CIFS_MAGIC_NUMBER 0xFF534D42
+#endif
+
+/* linux/nsfs.h */
+#ifndef NS_GET_NSTYPE /* d95fa3c76a66b6d76b1e109ea505c55e66360f3c (4.11) */
+#define NS_GET_NSTYPE _IO(0xb7, 0x3)
+#endif
#pragma once
#include <linux/input.h>
+#include <linux/types.h>
/* linux@c7dc65737c9a607d3e6f8478659876074ad129b8 (3.12) */
#ifndef EVIOCREVOKE
/* linux@06a16293f71927f756dcf37558a79c0b05a91641 (4.4) */
#ifndef EVIOCSMASK
struct input_mask {
- uint32_t type;
- uint32_t codes_size;
- uint64_t codes_ptr;
+ __u32 type;
+ __u32 codes_size;
+ __u64 codes_ptr;
};
#define EVIOCGMASK _IOR('E', 0x92, struct input_mask)
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <sys/mman.h>
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
#include <linux/loop.h>
#include <linux/rtnetlink.h>
+#include <net/ethernet.h>
#include "missing_ethtool.h"
#include "missing_fib_rules.h"
#define NET_NAME_RENAMED 4
#endif
+/* netlink.h */
+#ifndef NETLINK_LIST_MEMBERSHIPS /* b42be38b2778eda2237fc759e55e3b698b05b315 (4.2) */
+#define NETLINK_LIST_MEMBERSHIPS 9
+#endif
+
/* rtnetlink.h */
#ifndef RTA_PREF
#define RTA_PREF 20
#ifndef RTA_EXPIRES
#define RTA_EXPIRES 23
#endif
+
+/* Note that LOOPBACK_IFINDEX is currently not exported by the
+ * kernel/glibc, but hardcoded internally by the kernel. However, as
+ * it is exported to userspace indirectly via rtnetlink and the
+ * ioctls, and made use of widely we define it here too, in a way that
+ * is compatible with the kernel's internal definition. */
+#ifndef LOOPBACK_IFINDEX
+#define LOOPBACK_IFINDEX 1
+#endif
+
+/* Not exposed yet. Similar values are defined in net/ethernet.h */
+#ifndef ETHERTYPE_LLDP
+#define ETHERTYPE_LLDP 0x88cc
+#endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#if USE_SYS_RANDOM_H
+# include <sys/random.h>
+#else
+# include <linux/random.h>
+#endif
+
+#ifndef GRND_NONBLOCK
+#define GRND_NONBLOCK 0x0001
+#endif
+
+#ifndef GRND_RANDOM
+#define GRND_RANDOM 0x0002
+#endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <sys/resource.h>
+
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+
+/* If RLIMIT_RTTIME is not defined, then we cannot use RLIMIT_NLIMITS as is */
+#define _RLIMIT_MAX (RLIMIT_RTTIME+1 > RLIMIT_NLIMITS ? RLIMIT_RTTIME+1 : RLIMIT_NLIMITS)
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <sched.h>
+
+#ifndef CLONE_NEWCGROUP
+#define CLONE_NEWCGROUP 0x02000000
+#endif
+
+/* Not exposed yet. Defined at include/linux/sched.h */
+#ifndef PF_KTHREAD
+#define PF_KTHREAD 0x00200000
+#endif
+
+/* The maximum thread/process name length including trailing NUL byte. This mimics the kernel definition of the same
+ * name, which we need in userspace at various places but is not defined in userspace currently, neither under this
+ * name nor any other. */
+/* Not exposed yet. Defined at include/linux/sched.h */
+#ifndef TASK_COMM_LEN
+#define TASK_COMM_LEN 16
+#endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <sys/socket.h>
+
+#if HAVE_LINUX_VM_SOCKETS_H
+#include <linux/vm_sockets.h>
+#else
+#define VMADDR_CID_ANY -1U
+struct sockaddr_vm {
+ unsigned short svm_family;
+ unsigned short svm_reserved1;
+ unsigned int svm_port;
+ unsigned int svm_cid;
+ unsigned char svm_zero[sizeof(struct sockaddr) -
+ sizeof(unsigned short) -
+ sizeof(unsigned short) -
+ sizeof(unsigned int) -
+ sizeof(unsigned int)];
+};
+#endif /* !HAVE_LINUX_VM_SOCKETS_H */
+
+#ifndef AF_VSOCK
+#define AF_VSOCK 40
+#endif
+
+#ifndef SO_REUSEPORT
+#define SO_REUSEPORT 15
+#endif
+
+#ifndef SO_PEERGROUPS
+#define SO_PEERGROUPS 59
+#endif
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+#ifndef SOL_ALG
+#define SOL_ALG 279
+#endif
+
+/* Not exposed yet. Defined in include/linux/socket.h. */
+#ifndef SOL_SCTP
+#define SOL_SCTP 132
+#endif
+
+/* Not exposed yet. Defined in include/linux/socket.h */
+#ifndef SCM_SECURITY
+#define SCM_SECURITY 0x03
+#endif
+
+/* netinet/in.h */
+#ifndef IP_FREEBIND
+#define IP_FREEBIND 15
+#endif
+
+#ifndef IP_TRANSPARENT
+#define IP_TRANSPARENT 19
+#endif
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
#if !HAVE_STRUCT_STATX
struct statx_timestamp {
- int64_t tv_sec;
- uint32_t tv_nsec;
- uint32_t __reserved;
+ __s64 tv_sec;
+ __u32 tv_nsec;
+ __s32 __reserved;
};
struct statx {
- uint32_t stx_mask;
- uint32_t stx_blksize;
- uint64_t stx_attributes;
- uint32_t stx_nlink;
- uint32_t stx_uid;
- uint32_t stx_gid;
- uint16_t stx_mode;
- uint16_t __spare0[1];
- uint64_t stx_ino;
- uint64_t stx_size;
- uint64_t stx_blocks;
- uint64_t stx_attributes_mask;
+ __u32 stx_mask;
+ __u32 stx_blksize;
+ __u64 stx_attributes;
+ __u32 stx_nlink;
+ __u32 stx_uid;
+ __u32 stx_gid;
+ __u16 stx_mode;
+ __u16 __spare0[1];
+ __u64 stx_ino;
+ __u64 stx_size;
+ __u64 stx_blocks;
+ __u64 stx_attributes_mask;
struct statx_timestamp stx_atime;
struct statx_timestamp stx_btime;
struct statx_timestamp stx_ctime;
struct statx_timestamp stx_mtime;
- uint32_t stx_rdev_major;
- uint32_t stx_rdev_minor;
- uint32_t stx_dev_major;
- uint32_t stx_dev_minor;
- uint64_t __spare2[14];
+ __u32 stx_rdev_major;
+ __u32 stx_rdev_minor;
+ __u32 stx_dev_major;
+ __u32 stx_dev_minor;
+ __u64 __spare2[14];
};
#endif
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <stdlib.h>
+
+/* stdlib.h */
+#if !HAVE_SECURE_GETENV
+# if HAVE___SECURE_GETENV
+# define secure_getenv __secure_getenv
+# else
+# error "neither secure_getenv nor __secure_getenv are available"
+# endif
+#endif
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef ARCH_MIPS
+#include <asm/sgidefs.h>
+#endif
#include "missing_keyctl.h"
#include "missing_stat.h"
+/* linux/kcmp.h */
+#ifndef KCMP_FILE /* 3f4994cfc15f38a3159c6e3a4b3ab2e1481a6b02 (3.19) */
+#define KCMP_FILE 0
+#endif
+
#if !HAVE_PIVOT_ROOT
static inline int missing_pivot_root(const char *new_root, const char *put_old) {
return syscall(__NR_pivot_root, new_root, put_old);
/* ======================================================================= */
#if !HAVE_KEYCTL
-static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
+static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) {
# ifdef __NR_keyctl
return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
# else
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <sys/timerfd.h>
+
+#ifndef TFD_TIMER_CANCEL_ON_SET
+#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
+#endif
#include <errno.h>
#include <inttypes.h>
+#include <linux/oom.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include "missing.h"
#include "process-util.h"
#include "raw-clone.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "stat-util.h"
#include "string-table.h"
}
}
+ if (flags & FORK_RLIMIT_NOFILE_SAFE) {
+ r = rlimit_nofile_safe();
+ if (r < 0) {
+ log_full_errno(prio, r, "Failed to lower RLIMIT_NOFILE's soft limit to 1K: %m");
+ _exit(EXIT_FAILURE);
+ }
+ }
+
if (ret_pid)
*ret_pid = getpid_cached();
safe_close_above_stdio(fd);
}
+ (void) rlimit_nofile_safe();
+
/* Count arguments */
va_start(ap, path);
for (n = 0; va_arg(ap, char*); n++)
int must_be_root(void);
typedef enum ForkFlags {
- FORK_RESET_SIGNALS = 1 << 0,
- FORK_CLOSE_ALL_FDS = 1 << 1,
- FORK_DEATHSIG = 1 << 2,
- FORK_NULL_STDIO = 1 << 3,
- FORK_REOPEN_LOG = 1 << 4,
- FORK_LOG = 1 << 5,
- FORK_WAIT = 1 << 6,
- FORK_NEW_MOUNTNS = 1 << 7,
- FORK_MOUNTNS_SLAVE = 1 << 8,
+ FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
+ FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
+ FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child */
+ FORK_NULL_STDIO = 1 << 3, /* Connect 0,1,2 to /dev/null */
+ FORK_REOPEN_LOG = 1 << 4, /* Reopen log connection */
+ FORK_LOG = 1 << 5, /* Log above LOG_DEBUG log level about failures */
+ FORK_WAIT = 1 << 6, /* Wait until child exited */
+ FORK_NEW_MOUNTNS = 1 << 7, /* Run child in its own mount namespace */
+ FORK_MOUNTNS_SLAVE = 1 << 8, /* Make child's mount namespace MS_SLAVE */
+ FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
} ForkFlags;
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
-#include <linux/random.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
return 0;
}
+
+int rlimit_nofile_safe(void) {
+ struct rlimit rl;
+
+ /* Resets RLIMIT_NOFILE's soft limit FD_SETSIZE (i.e. 1024), for compatibility with software still using
+ * select() */
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
+ return log_debug_errno(errno, "Failed to query RLIMIT_NOFILE: %m");
+
+ if (rl.rlim_cur <= FD_SETSIZE)
+ return 0;
+
+ rl.rlim_cur = FD_SETSIZE;
+ if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
+ return log_debug_errno(errno, "Failed to lower RLIMIT_NOFILE's soft limit to " RLIM_FMT ": %m", rl.rlim_cur);
+
+ return 1;
+}
#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
int rlimit_nofile_bump(int limit);
+int rlimit_nofile_safe(void);
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include <inttypes.h>
+#include <linux/netlink.h>
+#include <linux/if_infiniband.h>
+#include <linux/if_packet.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
-#include <linux/netlink.h>
-#include <linux/if_infiniband.h>
-#include <linux/if_packet.h>
#include "macro.h"
-#include "missing.h"
-#include "util.h"
+#include "missing_socket.h"
+#include "sparse-endian.h"
union sockaddr_union {
/* The minimal, abstract version */
#include "io-util.h"
#include "log.h"
#include "macro.h"
-#include "missing.h"
+#include "missing_timerfd.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "dbus-automount.h"
+#include "dbus-unit.h"
#include "fd-util.h"
#include "format-util.h"
#include "io-util.h"
AutomountState old_state;
assert(a);
+ if (a->state != state)
+ bus_unit_send_pending_change_signal(UNIT(a), false);
+
old_state = a->state;
a->state = state;
#include "bpf-program.h"
#include "fd-util.h"
#include "ip-address-access.h"
+#include "missing_syscall.h"
#include "unit.h"
enum {
#include "alloc-util.h"
#include "dbus-job.h"
+#include "dbus-unit.h"
#include "dbus.h"
#include "job.h"
#include "log.h"
assert(j);
+ /* Make sure that any change signal on the unit is reflected before we send out the change signal on the job */
+ bus_unit_send_pending_change_signal(j->unit, true);
+
if (j->in_dbus_queue) {
LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
j->in_dbus_queue = false;
j->sent_dbus_new_signal = true;
}
+void bus_job_send_pending_change_signal(Job *j, bool including_new) {
+ assert(j);
+
+ if (!j->in_dbus_queue)
+ return;
+
+ if (!j->sent_dbus_new_signal && !including_new)
+ return;
+
+ if (MANAGER_IS_RELOADING(j->unit->manager))
+ return;
+
+ bus_job_send_change_signal(j);
+}
+
static int send_removed_signal(sd_bus *bus, void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_free_ char *p = NULL;
if (!j->sent_dbus_new_signal)
bus_job_send_change_signal(j);
+ /* Make sure that any change signal on the unit is reflected before we send out the change signal on the job */
+ bus_unit_send_pending_change_signal(j->unit, true);
+
r = bus_foreach_bus(j->manager, j->bus_track, send_removed_signal, j);
if (r < 0)
log_debug_errno(r, "Failed to send job remove signal for %u: %m", j->id);
int bus_job_method_get_waiting_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error);
void bus_job_send_change_signal(Job *j);
+void bus_job_send_pending_change_signal(Job *j, bool including_new);
void bus_job_send_removed_signal(Job *j);
int bus_job_coldplug_bus_track(Job *j);
SD_BUS_PROPERTY("AssertResult", "b", bus_property_get_bool, offsetof(Unit, assert_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_PROPERTY_DUAL_TIMESTAMP("ConditionTimestamp", offsetof(Unit, condition_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_PROPERTY_DUAL_TIMESTAMP("AssertTimestamp", offsetof(Unit, assert_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, offsetof(Unit, conditions), 0),
- SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0),
+ SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, offsetof(Unit, conditions), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+ SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Perpetual", "b", bus_property_get_bool, offsetof(Unit, perpetual), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SuccessAction", "s", property_get_emergency_action, offsetof(Unit, success_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SuccessActionExitStatus", "i", bus_property_get_int, offsetof(Unit, success_action_exit_status), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), 0),
- SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), 0),
+ SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Refs", "as", property_get_refs, 0, 0),
SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
u->sent_dbus_new_signal = true;
}
+void bus_unit_send_pending_change_signal(Unit *u, bool including_new) {
+
+ /* Sends out any pending change signals, but only if they really are pending. This call is used when we are
+ * about to change state in order to force out a PropertiesChanged signal beforehand if there was one pending
+ * so that clients can follow the full state transition */
+
+ if (!u->in_dbus_queue) /* If not enqueued, don't bother */
+ return;
+
+ if (!u->sent_dbus_new_signal && !including_new) /* If the unit was never announced, don't bother, it's fine if
+ * the unit appears in the new state right-away (except if the
+ * caller explicitly asked us to send it anyway) */
+ return;
+
+ if (MANAGER_IS_RELOADING(u->manager)) /* Don't generate unnecessary PropertiesChanged signals for the same unit
+ * when we are reloading. */
+ return;
+
+ bus_unit_send_change_signal(u);
+}
+
static int send_removed_signal(sd_bus *bus, void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_free_ char *p = NULL;
if (!path)
return -ENOMEM;
+ /* Before we send the method reply, force out the announcement JobNew for this job */
+ bus_job_send_pending_change_signal(j, true);
+
return sd_bus_reply_method_return(message, "o", path);
}
extern const sd_bus_vtable bus_unit_cgroup_vtable[];
void bus_unit_send_change_signal(Unit *u);
+void bus_unit_send_pending_change_signal(Unit *u, bool including_new);
void bus_unit_send_removed_signal(Unit *u);
int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error);
#include "alloc-util.h"
#include "bus-error.h"
#include "dbus-device.h"
+#include "dbus-unit.h"
#include "device-private.h"
#include "device-util.h"
#include "device.h"
DeviceState old_state;
assert(d);
+ if (d->state != state)
+ bus_unit_send_pending_change_signal(UNIT(d), false);
+
old_state = d->state;
d->state = state;
#include "cgroup-util.h"
#include "fdset.h"
#include "list.h"
-#include "missing.h"
+#include "missing_resource.h"
#include "namespace.h"
#include "nsflags.h"
job_add_to_gc_queue(j);
+ job_add_to_dbus_queue(j); /* announce this job to clients */
+ unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
+
return j;
}
else if (pid == 0) {
(void) setsid();
(void) make_console_stdio();
+ (void) rlimit_nofile_safe();
(void) execle("/bin/sh", "/bin/sh", NULL, environ);
log_emergency_errno(errno, "execle() failed: %m");
/* Reenable any blocked signals, especially important if we switch from initial ramdisk to init=... */
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
+ (void) rlimit_nofile_safe();
if (switch_root_init) {
args[0] = switch_root_init;
#include "alloc-util.h"
#include "dbus-mount.h"
+#include "dbus-unit.h"
#include "device.h"
#include "escape.h"
#include "exit-status.h"
MountState old_state;
assert(m);
+ if (m->state != state)
+ bus_unit_send_pending_change_signal(UNIT(m), false);
+
old_state = m->state;
m->state = state;
#include "bus-error.h"
#include "bus-util.h"
#include "dbus-path.h"
+#include "dbus-unit.h"
#include "fd-util.h"
#include "fs-util.h"
#include "glob-util.h"
PathState old_state;
assert(p);
+ if (p->state != state)
+ bus_unit_send_pending_change_signal(UNIT(p), false);
+
old_state = p->state;
p->state = state;
#include "alloc-util.h"
#include "dbus-scope.h"
+#include "dbus-unit.h"
#include "load-dropin.h"
#include "log.h"
#include "scope.h"
ScopeState old_state;
assert(s);
+ if (s->state != state)
+ bus_unit_send_pending_change_signal(UNIT(s), false);
+
old_state = s->state;
s->state = state;
#include "bus-kernel.h"
#include "bus-util.h"
#include "dbus-service.h"
+#include "dbus-unit.h"
#include "def.h"
#include "env-util.h"
#include "escape.h"
assert(s);
+ if (s->state != state)
+ bus_unit_send_pending_change_signal(UNIT(s), false);
+
table = s->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table;
old_state = s->state;
#include "parse-util.h"
#include "process-util.h"
#include "reboot-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "switch-root.h"
arguments[2] = NULL;
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL);
+ (void) rlimit_nofile_safe();
+
if (can_initrd) {
r = switch_root_initramfs();
if (r >= 0) {
argv[0] = (char*) "/shutdown";
- setsid();
- make_console_stdio();
+ (void) setsid();
+ (void) make_console_stdio();
log_info("Successfully changed into root pivot.\n"
"Returning to initrd...");
#include "alloc-util.h"
#include "dbus-slice.h"
+#include "dbus-unit.h"
#include "log.h"
#include "serialize.h"
#include "slice.h"
SliceState old_state;
assert(t);
+ if (t->state != state)
+ bus_unit_send_pending_change_signal(UNIT(t), false);
+
old_state = t->state;
t->state = state;
#include "bus-util.h"
#include "copy.h"
#include "dbus-socket.h"
+#include "dbus-unit.h"
#include "def.h"
#include "exit-status.h"
#include "fd-util.h"
SocketState old_state;
assert(s);
+ if (s->state != state)
+ bus_unit_send_pending_change_signal(UNIT(s), false);
+
old_state = s->state;
s->state = state;
#include "alloc-util.h"
#include "dbus-swap.h"
+#include "dbus-unit.h"
#include "device-private.h"
#include "device-util.h"
#include "device.h"
assert(s);
+ if (s->state != state)
+ bus_unit_send_pending_change_signal(UNIT(s), false);
+
old_state = s->state;
s->state = state;
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "dbus-target.h"
+#include "dbus-unit.h"
#include "log.h"
#include "serialize.h"
#include "special.h"
TargetState old_state;
assert(t);
+ if (t->state != state)
+ bus_unit_send_pending_change_signal(UNIT(t), false);
+
old_state = t->state;
t->state = state;
#include "bus-error.h"
#include "bus-util.h"
#include "dbus-timer.h"
+#include "dbus-unit.h"
#include "fs-util.h"
#include "parse-util.h"
#include "random-util.h"
TimerState old_state;
assert(t);
+ if (t->state != state)
+ bus_unit_send_pending_change_signal(UNIT(t), false);
+
old_state = t->state;
t->state = state;
dual_timestamp_get(&u->condition_timestamp);
u->condition_result = unit_condition_test_list(u, u->conditions, condition_type_to_string);
+ unit_add_to_dbus_queue(u);
+
return u->condition_result;
}
dual_timestamp_get(&u->assert_timestamp);
u->assert_result = unit_condition_test_list(u, u->asserts, assert_type_to_string);
+ unit_add_to_dbus_queue(u);
+
return u->assert_result;
}
m = u->manager;
+ /* Let's enqueue the change signal early. In case this unit has a job associated we want that this unit is in
+ * the bus queue, so that any job change signal queued will force out the unit change signal first. */
+ unit_add_to_dbus_queue(u);
+
/* Update timestamps for state changes */
if (!MANAGER_IS_RELOADING(m)) {
dual_timestamp_get(&u->state_change_timestamp);
}
}
- unit_add_to_dbus_queue(u);
unit_add_to_gc_queue(u);
}
r = unit_ref_uid_gid(u, uid, gid);
if (r > 0)
- bus_unit_send_change_signal(u);
+ unit_add_to_dbus_queue(u);
}
int unit_set_invocation_id(Unit *u, sd_id128_t id) {
if (r < 0)
return log_unit_error_errno(u, r, "Failed to set invocation ID for unit: %m");
+ unit_add_to_dbus_queue(u);
return 0;
}
fork_name = strjoina("(", arg_debugger, ")");
- r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid);
+ r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
goto finish;
if (r == 0) {
fflush(stdout);
- r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid);
+ r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
#include "path-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "special.h"
cmdline[i++] = device;
cmdline[i++] = NULL;
+ (void) rlimit_nofile_safe();
+
execv(cmdline[0], (char**) cmdline);
_exit(FSCK_OPERATIONAL_ERROR);
}
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include <netinet/icmp6.h>
#include <arpa/inet.h>
+#include <netinet/icmp6.h>
+#include <unistd.h>
#include "alloc-util.h"
#include "icmp6-util.h"
#include "process-util.h"
#include "pull-common.h"
#include "pull-job.h"
+#include "rlimit-util.h"
#include "rm-rf.h"
#include "signal-util.h"
#include "siphash24.h"
_exit(EXIT_FAILURE);
}
+ (void) rlimit_nofile_safe();
+
cmd[k++] = strjoina("--homedir=", gpg_home);
/* We add the user keyring only to the command line
_exit(EXIT_FAILURE);
}
+ (void) rlimit_nofile_safe();
+
execvp(child, argv);
log_error_errno(errno, "Failed to exec child %s: %m", child);
_exit(EXIT_FAILURE);
#include <arpa/inet.h>
#include <linux/sockios.h>
+#include <sys/ioctl.h>
#include "sd-lldp.h"
#include "macro.h"
#include "socket-util.h"
#include "tests.h"
+#include "util.h"
#include "virt.h"
static struct ether_addr mac_addr = {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_unique = NULL, *reply = NULL;
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
- const char *unique = NULL;
+ const char *unique;
pid_t pid = 0;
int r;
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
- /* Only query the owner if the caller wants to know it or if
- * the caller just wants to check whether a name exists */
- if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
+ /* If the name is unique anyway, we can use it directly */
+ unique = name[0] == ':' ? name : NULL;
+
+ /* Only query the owner if the caller wants to know it and the name is not unique anyway, or if the caller just
+ * wants to check whether a name exists */
+ if ((FLAGS_SET(mask, SD_BUS_CREDS_UNIQUE_NAME) && !unique) || mask == 0) {
r = sd_bus_call_method(
bus,
"org.freedesktop.DBus",
if (mask != 0) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
bool need_pid, need_uid, need_selinux, need_separate_calls;
+
c = bus_creds_new();
if (!c)
return -ENOMEM;
NULL,
&reply,
"s",
- unique ? unique : name);
+ unique ?: name);
if (r < 0)
return r;
&error,
&reply,
"s",
- unique ? unique : name);
+ unique ?: name);
if (r < 0) {
if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
return r;
if (r < 0)
return r;
- c->label = strndup(p, sz);
+ c->label = memdup_suffix0(p, sz);
if (!c->label)
return -ENOMEM;
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include <sys/time.h>
+
#include "alloc-util.h"
#include "bus-dump.h"
#include "bus-internal.h"
#include "bus-slot.h"
#include "bus-type.h"
#include "bus-util.h"
+#include "missing_capability.h"
#include "set.h"
#include "string-util.h"
#include "strv.h"
#include "missing.h"
#include "path-util.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "selinux-util.h"
#include "signal-util.h"
#include "stdio-util.h"
if (rearrange_stdio(s[1], s[1], STDERR_FILENO) < 0)
_exit(EXIT_FAILURE);
+ (void) rlimit_nofile_safe();
+
if (b->exec_argv)
execvp(b->exec_path, b->exec_argv);
else {
#include "bus-util.h"
#include "def.h"
#include "fd-util.h"
+#include "missing_resource.h"
#include "time-util.h"
#include "util.h"
#include <ctype.h>
#include <net/if.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
#include "sd-device.h"
};
static const struct NLType rtnl_prot_info_bridge_port_types[] = {
- [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 },
- [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 },
- [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_FAST_LEAVE] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_PROXYARP] = { .type = NETLINK_TYPE_U8 },
- [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_FAST_LEAVE] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_PROXYARP] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_ROOT_ID] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_BRIDGE_ID] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_DESIGNATED_PORT] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRPORT_DESIGNATED_COST] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRPORT_ID] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRPORT_NO] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_CONFIG_PENDING] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_MESSAGE_AGE_TIMER] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BRPORT_FORWARD_DELAY_TIMER] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BRPORT_HOLD_TIMER] = { .type = NETLINK_TYPE_U64 },
+ [IFLA_BRPORT_FLUSH] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_PAD] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_MCAST_FLOOD] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_BCAST_FLOOD] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_ISOLATED] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_BRPORT_BACKUP_PORT] = { .type = NETLINK_TYPE_U32 },
};
static const NLTypeSystem rtnl_prot_info_type_systems[] = {
return 0;
}
+int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, unsigned flags) {
+ struct rtmsg *routing_policy_rule;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
+
+ routing_policy_rule = NLMSG_DATA(m->hdr);
+ routing_policy_rule->rtm_flags |= flags;
+
+ return 0;
+}
+
+int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, unsigned *flags) {
+ struct rtmsg *routing_policy_rule;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
+
+ routing_policy_rule = NLMSG_DATA(m->hdr);
+ *flags = routing_policy_rule->rtm_flags;
+
+ return 0;
+}
+
int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type) {
struct rtmsg *routing_policy_rule;
#include "macro.h"
#include "socket-util.h"
#include "string-util.h"
+#include "time-util.h"
#define TEST_TIMEOUT_USEC (20*USEC_PER_SEC)
if (fd < 0)
return log_error_errno(fd, "Failed to inhibit: %s", bus_error_message(&error, fd));
- r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid);
+ r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
#include <fcntl.h>
#include <linux/input.h>
#include <string.h>
+#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/types.h>
+/* Old drm.h may needs to be included after stdint.h and sys/types.h */
+#include <drm/drm.h>
+
#include "sd-device.h"
#include "alloc-util.h"
#include "io-util.h"
#include "loop-util.h"
#include "machine-image.h"
+#include "missing_capability.h"
#include "mount-util.h"
#include "process-util.h"
#include "raw-clone.h"
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
- r = safe_fork("(imgclone)", FORK_RESET_SIGNALS, &child);
+ r = safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
#include "local-addresses.h"
#include "machine-dbus.h"
#include "machine.h"
+#include "missing_capability.h"
#include "mkdir.h"
#include "os-util.h"
#include "path-util.h"
#include "machine-image.h"
#include "machine-pool.h"
#include "machined.h"
+#include "missing_capability.h"
#include "path-util.h"
#include "process-util.h"
#include "stdio-util.h"
#endif
#include "in-addr-util.h"
-#include "missing.h"
+#include "missing_fou.h"
#include "netdev/netdev.h"
typedef enum FooOverUDPEncapType {
#include <linux/if_link.h>
-#include "missing.h"
+#include "missing_if_link.h"
#include "netdev/netdev.h"
typedef enum IPVlanMode {
Tunnel.IPv6RapidDeploymentPrefix, config_parse_6rd_prefix, 0, 0
Tunnel.ERSPANIndex, config_parse_uint32, 0, offsetof(Tunnel, erspan_index)
Tunnel.SerializeTunneledPackets, config_parse_tristate, 0, offsetof(Tunnel, erspan_sequence)
+Tunnel.ISATAP, config_parse_tristate, 0, offsetof(Tunnel, isatap)
FooOverUDP.Protocol, config_parse_uint8, 0, offsetof(FouTunnel, fou_protocol)
FooOverUDP.Encapsulation, config_parse_fou_encap_type, 0, offsetof(FouTunnel, fou_encap_type)
FooOverUDP.Port, config_parse_ip_port, 0, offsetof(FouTunnel, port)
r = sd_netlink_message_append_in6_addr(m, IFLA_IPTUN_6RD_PREFIX, &t->sixrd_prefix);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_6RD_PREFIX attribute: %m");
+
/* u16 is deliberate here, even though we're passing a netmask that can never be >128. The kernel is
* expecting to receive the prefixlen as a u16.
*/
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_6RD_PREFIXLEN attribute: %m");
}
+ if (t->isatap >= 0) {
+ uint16_t flags = 0;
+
+ SET_FLAG(flags, SIT_ISATAP, t->isatap);
+
+ r = sd_netlink_message_append_u16(m, IFLA_IPTUN_FLAGS, flags);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
+ }
+
return r;
}
assert(t);
t->pmtudisc = true;
+ t->isatap = -1;
}
static void vti_init(NetDev *n) {
int ipv6_flowlabel;
int allow_localremote;
int erspan_sequence;
+ int isatap;
unsigned ttl;
unsigned tos;
#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
+#include "missing_network.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "networkd-ipv6-proxy-ndp.h"
r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
+ }
+ if (link->network->multicast_to_unicast >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m");
}
if (link->network->cost != 0) {
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
}
+
if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) {
r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority);
if (r < 0)
#include "env-file.h"
#include "fd-util.h"
#include "hostname-util.h"
+#include "missing_network.h"
#include "networkd-lldp-tx.h"
#include "networkd-manager.h"
#include "parse-util.h"
RoutingPolicyRule.IPProtocol, config_parse_routing_policy_rule_ip_protocol, 0, 0
RoutingPolicyRule.SourcePort, config_parse_routing_policy_rule_port_range, 0, 0
RoutingPolicyRule.DestinationPort, config_parse_routing_policy_rule_port_range, 0, 0
+RoutingPolicyRule.InvertRule, config_parse_routing_policy_rule_invert, 0, 0
Route.Gateway, config_parse_gateway, 0, 0
Route.Destination, config_parse_destination, 0, 0
Route.Source, config_parse_destination, 0, 0
Bridge.FastLeave, config_parse_tristate, 0, offsetof(Network, fast_leave)
Bridge.AllowPortToBeRoot, config_parse_tristate, 0, offsetof(Network, allow_port_to_be_root)
Bridge.UnicastFlood, config_parse_tristate, 0, offsetof(Network, unicast_flood)
+Bridge.MulticastToUnicast, config_parse_tristate, 0, offsetof(Network, multicast_to_unicast)
Bridge.Priority, config_parse_bridge_port_priority, 0, offsetof(Network, priority)
BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0
BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0
.fast_leave = -1,
.allow_port_to_be_root = -1,
.unicast_flood = -1,
+ .multicast_to_unicast = -1,
.priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
.lldp_mode = LLDP_MODE_ROUTERS_ONLY,
int fast_leave;
int allow_port_to_be_root;
int unicast_flood;
+ int multicast_to_unicast;
uint32_t cost;
uint16_t priority;
return log_error_errno(r, "Could not append FRA_DPORT_RANGE attribute: %m");
}
+ if (rule->invert_rule) {
+ r = sd_rtnl_message_routing_policy_rule_set_flags(m, FIB_RULE_INVERT);
+ if (r < 0)
+ return log_error_errno(r, "Could not append FIB_RULE_INVERT attribute: %m");
+ }
+
rule->link = link;
r = netlink_call_async(link->manager->rtnl, NULL, m,
return 0;
}
+int config_parse_routing_policy_rule_invert(
+ 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_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ Network *network = userdata;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = routing_policy_rule_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule invert, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ n->invert_rule = r;
+
+ n = NULL;
+
+ return 0;
+}
+
static int routing_policy_rule_read_full_file(const char *state_file, char **ret) {
_cleanup_free_ char *s = NULL;
size_t size;
Link *link;
NetworkConfigSection *section;
+ bool invert_rule;
+
uint8_t tos;
uint8_t protocol;
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_device);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_port_range);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_ip_protocol);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_invert);
#include "alloc-util.h"
#include "ether-addr-util.h"
#include "lockfile-util.h"
+#include "missing_network.h"
#include "netlink-util.h"
#include "nspawn-network.h"
#include "siphash24.h"
#include "conf-parser.h"
#include "macro.h"
-#include "missing.h"
+#include "missing_resource.h"
#include "nspawn-expose-ports.h"
#include "nspawn-mount.h"
#include "mkdir.h"
#include "nspawn-setuid.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
close_all_fds(NULL, 0);
+ (void) rlimit_nofile_safe();
+
execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env);
execle("/bin/getent", "getent", database, key, NULL, &empty_env);
_exit(EXIT_FAILURE);
#include <errno.h>
#include <getopt.h>
#include <grp.h>
+#include <linux/fs.h>
#include <linux/loop.h>
#include <pwd.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
-#include <sys/mount.h>
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/types.h>
if (access(mkfs, X_OK) != 0)
return log_error_errno(errno, "%s is not executable: %m", mkfs);
- r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
#include "fd-util.h"
#include "io-util.h"
#include "machine-image.h"
+#include "missing_capability.h"
#include "portable.h"
#include "portabled-bus.h"
#include "portabled-image-bus.h"
#include "fileio.h"
#include "io-util.h"
#include "machine-image.h"
+#include "missing_capability.h"
#include "portable.h"
#include "portabled-bus.h"
#include "portabled-image-bus.h"
return 0;
}
- r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
+ r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_WAIT|FORK_LOG, NULL);
if (r < 0)
return r;
if (r == 0) {
log_debug("Remounting %s", me->mnt_dir);
- r = safe_fork("(remount)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork("(remount)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
#include "gcrypt-util.h"
#include "in-addr-util.h"
#include "main-func.h"
-#include "missing.h"
+#include "missing_network.h"
#include "netlink-util.h"
#include "pager.h"
#include "parse-util.h"
#include "bus-common-errors.h"
#include "bus-util.h"
#include "dns-domain.h"
+#include "missing_capability.h"
#include "resolved-bus.h"
#include "resolved-def.h"
#include "resolved-dns-synthesize.h"
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "fd-util.h"
+#include "missing_network.h"
#include "resolved-dns-stub.h"
#include "socket-util.h"
#include "alloc-util.h"
#include "hostname-util.h"
#include "local-addresses.h"
+#include "missing_network.h"
#include "resolved-dns-synthesize.h"
int dns_synthesize_ifindex(int ifindex) {
#include "alloc-util.h"
#include "bus-util.h"
+#include "missing_capability.h"
#include "resolved-dnssd.h"
#include "resolved-dnssd-bus.h"
#include "resolved-link.h"
#include "fileio.h"
#include "hostname-util.h"
#include "io-util.h"
+#include "missing_network.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "ordered-set.h"
f = fopen("/etc/hosts", "re");
if (!f) {
- assert_se(errno == -ENOENT);
+ assert_se(errno == ENOENT);
return;
}
#include "ip-protocol-list.h"
#include "list.h"
#include "locale-util.h"
+#include "missing_fs.h"
#include "mountpoint-util.h"
#include "nsflags.h"
#include "parse-util.h"
#include "fs-util.h"
#include "log.h"
#include "macro.h"
+#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "string-util.h"
#include "syslog-util.h"
#include "time-util.h"
#include "utf8.h"
-#include "rlimit-util.h"
int config_item_table_lookup(
const void *table,
#include "hashmap.h"
#include "macro.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "serialize.h"
#include "set.h"
#include "signal-util.h"
_exit(EXIT_FAILURE);
}
+ (void) rlimit_nofile_safe();
+
if (!argv) {
_argv[0] = (char*) path;
_argv[1] = NULL;
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
-#include <stddef.h>
-
-#include "macro.h"
-#include "missing.h"
-
typedef struct LockFile {
char *path;
int fd;
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
+#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fs.h>
reboot-util.h
resolve-util.c
resolve-util.h
- rlimit-util.c
- rlimit-util.h
seccomp-util.h
securebits-util.c
securebits-util.h
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include <sched.h>
+#include <errno.h>
#include "alloc-util.h"
#include "extract-word.h"
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
-#include <sched.h>
-
-#include "missing.h"
+#include "missing_sched.h"
/* The combination of all namespace flags defined by the kernel. The right type for this isn't clear. setns() and
* unshare() expect these flags to be passed as (signed) "int", while clone() wants them as "unsigned long". The latter
#include "macro.h"
#include "pager.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
file = fdopen(exe_name_fd, "r");
if (!file) {
safe_close(exe_name_fd);
- return log_debug_errno(errno, "Failed to create FILE object: %m");
+ return log_error_errno(errno, "Failed to create FILE object: %m");
}
/* Find the last line */
r = read_line(file, LONG_LINE_MAX, &t);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to read from socket: %m");
if (r == 0)
break;
return 0;
if (!is_main_thread())
- return -EPERM;
+ return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Pager invoked from wrong thread.");
pager = getenv("SYSTEMD_PAGER");
if (!pager)
if (pager) {
pager_args = strv_split(pager, WHITESPACE);
if (!pager_args)
- return -ENOMEM;
+ return log_oom();
/* If the pager is explicitly turned off, honour it */
if (strv_isempty(pager_args) || strv_equal(pager_args, STRV_MAKE("cat")))
if (flags & PAGER_JUMP_TO_END)
less_opts = strjoina(less_opts, " +G");
- r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pager_pid);
+ r = safe_fork_full("(pager)", fd, 2, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);
if (r < 0)
return r;
if (r == 0) {
/* In the child start the pager */
- (void) dup2(fd[0], STDIN_FILENO);
+ if (dup2(fd[0], STDIN_FILENO) < 0) {
+ log_error_errno(errno, "Failed to duplicate file descriptor to STDIN: %m");
+ _exit(EXIT_FAILURE);
+ }
+
safe_close_pair(fd);
- if (setenv("LESS", less_opts, 1) < 0)
+ if (setenv("LESS", less_opts, 1) < 0) {
+ log_error_errno(errno, "Failed to set environment variable LESS: %m");
_exit(EXIT_FAILURE);
+ }
/* Initialize a good charset for less. This is
* particularly important if we output UTF-8
if (!less_charset && is_locale_utf8())
less_charset = "utf-8";
if (less_charset &&
- setenv("LESSCHARSET", less_charset, 1) < 0)
+ setenv("LESSCHARSET", less_charset, 1) < 0) {
+ log_error_errno(errno, "Failed to set environment variable LESSCHARSET: %m");
_exit(EXIT_FAILURE);
+ }
if (pager_args) {
- if (loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false) < 0)
+ r = loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write pager name to socket: %m");
_exit(EXIT_FAILURE);
+ }
execvp(pager_args[0], pager_args);
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
+ "Failed execute %s, using fallback pagers: %m", pager_args[0]);
}
/* Debian's alternatives command for pagers is
* is similar to this one anyway, but is
* Debian-specific. */
FOREACH_STRING(exe, "pager", "less", "more") {
- if (loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false) < 0)
+ r = loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write pager name to socket: %m");
_exit(EXIT_FAILURE);
+ }
execlp(exe, exe, NULL);
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
+ "Failed execute %s, using next fallback pager: %m", exe);
}
- if (loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in") + 1, false) < 0)
+ r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in") + 1, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write pager name to socket: %m");
_exit(EXIT_FAILURE);
+ }
pager_fallback();
/* not reached */
}
} else
args[1] = desc;
- r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_LOG, &pid);
+ r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
pid_t pid;
int r;
- r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
}
static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ const char *path, *interface, *active_state = NULL, *job_path = NULL;
WaitContext *c = userdata;
- const char *path;
+ bool is_failed;
int r;
+ /* Called whenever we get a PropertiesChanged signal. Checks if ActiveState changed to inactive/failed.
+ *
+ * Signal parameters: (s interface, a{sv} changed_properties, as invalidated_properties) */
+
path = sd_bus_message_get_path(m);
if (!set_contains(c->unit_paths, path))
return 0;
- /* Check if ActiveState changed to inactive/failed */
- /* (s interface, a{sv} changed_properties, as invalidated_properties) */
- r = sd_bus_message_skip(m, "s");
+ r = sd_bus_message_read(m, "s", &interface);
if (r < 0)
return bus_log_parse_error(r);
+ if (!streq(interface, "org.freedesktop.systemd1.Unit")) /* ActiveState is on the Unit interface */
+ return 0;
+
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
if (r < 0)
return bus_log_parse_error(r);
- while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
+ for (;;) {
const char *s;
- r = sd_bus_message_read(m, "s", &s);
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
+ if (r < 0)
+ return bus_log_parse_error(r);
+ if (r == 0) /* end of array */
+ break;
+
+ r = sd_bus_message_read(m, "s", &s); /* Property name */
if (r < 0)
return bus_log_parse_error(r);
if (streq(s, "ActiveState")) {
- bool is_failed;
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "s");
+ r = sd_bus_message_read(m, "v", "s", &active_state);
if (r < 0)
return bus_log_parse_error(r);
- r = sd_bus_message_read(m, "s", &s);
+ if (job_path) /* Found everything we need */
+ break;
+
+ } else if (streq(s, "Job")) {
+ uint32_t job_id;
+
+ r = sd_bus_message_read(m, "v", "(uo)", &job_id, &job_path);
if (r < 0)
return bus_log_parse_error(r);
- is_failed = streq(s, "failed");
- if (streq(s, "inactive") || is_failed) {
- log_debug("%s became %s, dropping from --wait tracking", path, s);
- free(set_remove(c->unit_paths, path));
- c->any_failed = c->any_failed || is_failed;
- } else
- log_debug("ActiveState on %s changed to %s", path, s);
+ /* There's still a job pending for this unit, let's ignore this for now, and return right-away. */
+ if (job_id != 0)
+ return 0;
+
+ if (active_state) /* Found everything we need */
+ break;
- break; /* no need to dissect the rest of the message */
} else {
- /* other property */
- r = sd_bus_message_skip(m, "v");
+ r = sd_bus_message_skip(m, "v"); /* Other property */
if (r < 0)
return bus_log_parse_error(r);
}
+
r = sd_bus_message_exit_container(m);
if (r < 0)
return bus_log_parse_error(r);
}
- if (r < 0)
- return bus_log_parse_error(r);
+
+ /* If this didn't contain the ActiveState property we can't do anything */
+ if (!active_state)
+ return 0;
+
+ is_failed = streq(active_state, "failed");
+ if (streq(active_state, "inactive") || is_failed) {
+ log_debug("%s became %s, dropping from --wait tracking", path, active_state);
+ free(set_remove(c->unit_paths, path));
+ c->any_failed = c->any_failed || is_failed;
+ } else
+ log_debug("ActiveState on %s changed to %s", path, active_state);
if (set_isempty(c->unit_paths))
sd_event_exit(c->event, EXIT_SUCCESS);
if (arg_dry_run)
return 0;
- r = safe_fork("(kexec)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork("(kexec)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
if (!arg_quiet)
log_info("Executing: %s", l);
- j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (j < 0)
return j;
if (j == 0) {
assert(paths);
- r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
+ r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_WAIT, NULL);
if (r < 0)
return r;
if (r == 0) {
/* Hmm, so some other init system is running, we need to forward this request to
* it. For now we simply guess that it is Upstart. */
+ (void) rlimit_nofile_safe();
execv(TELINIT, argv);
return log_error_errno(SYNTHETIC_ERRNO(EIO),
int sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char *len);
int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type);
int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsigned char *type);
+int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, unsigned flags);
+int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, unsigned *flags);
/* genl */
int sd_genl_socket_open(sd_netlink **nl);
#include "io-util.h"
#include "log.h"
#include "macro.h"
+#include "missing_network.h"
#include "process-util.h"
#include "socket-util.h"
#include "string-util.h"
#include <linux/ethtool.h>
#include "conf-parser.h"
-#include "missing.h"
+#include "missing_network.h"
struct link_config;
#include "socket-util.h"
#include "strxcpyx.h"
#include "udev-ctrl.h"
+#include "util.h"
/* wire protocol magic must match */
#define UDEV_CTRL_MAGIC 0xdead1dea
#include "netlink-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "stdio-util.h"
#include "string-util.h"
_exit(EXIT_FAILURE);
(void) close_all_fds(NULL, 0);
+ (void) rlimit_nofile_safe();
execve(argv[0], argv, envp);
_exit(EXIT_FAILURE);
if (r < 0)
return log_error_errno(r, "Worker: Failed to enable receiving of device: %m");
- r = safe_fork(NULL, FORK_DEATHSIG, &pid);
+ r = safe_fork("(worker)", FORK_DEATHSIG, &pid);
if (r < 0) {
event->state = EVENT_QUEUED;
return log_error_errno(r, "Failed to fork() worker: %m");
return 0;
/* child */
- setsid();
+ (void) setsid();
r = set_oom_score_adjust(-1000);
if (r < 0)
log_debug("Executing \"%s\"...", strnull(cmd));
}
- r = safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid);
+ r = safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
log_debug("Executing \"%s\"...", strnull(cmd));
}
- r = safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid);
+ r = safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
if (r < 0)
return r;
if (r == 0) {
IPv6RapidDeploymentPrefix=
ERSPANIndex=
SerializeTunneledPackets=
+ISATAP=
[VXLAN]
UDP6ZeroChecksumRx=
ARPProxy=
HairPin = true
FastLeave = true
UnicastFlood = true
+MulticastToUnicast = true
FastLeave=
Priority=
AllowPortToBeRoot=
+MulticastToUnicast=
[Match]
KernelVersion=
Type=
SourcePort=
DestinationPort=
IPProtocol=
+InvertRule=
[IPv6PrefixDelegation]
RouterPreference=
DNSLifetimeSec=
GroupForwardMask=
GroupPolicyExtension=
HairPin=
+MulticastToUnicast=
HelloTimeSec=
HomeAddress=
Host=
InitialAdvertisedReceiveWindow=
InitialCongestionWindow=
InputKey=
+InvertRule=
KernelCommandLine=
KernelVersion=
Key=
--- /dev/null
+[Match]
+Name=test1
+
+[RoutingPolicyRule]
+TypeOfService=0x08
+Table=7
+From= 192.168.100.18
+Priority=111
+IPProtocol = tcp
+InvertRule=true
--- /dev/null
+[NetDev]
+Name=isataptun99
+Kind=sit
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
+ISATAP=true
HairPin = true
FastLeave = true
UnicastFlood = true
+MulticastToUnicast = true
--- /dev/null
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=isataptun99
# systemd-networkd tests
import os
-import sys
-import unittest
-import subprocess
-import time
import re
import shutil
import signal
import socket
+import subprocess
+import sys
import threading
+import time
+import unittest
from shutil import copytree
network_unit_file_path='/run/systemd/network'
with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
return f.readline().strip()
+ def read_bridge_port_attr(self, bridge, link, attribute):
+
+ path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
+ path_port = 'lower_' + link + '/brport'
+ path = os.path.join(path_bridge, path_port)
+
+ with open(os.path.join(path, attribute)) as f:
+ return f.readline().strip()
+
def link_exits(self, link):
return os.path.exists(os.path.join('/sys/class/net', link))
os.remove(pid_file)
- def search_words_in_file(self, word):
+ def search_words_in_dnsmasq_log(self, words, show_all=False):
if os.path.exists(dnsmasq_log_file):
with open (dnsmasq_log_file) as in_file:
contents = in_file.read()
- print(contents)
- for part in contents.split():
- if word in part:
+ if show_all:
+ print(contents)
+ for line in contents.split('\n'):
+ if words in line:
in_file.close()
- print("%s, %s" % (word, part))
+ print("%s, %s" % (words, line))
return True
return False
else:
subprocess.check_call('systemctl restart systemd-networkd', shell=True)
time.sleep(5)
+ print()
global ip
global port
class NetworkdNetDevTests(unittest.TestCase, Utilities):
- links =['bridge99', 'bond99', 'bond99', 'vlan99', 'test1', 'macvtap99',
- 'macvlan99', 'ipvlan99', 'vxlan99', 'veth99', 'vrf99', 'tun99',
- 'tap99', 'vcan99', 'geneve99', 'dummy98', 'ipiptun99', 'sittun99', '6rdtun99',
- 'gretap99', 'vtitun99', 'vti6tun99','ip6tnl99', 'gretun99', 'ip6gretap99',
- 'wg99', 'dropin-test', 'erspan-test']
-
- units = ['25-bridge.netdev', '25-bond.netdev', '21-vlan.netdev', '11-dummy.netdev', '21-vlan.network',
- '21-macvtap.netdev', 'macvtap.network', '21-macvlan.netdev', 'macvlan.network', 'vxlan.network',
- '25-vxlan.netdev', '25-ipvlan.netdev', 'ipvlan.network', '25-veth.netdev', '25-vrf.netdev',
- '25-tun.netdev', '25-tun.netdev', '25-vcan.netdev', '25-geneve.netdev', '25-ipip-tunnel.netdev',
- '25-ip6tnl-tunnel.netdev', '25-ip6gre-tunnel.netdev', '25-sit-tunnel.netdev', '25-6rd-tunnel.netdev',
- '25-erspan-tunnel.netdev', '25-gre-tunnel.netdev', '25-gretap-tunnel.netdev', '25-vti-tunnel.netdev',
- '25-vti6-tunnel.netdev', '12-dummy.netdev', 'gre.network', 'ipip.network', 'ip6gretap.network',
- 'gretun.network', 'ip6tnl.network', '25-tap.netdev', 'vti6.network', 'vti.network', 'gretap.network',
- 'sit.network', '25-ipip-tunnel-independent.netdev', '25-wireguard.netdev', '6rd.network', '10-dropin-test.netdev']
+ links =[
+ '6rdtun99',
+ 'bond99',
+ 'bridge99',
+ 'dropin-test',
+ 'dummy98',
+ 'erspan-test',
+ 'geneve99',
+ 'gretap99',
+ 'gretun99',
+ 'ip6gretap99',
+ 'ip6tnl99',
+ 'ipiptun99',
+ 'ipvlan99',
+ 'isataptun99',
+ 'macvlan99',
+ 'macvtap99',
+ 'sittun99',
+ 'tap99',
+ 'test1',
+ 'tun99',
+ 'vcan99',
+ 'veth99',
+ 'vlan99',
+ 'vrf99',
+ 'vti6tun99',
+ 'vtitun99',
+ 'vxlan99',
+ 'wg99']
+
+ units = [
+ '10-dropin-test.netdev',
+ '11-dummy.netdev',
+ '12-dummy.netdev',
+ '21-macvlan.netdev',
+ '21-macvtap.netdev',
+ '21-vlan.netdev',
+ '21-vlan.network',
+ '25-6rd-tunnel.netdev',
+ '25-bond.netdev',
+ '25-bridge.netdev',
+ '25-erspan-tunnel.netdev',
+ '25-geneve.netdev',
+ '25-gretap-tunnel.netdev',
+ '25-gre-tunnel.netdev',
+ '25-ip6gre-tunnel.netdev',
+ '25-ip6tnl-tunnel.netdev',
+ '25-ipip-tunnel-independent.netdev',
+ '25-ipip-tunnel.netdev',
+ '25-ipvlan.netdev',
+ '25-isatap-tunnel.netdev',
+ '25-sit-tunnel.netdev',
+ '25-tap.netdev',
+ '25-tun.netdev',
+ '25-vcan.netdev',
+ '25-veth.netdev',
+ '25-vrf.netdev',
+ '25-vti6-tunnel.netdev',
+ '25-vti-tunnel.netdev',
+ '25-vxlan.netdev',
+ '25-wireguard.netdev',
+ '6rd.network',
+ 'gre.network',
+ 'gretap.network',
+ 'gretun.network',
+ 'ip6gretap.network',
+ 'ip6tnl.network',
+ 'ipip.network',
+ 'ipvlan.network',
+ 'isatap.network',
+ 'macvlan.network',
+ 'macvtap.network',
+ 'sit.network',
+ 'vti6.network',
+ 'vti.network',
+ 'vxlan.network']
def setUp(self):
self.link_remove(self.links)
def test_dropin(self):
self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('dropin-test'))
def test_vlan(self):
self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
-
self.start_networkd()
self.assertTrue(self.link_exits('vlan99'))
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
+ print(output)
self.assertTrue(output, 'REORDER_HDR')
self.assertTrue(output, 'LOOSE_BINDING')
self.assertTrue(output, 'GVRP')
def test_macvtap(self):
self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
-
self.start_networkd()
self.assertTrue(self.link_exits('macvtap99'))
def test_macvlan(self):
self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
-
self.start_networkd()
self.assertTrue(self.link_exits('macvlan99'))
@expectedFailureIfModuleIsNotAvailable('ipvlan')
def test_ipvlan(self):
self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
-
self.start_networkd()
self.assertTrue(self.link_exits('ipvlan99'))
def test_veth(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('veth99'))
def test_dummy(self):
self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('test1'))
def test_tun(self):
self.copy_unit_to_networkd_unit_path('25-tun.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('tun99'))
def test_tap(self):
self.copy_unit_to_networkd_unit_path('25-tap.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('tap99'))
@expectedFailureIfModuleIsNotAvailable('vrf')
def test_vrf(self):
self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('vrf99'))
@expectedFailureIfModuleIsNotAvailable('vcan')
def test_vcan(self):
self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('vcan99'))
@expectedFailureIfModuleIsNotAvailable('wireguard')
def test_wireguard(self):
self.copy_unit_to_networkd_unit_path('25-wireguard.netdev')
-
self.start_networkd()
if shutil.which('wg'):
def test_geneve(self):
self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('geneve99'))
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
+ print(output)
self.assertTrue(output, '192.168.22.1')
self.assertTrue(output, '6082')
self.assertTrue(output, 'udpcsum')
self.assertTrue(self.link_exits('dummy98'))
self.assertTrue(self.link_exits('sittun99'))
+ def test_isatap_tunnel(self):
+ self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-isatap-tunnel.netdev', 'isatap.network')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('dummy98'))
+ self.assertTrue(self.link_exits('isataptun99'))
+
+ output = subprocess.check_output(['ip', '-d', 'link', 'show', 'isataptun99']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, "isatap ")
+
def test_6rd_tunnel(self):
self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-6rd-tunnel.netdev', '6rd.network')
self.start_networkd()
def test_tunnel_independent(self):
self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
-
self.start_networkd()
+
self.assertTrue(self.link_exits('ipiptun99'))
def test_vxlan(self):
self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network','11-dummy.netdev')
-
self.start_networkd()
self.assertTrue(self.link_exits('vxlan99'))
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
+ print(output)
self.assertRegex(output, "999")
self.assertRegex(output, '5555')
self.assertRegex(output, 'l2miss')
self.assertRegex(output, 'gbp')
class NetworkdNetWorkTests(unittest.TestCase, Utilities):
- links = ['dummy98', 'test1', 'bond199']
-
- units = ['12-dummy.netdev', 'test-static.network', 'configure-without-carrier.network', '11-dummy.netdev',
- '23-primary-slave.network', '23-test1-bond199.network', '11-dummy.netdev', '23-bond199.network',
- '25-bond-active-backup-slave.netdev', '12-dummy.netdev', '23-active-slave.network',
- 'routing-policy-rule.network', '25-fibrule-port-range.network', '25-address-section.network',
- '25-address-section-miscellaneous.network', '25-route-section.network', '25-route-type.network',
- '25-route-tcp-window-settings.network', '25-route-gateway.network', '25-route-gateway-on-link.network',
- '25-address-link-section.network', '25-ipv6-address-label-section.network', '25-link-section-unmanaged.network',
- '25-sysctl.network', '25-route-reverse-order.network']
+ links = [
+ 'bond199',
+ 'dummy98',
+ 'test1']
+
+ units = [
+ '11-dummy.netdev',
+ '12-dummy.netdev',
+ '23-active-slave.network',
+ '23-bond199.network',
+ '23-primary-slave.network',
+ '23-test1-bond199.network',
+ '25-address-link-section.network',
+ '25-address-section-miscellaneous.network',
+ '25-address-section.network',
+ '25-bond-active-backup-slave.netdev',
+ '25-fibrule-invert.network',
+ '25-fibrule-port-range.network',
+ '25-ipv6-address-label-section.network',
+ '25-link-section-unmanaged.network',
+ '25-route-gateway.network',
+ '25-route-gateway-on-link.network',
+ '25-route-reverse-order.network',
+ '25-route-section.network',
+ '25-route-tcp-window-settings.network',
+ '25-route-type.network',
+ '25-sysctl.network',
+ 'configure-without-carrier.network',
+ 'routing-policy-rule.network',
+ 'test-static.network']
def setUp(self):
self.link_remove(self.links)
self.start_networkd()
self.assertTrue(self.link_exits('dummy98'))
+
output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '192.168.0.15')
self.start_networkd()
self.assertTrue(self.link_exits('test1'))
+
output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '192.168.0.15')
self.assertTrue(self.link_exits('dummy98'))
self.assertTrue(self.link_exits('bond199'))
+
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'active_slave dummy98')
self.assertTrue(self.link_exits('test1'))
self.assertTrue(self.link_exits('bond199'))
+
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'primary test1')
self.start_networkd()
self.assertTrue(self.link_exits('test1'))
+
output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '111')
self.assertRegex(output, 'oif test1')
self.assertRegex(output, 'lookup 7')
+ subprocess.call(['ip', 'rule', 'del', 'table', '7'])
+
def test_routing_policy_rule_port_range(self):
self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
self.start_networkd()
self.assertTrue(self.link_exits('test1'))
+
output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '111')
self.assertRegex(output, 'tcp')
self.assertRegex(output, 'lookup 7')
+ subprocess.call(['ip', 'rule', 'del', 'table', '7'])
+
+ def test_routing_policy_rule_invert(self):
+ self.copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('test1'))
+
+ output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, '111')
+ self.assertRegex(output, 'not.*?from.*?192.168.100.18')
+ self.assertRegex(output, 'tcp')
+ self.assertRegex(output, 'lookup 7')
+
+ subprocess.call(['ip', 'rule', 'del', 'table', '7'])
+
def test_address_preferred_lifetime_zero_ipv6(self):
self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
self.start_networkd()
self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
-class NetworkdNetWorkBrideTests(unittest.TestCase, Utilities):
- links = ['dummy98', 'test1', 'bridge99']
+class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
+ links = [
+ 'bridge99',
+ 'dummy98',
+ 'test1']
- units = ['11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev', '26-bridge-slave-interface-1.network',
- '26-bridge-slave-interface-2.network', 'bridge99.network']
+ units = [
+ '11-dummy.netdev',
+ '12-dummy.netdev',
+ '26-bridge.netdev',
+ '26-bridge-slave-interface-1.network',
+ '26-bridge-slave-interface-2.network',
+ 'bridge99.network']
def setUp(self):
self.link_remove(self.links)
output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
print(output)
- self.assertRegex(output, 'cost 400')
- self.assertRegex(output, 'hairpin on')
- self.assertRegex(output, 'flood on')
- self.assertRegex(output, 'fastleave on')
+ self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
+ self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
+ self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
+ self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
+
+ # CONFIG_BRIDGE_IGMP_SNOOPING=y
+ if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
+ self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
links = ['veth99']
- units = ['23-emit-lldp.network', '24-lldp.network', '25-veth.netdev']
+ units = [
+ '23-emit-lldp.network',
+ '24-lldp.network',
+ '25-veth.netdev']
def setUp(self):
self.link_remove(self.links)
class NetworkdNetworkRATests(unittest.TestCase, Utilities):
links = ['veth99']
- units = ['25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network']
+ units = [
+ '25-veth.netdev',
+ 'ipv6-prefix.network',
+ 'ipv6-prefix-veth.network']
def setUp(self):
self.link_remove(self.links)
self.assertRegex(output, '2002:da8:1:0')
class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
- links = ['veth99', 'dummy98']
-
- units = ['25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network', '12-dummy.netdev', '24-search-domain.network',
- 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network']
+ links = [
+ 'dummy98',
+ 'veth99']
+
+ units = [
+ '12-dummy.netdev',
+ '24-search-domain.network',
+ '25-veth.netdev',
+ 'dhcp-client.network',
+ 'dhcp-client-timezone-router.network',
+ 'dhcp-server.network',
+ 'dhcp-server-timezone-router.network']
def setUp(self):
self.link_remove(self.links)
self.assertTrue(self.link_exits('veth99'))
- time.sleep(5)
-
output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '192.168.5.*')
self.assertRegex(output, 'Europe/Berlin')
class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
- links = ['veth99', 'dummy98']
-
- units = ['25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network',
- 'dhcp-client-ipv4-only-ipv6-disabled.network', 'dhcp-client-ipv4-only.network',
- 'dhcp-client-ipv4-dhcp-settings.network', 'dhcp-client-anonymize.network',
- 'dhcp-client-ipv6-rapid-commit.network', 'dhcp-client-route-table.network',
- 'dhcp-v4-server-veth-peer.network', 'dhcp-client-listen-port.network',
- 'dhcp-client-route-metric.network', 'dhcp-client-critical-connection.network']
+ links = [
+ 'dummy98',
+ 'veth99']
+
+ units = [
+ '25-veth.netdev',
+ 'dhcp-client-anonymize.network',
+ 'dhcp-client-critical-connection.network',
+ 'dhcp-client-ipv4-dhcp-settings.network',
+ 'dhcp-client-ipv4-only-ipv6-disabled.network',
+ 'dhcp-client-ipv4-only.network',
+ 'dhcp-client-ipv6-only.network',
+ 'dhcp-client-ipv6-rapid-commit.network',
+ 'dhcp-client-listen-port.network',
+ 'dhcp-client-route-metric.network',
+ 'dhcp-client-route-table.network',
+ 'dhcp-server-veth-peer.network',
+ 'dhcp-v4-server-veth-peer.network']
def setUp(self):
self.link_remove(self.links)
print(output)
self.assertRegex(output, 'default.*dev veth99 proto dhcp')
- self.search_words_in_file('vendor class: SusantVendorTest')
- self.search_words_in_file('client MAC address: 12:34:56:78:9a:bc')
- self.search_words_in_file('client provides name: test-hostname')
- self.search_words_in_file('26:mtu')
+ self.assertTrue(self.search_words_in_dnsmasq_log('vendor class: SusantVendorTest', True))
+ self.assertTrue(self.search_words_in_dnsmasq_log('DHCPDISCOVER(veth-peer) 12:34:56:78:9a:bc'))
+ self.assertTrue(self.search_words_in_dnsmasq_log('client provides name: test-hostname'))
+ self.assertTrue(self.search_words_in_dnsmasq_log('26:mtu'))
def test_dhcp6_client_settings_rapidcommit_true(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '12:34:56:78:9a:bc')
-
- self.assertTrue(self.search_words_in_file('14:rapid-commit'))
+ self.assertTrue(self.search_words_in_dnsmasq_log('14:rapid-commit', True))
def test_dhcp6_client_settings_rapidcommit_false(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, '12:34:56:78:9a:bc')
-
- self.assertFalse(self.search_words_in_file('14:rapid-commit'))
+ self.assertFalse(self.search_words_in_dnsmasq_log('14:rapid-commit', True))
def test_dhcp_client_settings_anonymize(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
self.assertTrue(self.link_exits('veth99'))
self.start_dnsmasq()
- self.assertFalse(self.search_words_in_file('VendorClassIdentifier=SusantVendorTest'))
- self.assertFalse(self.search_words_in_file('test-hostname'))
- self.assertFalse(self.search_words_in_file('26:mtu'))
+
+ self.assertFalse(self.search_words_in_dnsmasq_log('VendorClassIdentifier=SusantVendorTest', True))
+ self.assertFalse(self.search_words_in_dnsmasq_log('test-hostname'))
+ self.assertFalse(self.search_words_in_dnsmasq_log('26:mtu'))
def test_dhcp_client_listen_port(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
+
dh_server = DHCPServer("dhcp_server")
dh_server.start()
def test_dhcp_route_table_id(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
self.start_networkd()
- self.start_dnsmasq()
self.assertTrue(self.link_exits('veth99'))
+ self.start_dnsmasq()
+
output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
print(output)
-
self.assertRegex(output, 'veth99 proto dhcp')
self.assertRegex(output, '192.168.5.1')
def test_dhcp_route_metric(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
self.start_networkd()
- self.start_dnsmasq()
self.assertTrue(self.link_exits('veth99'))
+ self.start_dnsmasq()
+
output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
print(output)
-
self.assertRegex(output, 'metric 24')
def test_dhcp_route_criticalconnection_true(self):
self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
self.start_networkd()
- self.start_dnsmasq()
self.assertTrue(self.link_exits('veth99'))
+ self.start_dnsmasq()
+
output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
print(output)
-
self.assertRegex(output, '192.168.5.*')
+
# Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
self.stop_dnsmasq(dnsmasq_pid_file)