]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #11056 from poettering/resolved-ifindex
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 6 Dec 2018 18:29:42 +0000 (19:29 +0100)
committerGitHub <noreply@github.com>
Thu, 6 Dec 2018 18:29:42 +0000 (19:29 +0100)
resolved: request incoming ifindex for DNS UDP packets, too

128 files changed:
TODO
man/systemd.netdev.xml
man/systemd.network.xml
src/activate/activate.c
src/basic/fd-util.c
src/basic/macro.h
src/basic/meson.build
src/basic/missing.h
src/basic/missing_audit.h [new file with mode: 0644]
src/basic/missing_fcntl.h [new file with mode: 0644]
src/basic/missing_fs.h [new file with mode: 0644]
src/basic/missing_input.h
src/basic/missing_mman.h [new file with mode: 0644]
src/basic/missing_network.h
src/basic/missing_random.h [new file with mode: 0644]
src/basic/missing_resource.h [new file with mode: 0644]
src/basic/missing_sched.h [new file with mode: 0644]
src/basic/missing_socket.h [new file with mode: 0644]
src/basic/missing_stat.h
src/basic/missing_stdlib.h [new file with mode: 0644]
src/basic/missing_syscall.h
src/basic/missing_timerfd.h [new file with mode: 0644]
src/basic/parse-util.c
src/basic/process-util.c
src/basic/process-util.h
src/basic/random-util.c
src/basic/rlimit-util.c [moved from src/shared/rlimit-util.c with 94% similarity]
src/basic/rlimit-util.h [moved from src/shared/rlimit-util.h with 96% similarity]
src/basic/socket-util.h
src/basic/time-util.c
src/core/automount.c
src/core/bpf-firewall.c
src/core/dbus-job.c
src/core/dbus-job.h
src/core/dbus-unit.c
src/core/dbus-unit.h
src/core/device.c
src/core/execute.h
src/core/job.c
src/core/main.c
src/core/mount.c
src/core/path.c
src/core/scope.c
src/core/service.c
src/core/shutdown.c
src/core/slice.c
src/core/socket.c
src/core/swap.c
src/core/target.c
src/core/timer.c
src/core/unit.c
src/coredump/coredumpctl.c
src/delta/delta.c
src/fsck/fsck.c
src/fuzz/fuzz-ndisc-rs.c
src/import/pull-common.c
src/journal-remote/journal-remote-main.c
src/libsystemd-network/sd-lldp.c
src/libsystemd-network/test-dhcp6-client.c
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/test-bus-benchmark.c
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-netlink/netlink-types.c
src/libsystemd/sd-netlink/rtnl-message.c
src/libsystemd/sd-resolve/test-resolve.c
src/login/inhibit.c
src/login/logind-session-device.c
src/machine/image-dbus.c
src/machine/machine-dbus.c
src/machine/machined-dbus.c
src/network/netdev/fou-tunnel.h
src/network/netdev/ipvlan.h
src/network/netdev/netdev-gperf.gperf
src/network/netdev/tunnel.c
src/network/netdev/tunnel.h
src/network/networkd-link.c
src/network/networkd-lldp-tx.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h
src/nspawn/nspawn-network.c
src/nspawn/nspawn-settings.h
src/nspawn/nspawn-setuid.c
src/nspawn/nspawn.c
src/partition/makefs.c
src/portable/portabled-bus.c
src/portable/portabled-image-bus.c
src/quotacheck/quotacheck.c
src/remount-fs/remount-fs.c
src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-dns-stub.c
src/resolve/resolved-dns-synthesize.c
src/resolve/resolved-dnssd-bus.c
src/resolve/resolved-manager.c
src/resolve/test-resolved-etc-hosts.c
src/shared/bus-unit-util.c
src/shared/conf-parser.c
src/shared/exec-util.c
src/shared/lockfile-util.h
src/shared/machine-image.c
src/shared/meson.build
src/shared/nsflags.c
src/shared/nsflags.h
src/shared/pager.c
src/sulogin-shell/sulogin-shell.c
src/systemctl/systemctl.c
src/systemd/sd-netlink.h
src/test/test-socket-util.c
src/udev/net/ethtool-util.h
src/udev/udev-ctrl.c
src/udev/udev-event.c
src/udev/udevd.c
src/vconsole/vconsole-setup.c
test/fuzz/fuzz-netdev-parser/directives.netdev
test/fuzz/fuzz-network-parser/26-bridge-slave-interface-1.network
test/fuzz/fuzz-network-parser/directives.network
test/fuzz/fuzz-unit-file/directives.service
test/test-network/conf/25-fibrule-invert.network [new file with mode: 0644]
test/test-network/conf/25-isatap-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/26-bridge-slave-interface-1.network
test/test-network/conf/isatap.network [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py

diff --git a/TODO b/TODO
index cafd75a01daa5c3952b7ad0b183062d9be530c4c..3a4eac4b2c0b15abdb54841562cb7f5b8dbd9f4a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -23,8 +23,16 @@ Janitorial Clean-ups:
 
 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.
index f17a6a961905a81aadc794d282e7beba1cbe8d12..67ccc66dd8ed09ffd17378504c23b6140453ece9 100644 (file)
           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>
index 229449c5ac569c843c199737420dc0c3d7e9ce73..f7234537d86e954d4f5275c744997420df3e1da1 100644 (file)
             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>
index 912772d590c974547dc72fd3e3bad7997b0eee8a..9a83bc7f24378e9f0484a2e1007c3892af71c76a 100644 (file)
@@ -249,7 +249,7 @@ static int fork_and_exec_process(const char* child, char** argv, char **env, int
         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) {
index 2fae4da15bcde170de90f97a69cf39455dcbf172..c06f2fac7e80dc8f44996d711a7bae5537ffc9c5 100644 (file)
@@ -114,7 +114,7 @@ FILE* safe_fclose(FILE *f) {
         if (f) {
                 PROTECT_ERRNO;
 
-                assert_se(fclose_nointr(f) != EBADF);
+                assert_se(fclose_nointr(f) != -EBADF);
         }
 
         return NULL;
index 3b7971fe842f987800a2cfd8b1c1a5f41923060d..1971e912db4f497e676af561733f98286397e4ad 100644 (file)
@@ -2,6 +2,7 @@
 #pragma once
 
 #include <assert.h>
+#include <errno.h>
 #include <inttypes.h>
 #include <stdbool.h>
 #include <sys/param.h>
index 153a38f9d050074726c194aa15b528594b496856..78e69feb4df2652bf83082f413fabb2ae3fd849c 100644 (file)
@@ -91,23 +91,33 @@ basic_sources = files('''
         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
@@ -139,6 +149,8 @@ basic_sources = files('''
         refcnt.h
         replace-var.c
         replace-var.h
+        rlimit-util.c
+        rlimit-util.h
         rm-rf.c
         rm-rf.h
         selinux-util.c
index e3ee46bccea3a407dcbe6e363242824dc933cf2c..7e14e0a2a401f6137244c136e0054060838fb580 100644 (file)
 
 /* 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"
diff --git a/src/basic/missing_audit.h b/src/basic/missing_audit.h
new file mode 100644 (file)
index 0000000..b00d537
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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
diff --git a/src/basic/missing_fcntl.h b/src/basic/missing_fcntl.h
new file mode 100644 (file)
index 0000000..5d1c635
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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
diff --git a/src/basic/missing_fs.h b/src/basic/missing_fs.h
new file mode 100644 (file)
index 0000000..48c1af0
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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
index 93cdf9a310beec1b6d0ec3908f671f650733f191..b91ccb6485a88fe28493b13b447bf14d4836eba1 100644 (file)
@@ -2,6 +2,7 @@
 #pragma once
 
 #include <linux/input.h>
+#include <linux/types.h>
 
 /* linux@c7dc65737c9a607d3e6f8478659876074ad129b8 (3.12) */
 #ifndef EVIOCREVOKE
@@ -11,9 +12,9 @@
 /* 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)
diff --git a/src/basic/missing_mman.h b/src/basic/missing_mman.h
new file mode 100644 (file)
index 0000000..7ff12f7
--- /dev/null
@@ -0,0 +1,12 @@
+/* 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
index cba236b64db13d06004c9f50728cdf97489ce394..d9c73c54a96e0f751aca1c7630141bf0346cc6ac 100644 (file)
@@ -3,6 +3,7 @@
 
 #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
diff --git a/src/basic/missing_random.h b/src/basic/missing_random.h
new file mode 100644 (file)
index 0000000..2e76031
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#if USE_SYS_RANDOM_H
+#  include <sys/random.h>
+#else
+#  include <linux/random.h>
+#endif
+
+#ifndef GRND_NONBLOCK
+#define GRND_NONBLOCK 0x0001
+#endif
+
+#ifndef GRND_RANDOM
+#define GRND_RANDOM 0x0002
+#endif
diff --git a/src/basic/missing_resource.h b/src/basic/missing_resource.h
new file mode 100644 (file)
index 0000000..22ba8ab
--- /dev/null
@@ -0,0 +1,11 @@
+/* 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)
diff --git a/src/basic/missing_sched.h b/src/basic/missing_sched.h
new file mode 100644 (file)
index 0000000..baa3913
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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
diff --git a/src/basic/missing_socket.h b/src/basic/missing_socket.h
new file mode 100644 (file)
index 0000000..a5fd457
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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
index 85f98e2690c795aae790e861072d2cca9130ca1d..5116206a2e53cdb265b7facbd21584ff908b7489 100644 (file)
 /* 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
 
diff --git a/src/basic/missing_stdlib.h b/src/basic/missing_stdlib.h
new file mode 100644 (file)
index 0000000..188a8d4
--- /dev/null
@@ -0,0 +1,13 @@
+/* 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
index b009ea5bfa6904b65deedbdb0697a1cc617eab7d..d5d4b26acb3776a188329e6a863a13a7ad759975 100644 (file)
@@ -6,10 +6,20 @@
 #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);
@@ -257,7 +267,7 @@ static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long i
 /* ======================================================================= */
 
 #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
diff --git a/src/basic/missing_timerfd.h b/src/basic/missing_timerfd.h
new file mode 100644 (file)
index 0000000..6b04044
--- /dev/null
@@ -0,0 +1,8 @@
+/* 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
index 5b4e94c13488fef0f70cca5d1c4b6446b4cd7965..87724af693068b624a0f9f0a366404ca3597239c 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <errno.h>
 #include <inttypes.h>
+#include <linux/oom.h>
 #include <locale.h>
 #include <stdio.h>
 #include <stdlib.h>
index 981628504b3fd5edd327d41f4788d375004b2b79..5b700df33a973f42365a476494b6a5aa24d0a4ab 100644 (file)
@@ -35,6 +35,7 @@
 #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"
@@ -1401,6 +1402,14 @@ int safe_fork_full(
                 }
         }
 
+        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();
 
@@ -1512,6 +1521,8 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
                 safe_close_above_stdio(fd);
         }
 
+        (void) rlimit_nofile_safe();
+
         /* Count arguments */
         va_start(ap, path);
         for (n = 0; va_arg(ap, char*); n++)
index af47513fab0f0b16ae210a5d1084de8ea3719337..496e14d3de17667217e455c43471bf9f9dd39b8c 100644 (file)
@@ -142,15 +142,16 @@ void reset_cached_pid(void);
 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);
index 4a36ad51195aa9e1b54f489c63fd939e15b12561..f7decf60b6189a7206577dc44ce650b2b148273e 100644 (file)
@@ -7,7 +7,6 @@
 #include <elf.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <linux/random.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
similarity index 94%
rename from src/shared/rlimit-util.c
rename to src/basic/rlimit-util.c
index c133f84b7e90e24c7dd10149d09188b11beeb371..74b3a023f18ab6c6fa218397a56f8447149bcd91 100644 (file)
@@ -389,3 +389,22 @@ int rlimit_nofile_bump(int limit) {
 
         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;
+}
similarity index 96%
rename from src/shared/rlimit-util.h
rename to src/basic/rlimit-util.h
index 6139af3ff50ff5fec8e5cf56bdbfc2719cd676e4..d4fca2b8556d9b00b3a080c02c11e64737dd8ccb 100644 (file)
@@ -22,3 +22,4 @@ void rlimit_free_all(struct rlimit **rl);
 #define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
 
 int rlimit_nofile_bump(int limit);
+int rlimit_nofile_safe(void);
index 37b1bca81a8e104ffea667f1265867e06a5e61ec..574d2b73f5627e8dc52194a8ac4cbd3996bfbad5 100644 (file)
@@ -1,6 +1,10 @@
 /* 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 */
index 12c1fc71dfcc8c4921b3432c0e3c0ef66fc7e343..557c75debc53ba264c37159fe4020ef11ce3ec30 100644 (file)
@@ -20,7 +20,7 @@
 #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"
index 3d8348e0b7fc0229b90a66ccae87b1b9d5eb4c85..de8010bf2e5d86865cb7fff98033423713959e77 100644 (file)
@@ -16,6 +16,7 @@
 #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"
@@ -237,6 +238,9 @@ static void automount_set_state(Automount *a, AutomountState state) {
         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;
 
index 946c0516e142effb7a2abbffaa3421deb2a31a93..b9a611fd9e25194eeb3c53d9c3341c91a4a53009 100644 (file)
@@ -20,6 +20,7 @@
 #include "bpf-program.h"
 #include "fd-util.h"
 #include "ip-address-access.h"
+#include "missing_syscall.h"
 #include "unit.h"
 
 enum {
index 20d890b36c37685201a28e3ba5e680ade9094101..d11e58b51ddd5cde5a0a23ed8f6842416984634f 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "alloc-util.h"
 #include "dbus-job.h"
+#include "dbus-unit.h"
 #include "dbus.h"
 #include "job.h"
 #include "log.h"
@@ -173,6 +174,9 @@ void bus_job_send_change_signal(Job *j) {
 
         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;
@@ -185,6 +189,21 @@ void bus_job_send_change_signal(Job *j) {
         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;
@@ -222,6 +241,9 @@ void bus_job_send_removed_signal(Job *j) {
         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);
index 3cc60f22ee069199bb545b6b8767c477389929f0..c9f6fc718719861cd6e8fae308843fcb17fc1003 100644 (file)
@@ -12,6 +12,7 @@ int bus_job_method_cancel(sd_bus_message *message, void *job, sd_bus_error *erro
 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);
index 6d9b559d2c7d522ff63f561edb41b66f9fc007b6..968166ee60409dca2970490cbfa2bbfd1c85af3e 100644 (file)
@@ -662,8 +662,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
         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),
@@ -675,8 +675,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
         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),
@@ -1202,6 +1202,27 @@ void bus_unit_send_change_signal(Unit *u) {
         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;
@@ -1300,6 +1321,9 @@ int bus_unit_queue_job(
         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);
 }
 
index 68eb621836b1a77d79e8f46e4d0e2c4f1c44aceb..345345e3ebadea254c0ab0bd1697b40b15fea79c 100644 (file)
@@ -11,6 +11,7 @@ extern const sd_bus_vtable bus_unit_vtable[];
 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);
index 8b6126c4cfe8e95e9b0e4fb06421d6fc8e177e17..5acd9b7a7036de7652f2255de69e92f6f3eb4109 100644 (file)
@@ -6,6 +6,7 @@
 #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"
@@ -115,6 +116,9 @@ static void device_set_state(Device *d, DeviceState state) {
         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;
 
index 16124cf28c41af5dcc5ed127440cd450ccdcc1ae..fb8c752efaa1af9815a6b5f6a232aa0eecf90e82 100644 (file)
@@ -16,7 +16,7 @@ typedef struct Manager Manager;
 #include "cgroup-util.h"
 #include "fdset.h"
 #include "list.h"
-#include "missing.h"
+#include "missing_resource.h"
 #include "namespace.h"
 #include "nsflags.h"
 
index 40be7213ebd56e5647403c66b3751d62b7da3117..af5070b8cf9acb3c3802b4fe0bdf0ef5e4be9ab5 100644 (file)
@@ -236,6 +236,9 @@ Job* job_install(Job *j) {
 
         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;
 }
 
index 6d03b066847d5c45c5c52b1e64f7fc2a28a26f46..839dc062ff780700c9213beec517468c6ed66bcb 100644 (file)
@@ -236,6 +236,7 @@ _noreturn_ static void crash(int sig) {
                 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");
@@ -1733,6 +1734,7 @@ static void do_reexecute(
         /* 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;
index 99b2aa0904c39a78782b498802ca143cb9f441f3..afdbaa1d9d0389c6f4b299f42e897c8e612eb72c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "alloc-util.h"
 #include "dbus-mount.h"
+#include "dbus-unit.h"
 #include "device.h"
 #include "escape.h"
 #include "exit-status.h"
@@ -640,6 +641,9 @@ static void mount_set_state(Mount *m, MountState state) {
         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;
 
index 01019b0cf77f9e7027ab4d4e9ba87baa45598ed9..831e49df29f2623b0f9e0a49ffaeae66fcf198a8 100644 (file)
@@ -8,6 +8,7 @@
 #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"
@@ -410,6 +411,9 @@ static void path_set_state(Path *p, PathState state) {
         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;
 
index 151b8989a6416bb38bd7aada60a2ffdb6874636c..e478661f9486fb52849da49f4ebe745b27e3ce16 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "alloc-util.h"
 #include "dbus-scope.h"
+#include "dbus-unit.h"
 #include "load-dropin.h"
 #include "log.h"
 #include "scope.h"
@@ -82,6 +83,9 @@ static void scope_set_state(Scope *s, ScopeState state) {
         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;
 
index 964a7fd05725d62e057c5c4a1e292d9bb5992be1..76f1e160697f7d22f53c4554c9d4645f67368505 100644 (file)
@@ -12,6 +12,7 @@
 #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"
@@ -1035,6 +1036,9 @@ static void service_set_state(Service *s, ServiceState state) {
 
         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;
index eae7295acb20a3f63efaef1a31ae2ee5597d599f..cb47ee8984b20322429ed25c51b98d6cdaa84bc5 100644 (file)
@@ -28,6 +28,7 @@
 #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"
@@ -443,13 +444,15 @@ int main(int argc, char *argv[]) {
         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...");
index dc087680e1931dcc74feb701c9b55d7bd9b05e93..15b18bcad3562fb9876a80db1a452e73a1eca0ff 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "alloc-util.h"
 #include "dbus-slice.h"
+#include "dbus-unit.h"
 #include "log.h"
 #include "serialize.h"
 #include "slice.h"
@@ -29,6 +30,9 @@ static void slice_set_state(Slice *t, SliceState state) {
         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;
 
index 6697f05fbfd9daa546afd85b34d83d13ea5fb522..dd126a7f21b7d06fe27f2ea3c9fde6452c63ef17 100644 (file)
@@ -17,6 +17,7 @@
 #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"
@@ -1742,6 +1743,9 @@ static void socket_set_state(Socket *s, SocketState state) {
         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;
 
index db806fe0bb3bc8a2928f7bf1872ab8ce35273adb..90207a48fa6c76f52d506346341b6e495ceabdd4 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "alloc-util.h"
 #include "dbus-swap.h"
+#include "dbus-unit.h"
 #include "device-private.h"
 #include "device-util.h"
 #include "device.h"
@@ -480,6 +481,9 @@ static void swap_set_state(Swap *s, SwapState state) {
 
         assert(s);
 
+        if (s->state != state)
+                bus_unit_send_pending_change_signal(UNIT(s), false);
+
         old_state = s->state;
         s->state = state;
 
index b8b8e32805eb0988b4a90150457c93dc2063abe6..421a304c73da421b14a962ab2cb35e962e23a248 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "dbus-target.h"
+#include "dbus-unit.h"
 #include "log.h"
 #include "serialize.h"
 #include "special.h"
@@ -18,6 +19,9 @@ static void target_set_state(Target *t, TargetState state) {
         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;
 
index 1527aab158279b9ce18c9e04658e261e09df15b2..d9ba2f76b3d3984d6745824ee74cc4abdea9185c 100644 (file)
@@ -6,6 +6,7 @@
 #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"
@@ -247,6 +248,9 @@ static void timer_set_state(Timer *t, TimerState state) {
         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;
 
index 122b399d66805c4123268a83ca4918dd0f1ef75b..e1b6e9f11cc67a8f0ecc84672d575a811709caae 100644 (file)
@@ -1639,6 +1639,8 @@ static bool unit_condition_test(Unit *u) {
         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;
 }
 
@@ -1648,6 +1650,8 @@ static bool unit_assert_test(Unit *u) {
         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;
 }
 
@@ -2339,6 +2343,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
 
         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);
@@ -2497,7 +2505,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
                 }
         }
 
-        unit_add_to_dbus_queue(u);
         unit_add_to_gc_queue(u);
 }
 
@@ -4930,7 +4937,7 @@ void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid) {
 
         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) {
@@ -4984,6 +4991,7 @@ int unit_acquire_invocation_id(Unit *u) {
         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;
 }
 
index 8fbe653f0cc9e49d6b848473183fff0a72c71e97..fbee242962feb699c8360cf09edde25c16e2030e 100644 (file)
@@ -968,7 +968,7 @@ static int run_debug(int argc, char **argv, void *userdata) {
 
         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) {
index 328f5654e88be779b40aa5b68986747d4108799d..379226641e5c31065944109eade7b89f2744bcef 100644 (file)
@@ -169,7 +169,7 @@ static int found_override(const char *top, const char *bottom) {
 
         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) {
index 995cf92ef121cbd3ddfcfd75d1af26e68abf97a7..7fc4a283ce838ff762a1a7f91ef82261739a06e3 100644 (file)
@@ -27,6 +27,7 @@
 #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"
@@ -401,6 +402,8 @@ static int run(int argc, char *argv[]) {
                 cmdline[i++] = device;
                 cmdline[i++] = NULL;
 
+                (void) rlimit_nofile_safe();
+
                 execv(cmdline[0], (char**) cmdline);
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
index 389b545ac27ce14801d07727e5b8e394f0153bb3..3a1e60fc5dd4db82f286a94449c4ff45ea8eb8ed 100644 (file)
@@ -1,7 +1,8 @@
 /* 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"
index a90693c802b83be1a936e557ea596e28897dc577..acfe3809695dc9324f42fc95ee469349d90f91ec 100644 (file)
@@ -14,6 +14,7 @@
 #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"
@@ -472,6 +473,8 @@ int pull_verify(PullJob *main_job,
                         _exit(EXIT_FAILURE);
                 }
 
+                (void) rlimit_nofile_safe();
+
                 cmd[k++] = strjoina("--homedir=", gpg_home);
 
                 /* We add the user keyring only to the command line
index c46e0acdd369354d4a20ec64484b1d4e6d2e2614..b82d4b4a1b61e254194f5ddbfbf1793b650359a4 100644 (file)
@@ -81,6 +81,8 @@ static int spawn_child(const char* child, char** argv) {
                         _exit(EXIT_FAILURE);
                 }
 
+                (void) rlimit_nofile_safe();
+
                 execvp(child, argv);
                 log_error_errno(errno, "Failed to exec child %s: %m", child);
                 _exit(EXIT_FAILURE);
index e5cd134d57f74d3149e697c57f3d7dd8d883afa2..969fc71051bcead68d4eed3096e30381fa9a6869 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <arpa/inet.h>
 #include <linux/sockios.h>
+#include <sys/ioctl.h>
 
 #include "sd-lldp.h"
 
index d88b018dc9432d073e22ca397875f7bb89e31469..fa94b3cb7529bb632aaa1947e1cf35e63a90069f 100644 (file)
@@ -20,6 +20,7 @@
 #include "macro.h"
 #include "socket-util.h"
 #include "tests.h"
+#include "util.h"
 #include "virt.h"
 
 static struct ether_addr mac_addr = {
index 2787e8505ba404c5b0d6c0cdffdc73400d121d66..7775d2b376253edae1ffcd061b45e96f989e2018 100644 (file)
@@ -430,7 +430,7 @@ _public_ int sd_bus_get_name_creds(
 
         _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;
 
@@ -459,9 +459,12 @@ _public_ int sd_bus_get_name_creds(
         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",
@@ -483,6 +486,7 @@ _public_ int sd_bus_get_name_creds(
         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;
@@ -661,7 +665,7 @@ _public_ int sd_bus_get_name_creds(
                                                 NULL,
                                                 &reply,
                                                 "s",
-                                                unique ? unique : name);
+                                                unique ?: name);
                                 if (r < 0)
                                         return r;
 
@@ -688,7 +692,7 @@ _public_ int sd_bus_get_name_creds(
                                                 &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;
@@ -699,7 +703,7 @@ _public_ int sd_bus_get_name_creds(
                                         if (r < 0)
                                                 return r;
 
-                                        c->label = strndup(p, sz);
+                                        c->label = memdup_suffix0(p, sz);
                                         if (!c->label)
                                                 return -ENOMEM;
 
index 506ed0d73c3303444258796b490217f7e7c032d6..38900cf718be84051211bd2ab2d37980b3085f17 100644 (file)
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
+#include <sys/time.h>
+
 #include "alloc-util.h"
 #include "bus-dump.h"
 #include "bus-internal.h"
index 7e90a56e6774689e681f414bdba755e57a225a78..d0538104ae251100f2e1ffd1f366040d646d6bfc 100644 (file)
@@ -9,6 +9,7 @@
 #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"
index f7485211ac60ec15c6eedef4c1dba6246fe75424..ed185131b83ae40215398b0453191cc67b2db2b4 100644 (file)
@@ -21,6 +21,7 @@
 #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"
@@ -932,6 +933,8 @@ int bus_socket_exec(sd_bus *b) {
                 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 {
index 92624909e00132245fe84aab2f25bd8357ee8b0c..2dd3d41a302a290b6c9409e26ce1292909d3ac2d 100644 (file)
@@ -10,6 +10,7 @@
 #include "bus-util.h"
 #include "def.h"
 #include "fd-util.h"
+#include "missing_resource.h"
 #include "time-util.h"
 #include "util.h"
 
index 39def1681eeb22697b83fe19940325f63621fee1..d5583488f20ce828fb430ba20ab77b60b22aecef 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <ctype.h>
 #include <net/if.h>
+#include <sys/ioctl.h>
 #include <sys/types.h>
 
 #include "sd-device.h"
index 874babc9efdbcc87a787fa807ccab4a4895980a0..64ab386df3f1c0a7378a62254976c79f0a34bc3e 100644 (file)
@@ -412,17 +412,40 @@ static const NLTypeSystem rtnl_link_info_type_system = {
 };
 
 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[] = {
index 4416e1720cb2e65a48a464a1aa93f0497130a978..2d4d00e0eb128571b191f0c1629be9685c4ba215 100644 (file)
@@ -852,6 +852,32 @@ int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message *m, unsigne
         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;
 
index 77481002106f673a06583df12d31158beedc3381..bff2c4976b9e5d4b171c60b0ac9a18a20e97cb68 100644 (file)
@@ -14,6 +14,7 @@
 #include "macro.h"
 #include "socket-util.h"
 #include "string-util.h"
+#include "time-util.h"
 
 #define TEST_TIMEOUT_USEC (20*USEC_PER_SEC)
 
index 03bbf3b82604f2ca4491f1f5b1f6df2c0c0046ba..f574d429f49f8d0e1d87d331859dddc5d5391816 100644 (file)
@@ -303,7 +303,7 @@ static int run(int argc, char *argv[]) {
                 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) {
index f358524ebcaae8484a006bfbbab927c9c8ccf473..0fcbe98c2a3dccdf2f02ef9fd0a0dcc44b9a691e 100644 (file)
@@ -3,9 +3,13 @@
 #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"
index a311ed9077d537ca4ddb590569bda165d34d6a07..7e7f0d51bfb0db5ea8a2adaf82b9d626788a6442 100644 (file)
@@ -15,6 +15,7 @@
 #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"
@@ -169,7 +170,7 @@ int bus_image_method_clone(
         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) {
index 95489a3d9492982a4b444f0334b905bedac19a17..285918b4cc5c63f9badd98718a8371924e953ac9 100644 (file)
@@ -27,6 +27,7 @@
 #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"
index bbcfc626a1d01a2d9aa129cd2a6ac1287e1fd18e..d613414fded43b55efb3b0b6d842c2a6f1add0e5 100644 (file)
@@ -21,6 +21,7 @@
 #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"
index 9e4c1e962939e6b6f75041cd1c66a456637a8e72..b8abed19bd9160085e4507e11b3d2b6fd0855751 100644 (file)
@@ -6,7 +6,7 @@
 #endif
 
 #include "in-addr-util.h"
-#include "missing.h"
+#include "missing_fou.h"
 #include "netdev/netdev.h"
 
 typedef enum FooOverUDPEncapType {
index b60587f2b6f3c6bf69f7fbd9d3368bda719a721b..fb426d37e5d814a4eedb5b8a4b89d138d514d879 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <linux/if_link.h>
 
-#include "missing.h"
+#include "missing_if_link.h"
 #include "netdev/netdev.h"
 
 typedef enum IPVlanMode {
index 49752c2d8a2e96bcd57dc61573c37b08aee636ae..fbc7a59e9e8ca3749947b14ff0fd8be20d63b232 100644 (file)
@@ -73,6 +73,7 @@ Tunnel.Encapsulation,              config_parse_fou_encap_type,          0,
 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)
index 36f1fe7b03403c959d23422f9727b66010b7a704..684edddb5f5307a1ac25940097cebb7fce63e68a 100644 (file)
@@ -118,6 +118,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink
                 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.
                  */
@@ -126,6 +127,16 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink
                         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;
 }
 
@@ -761,6 +772,7 @@ static void sit_init(NetDev *n) {
         assert(t);
 
         t->pmtudisc = true;
+        t->isatap = -1;
 }
 
 static void vti_init(NetDev *n) {
index 51b61637ad44a92fcf25ed848f7e583d3826a022..8f511dd1f64a90cd8e68ab4a568df925eb25bf3c 100644 (file)
@@ -30,6 +30,7 @@ typedef struct Tunnel {
         int ipv6_flowlabel;
         int allow_localremote;
         int erspan_sequence;
+        int isatap;
 
         unsigned ttl;
         unsigned tos;
index 5296f687a78bc6888ceb47f2a020b62c85b122a6..86f2e6dca9c1fc00c71394aaf1d2fbd85fff5739 100644 (file)
@@ -13,6 +13,7 @@
 #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"
@@ -1421,7 +1422,12 @@ static int link_set_bridge(Link *link) {
                 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) {
@@ -1429,6 +1435,7 @@ static int link_set_bridge(Link *link) {
                 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)
index 253308e36cd3129f4aeb6a38fb1806689d649472..8fd6365e68b42870ba5c719d91dcfce59ccc383c 100644 (file)
@@ -8,6 +8,7 @@
 #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"
index ed15d221785c4080ce96b4917e09a58d6562854f..945a3c5705c08a474b0c4bf35ef3790308dc3e2b 100644 (file)
@@ -104,6 +104,7 @@ RoutingPolicyRule.OutgoingInterface,    config_parse_routing_policy_rule_device,
 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
@@ -162,6 +163,7 @@ Bridge.HairPin,                         config_parse_tristate,
 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
index 0225f72bdbd911029512a58ded0c6be0c7db2804..178cdff82b73f0f4d5d8401e9b8a86ce70f202ac 100644 (file)
@@ -163,6 +163,7 @@ int network_load_one(Manager *manager, const char *filename) {
                 .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,
index 5c1fccbc41e346d26e6957478a3c4a61856963cf..3592b563c09b390548f371fb50be8f90cb84723c 100644 (file)
@@ -183,6 +183,7 @@ struct Network {
         int fast_leave;
         int allow_port_to_be_root;
         int unicast_flood;
+        int multicast_to_unicast;
         uint32_t cost;
         uint16_t priority;
 
index 96013e7026ec1c2c710d896237157880a4289fb7..2dc78622cecf9a7853b7a86271f8c100d6ae00ac 100644 (file)
@@ -588,6 +588,12 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
                         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,
@@ -959,6 +965,45 @@ int config_parse_routing_policy_rule_ip_protocol(
         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;
index 0e4215bffdc83ffb350f03b11fd27813c9b59c3b..b35126e2cfd1a2be7252c73d5cba7709801df35c 100644 (file)
@@ -25,6 +25,8 @@ struct RoutingPolicyRule {
         Link *link;
         NetworkConfigSection *section;
 
+        bool invert_rule;
+
         uint8_t tos;
         uint8_t protocol;
 
@@ -79,3 +81,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_priority);
 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);
index 214fa40804c00abba02969cb6ebf7f05bf6a7b0f..9d0f8a9956b3fc47b93728f93915183f397c31da 100644 (file)
@@ -11,6 +11,7 @@
 #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"
index cb082d163584377cf7f9c7bada8bbc63d574f964..a63aa32e909c247c40882b626b8764c3dc3110bf 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "conf-parser.h"
 #include "macro.h"
-#include "missing.h"
+#include "missing_resource.h"
 #include "nspawn-expose-ports.h"
 #include "nspawn-mount.h"
 
index e865d5b2a824bcc518d298d86e7748ef3bbb83bb..86fd9deec0fee11dd533d8a45589fd977639eabd 100644 (file)
@@ -12,6 +12,7 @@
 #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"
@@ -44,6 +45,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
 
                 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);
index 0fb42d1a74779d42e2c6cb716fb9c8f006e8f37b..03538d1c2f384846fb72d27f13cffc9e5385c4a5 100644 (file)
@@ -6,6 +6,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <grp.h>
+#include <linux/fs.h>
 #include <linux/loop.h>
 #include <pwd.h>
 #include <sched.h>
@@ -17,7 +18,6 @@
 #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>
index 88834092bde332cdeebc781c419e7f719cbd2ec5..0b9bae55e7b3435d3416a35b9b764b8908b0ac2d 100644 (file)
@@ -28,7 +28,7 @@ static int makefs(const char *type, const char *device) {
         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) {
index ec93838538139657618df2faa0c8963f0f21c4ab..3cbdb0b0cc22ded9660717fa1776ba851453e51f 100644 (file)
@@ -7,6 +7,7 @@
 #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"
index 77eb2df1180c241f3a98c12fd8d0b695503dbc9f..1e618175c72b24299e0c351578d320f9ab4e1f12 100644 (file)
@@ -8,6 +8,7 @@
 #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"
index a51a76411e7c56893fee49d91bfa7e30621ebaf6..90f542a058c4928f5df35c72595882a33e1f2fc9 100644 (file)
@@ -78,7 +78,7 @@ static int run(int argc, char *argv[]) {
                         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) {
index 28edbbd856cba1d8fcec727d7f8bc508cc234188..af92ddb96cf5499a22c5a1692d0a9bf6cb7f11c1 100644 (file)
@@ -62,7 +62,7 @@ static int run(int argc, char *argv[]) {
 
                 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) {
index 64abc3c46e8344b61ab4e1667178cd721400a760..8a175ebefc7247a55c9cf2679da64b7776643122 100644 (file)
@@ -16,7 +16,7 @@
 #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"
index 75702d593f41a607c759f38b056400f13cb76f15..b9fd77552612229cc137dd447704f9454cbb4b78 100644 (file)
@@ -4,6 +4,7 @@
 #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"
index c8c4d829e844840a993ee23f19d657aeb5121be7..015aabaf9bb5f19c7c14e4413e422c45fbcd52ca 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "fd-util.h"
+#include "missing_network.h"
 #include "resolved-dns-stub.h"
 #include "socket-util.h"
 
index 9a8ce7ae2d8dfdbd97ca8216310f86d07bcbec76..f65116c3b45462f93109267c6386aa1422c97ca0 100644 (file)
@@ -3,6 +3,7 @@
 #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) {
index c2db31df0fdfd8dde3bdbd6249fb02b875e9c34d..24bb37b35e848eaaf59195267ad887046f94b508 100644 (file)
@@ -1,6 +1,7 @@
 
 #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"
index 2174d660ff0e781f97d014ae1a0074b521907ffa..23a7b87801c940bf0667f34992dbffe813b42025 100644 (file)
@@ -17,6 +17,7 @@
 #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"
index da10391d74eec6e35ad1d8e61fed7cf4aea9bae5..6130a036fd0342dd19be5f8211e8ae4acb27c549 100644 (file)
@@ -11,7 +11,7 @@ static void test_parse_etc_hosts_system(void) {
 
         f = fopen("/etc/hosts", "re");
         if (!f) {
-                assert_se(errno == -ENOENT);
+                assert_se(errno == ENOENT);
                 return;
         }
 
index 625bebbe35890ebb214efc0fb78f4f44f8bdcf59..e324a2ffc7fce9f4d5b0f7b9343e3a33e424e276 100644 (file)
@@ -18,6 +18,7 @@
 #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"
index 8110b2cb16884e66bc8f2e0250463365d3780148..8fe177990a6b7ae975f4d9cff0b1d94ad1b19546 100644 (file)
 #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"
@@ -28,7 +30,6 @@
 #include "syslog-util.h"
 #include "time-util.h"
 #include "utf8.h"
-#include "rlimit-util.h"
 
 int config_item_table_lookup(
                 const void *table,
index 7ea8ad351c63701d15df8d5e2bbea5ef34da08e9..d66b3004590a12495759cb6d50167b06db27f27d 100644 (file)
@@ -17,6 +17,7 @@
 #include "hashmap.h"
 #include "macro.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "serialize.h"
 #include "set.h"
 #include "signal-util.h"
@@ -52,6 +53,8 @@ static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) {
                                 _exit(EXIT_FAILURE);
                 }
 
+                (void) rlimit_nofile_safe();
+
                 if (!argv) {
                         _argv[0] = (char*) path;
                         _argv[1] = NULL;
index c2abd9956f2d51cd3c2f34f3857322e53d4c127f..e0eef34cdc6d0680cee93f2cd804e14515a01391 100644 (file)
@@ -1,11 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
-#include <stddef.h>
-
-#include "macro.h"
-#include "missing.h"
-
 typedef struct LockFile {
         char *path;
         int fd;
index b39ff42b84043f6b055758e2f3782bfccd0dab5c..af06ab22e88bbb6de10cd5cb72dd8f6ad433b14d 100644 (file)
@@ -7,6 +7,7 @@
 #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>
index 20a537e3cf19383541fe30feab35b9d6fcbbe976..5917d43ef9d2149f23b5819cafa96a370893e51e 100644 (file)
@@ -120,8 +120,6 @@ shared_sources = files('''
         reboot-util.h
         resolve-util.c
         resolve-util.h
-        rlimit-util.c
-        rlimit-util.h
         seccomp-util.h
         securebits-util.c
         securebits-util.h
index a5beb9200fafbcaeaa01c0a3d798c6cdd0543737..8cc2d0873db2da20252a4f37d0f00c1024512792 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#include <sched.h>
+#include <errno.h>
 
 #include "alloc-util.h"
 #include "extract-word.h"
index 7cc26a441d4bb44558321cebfc73dac14ae70da5..0aeb0bc89143921538323d86eb12bf74efc718e6 100644 (file)
@@ -1,9 +1,7 @@
 /* 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
index 88d9ef349e7ee00d213d35ed60204094ddea4afc..69484384d3532578d7405fbeaf9cf3d8f20d32d1 100644 (file)
@@ -19,6 +19,7 @@
 #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"
@@ -55,7 +56,7 @@ static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) {
         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 */
@@ -64,7 +65,7 @@ static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) {
 
                 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;
 
@@ -96,7 +97,7 @@ int pager_open(PagerFlags flags) {
                 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)
@@ -105,7 +106,7 @@ int pager_open(PagerFlags flags) {
         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")))
@@ -131,7 +132,7 @@ int pager_open(PagerFlags flags) {
         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) {
@@ -139,11 +140,17 @@ int pager_open(PagerFlags flags) {
 
                 /* 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
@@ -152,14 +159,21 @@ int pager_open(PagerFlags flags) {
                 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
@@ -169,13 +183,21 @@ int pager_open(PagerFlags flags) {
                  * 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 */
         }
@@ -256,7 +278,7 @@ int show_man_page(const char *desc, bool null_stdio) {
         } 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) {
index 82481972f08dd8269c00c30c21a8b6f36f4d65e6..6d65efbb9ea55ab691f1566bca06ba43ca48a5fe 100644 (file)
@@ -69,7 +69,7 @@ static int fork_wait(const char* const cmdline[]) {
         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) {
index 8f8e9ace1e8b8950b66e687911295de9ff4455ab..9e549db9444bb0e717331dcf98ae7ddbb96c2397 100644 (file)
@@ -2799,63 +2799,87 @@ static void wait_context_free(WaitContext *c) {
 }
 
 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);
@@ -3529,7 +3553,7 @@ static int load_kexec_kernel(void) {
         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) {
@@ -6002,7 +6026,7 @@ static int enable_sysv_units(const char *verb, char **args) {
                 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) {
@@ -6897,7 +6921,7 @@ static int run_editor(char **paths) {
 
         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) {
@@ -8299,6 +8323,7 @@ static int parse_argv(int argc, char *argv[]) {
                                 /* 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),
index 20bff2838e2fb942f1fd9031d670e0b6dc3d7863..30be5b113ca36e6c40241b72873536cebd37272a 100644 (file)
@@ -179,6 +179,8 @@ int sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(sd_netlink_message
 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);
index f902f500e0cc349052a0572bb88ce58498bb94b1..07ff4878340f057d8dfd10733e4f4613b67ffd42 100644 (file)
@@ -13,6 +13,7 @@
 #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"
index 93d4ea4d3f38046a8ad09fc7ec8a252cc4396d97..e4bc5161d5848673870c15b4b94ce6301ff18910 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/ethtool.h>
 
 #include "conf-parser.h"
-#include "missing.h"
+#include "missing_network.h"
 
 struct link_config;
 
index f2238ae14edd8e6686dd79ddb423956c58f5f266..d90ebb72599fdfbdf147f02d7c9c9e2d4b5685ea 100644 (file)
@@ -24,6 +24,7 @@
 #include "socket-util.h"
 #include "strxcpyx.h"
 #include "udev-ctrl.h"
+#include "util.h"
 
 /* wire protocol magic must match */
 #define UDEV_CTRL_MAGIC                                0xdead1dea
index 3782d892c2df5882c338d73dbde4fcaa58c41c92..bb3e1b9f2381f72d03796eddc8ee740fc606d3c0 100644 (file)
@@ -20,6 +20,7 @@
 #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"
@@ -650,6 +651,7 @@ int udev_event_spawn(struct udev_event *event,
                         _exit(EXIT_FAILURE);
 
                 (void) close_all_fds(NULL, 0);
+                (void) rlimit_nofile_safe();
 
                 execve(argv[0], argv, envp);
                 _exit(EXIT_FAILURE);
index c9e3d426b30a17f06de59817b408a8f0ff09c988..fa85f6e2632dc10f74bb15c922d2c3c2901ca4fe 100644 (file)
@@ -534,7 +534,7 @@ static int worker_spawn(Manager *manager, struct event *event) {
         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");
@@ -1850,7 +1850,7 @@ static int run(int argc, char *argv[]) {
                         return 0;
 
                 /* child */
-                setsid();
+                (void) setsid();
 
                 r = set_oom_score_adjust(-1000);
                 if (r < 0)
index 71fc59cbfada9a55919937b6154f21e1ab1c9d11..efaa8c28d390e9549e167abc11b204d358fb8a03 100644 (file)
@@ -150,7 +150,7 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m
                 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) {
@@ -193,7 +193,7 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map,
                 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) {
index 19226df80621846226a4889e684b0b405120981b..5a8d41eb68385e2949940b80752062eb4207e492 100644 (file)
@@ -76,6 +76,7 @@ FOUSourcePort=
 IPv6RapidDeploymentPrefix=
 ERSPANIndex=
 SerializeTunneledPackets=
+ISATAP=
 [VXLAN]
 UDP6ZeroChecksumRx=
 ARPProxy=
index 84f221d538549aaaeec91bf1276f66ff57d4d6b2..81b372fb6d091e78dadd8762001f360544f8d51b 100644 (file)
@@ -9,3 +9,4 @@ Cost=400
 HairPin = true
 FastLeave = true
 UnicastFlood = true
+MulticastToUnicast = true
index 8ea809a7e1f1ebdf9f6fdd5f31451877411de7e0..6afdd05e877f7f671a437af94fb74da5d2f13fc6 100644 (file)
@@ -6,6 +6,7 @@ UnicastFlood=
 FastLeave=
 Priority=
 AllowPortToBeRoot=
+MulticastToUnicast=
 [Match]
 KernelVersion=
 Type=
@@ -153,6 +154,7 @@ FirewallMark=
 SourcePort=
 DestinationPort=
 IPProtocol=
+InvertRule=
 [IPv6PrefixDelegation]
 RouterPreference=
 DNSLifetimeSec=
index f454fd313ec63044a4ac823bc509f28a43817bc2..4d7526f63619d37f626f9270d654ce5c8e34f385 100644 (file)
@@ -417,6 +417,7 @@ Group=
 GroupForwardMask=
 GroupPolicyExtension=
 HairPin=
+MulticastToUnicast=
 HelloTimeSec=
 HomeAddress=
 Host=
@@ -442,6 +443,7 @@ Independent=
 InitialAdvertisedReceiveWindow=
 InitialCongestionWindow=
 InputKey=
+InvertRule=
 KernelCommandLine=
 KernelVersion=
 Key=
diff --git a/test/test-network/conf/25-fibrule-invert.network b/test/test-network/conf/25-fibrule-invert.network
new file mode 100644 (file)
index 0000000..bcca0c2
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=test1
+
+[RoutingPolicyRule]
+TypeOfService=0x08
+Table=7
+From= 192.168.100.18
+Priority=111
+IPProtocol = tcp
+InvertRule=true
diff --git a/test/test-network/conf/25-isatap-tunnel.netdev b/test/test-network/conf/25-isatap-tunnel.netdev
new file mode 100644 (file)
index 0000000..3aa882a
--- /dev/null
@@ -0,0 +1,8 @@
+[NetDev]
+Name=isataptun99
+Kind=sit
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
+ISATAP=true
index 84f221d538549aaaeec91bf1276f66ff57d4d6b2..81b372fb6d091e78dadd8762001f360544f8d51b 100644 (file)
@@ -9,3 +9,4 @@ Cost=400
 HairPin = true
 FastLeave = true
 UnicastFlood = true
+MulticastToUnicast = true
diff --git a/test/test-network/conf/isatap.network b/test/test-network/conf/isatap.network
new file mode 100644 (file)
index 0000000..e8d03ed
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=isataptun99
index 806f4a496c4930e0499609583afed13d8dc4e9c6..8fb1c7f38d1e5596fa1123205e8dc535467c874c 100755 (executable)
@@ -3,15 +3,15 @@
 # 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'
@@ -61,6 +61,15 @@ class Utilities():
         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))
 
@@ -104,15 +113,16 @@ class Utilities():
 
             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
 
@@ -132,6 +142,7 @@ class Utilities():
         else:
             subprocess.check_call('systemctl restart systemd-networkd', shell=True)
         time.sleep(5)
+        print()
 
 global ip
 global port
@@ -162,21 +173,82 @@ class DHCPServer(threading.Thread):
 
 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)
@@ -187,7 +259,6 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
     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'))
@@ -231,12 +302,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
     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')
@@ -245,14 +316,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
     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'))
@@ -260,35 +329,30 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
     @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'))
@@ -296,7 +360,6 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
     @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'))
@@ -304,7 +367,6 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
     @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'))
@@ -312,7 +374,6 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
     @expectedFailureIfModuleIsNotAvailable('wireguard')
     def test_wireguard(self):
         self.copy_unit_to_networkd_unit_path('25-wireguard.netdev')
-
         self.start_networkd()
 
         if shutil.which('wg'):
@@ -322,12 +383,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
     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')
@@ -389,6 +450,17 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         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()
@@ -410,18 +482,18 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
     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')
@@ -434,16 +506,36 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         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)
@@ -457,6 +549,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
         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')
@@ -468,6 +561,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
         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')
@@ -480,6 +574,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
 
         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')
@@ -490,6 +585,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
 
         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')
@@ -499,6 +595,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
         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')
@@ -508,11 +605,14 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
         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')
@@ -522,6 +622,23 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
         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()
@@ -672,11 +789,19 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities):
         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)
@@ -712,15 +837,22 @@ class NetworkdNetWorkBrideTests(unittest.TestCase, Utilities):
 
         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)
@@ -743,7 +875,10 @@ class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
 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)
@@ -763,10 +898,18 @@ class NetworkdNetworkRATests(unittest.TestCase, Utilities):
         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)
@@ -781,8 +924,6 @@ class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
 
         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.*')
@@ -815,14 +956,24 @@ class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
         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)
@@ -893,10 +1044,10 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
         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')
@@ -909,8 +1060,7 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
         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')
@@ -923,8 +1073,7 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
         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')
@@ -933,12 +1082,14 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
         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()
 
@@ -957,39 +1108,40 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
     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)