summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mkosi/mkosi.arch2
-rw-r--r--NEWS3
-rw-r--r--TODO14
-rw-r--r--man/systemd.network.xml8
-rw-r--r--src/basic/fs-util.c9
-rw-r--r--src/basic/static-destruct.h4
-rw-r--r--src/basic/util.c8
-rw-r--r--src/basic/util.h3
-rw-r--r--src/core/cgroup.c14
-rw-r--r--src/core/dbus-cgroup.c12
-rw-r--r--src/core/main.c26
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c8
-rw-r--r--src/network/networkd-network-gperf.gperf3
-rw-r--r--src/network/tc/netem.c17
-rw-r--r--src/network/tc/netem.h3
-rw-r--r--src/network/tc/qdisc.c19
-rw-r--r--src/nspawn/nspawn.c12
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network1
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py92
19 files changed, 154 insertions, 104 deletions
diff --git a/.mkosi/mkosi.arch b/.mkosi/mkosi.arch
index ce0c1ae38e..350d7cd2b8 100644
--- a/.mkosi/mkosi.arch
+++ b/.mkosi/mkosi.arch
@@ -27,11 +27,11 @@ BuildPackages=
docbook-xsl
elfutils
gcc
- gettext
git
gnu-efi-libs
gnutls
gperf
+ inetutils
iptables
kmod
libcap
diff --git a/NEWS b/NEWS
index 9c46472aac..56d05ac7ef 100644
--- a/NEWS
+++ b/NEWS
@@ -127,7 +127,8 @@ CHANGES WITH 244 in spe:
disciplines in the kernel using the new
[TrafficControlQueueingDiscipline] section and Parent=,
NetworkEmulatorDelaySec=, NetworkEmulatorDelayJitterSec=,
- NetworkEmulatorPacketLimit=, NetworkEmulatorLossRate= settings.
+ NetworkEmulatorPacketLimit=, NetworkEmulatorLossRate=,
+ NetworkEmulatorDuplicateRate= settings.
* systemd-tmpfiles gained a new w+ setting to append to files.
diff --git a/TODO b/TODO
index 03d38da9a0..36eb2c24ce 100644
--- a/TODO
+++ b/TODO
@@ -17,6 +17,17 @@ Janitorial Clean-ups:
* rework mount.c and swap.c to follow proper state enumeration/deserialization
semantics, like we do for device.c now
+Before v244:
+
+* revisit SystemdOptions EFI variable. Find a better, systematic name and use
+ it for the env var, the bootctl verb and the EFI variable itself, clear up
+ semantics.
+
+* Figure out a better name for the global per-unit-type drop-in dirs, it's
+ confusing when it comes to -.mount.d/ (is it a drop-in-dir for all mount
+ units, or one for the root mount?). Also, OOM handling in
+ service_unit_name_is_valid() is borked.
+
Features:
* coredump: maybe when coredumping read a new xattr from /proc/$PID/exe that
@@ -257,9 +268,6 @@ Features:
* bypass SIGTERM state in unit files if KillSignal is SIGKILL
-* tree-wide: ensure we always block the signals we hook into with
- sd_event_add_signal() first
-
* add proper dbus APIs for the various sd_notify() commands, such as MAINPID=1
and so on, which would mean we could report errors and such.
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 0d49bf9589..fb2f199ba8 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2351,6 +2351,14 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>NetworkEmulatorDuplicateRate=</varname></term>
+ <listitem>
+ <para>Specifies that the chosen percent of packets is duplicated before queuing them.
+ Takes a percentage value, suffixed with "%". Defaults to unset.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 9d2cff0d24..6e6fa20053 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -662,15 +662,12 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
}
int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
- if (inotify_add_watch(fd, pathname, mask) < 0) {
- const char *reason;
+ if (inotify_add_watch(fd, pathname, mask) < 0) {
if (errno == ENOSPC)
- reason = "inotify watch limit reached";
- else
- reason = strerror_safe(errno);
+ return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname);
- return log_error_errno(errno, "Failed to add a watch for %s: %s", pathname, reason);
+ return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname);
}
return 0;
diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h
index 443c0e8ebb..8fbc07c587 100644
--- a/src/basic/static-destruct.h
+++ b/src/basic/static-destruct.h
@@ -40,8 +40,8 @@ typedef struct StaticDestructor {
extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[];
-/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in the same
- * linking unit as the variables we want to destroy. */
+/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in
+ * the same linking unit as the variables we want to destroy.) */
static inline void static_destruct(void) {
const StaticDestructor *d;
diff --git a/src/basic/util.c b/src/basic/util.c
index b02471c483..f74ed95a60 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -38,7 +38,6 @@
#include "set.h"
#include "signal-util.h"
#include "stat-util.h"
-#include "static-destruct.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
@@ -49,11 +48,8 @@
int saved_argc = 0;
char **saved_argv = NULL;
-char **saved_env = NULL;
static int saved_in_initrd = -1;
-STATIC_DESTRUCTOR_REGISTER(saved_env, strv_freep);
-
bool kexec_loaded(void) {
_cleanup_free_ char *s = NULL;
@@ -301,7 +297,3 @@ void disable_coredumps(void) {
if (r < 0)
log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
}
-
-void save_env(void) {
- saved_env = strv_copy(environ);
-}
diff --git a/src/basic/util.h b/src/basic/util.h
index 15444b2e5c..6fc7480fcb 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -13,9 +13,6 @@ static inline void save_argc_argv(int argc, char **argv) {
saved_argv = argv;
}
-extern char **saved_env;
-void save_env(void);
-
bool kexec_loaded(void);
int prot_from_flags(int flags) _const_;
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 981aca53cd..ec8a262314 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -360,9 +360,7 @@ static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u,
}
void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
- _cleanup_free_ char *disable_controllers_str = NULL;
- _cleanup_free_ char *cpuset_cpus = NULL;
- _cleanup_free_ char *cpuset_mems = NULL;
+ _cleanup_free_ char *disable_controllers_str = NULL, *cpuset_cpus = NULL, *cpuset_mems = NULL;
CGroupIODeviceLimit *il;
CGroupIODeviceWeight *iw;
CGroupIODeviceLatency *l;
@@ -437,8 +435,8 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
prefix, c->startup_cpu_shares,
prefix, format_timespan(q, sizeof(q), c->cpu_quota_per_sec_usec, 1),
prefix, format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1),
- prefix, cpuset_cpus,
- prefix, cpuset_mems,
+ prefix, strempty(cpuset_cpus),
+ prefix, strempty(cpuset_mems),
prefix, c->io_weight,
prefix, c->startup_io_weight,
prefix, c->blockio_weight,
@@ -974,8 +972,10 @@ static void cgroup_apply_unified_cpuset(Unit *u, const CPUSet *cpus, const char
_cleanup_free_ char *buf = NULL;
buf = cpu_set_to_range_string(cpus);
- if (!buf)
- return;
+ if (!buf) {
+ log_oom();
+ return;
+ }
(void) set_attribute_and_warn(u, "cpuset", name, buf);
}
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index b30318b943..647c3a512c 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -926,23 +926,23 @@ int bus_cgroup_set_property(
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
_cleanup_free_ char *setstr = NULL;
- _cleanup_free_ char *data = NULL;
CPUSet *set;
setstr = cpu_set_to_range_string(&new_set);
+ if (!setstr)
+ return -ENOMEM;
if (streq(name, "AllowedCPUs"))
set = &c->cpuset_cpus;
else
set = &c->cpuset_mems;
- if (asprintf(&data, "%s=%s", name, setstr) < 0)
- return -ENOMEM;
-
cpu_set_reset(set);
- cpu_set_add_all(set, &new_set);
+ *set = new_set;
+ new_set = (CPUSet) {};
+
unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET);
- unit_write_setting(u, flags, name, data);
+ unit_write_settingf(u, flags, name, "%s=%s", name, setstr);
}
return 1;
diff --git a/src/core/main.c b/src/core/main.c
index 7c814f3237..3545fde71d 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -146,6 +146,9 @@ static OOMPolicy arg_default_oom_policy;
static CPUSet arg_cpu_affinity;
static NUMAPolicy arg_numa_policy;
+/* A copy of the original environment block */
+static char **saved_env = NULL;
+
static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
const struct rlimit *saved_rlimit_memlock);
@@ -2353,6 +2356,17 @@ static bool early_skip_setup_check(int argc, char *argv[]) {
return found_deserialize; /* When we are deserializing, then we are reexecuting, hence avoid the extensive setup */
}
+static int save_env(void) {
+ char **l;
+
+ l = strv_copy(environ);
+ if (!l)
+ return -ENOMEM;
+
+ strv_free_and_replace(saved_env, l);
+ return 0;
+}
+
int main(int argc, char *argv[]) {
dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL,
@@ -2391,9 +2405,13 @@ int main(int argc, char *argv[]) {
/* Save the original command line */
save_argc_argv(argc, argv);
- /* Save the original environment as we might need to restore it if we're requested to
- * execute another system manager later. */
- save_env();
+ /* Save the original environment as we might need to restore it if we're requested to execute another
+ * system manager later. */
+ r = save_env();
+ if (r < 0) {
+ error_message = "Failed to copy environment block";
+ goto finish;
+ }
/* Make sure that if the user says "syslog" we actually log to the journal. */
log_set_upgrade_syslog_to_journal(true);
@@ -2681,6 +2699,8 @@ finish:
arg_serialization = safe_fclose(arg_serialization);
fds = fdset_free(fds);
+ saved_env = strv_free(saved_env);
+
#if HAVE_VALGRIND_VALGRIND_H
/* If we are PID 1 and running under valgrind, then let's exit
* here explicitly. valgrind will only generate nice output on
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index f7022dd715..3316c8bda4 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -136,7 +136,7 @@ static sd_dhcp_raw_option* raw_option_free(sd_dhcp_raw_option *i) {
}
_public_ int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t length, sd_dhcp_raw_option **ret) {
- sd_dhcp_raw_option *p;
+ _cleanup_(sd_dhcp_raw_option_unrefp) sd_dhcp_raw_option *p = NULL;
assert_return(ret, -EINVAL);
@@ -151,12 +151,10 @@ _public_ int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t length, sd_
.type = type,
};
- if (!p->data) {
- free(p);
+ if (!p->data)
return -ENOMEM;
- }
- *ret = p;
+ *ret = TAKE_PTR(p);
return 0;
}
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 9f53385602..7fca93dccb 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -247,7 +247,8 @@ CAN.TripleSampling, config_parse_tristate,
TrafficControlQueueingDiscipline.Parent, config_parse_tc_qdiscs_parent, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec, config_parse_tc_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_tc_network_emulator_delay, 0, 0
-TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_tc_network_emulator_loss_rate, 0, 0
+TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_tc_network_emulator_rate, 0, 0
+TrafficControlQueueingDiscipline.NetworkEmulatorDuplicateRate, config_parse_tc_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorPacketLimit, config_parse_tc_network_emulator_packet_limit, 0, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
diff --git a/src/network/tc/netem.c b/src/network/tc/netem.c
index e0e3e9a48e..053af3e7db 100644
--- a/src/network/tc/netem.c
+++ b/src/network/tc/netem.c
@@ -50,6 +50,9 @@ int network_emulator_fill_message(Link *link, QDiscs *qdisc, sd_netlink_message
if (qdisc->ne.loss > 0)
opt.loss = qdisc->ne.loss;
+ if (qdisc->ne.duplicate > 0)
+ opt.duplicate = qdisc->ne.duplicate;
+
if (qdisc->ne.delay != USEC_INFINITY) {
r = tc_time_to_tick(qdisc->ne.delay, &opt.latency);
if (r < 0)
@@ -124,7 +127,7 @@ int config_parse_tc_network_emulator_delay(
return 0;
}
-int config_parse_tc_network_emulator_loss_rate(
+int config_parse_tc_network_emulator_rate(
const char *unit,
const char *filename,
unsigned line,
@@ -138,6 +141,7 @@ int config_parse_tc_network_emulator_loss_rate(
_cleanup_(qdisc_free_or_set_invalidp) QDiscs *qdisc = NULL;
Network *network = data;
+ uint32_t rate;
int r;
assert(filename);
@@ -156,14 +160,19 @@ int config_parse_tc_network_emulator_loss_rate(
return 0;
}
- r = parse_tc_percent(rvalue, &qdisc->ne.loss);
+ r = parse_tc_percent(rvalue, &rate);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse 'NetworkEmularorLossRate=', ignoring assignment: %s",
- rvalue);
+ "Failed to parse '%s=', ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
+ if (streq(lvalue, "NetworkEmulatorLossRate"))
+ qdisc->ne.loss = rate;
+ else if (streq(lvalue, "NetworkEmulatorDuplicateRate"))
+ qdisc->ne.duplicate = rate;
+
qdisc = NULL;
return 0;
}
diff --git a/src/network/tc/netem.h b/src/network/tc/netem.h
index 4bac44ca5a..43abf20af8 100644
--- a/src/network/tc/netem.h
+++ b/src/network/tc/netem.h
@@ -16,11 +16,12 @@ typedef struct NetworkEmulator {
uint32_t limit;
uint32_t loss;
+ uint32_t duplicate;
} NetworkEmulator;
int network_emulator_new(NetworkEmulator **ret);
int network_emulator_fill_message(Link *link, QDiscs *qdisc, sd_netlink_message *req);
CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_delay);
-CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_loss_rate);
+CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_rate);
CONFIG_PARSER_PROTOTYPE(config_parse_tc_network_emulator_packet_limit);
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
index ed4a11d265..7f4b2b53cb 100644
--- a/src/network/tc/qdisc.c
+++ b/src/network/tc/qdisc.c
@@ -116,6 +116,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int qdisc_configure(Link *link, QDiscs *qdisc) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ _cleanup_free_ char *tca_kind = NULL;
int r;
assert(link);
@@ -132,25 +133,31 @@ int qdisc_configure(Link *link, QDiscs *qdisc) {
return log_link_error_errno(link, r, "Could not create tcm_parent message: %m");
if (qdisc->parent == TC_H_CLSACT) {
+ tca_kind = strdup("clsact");
+ if (!tca_kind)
+ return log_oom();
+
r = sd_rtnl_message_set_qdisc_handle(req, TC_H_MAKE(TC_H_CLSACT, 0));
if (r < 0)
return log_link_error_errno(link, r, "Could not set tcm_handle message: %m");
-
- r = sd_netlink_message_append_string(req, TCA_KIND, "clsact");
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
}
if (qdisc->has_network_emulator) {
- r = sd_netlink_message_append_string(req, TCA_KIND, "netem");
+ r = free_and_strdup(&tca_kind, "netem");
if (r < 0)
- return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
+ return log_oom();
r = network_emulator_fill_message(link, qdisc, req);
if (r < 0)
return r;
}
+ if (tca_kind) {
+ r = sd_netlink_message_append_string(req, TCA_KIND, tca_kind);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
+ }
+
r = netlink_call_async(link->manager->rtnl, NULL, req, qdisc_handler, link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index c9ff00544c..3513c015b8 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -103,6 +103,7 @@
#include "terminal-util.h"
#include "tmpfile-util.h"
#include "umask-util.h"
+#include "unit-name.h"
#include "user-util.h"
#include "util.h"
@@ -891,13 +892,17 @@ static int parse_argv(int argc, char *argv[]) {
arg_settings_mask |= SETTING_MACHINE_ID;
break;
- case 'S':
- r = free_and_strdup(&arg_slice, optarg);
+ case 'S': {
+ _cleanup_free_ char *mangled = NULL;
+
+ r = unit_name_mangle_with_suffix(optarg, NULL, UNIT_NAME_MANGLE_WARN, ".slice", &mangled);
if (r < 0)
return log_oom();
+ free_and_replace(arg_slice, mangled);
arg_settings_mask |= SETTING_SLICE;
break;
+ }
case 'M':
if (isempty(optarg))
@@ -2385,7 +2390,8 @@ static int drop_capabilities(uid_t uid) {
/* If we're not using OCI, proceed with mangled capabilities (so we don't error out)
* in order to maintain the same behavior as systemd < 242. */
if (capability_quintet_mangle(&q))
- log_warning("Some capabilities will not be set because they are not in the current bounding set.");
+ log_full(arg_quiet ? LOG_DEBUG : LOG_WARNING,
+ "Some capabilities will not be set because they are not in the current bounding set.");
}
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index 3469dd443e..a5f54610da 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -268,4 +268,5 @@ Parent=
NetworkEmulatorDelaySec=
NetworkEmulatorDelayJitterSec=
NetworkEmulatorLossRate=
+NetworkEmulatorDuplicateRate=
NetworkEmulatorPacketLimit=
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index e9b9fb0d7c..ab6e11e0e5 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -22,12 +22,16 @@ network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
-networkd_bin='/usr/lib/systemd/systemd-networkd'
-resolved_bin='/usr/lib/systemd/systemd-resolved'
-wait_online_bin='/usr/lib/systemd/systemd-networkd-wait-online'
-networkctl_bin='/usr/bin/networkctl'
-resolvectl_bin='/usr/bin/resolvectl'
-timedatectl_bin='/usr/bin/timedatectl'
+systemd_lib_paths=['/usr/lib/systemd', '/lib/systemd']
+which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':').split(':'))
+
+networkd_bin=shutil.which('systemd-networkd', path=which_paths)
+resolved_bin=shutil.which('systemd-resolved', path=which_paths)
+wait_online_bin=shutil.which('systemd-networkd-wait-online', path=which_paths)
+networkctl_bin=shutil.which('networkctl', path=which_paths)
+resolvectl_bin=shutil.which('resolvectl', path=which_paths)
+timedatectl_bin=shutil.which('timedatectl', path=which_paths)
+
use_valgrind=False
enable_debug=True
env = {}
@@ -53,7 +57,7 @@ def run(*command, **kwargs):
def is_module_available(module_name):
lsmod_output = check_output('lsmod')
module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE)
- return module_re.search(lsmod_output) or not call('modprobe', module_name)
+ return module_re.search(lsmod_output) or not call('modprobe', module_name, stderr=subprocess.DEVNULL)
def expectedFailureIfModuleIsNotAvailable(module_name):
def f(func):
@@ -65,7 +69,7 @@ def expectedFailureIfModuleIsNotAvailable(module_name):
def expectedFailureIfERSPANModuleIsNotAvailable():
def f(func):
- rc = call('ip link add dev erspan99 type erspan seq key 30 local 192.168.1.4 remote 192.168.1.1 erspan_ver 1 erspan 123')
+ rc = call('ip link add dev erspan99 type erspan seq key 30 local 192.168.1.4 remote 192.168.1.1 erspan_ver 1 erspan 123', stderr=subprocess.DEVNULL)
if rc == 0:
call('ip link del erspan99')
return func
@@ -76,7 +80,7 @@ def expectedFailureIfERSPANModuleIsNotAvailable():
def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
def f(func):
- rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
+ rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7', stderr=subprocess.DEVNULL)
if rc == 0:
call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
return func
@@ -87,7 +91,7 @@ def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
def f(func):
- rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7')
+ rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7', stderr=subprocess.DEVNULL)
if rc == 0:
call('ip rule del not from 192.168.100.19 ipproto tcp table 7')
return func
@@ -99,7 +103,7 @@ def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
def expectedFailureIfLinkFileFieldIsNotSet():
def f(func):
support = False
- rc = call('ip link add name dummy99 type dummy')
+ rc = call('ip link add name dummy99 type dummy', stderr=subprocess.DEVNULL)
if rc == 0:
ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if ret.returncode == 0 and 'E: ID_NET_LINK_FILE=' in ret.stdout.rstrip():
@@ -115,7 +119,7 @@ def expectedFailureIfLinkFileFieldIsNotSet():
def expectedFailureIfNexthopIsNotAvailable():
def f(func):
- rc = call('ip nexthop list')
+ rc = call('ip nexthop list', stderr=subprocess.DEVNULL)
if rc == 0:
return func
else:
@@ -510,12 +514,12 @@ class NetworkctlTests(unittest.TestCase, Utilities):
output = check_output(*networkctl_cmd, 'status', 'test1')
print(output)
- self.assertRegex(output, r'Link File: (?:/usr)/lib/systemd/network/99-default.link')
+ self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
output = check_output(*networkctl_cmd, 'status', 'lo')
print(output)
- self.assertRegex(output, r'Link File: (?:/usr)/lib/systemd/network/99-default.link')
+ self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
self.assertRegex(output, r'Network File: n/a')
def test_delete_links(self):
@@ -748,7 +752,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.wait_online(['bridge99', 'test1:degraded'], bool_any=True)
- self.check_operstate('bridge99', '(?:off|no-carrier)', setup_state='configuring')
+ self.check_operstate('bridge99', '(off|no-carrier)', setup_state='configuring')
self.check_operstate('test1', 'degraded')
def test_bridge(self):
@@ -921,7 +925,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show tun99')
print(output)
# Old ip command does not support IFF_ flags
- self.assertRegex(output, 'tun (?:type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
+ self.assertRegex(output, 'tun (type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
def test_tap(self):
copy_unit_to_networkd_unit_path('25-tap.netdev')
@@ -932,7 +936,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show tap99')
print(output)
# Old ip command does not support IFF_ flags
- self.assertRegex(output, 'tun (?:type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
+ self.assertRegex(output, 'tun (type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
@expectedFailureIfModuleIsNotAvailable('vrf')
def test_vrf(self):
@@ -1010,16 +1014,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show ipiptun99')
print(output)
- self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local 192.168.223.238 dev dummy98')
+ self.assertRegex(output, 'ipip (ipip )?remote 192.169.224.239 local 192.168.223.238 dev dummy98')
output = check_output('ip -d link show ipiptun98')
print(output)
- self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local any dev dummy98')
+ self.assertRegex(output, 'ipip (ipip )?remote 192.169.224.239 local any dev dummy98')
output = check_output('ip -d link show ipiptun97')
print(output)
- self.assertRegex(output, 'ipip (?:ipip |)remote any local 192.168.223.238 dev dummy98')
+ self.assertRegex(output, 'ipip (ipip )?remote any local 192.168.223.238 dev dummy98')
output = check_output('ip -d link show ipiptun96')
print(output)
- self.assertRegex(output, 'ipip (?:ipip |)remote any local any dev dummy98')
+ self.assertRegex(output, 'ipip (ipip )?remote any local any dev dummy98')
def test_gre_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network',
@@ -1159,10 +1163,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
output = check_output('ip -d link show vti6tun98')
print(output)
- self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
+ self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
output = check_output('ip -d link show vti6tun97')
print(output)
- self.assertRegex(output, 'vti6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
+ self.assertRegex(output, 'vti6 remote (any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
def test_ip6tnl_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network',
@@ -1177,10 +1181,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
output = check_output('ip -d link show ip6tnl98')
print(output)
- self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
+ self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
output = check_output('ip -d link show ip6tnl97')
print(output)
- self.assertRegex(output, 'ip6tnl ip6ip6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
+ self.assertRegex(output, 'ip6tnl ip6ip6 remote (any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
def test_sit_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network',
@@ -1193,16 +1197,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show sittun99')
print(output)
- self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local 10.65.223.238 dev dummy98")
+ self.assertRegex(output, "sit (ip6ip )?remote 10.65.223.239 local 10.65.223.238 dev dummy98")
output = check_output('ip -d link show sittun98')
print(output)
- self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local any dev dummy98")
+ self.assertRegex(output, "sit (ip6ip )?remote 10.65.223.239 local any dev dummy98")
output = check_output('ip -d link show sittun97')
print(output)
- self.assertRegex(output, "sit (?:ip6ip |)remote any local 10.65.223.238 dev dummy98")
+ self.assertRegex(output, "sit (ip6ip )?remote any local 10.65.223.238 dev dummy98")
output = check_output('ip -d link show sittun96')
print(output)
- self.assertRegex(output, "sit (?:ip6ip |)remote any local any dev dummy98")
+ self.assertRegex(output, "sit (ip6ip )?remote any local any dev dummy98")
def test_isatap_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network',
@@ -1596,7 +1600,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, '111:')
self.assertRegex(output, 'from 192.168.100.18')
- self.assertRegex(output, r'tos (?:0x08|throughput)\s')
+ self.assertRegex(output, r'tos (0x08|throughput)\s')
self.assertRegex(output, 'iif test1')
self.assertRegex(output, 'oif test1')
self.assertRegex(output, 'lookup 7')
@@ -1634,11 +1638,11 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
output = check_output('ip rule list table 7')
print(output)
- self.assertRegex(output, '111: from 192.168.100.18 tos (?:0x08|throughput) iif test1 oif test1 lookup 7')
+ self.assertRegex(output, '111: from 192.168.100.18 tos (0x08|throughput) iif test1 oif test1 lookup 7')
output = check_output('ip rule list table 8')
print(output)
- self.assertRegex(output, '112: from 192.168.101.18 tos (?:0x08|throughput) iif dummy98 oif dummy98 lookup 8')
+ self.assertRegex(output, '112: from 192.168.101.18 tos (0x08|throughput) iif dummy98 oif dummy98 lookup 8')
stop_networkd(remove_state_files=False)
@@ -2109,7 +2113,7 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
self.assertRegex(data, r'LLMNR=no')
self.assertRegex(data, r'MDNS=yes')
self.assertRegex(data, r'DNSSEC=no')
- self.assertRegex(data, r'ADDRESSES=192.168.(?:10.10|12.12)/24 192.168.(?:12.12|10.10)/24')
+ self.assertRegex(data, r'ADDRESSES=192.168.(10.10|12.12)/24 192.168.(12.12|10.10)/24')
check_output(*resolvectl_cmd, 'dns', 'dummy98', '10.10.10.12', '10.10.10.13', env=env)
check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env)
@@ -2379,7 +2383,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
print('### ip -6 route list table all dev bridge99')
output = check_output('ip -6 route list table all dev bridge99')
print(output)
- self.assertRegex(output, 'ff00::/8 table local metric 256 (?:linkdown |)pref medium')
+ self.assertRegex(output, 'ff00::/8 table local metric 256 (linkdown )?pref medium')
def test_bridge_ignore_carrier_loss(self):
copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
@@ -2645,7 +2649,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
print(output)
@@ -2824,7 +2828,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet6 2600::[0-9a-f]*/128 scope global (?:noprefixroute dynamic|dynamic noprefixroute)')
+ self.assertRegex(output, r'inet6 2600::[0-9a-f]*/128 scope global (noprefixroute dynamic|dynamic noprefixroute)')
output = check_output('ip -6 route show dev veth99')
print(output)
@@ -2933,7 +2937,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
output = check_output('ip address show dev veth99 scope global')
print(output)
@@ -2976,7 +2980,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
print('## ip -d link show dev vrf99')
output = check_output('ip -d link show dev vrf99')
@@ -2988,7 +2992,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
- self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)')
+ self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link')
print('## ip address show dev veth99')
@@ -2996,7 +3000,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
- self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)')
+ self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link')
print('## ip route show vrf vrf99')
@@ -3145,7 +3149,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
@@ -3163,7 +3167,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
@@ -3181,7 +3185,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
@@ -3199,7 +3203,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
- self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
+ self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)