Compare commits

..

No commits in common. "f4dad55b8b2861426a7b9e7104dec33acb770894" and "df957acc6603a04e62dee7e911c65dc7dbcb6208" have entirely different histories.

9 changed files with 85 additions and 130 deletions

View File

@ -662,12 +662,15 @@ 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) { int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask) {
if (inotify_add_watch(fd, pathname, mask) < 0) { if (inotify_add_watch(fd, pathname, mask) < 0) {
if (errno == ENOSPC) const char *reason;
return log_error_errno(errno, "Failed to add a watch for %s: inotify watch limit reached", pathname);
return log_error_errno(errno, "Failed to add a watch for %s: %m", pathname); 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: %s", pathname, reason);
} }
return 0; return 0;

View File

@ -40,8 +40,8 @@ typedef struct StaticDestructor {
extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[]; extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[];
extern const struct StaticDestructor _weak_ __stop_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 function to destroy everything. (Note that this must be static inline, as it's key that it remains in the same
* the same linking unit as the variables we want to destroy.) */ * linking unit as the variables we want to destroy. */
static inline void static_destruct(void) { static inline void static_destruct(void) {
const StaticDestructor *d; const StaticDestructor *d;

View File

@ -409,10 +409,8 @@ char* gid_to_name(gid_t gid) {
} }
int in_gid(gid_t gid) { int in_gid(gid_t gid) {
_cleanup_free_ gid_t *allocated = NULL; gid_t *gids;
gid_t local[16], *p = local; int ngroups, r, i;
int ngroups = ELEMENTSOF(local);
unsigned attempt = 0;
if (getgid() == gid) if (getgid() == gid)
return 1; return 1;
@ -423,39 +421,23 @@ int in_gid(gid_t gid) {
if (!gid_is_valid(gid)) if (!gid_is_valid(gid))
return -EINVAL; return -EINVAL;
for (;;) {
ngroups = getgroups(ngroups, p);
if (ngroups >= 0)
break;
if (errno != EINVAL)
return -errno;
/* Give up eventually */
if (attempt++ > 10)
return -EINVAL;
/* Get actual size needed, and size the array explicitly. Note that this is potentially racy
* to use (in multi-threaded programs), hence let's call this in a loop. */
ngroups = getgroups(0, NULL); ngroups = getgroups(0, NULL);
if (ngroups < 0) if (ngroups < 0)
return -errno; return -errno;
if (ngroups == 0) if (ngroups == 0)
return false; return 0;
free(allocated); gids = newa(gid_t, ngroups);
allocated = new(gid_t, ngroups); r = getgroups(ngroups, gids);
if (!allocated) if (r < 0)
return -ENOMEM; return -errno;
p = allocated; for (i = 0; i < r; i++)
} if (gids[i] == gid)
return 1;
for (int i = 0; i < ngroups; i++) return 0;
if (p[i] == gid)
return true;
return false;
} }
int in_group(const char *name) { int in_group(const char *name) {

View File

@ -38,6 +38,7 @@
#include "set.h" #include "set.h"
#include "signal-util.h" #include "signal-util.h"
#include "stat-util.h" #include "stat-util.h"
#include "static-destruct.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
#include "time-util.h" #include "time-util.h"
@ -48,8 +49,11 @@
int saved_argc = 0; int saved_argc = 0;
char **saved_argv = NULL; char **saved_argv = NULL;
char **saved_env = NULL;
static int saved_in_initrd = -1; static int saved_in_initrd = -1;
STATIC_DESTRUCTOR_REGISTER(saved_env, strv_freep);
bool kexec_loaded(void) { bool kexec_loaded(void) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
@ -297,3 +301,7 @@ void disable_coredumps(void) {
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m"); log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
} }
void save_env(void) {
saved_env = strv_copy(environ);
}

View File

@ -13,6 +13,9 @@ static inline void save_argc_argv(int argc, char **argv) {
saved_argv = argv; saved_argv = argv;
} }
extern char **saved_env;
void save_env(void);
bool kexec_loaded(void); bool kexec_loaded(void);
int prot_from_flags(int flags) _const_; int prot_from_flags(int flags) _const_;

View File

@ -146,9 +146,6 @@ static OOMPolicy arg_default_oom_policy;
static CPUSet arg_cpu_affinity; static CPUSet arg_cpu_affinity;
static NUMAPolicy arg_numa_policy; 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, static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
const struct rlimit *saved_rlimit_memlock); const struct rlimit *saved_rlimit_memlock);
@ -2356,17 +2353,6 @@ 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 */ 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[]) { int main(int argc, char *argv[]) {
dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL, dual_timestamp initrd_timestamp = DUAL_TIMESTAMP_NULL, userspace_timestamp = DUAL_TIMESTAMP_NULL, kernel_timestamp = DUAL_TIMESTAMP_NULL,
@ -2405,13 +2391,9 @@ int main(int argc, char *argv[]) {
/* Save the original command line */ /* Save the original command line */
save_argc_argv(argc, argv); save_argc_argv(argc, argv);
/* Save the original environment as we might need to restore it if we're requested to execute another /* Save the original environment as we might need to restore it if we're requested to
* system manager later. */ * execute another system manager later. */
r = save_env(); 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. */ /* Make sure that if the user says "syslog" we actually log to the journal. */
log_set_upgrade_syslog_to_journal(true); log_set_upgrade_syslog_to_journal(true);
@ -2699,8 +2681,6 @@ finish:
arg_serialization = safe_fclose(arg_serialization); arg_serialization = safe_fclose(arg_serialization);
fds = fdset_free(fds); fds = fdset_free(fds);
saved_env = strv_free(saved_env);
#if HAVE_VALGRIND_VALGRIND_H #if HAVE_VALGRIND_VALGRIND_H
/* If we are PID 1 and running under valgrind, then let's exit /* If we are PID 1 and running under valgrind, then let's exit
* here explicitly. valgrind will only generate nice output on * here explicitly. valgrind will only generate nice output on

View File

@ -103,7 +103,6 @@
#include "terminal-util.h" #include "terminal-util.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
#include "umask-util.h" #include "umask-util.h"
#include "unit-name.h"
#include "user-util.h" #include "user-util.h"
#include "util.h" #include "util.h"
@ -892,17 +891,13 @@ static int parse_argv(int argc, char *argv[]) {
arg_settings_mask |= SETTING_MACHINE_ID; arg_settings_mask |= SETTING_MACHINE_ID;
break; break;
case 'S': { case 'S':
_cleanup_free_ char *mangled = NULL; r = free_and_strdup(&arg_slice, optarg);
r = unit_name_mangle_with_suffix(optarg, NULL, UNIT_NAME_MANGLE_WARN, ".slice", &mangled);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
free_and_replace(arg_slice, mangled);
arg_settings_mask |= SETTING_SLICE; arg_settings_mask |= SETTING_SLICE;
break; break;
}
case 'M': case 'M':
if (isempty(optarg)) if (isempty(optarg))
@ -2390,8 +2385,7 @@ static int drop_capabilities(uid_t uid) {
/* If we're not using OCI, proceed with mangled capabilities (so we don't error out) /* 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. */ * in order to maintain the same behavior as systemd < 242. */
if (capability_quintet_mangle(&q)) if (capability_quintet_mangle(&q))
log_full(arg_quiet ? LOG_DEBUG : LOG_WARNING, log_warning("Some capabilities will not be set because they are not in the current bounding set.");
"Some capabilities will not be set because they are not in the current bounding set.");
} }

View File

@ -286,15 +286,6 @@ static void test_make_salt(void) {
assert(!streq(s, t)); assert(!streq(s, t));
} }
static void test_in_gid(void) {
assert(in_gid(getgid()) >= 0);
assert(in_gid(getegid()) >= 0);
assert(in_gid(GID_INVALID) < 0);
assert(in_gid(TTY_GID) == 0); /* The TTY gid is for owning ttys, it would be really really weird if we were in it. */
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_uid_to_name_one(0, "root"); test_uid_to_name_one(0, "root");
test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME); test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
@ -329,7 +320,5 @@ int main(int argc, char *argv[]) {
test_make_salt(); test_make_salt();
test_in_gid();
return 0; return 0;
} }

View File

@ -22,16 +22,12 @@ network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid' dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file' dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
systemd_lib_paths=['/usr/lib/systemd', '/lib/systemd'] networkd_bin='/usr/lib/systemd/systemd-networkd'
which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':').split(':')) resolved_bin='/usr/lib/systemd/systemd-resolved'
wait_online_bin='/usr/lib/systemd/systemd-networkd-wait-online'
networkd_bin=shutil.which('systemd-networkd', path=which_paths) networkctl_bin='/usr/bin/networkctl'
resolved_bin=shutil.which('systemd-resolved', path=which_paths) resolvectl_bin='/usr/bin/resolvectl'
wait_online_bin=shutil.which('systemd-networkd-wait-online', path=which_paths) timedatectl_bin='/usr/bin/timedatectl'
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 use_valgrind=False
enable_debug=True enable_debug=True
env = {} env = {}
@ -57,7 +53,7 @@ def run(*command, **kwargs):
def is_module_available(module_name): def is_module_available(module_name):
lsmod_output = check_output('lsmod') lsmod_output = check_output('lsmod')
module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE) module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE)
return module_re.search(lsmod_output) or not call('modprobe', module_name, stderr=subprocess.DEVNULL) return module_re.search(lsmod_output) or not call('modprobe', module_name)
def expectedFailureIfModuleIsNotAvailable(module_name): def expectedFailureIfModuleIsNotAvailable(module_name):
def f(func): def f(func):
@ -69,7 +65,7 @@ def expectedFailureIfModuleIsNotAvailable(module_name):
def expectedFailureIfERSPANModuleIsNotAvailable(): def expectedFailureIfERSPANModuleIsNotAvailable():
def f(func): 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', stderr=subprocess.DEVNULL) 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')
if rc == 0: if rc == 0:
call('ip link del erspan99') call('ip link del erspan99')
return func return func
@ -80,7 +76,7 @@ def expectedFailureIfERSPANModuleIsNotAvailable():
def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable(): def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
def f(func): def f(func):
rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7', stderr=subprocess.DEVNULL) rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
if rc == 0: if rc == 0:
call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7') call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
return func return func
@ -91,7 +87,7 @@ def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable(): def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
def f(func): def f(func):
rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7', stderr=subprocess.DEVNULL) rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7')
if rc == 0: if rc == 0:
call('ip rule del not from 192.168.100.19 ipproto tcp table 7') call('ip rule del not from 192.168.100.19 ipproto tcp table 7')
return func return func
@ -103,7 +99,7 @@ def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
def expectedFailureIfLinkFileFieldIsNotSet(): def expectedFailureIfLinkFileFieldIsNotSet():
def f(func): def f(func):
support = False support = False
rc = call('ip link add name dummy99 type dummy', stderr=subprocess.DEVNULL) rc = call('ip link add name dummy99 type dummy')
if rc == 0: if rc == 0:
ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 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(): if ret.returncode == 0 and 'E: ID_NET_LINK_FILE=' in ret.stdout.rstrip():
@ -119,7 +115,7 @@ def expectedFailureIfLinkFileFieldIsNotSet():
def expectedFailureIfNexthopIsNotAvailable(): def expectedFailureIfNexthopIsNotAvailable():
def f(func): def f(func):
rc = call('ip nexthop list', stderr=subprocess.DEVNULL) rc = call('ip nexthop list')
if rc == 0: if rc == 0:
return func return func
else: else:
@ -514,12 +510,12 @@ class NetworkctlTests(unittest.TestCase, Utilities):
output = check_output(*networkctl_cmd, 'status', 'test1') output = check_output(*networkctl_cmd, 'status', 'test1')
print(output) 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') self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
output = check_output(*networkctl_cmd, 'status', 'lo') output = check_output(*networkctl_cmd, 'status', 'lo')
print(output) 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') self.assertRegex(output, r'Network File: n/a')
def test_delete_links(self): def test_delete_links(self):
@ -752,7 +748,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.wait_online(['bridge99', 'test1:degraded'], bool_any=True) 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') self.check_operstate('test1', 'degraded')
def test_bridge(self): def test_bridge(self):
@ -925,7 +921,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show tun99') output = check_output('ip -d link show tun99')
print(output) print(output)
# Old ip command does not support IFF_ flags # 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): def test_tap(self):
copy_unit_to_networkd_unit_path('25-tap.netdev') copy_unit_to_networkd_unit_path('25-tap.netdev')
@ -936,7 +932,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show tap99') output = check_output('ip -d link show tap99')
print(output) print(output)
# Old ip command does not support IFF_ flags # 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') @expectedFailureIfModuleIsNotAvailable('vrf')
def test_vrf(self): def test_vrf(self):
@ -1014,16 +1010,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show ipiptun99') output = check_output('ip -d link show ipiptun99')
print(output) 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') output = check_output('ip -d link show ipiptun98')
print(output) 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') output = check_output('ip -d link show ipiptun97')
print(output) 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') output = check_output('ip -d link show ipiptun96')
print(output) 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): def test_gre_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network', copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network',
@ -1163,10 +1159,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98') 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') output = check_output('ip -d link show vti6tun98')
print(output) 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') output = check_output('ip -d link show vti6tun97')
print(output) 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): def test_ip6tnl_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network', copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network',
@ -1181,10 +1177,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') 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') output = check_output('ip -d link show ip6tnl98')
print(output) 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') output = check_output('ip -d link show ip6tnl97')
print(output) 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): def test_sit_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network', copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network',
@ -1197,16 +1193,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip -d link show sittun99') output = check_output('ip -d link show sittun99')
print(output) 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') output = check_output('ip -d link show sittun98')
print(output) 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') output = check_output('ip -d link show sittun97')
print(output) 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') output = check_output('ip -d link show sittun96')
print(output) 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): def test_isatap_tunnel(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network', copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network',
@ -1600,7 +1596,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertRegex(output, '111:') self.assertRegex(output, '111:')
self.assertRegex(output, 'from 192.168.100.18') 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, 'iif test1')
self.assertRegex(output, 'oif test1') self.assertRegex(output, 'oif test1')
self.assertRegex(output, 'lookup 7') self.assertRegex(output, 'lookup 7')
@ -1638,11 +1634,11 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
output = check_output('ip rule list table 7') output = check_output('ip rule list table 7')
print(output) 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') output = check_output('ip rule list table 8')
print(output) 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) stop_networkd(remove_state_files=False)
@ -2113,7 +2109,7 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
self.assertRegex(data, r'LLMNR=no') self.assertRegex(data, r'LLMNR=no')
self.assertRegex(data, r'MDNS=yes') self.assertRegex(data, r'MDNS=yes')
self.assertRegex(data, r'DNSSEC=no') 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, 'dns', 'dummy98', '10.10.10.12', '10.10.10.13', env=env)
check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env) check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env)
@ -2383,7 +2379,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
print('### ip -6 route list table all dev bridge99') print('### ip -6 route list table all dev bridge99')
output = check_output('ip -6 route list table all dev bridge99') output = check_output('ip -6 route list table all dev bridge99')
print(output) 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): def test_bridge_ignore_carrier_loss(self):
copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev', copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
@ -2649,7 +2645,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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) output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
print(output) print(output)
@ -2828,7 +2824,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip address show dev veth99 scope global') output = check_output('ip address show dev veth99 scope global')
print(output) 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') output = check_output('ip -6 route show dev veth99')
print(output) print(output)
@ -2937,7 +2933,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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') output = check_output('ip address show dev veth99 scope global')
print(output) print(output)
@ -2980,7 +2976,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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') print('## ip -d link show dev vrf99')
output = check_output('ip -d link show dev vrf99') output = check_output('ip -d link show dev vrf99')
@ -2992,7 +2988,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output) 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 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, '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') self.assertRegex(output, 'inet6 .* scope link')
print('## ip address show dev veth99') print('## ip address show dev veth99')
@ -3000,7 +2996,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print(output) 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 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, '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') self.assertRegex(output, 'inet6 .* scope link')
print('## ip route show vrf vrf99') print('## ip route show vrf vrf99')
@ -3149,7 +3145,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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) time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env) output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
@ -3167,7 +3163,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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) time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env) output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
@ -3185,7 +3181,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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) time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env) output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
@ -3203,7 +3199,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
# link become 'routable' when at least one protocol provide an valid address. # 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'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) time.sleep(3)
output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env) output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)