# systemd-networkd tests
# These tests can be executed in the systemd mkosi image when booted in QEMU. After booting the QEMU VM,
-# simply run this file which can be found in the VM at /usr/lib/systemd/tests/testdata/test-network/systemd-networkd-tests.py.
+# simply run this file which can be found in the VM at
+# /usr/lib/systemd/tests/testdata/test-network/systemd-networkd-tests.py.
#
# To run an individual test, specify it as a command line argument in the form
# of <class>.<test_function>. E.g. the NetworkdMTUTests class has a test
import datetime
import enum
import errno
-import itertools
import ipaddress
+import itertools
import json
import os
import pathlib
asan_options = os.getenv('ASAN_OPTIONS')
lsan_options = os.getenv('LSAN_OPTIONS')
ubsan_options = os.getenv('UBSAN_OPTIONS')
-with_coverage = os.getenv('COVERAGE_BUILD_DIR') != None
-show_journal = True # When true, show journal on stopping networkd.
+with_coverage = os.getenv('COVERAGE_BUILD_DIR') is not None
+show_journal = True # When true, show journal on stopping networkd.
active_units = []
protected_links = {
saved_ipv6_rules = None
saved_timezone = None
+
def rm_f(path):
if os.path.exists(path):
os.remove(path)
+
def rm_rf(path):
shutil.rmtree(path, ignore_errors=True)
+
def cp(src, dst):
shutil.copy(src, dst)
+
def cp_r(src, dst):
shutil.copytree(src, dst, copy_function=shutil.copy, dirs_exist_ok=True)
+
def mkdir_p(path):
os.makedirs(path, exist_ok=True)
+
def touch(path):
pathlib.Path(path).touch()
+
# pylint: disable=R1710
def check_output(*command, **kwargs):
# This checks the result and returns stdout (and stderr) on success.
command = command[0].split() + list(command[1:])
- ret = subprocess.run(command, check=False, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
+ ret = subprocess.run(
+ command,
+ check=False,
+ text=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ **kwargs,
+ )
if ret.returncode == 0:
return ret.stdout.rstrip()
# When returncode != 0, print stdout and stderr, then trigger CalledProcessError.
print(ret.stdout)
ret.check_returncode()
+
def call(*command, **kwargs):
# This returns returncode. stdout and stderr are merged and shown in console
command = command[0].split() + list(command[1:])
- return subprocess.run(command, check=False, universal_newlines=True, stderr=subprocess.STDOUT, **kwargs).returncode
+ return subprocess.run(
+ command,
+ check=False,
+ text=True,
+ stderr=subprocess.STDOUT,
+ **kwargs,
+ ).returncode
+
def call_check(*command, **kwargs):
# Same as call() above, but it triggers CalledProcessError if rc != 0
command = command[0].split() + list(command[1:])
- return subprocess.run(command, check=False, universal_newlines=True, stderr=subprocess.STDOUT, **kwargs).check_returncode()
+ return subprocess.run(
+ command,
+ check=False,
+ text=True,
+ stderr=subprocess.STDOUT,
+ **kwargs,
+ ).check_returncode()
+
def call_quiet(*command, **kwargs):
command = command[0].split() + list(command[1:])
- return subprocess.run(command, check=False, universal_newlines=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, **kwargs).returncode
+ return subprocess.run(
+ command,
+ check=False,
+ text=True,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ **kwargs,
+ ).returncode
+
def run(*command, **kwargs):
# This returns CompletedProcess instance.
command = command[0].split() + list(command[1:])
- return subprocess.run(command, check=False, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
+ return subprocess.run(
+ command,
+ check=False,
+ text=True,
+ capture_output=True,
+ **kwargs,
+ )
+
def check_json(string):
try:
print(f"String is not a valid JSON: '{string}'")
raise
+
def is_module_available(*module_names):
for module_name in module_names:
lsmod_output = check_output('lsmod')
return False
return True
+
def expectedFailureIfModuleIsNotAvailable(*module_names):
def f(func):
return func if is_module_available(*module_names) else unittest.expectedFailure(func)
return f
+
# pylint: disable=C0415
def compare_kernel_version(min_kernel_version):
try:
import platform
+
from packaging import version
except ImportError:
print('Failed to import either platform or packaging module, assuming the comparison failed')
return version.parse(kver) >= version.parse(min_kernel_version)
+
def copy_network_unit(*units, copy_dropins=True):
"""
Copy networkd unit files into the testbed.
mkdir_p(network_unit_dir)
for unit in units:
if copy_dropins and os.path.exists(os.path.join(networkd_ci_temp_dir, unit + '.d')):
- cp_r(os.path.join(networkd_ci_temp_dir, unit + '.d'), os.path.join(network_unit_dir, unit + '.d'))
+ cp_r(
+ os.path.join(networkd_ci_temp_dir, unit + '.d'),
+ os.path.join(network_unit_dir, unit + '.d'),
+ )
if unit.endswith('.conf'):
dropin = unit
if has_link:
udevadm_reload()
+
def copy_credential(src, target):
- mkdir_p(credstore_dir)
- cp(os.path.join(networkd_ci_temp_dir, src),
- os.path.join(credstore_dir, target))
+ mkdir_p(credstore_dir)
+ cp(os.path.join(networkd_ci_temp_dir, src), os.path.join(credstore_dir, target))
+
def remove_network_unit(*units):
"""
if has_link:
udevadm_reload()
+
def touch_network_unit(*units):
for unit in units:
touch(os.path.join(network_unit_dir, unit))
+
def clear_network_units():
has_link = False
if os.path.exists(network_unit_dir):
if has_link:
udevadm_reload()
+
def copy_networkd_conf_dropin(*dropins):
"""Copy networkd.conf dropin files into the testbed."""
mkdir_p(networkd_conf_dropin_dir)
for dropin in dropins:
cp(os.path.join(networkd_ci_temp_dir, dropin), networkd_conf_dropin_dir)
+
def remove_networkd_conf_dropin(*dropins):
"""Remove previously copied networkd.conf dropin files from the testbed."""
for dropin in dropins:
rm_f(os.path.join(networkd_conf_dropin_dir, dropin))
+
def clear_networkd_conf_dropins():
rm_rf(networkd_conf_dropin_dir)
+
def setup_systemd_udev_rules():
if not build_dir and not source_dir:
return
if not path:
continue
- path = os.path.join(path, "rules.d")
- print(f"Copying udev rules from {path} to {udev_rules_dir}")
+ path = os.path.join(path, 'rules.d')
+ print(f'Copying udev rules from {path} to {udev_rules_dir}')
for rule in os.listdir(path):
- if not rule.endswith(".rules"):
+ if not rule.endswith('.rules'):
continue
cp(os.path.join(path, rule), udev_rules_dir)
+
def clear_networkd_state_files():
rm_rf('/var/lib/systemd/network/')
+
def copy_udev_rule(*rules):
"""Copy udev rules"""
mkdir_p(udev_rules_dir)
for rule in rules:
cp(os.path.join(networkd_ci_temp_dir, rule), udev_rules_dir)
+
def remove_udev_rule(*rules):
"""Remove previously copied udev rules"""
for rule in rules:
rm_f(os.path.join(udev_rules_dir, rule))
+
def clear_udev_rules():
rm_rf(udev_rules_dir)
+
def save_active_units():
for u in [
- 'systemd-networkd.socket',
- 'systemd-networkd-resolve-hook.socket',
- 'systemd-networkd-varlink.socket',
- 'systemd-networkd-varlink-metrics.socket',
- 'systemd-networkd.service',
- 'systemd-resolved-monitor.socket',
- 'systemd-resolved-varlink.socket',
- 'systemd-resolved.service',
- 'systemd-timesyncd.service',
- 'firewalld.service',
- 'nftables.service',
+ 'systemd-networkd.socket',
+ 'systemd-networkd-resolve-hook.socket',
+ 'systemd-networkd-varlink.socket',
+ 'systemd-networkd-varlink-metrics.socket',
+ 'systemd-networkd.service',
+ 'systemd-resolved-monitor.socket',
+ 'systemd-resolved-varlink.socket',
+ 'systemd-resolved.service',
+ 'systemd-timesyncd.service',
+ 'firewalld.service',
+ 'nftables.service',
]:
if call(f'systemctl is-active --quiet {u}') == 0:
call(f'systemctl stop {u}')
active_units.append(u)
+
def restore_active_units():
has_network_socket = False
has_resolve_socket = False
for u in active_units:
call(f'systemctl restart {u}')
+
def create_unit_dropin(unit, contents):
mkdir_p(f'/run/systemd/system/{unit}.d')
with open(f'/run/systemd/system/{unit}.d/00-override.conf', mode='w', encoding='utf-8') as f:
f.write('\n'.join(contents))
+
def create_service_dropin(service, command, additional_settings=None):
drop_in = ['[Service]']
if command:
create_unit_dropin(f'{service}.service', drop_in)
+
def setup_system_units():
if build_dir or source_dir:
mkdir_p('/run/systemd/system/')
for unit in [
- 'systemd-networkd.service',
- 'systemd-networkd.socket',
- 'systemd-networkd-persistent-storage.service',
- 'systemd-networkd-resolve-hook.socket',
- 'systemd-networkd-varlink.socket',
- 'systemd-networkd-varlink-metrics.socket',
- 'systemd-resolved.service',
- 'systemd-timesyncd.service',
- 'systemd-udevd.service',
+ 'systemd-networkd.service',
+ 'systemd-networkd.socket',
+ 'systemd-networkd-persistent-storage.service',
+ 'systemd-networkd-resolve-hook.socket',
+ 'systemd-networkd-varlink.socket',
+ 'systemd-networkd-varlink-metrics.socket',
+ 'systemd-resolved.service',
+ 'systemd-timesyncd.service',
+ 'systemd-udevd.service',
]:
for path in [build_dir, source_dir]:
if not path:
continue
- fullpath = os.path.join(os.path.join(path, "units"), unit)
+ fullpath = os.path.join(os.path.join(path, 'units'), unit)
if os.path.exists(fullpath):
- print(f"Copying unit file from {fullpath} to /run/systemd/system/")
+ print(f'Copying unit file from {fullpath} to /run/systemd/system/')
cp(fullpath, '/run/systemd/system/')
break
- create_service_dropin('systemd-networkd', networkd_bin,
- ['[Service]',
- 'Restart=no',
- 'Environment=SYSTEMD_NETWORK_TEST_MODE=yes',
- '[Unit]',
- 'StartLimitIntervalSec=0'])
+ create_service_dropin(
+ 'systemd-networkd',
+ networkd_bin,
+ [
+ '[Service]',
+ 'Restart=no',
+ 'Environment=SYSTEMD_NETWORK_TEST_MODE=yes',
+ '[Unit]',
+ 'StartLimitIntervalSec=0',
+ ],
+ )
create_service_dropin('systemd-resolved', resolved_bin)
create_service_dropin('systemd-timesyncd', timesyncd_bin)
[
'[Unit]',
'StartLimitIntervalSec=0',
- ]
+ ],
)
create_unit_dropin(
'systemd-networkd-persistent-storage.service',
'ExecStop=',
f'ExecStop={networkctl_bin} persistent-storage no',
'Environment=SYSTEMD_LOG_LEVEL=debug' if enable_debug else '',
- ]
+ ],
)
create_unit_dropin(
'systemd-networkd-resolve-hook.socket',
[
'[Unit]',
'StartLimitIntervalSec=0',
- ]
+ ],
)
create_unit_dropin(
'systemd-networkd-varlink.socket',
[
'[Unit]',
'StartLimitIntervalSec=0',
- ]
+ ],
)
create_unit_dropin(
'systemd-networkd-varlink-metrics.socket',
[
'[Unit]',
'StartLimitIntervalSec=0',
- ]
+ ],
)
create_unit_dropin(
'systemd-udevd.service',
'[Service]',
'ExecStart=',
f'ExecStart=@{udevadm_bin} systemd-udevd',
- ]
+ ],
)
check_output('systemctl daemon-reload')
check_output('systemctl restart systemd-timesyncd.service')
check_output('systemctl restart systemd-udevd.service')
+
def clear_system_units():
def rm_unit(name):
rm_f(f'/run/systemd/system/{name}')
check_output('systemctl daemon-reload')
check_output('systemctl restart systemd-udevd.service')
+
def link_exists(*links):
for link in links:
if call_quiet(f'ip link show {link}') != 0:
return False
return True
+
def link_resolve(link):
return check_output(f'ip link show {link}').split(':')[1].strip().split('@')[0]
+
def remove_link(*links, protect=False):
for link in links:
if protect and link in protected_links:
if link_exists(link):
call(f'ip link del dev {link}')
+
def save_existing_links():
links = os.listdir('/sys/class/net')
for link in links:
print('### The following links will be protected:')
print(', '.join(sorted(list(protected_links))))
+
def unmanage_existing_links():
mkdir_p(network_unit_dir)
f.write(f'Name={link}\n')
f.write('\n[Link]\nUnmanaged=yes\n')
+
def flush_links():
links = os.listdir('/sys/class/net')
remove_link(*links, protect=True)
+
def flush_nexthops():
# Currently, the 'ip nexthop' command does not have 'save' and 'restore'.
# Hence, we cannot restore nexthops in a simple way.
# Let's assume there is no nexthop used in the system
call_quiet('ip nexthop flush')
+
def save_routes():
# pylint: disable=global-statement
global saved_routes
print('### The following routes will be protected:')
print(saved_routes)
+
def flush_routes():
have = False
output = check_output('ip route show table all')
continue
if 'proto kernel' in line:
continue
- if ' dev ' in line and not ' dev lo ' in line:
+ if ' dev ' in line and ' dev lo ' not in line:
continue
if not have:
have = True
print(f'# {line}')
call(f'ip route del {line}')
+
def save_routing_policy_rules():
# pylint: disable=global-statement
global saved_ipv4_rules, saved_ipv6_rules
+
def save(ipv):
output = check_output(f'ip -{ipv} rule show')
print(f'### The following IPv{ipv} routing policy rules will be protected:')
saved_ipv4_rules = save(4)
saved_ipv6_rules = save(6)
+
def flush_routing_policy_rules():
def flush(ipv, saved_rules):
have = False
continue
if not have:
have = True
- print(f'### Removing IPv{ipv} routing policy rules that did not exist when the test started.')
+ print(f'### Removing IPv{ipv} routing policy rules that did not exist when the test started.') # fmt: skip
print(f'# {line}')
words = line.replace('lookup [l3mdev-table]', 'l3mdev').replace('[detached]', '').split()
priority = words[0].rstrip(':')
flush(4, saved_ipv4_rules)
flush(6, saved_ipv6_rules)
+
def flush_fou_ports():
ret = run('ip fou show')
if ret.returncode != 0:
- return # fou may not be supported
+ return # fou may not be supported
for line in ret.stdout.splitlines():
port = line.split()[1]
call(f'ip fou del port {port}')
+
def flush_l2tp_tunnels():
tids = []
ret = run('ip l2tp show tunnel')
if ret.returncode != 0:
- return # l2tp may not be supported
+ return # l2tp may not be supported
for line in ret.stdout.splitlines():
words = line.split()
if words[0] == 'Tunnel':
r = run(f'ip l2tp show tunnel tunnel_id {tid}')
if r.returncode != 0 or len(r.stdout.rstrip()) == 0:
break
- time.sleep(.2)
+ time.sleep(0.2)
else:
print(f'Cannot remove L2TP tunnel {tid}, ignoring.')
+
def save_timezone():
# pylint: disable=global-statement
global saved_timezone
saved_timezone = r.stdout.rstrip()
print(f'### Saved timezone: {saved_timezone}')
+
def restore_timezone():
if saved_timezone:
call(*timedatectl_cmd, 'set-timezone', f'{saved_timezone}', env=env)
+
def read_link_attr(*args):
with open(os.path.join('/sys/class/net', *args), encoding='utf-8') as f:
return f.readline().strip()
+
def read_manager_state_file():
with open('/run/systemd/netif/state', encoding='utf-8') as f:
return f.read()
+
def read_link_state_file(link):
ifindex = read_link_attr(link, 'ifindex')
path = os.path.join('/run/systemd/netif/links', ifindex)
with open(path, encoding='utf-8') as f:
return f.read()
+
def read_ip_sysctl_attr(link, attribute, ipv):
with open(os.path.join('/proc/sys/net', ipv, 'conf', link, attribute), encoding='utf-8') as f:
return f.readline().strip()
+
def read_ip_neigh_sysctl_attr(link, attribute, ipv):
with open(os.path.join('/proc/sys/net', ipv, 'neigh', link, attribute), encoding='utf-8') as f:
return f.readline().strip()
+
def read_ipv6_sysctl_attr(link, attribute):
return read_ip_sysctl_attr(link, attribute, 'ipv6')
+
def read_ipv6_neigh_sysctl_attr(link, attribute):
return read_ip_neigh_sysctl_attr(link, attribute, 'ipv6')
+
def read_ipv4_sysctl_attr(link, attribute):
return read_ip_sysctl_attr(link, attribute, 'ipv4')
+
def read_mpls_sysctl_attr(link, attribute):
return read_ip_sysctl_attr(link, attribute, 'mpls')
+
def stop_by_pid_file(pid_file):
if not os.path.exists(pid_file):
return
- with open(pid_file, 'r', encoding='utf-8') as f:
+ with open(pid_file, encoding='utf-8') as f:
pid = f.read().rstrip(' \t\r\n\0')
os.kill(int(pid), signal.SIGTERM)
for _ in range(25):
try:
os.kill(int(pid), 0)
- print(f"PID {pid} is still alive, waiting...")
- time.sleep(.2)
+ print(f'PID {pid} is still alive, waiting...')
+ time.sleep(0.2)
except OSError as e:
if e.errno == errno.ESRCH:
break
- print(f"Unexpected exception when waiting for {pid} to die: {e.errno}")
+ print(f'Unexpected exception when waiting for {pid} to die: {e.errno}')
rm_f(pid_file)
-def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=("dot",), dohpath=None):
- b = bytes()
- pack = lambda c, w=1: struct.pack('>' + "_BH_I"[w], len(c)) + c
- pyton = lambda n, w=2: struct.pack('>' + "_BH_I"[w], n)
+
+def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None):
+ b = b''
+ pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c
+ pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n)
ipv4 = ipaddress.IPv4Address
+
class SvcParam(enum.Enum):
ALPN = 1
DOHPATH = 7
adn = adn.rstrip('.') + '.'
data += pack(b.join(pack(label.encode('ascii')) for label in adn.split('.')))
- if not addrs: # adn-only mode
+ if not addrs: # adn-only mode
return pack(data, 2)
data += pack(b.join(ipv4(addr).packed for addr in addrs))
return pack(data, 2)
-def dnr_v6_instance_data(adn, addrs=None, prio=1, alpns=("dot",), dohpath=None):
- b = bytes()
- pack = lambda c, w=1: struct.pack('>' + "_BH_I"[w], len(c)) + c
- pyton = lambda n, w=2: struct.pack('>' + "_BH_I"[w], n)
+
+def dnr_v6_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None):
+ b = b''
+ pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c
+ pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n)
ipv6 = ipaddress.IPv6Address
+
class SvcParam(enum.Enum):
ALPN = 1
DOHPATH = 7
adn = adn.rstrip('.') + '.'
data += pack(b.join(pack(label.encode('ascii')) for label in adn.split('.')), 2)
- if not addrs: # adn-only mode
+ if not addrs: # adn-only mode
return data
data += pack(b.join(ipv6(addr).packed for addr in addrs), 2)
return data
-def start_dnsmasq(*additional_options, namespace=None, interface='veth-peer', ra_mode=None, ipv4_range='192.168.5.10,192.168.5.200', ipv4_router='192.168.5.1', ipv6_range='2600::10,2600::20'):
+
+def start_dnsmasq(
+ *additional_options,
+ namespace=None,
+ interface='veth-peer',
+ ra_mode=None,
+ ipv4_range='192.168.5.10,192.168.5.200',
+ ipv4_router='192.168.5.1',
+ ipv6_range='2600::10,2600::20',
+):
if ra_mode:
ra_mode = f',{ra_mode}'
else:
else:
ns_command = ()
- command = ns_command + (
- 'dnsmasq',
- f'--log-facility={dnsmasq_log_file}',
- '--log-queries=extra',
- '--log-dhcp',
- f'--pid-file={dnsmasq_pid_file}',
- '--conf-file=/dev/null',
- '--bind-interfaces',
- f'--interface={interface}',
- f'--dhcp-leasefile={dnsmasq_lease_file}',
- '--enable-ra',
- f'--dhcp-range={ipv6_range}{ra_mode},2m',
- f'--dhcp-range={ipv4_range},2m',
- '--dhcp-option=option:mtu,1492',
- f'--dhcp-option=option:router,{ipv4_router}',
- '--port=0',
- '--no-resolv',
- ) + additional_options
+ command = (
+ ns_command
+ + (
+ 'dnsmasq',
+ f'--log-facility={dnsmasq_log_file}',
+ '--log-queries=extra',
+ '--log-dhcp',
+ f'--pid-file={dnsmasq_pid_file}',
+ '--conf-file=/dev/null',
+ '--bind-interfaces',
+ f'--interface={interface}',
+ f'--dhcp-leasefile={dnsmasq_lease_file}',
+ '--enable-ra',
+ f'--dhcp-range={ipv6_range}{ra_mode},2m',
+ f'--dhcp-range={ipv4_range},2m',
+ '--dhcp-option=option:mtu,1492',
+ f'--dhcp-option=option:router,{ipv4_router}',
+ '--port=0',
+ '--no-resolv',
+ )
+ + additional_options
+ )
check_output(*command)
+
def stop_dnsmasq():
stop_by_pid_file(dnsmasq_pid_file)
rm_f(dnsmasq_lease_file)
rm_f(dnsmasq_log_file)
+
def read_dnsmasq_log_file():
with open(dnsmasq_log_file, encoding='utf-8') as f:
return f.read()
+
def start_isc_dhcpd(conf_file, ipv, interface='veth-peer'):
conf_file_path = os.path.join(networkd_ci_temp_dir, conf_file)
- isc_dhcpd_command = f'dhcpd {ipv} -cf {conf_file_path} -lf {isc_dhcpd_lease_file} -pf {isc_dhcpd_pid_file} {interface}'
+ isc_dhcpd_command = f'dhcpd {ipv} -cf {conf_file_path} -lf {isc_dhcpd_lease_file} -pf {isc_dhcpd_pid_file} {interface}' # fmt: skip
touch(isc_dhcpd_lease_file)
check_output(isc_dhcpd_command)
+
def stop_isc_dhcpd():
stop_by_pid_file(isc_dhcpd_pid_file)
rm_f(isc_dhcpd_lease_file)
+
def get_dbus_link_path(link):
- out = subprocess.check_output(['busctl', 'call', 'org.freedesktop.network1',
- '/org/freedesktop/network1', 'org.freedesktop.network1.Manager',
- 'GetLinkByName', 's', link])
+ out = subprocess.check_output(
+ [
+ 'busctl',
+ 'call',
+ 'org.freedesktop.network1',
+ '/org/freedesktop/network1',
+ 'org.freedesktop.network1.Manager',
+ 'GetLinkByName',
+ 's',
+ link,
+ ]
+ )
assert out.startswith(b'io ')
out = out.strip()
out = out.decode()
return out[:-1].split('"')[1]
+
def get_dhcp_server_property(link, prop):
link_path = get_dbus_link_path(link)
- out = subprocess.check_output(['busctl', 'get-property', 'org.freedesktop.network1',
- link_path, 'org.freedesktop.network1.DHCPServer', prop])
+ out = subprocess.check_output(
+ [
+ 'busctl',
+ 'get-property',
+ 'org.freedesktop.network1',
+ link_path,
+ 'org.freedesktop.network1.DHCPServer',
+ prop,
+ ]
+ )
return out.strip().decode()
+
def get_dhcp_client_state(link, family):
link_path = get_dbus_link_path(link)
- out = subprocess.check_output(['busctl', 'get-property', 'org.freedesktop.network1',
- link_path, f'org.freedesktop.network1.DHCPv{family}Client', 'State'])
+ out = subprocess.check_output(
+ [
+ 'busctl',
+ 'get-property',
+ 'org.freedesktop.network1',
+ link_path,
+ f'org.freedesktop.network1.DHCPv{family}Client',
+ 'State',
+ ]
+ )
assert out.startswith(b's "')
out = out.strip()
assert out.endswith(b'"')
return out[3:-1].decode()
+
def get_dhcp4_client_state(link):
return get_dhcp_client_state(link, '4')
+
def get_dhcp6_client_state(link):
return get_dhcp_client_state(link, '6')
+
def get_link_description(link):
link_path = get_dbus_link_path(link)
- out = subprocess.check_output(['busctl', 'call', 'org.freedesktop.network1',
- link_path, 'org.freedesktop.network1.Link', 'Describe'])
+ out = subprocess.check_output(
+ [
+ 'busctl',
+ 'call',
+ 'org.freedesktop.network1',
+ link_path,
+ 'org.freedesktop.network1.Link',
+ 'Describe',
+ ]
+ )
assert out.startswith(b's "')
out = out.strip()
assert out.endswith(b'"')
json_raw = out[2:].decode()
check_json(json_raw)
- description = json.loads(json_raw) # Convert from escaped sequences to json
+ description = json.loads(json_raw) # Convert from escaped sequences to json
check_json(description)
- return json.loads(description) # Now parse the json
+ return json.loads(description) # Now parse the json
+
def start_radvd(*additional_options, config_file):
config_file_path = os.path.join(networkd_ci_temp_dir, 'radvd', config_file)
) + additional_options
check_output(*command)
+
def stop_radvd():
stop_by_pid_file(radvd_pid_file)
+
def start_modem_manager_mock(*additional_options):
dbus_policy_src = os.path.join(networkd_ci_temp_dir, 'mock-modem-manager.conf')
cp(dbus_policy_src, '/etc/dbus-1/system.d/mock-modem-manager.conf')
command = ' '.join([test_modem_manager_mock] + list(additional_options))
with open('/run/systemd/system/test-modem-manager-mock.service', mode='w', encoding='utf-8') as f:
- f.write('[Unit]\n'
- 'Description=Mock ModemManager for networkd testing\n'
- '[Service]\n'
- 'Type=notify\n'
- 'BusName=org.freedesktop.ModemManager1\n'
- f'ExecStart={command}\n')
+ f.write(
+ '[Unit]\n'
+ 'Description=Mock ModemManager for networkd testing\n'
+ '[Service]\n'
+ 'Type=notify\n'
+ 'BusName=org.freedesktop.ModemManager1\n'
+ f'ExecStart={command}\n'
+ )
check_output('systemctl daemon-reload')
check_output('systemctl start test-modem-manager-mock.service')
+
def stop_modem_manager_mock():
call('systemctl stop test-modem-manager-mock.service')
rm_f('/run/systemd/system/test-modem-manager-mock.service')
call('systemctl daemon-reload')
rm_f('/etc/dbus-1/system.d/mock-modem-manager.conf')
+
def radvd_check_config(config_file):
if not shutil.which('radvd'):
print('radvd is not installed, assuming the config check failed')
config_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf/radvd', config_file)
return call(f'radvd --config={config_file_path} --configtest') == 0
+
def networkd_invocation_id():
return check_output('systemctl show --value -p InvocationID systemd-networkd.service')
+
def networkd_pid():
return int(check_output('systemctl show --value -p MainPID systemd-networkd.service'))
+
def read_networkd_log(invocation_id=None, since=None):
if not invocation_id:
invocation_id = networkd_invocation_id()
check_output('journalctl --sync')
return check_output(*command)
+
def networkd_is_failed():
return call_quiet('systemctl is-failed -q systemd-networkd.service') != 1
+
def stop_networkd(show_logs=True, check_failed=True):
global show_journal
show_logs = show_logs and show_journal
if check_failed:
assert not networkd_is_failed()
+
def start_networkd():
check_output('systemctl start systemd-networkd')
invocation_id = networkd_invocation_id()
pid = networkd_pid()
print(f'Started systemd-networkd.service: PID={pid}, Invocation ID={invocation_id}')
+
def restart_networkd(show_logs=True):
global show_journal
show_logs = show_logs and show_journal
pid = networkd_pid()
print(f'Restarted systemd-networkd.service: PID={pid}, Invocation ID={invocation_id}')
+
def networkctl(*args):
# Do not call networkctl if networkd is in failed state.
# Otherwise, networkd may be restarted and we may get wrong results.
assert not networkd_is_failed()
return check_output(*(networkctl_cmd + list(args)), env=env)
+
def networkctl_status(*args):
return networkctl('-n', '0', 'status', *args)
+
def networkctl_json(*args):
return networkctl('--json=short', 'status', *args)
+
def networkctl_reconfigure(*links):
networkctl('reconfigure', *links)
+
def networkctl_reload():
networkctl('reload')
+
def resolvectl(*args):
return check_output(*(resolvectl_cmd + list(args)), env=env)
+
def timedatectl(*args):
return check_output(*(timedatectl_cmd + list(args)), env=env)
+
def udevadm(*args):
return check_output(*(udevadm_cmd + list(args)))
+
def udevadm_reload():
udevadm('control', '--reload')
+
def udevadm_trigger(*args, action='add'):
udevadm('trigger', '--settle', f'--action={action}', *args)
+
def setup_common():
# Protect existing links
unmanage_existing_links()
sys.stdout.flush()
check_output('journalctl --sync')
+
def tear_down_common():
# 1. stop DHCP/RA servers
stop_dnsmasq()
# 9. check the status of networkd
assert not networkd_is_failed()
+
def setUpModule():
rm_rf(networkd_ci_temp_dir)
cp_r(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_temp_dir)
setup_system_units()
+
def tearDownModule():
rm_rf(networkd_ci_temp_dir)
clear_udev_rules()
sys.stdout.flush()
check_output('journalctl --sync')
-class Utilities():
+
+class Utilities:
# pylint: disable=no-member
def check_link_exists(self, *link, expected=True):
else:
self.fail(f'Timed out waiting for {link} activated.')
- def wait_operstate(self, link, operstate='degraded', setup_state='configured', setup_timeout=5, fail_assert=True):
+ def wait_operstate(
+ self, link, operstate='degraded', setup_state='configured', setup_timeout=5, fail_assert=True
+ ):
"""Wait for the link to reach the specified operstate and/or setup state.
Specify None or '' for either operstate or setup_state to ignore that state.
self.fail(f'Timed out waiting for {link} to reach state {operstate}/{setup_state}')
return False
- def wait_online(self, *links_with_operstate, timeout='20s', bool_any=False, ipv4=False, ipv6=False, setup_state='configured', setup_timeout=5, bool_dns=False):
+ def wait_online(
+ self,
+ *links_with_operstate,
+ timeout='20s',
+ bool_any=False,
+ ipv4=False,
+ ipv6=False,
+ setup_state='configured',
+ setup_timeout=5,
+ bool_dns=False,
+ ):
"""Wait for the links to reach the specified operstate and/or setup state.
This is similar to wait_operstate() but can be used for multiple links,
Set 'bool_dns' to True to wait for DNS servers to be accessible.
- Set 'ipv4' or 'ipv6' to True to wait for IPv4 address or IPv6 address, respectively, of each of the given links.
- This is applied only for the operational state 'degraded' or above.
+ Set 'ipv4' or 'ipv6' to True to wait for IPv4 address or IPv6 address, respectively, of each of the
+ given links. This is applied only for the operational state 'degraded' or above.
Note that this function waits for the links to reach *or exceed* the given operstate.
However, the setup_state, if specified, must be matched *exactly*.
This returns if the links reached the requested operstate/setup_state; otherwise it
raises CalledProcessError or fails test assertion.
"""
- args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate] + [f'--ignore={link}' for link in protected_links]
+ args = (
+ wait_online_cmd
+ + [f'--timeout={timeout}']
+ + [f'--interface={link}' for link in links_with_operstate]
+ + [f'--ignore={link}' for link in protected_links]
+ )
if bool_any:
args += ['--any']
if bool_dns:
print('## Checking NetLabel skipped: selinuxenabled command not found.')
elif call_quiet('selinuxenabled') != 0:
print('## Checking NetLabel skipped: SELinux disabled.')
- elif not shutil.which('netlabelctl'): # not packaged by all distros
+ elif not shutil.which('netlabelctl'): # not packaged by all distros
print('## Checking NetLabel skipped: netlabelctl command not found.')
else:
output = check_output('netlabelctl unlbl list')
if not shutil.which('nft'):
print('## Setting up NFT sets skipped: nft command not found.')
else:
- if call(f'nft add table inet sd_test') != 0:
+ if call('nft add table inet sd_test') != 0:
print('## Setting up NFT table failed.')
self.fail()
if call(f'nft add set inet sd_test {filter_name} {{ type {filter_type}; {flags} }}') != 0:
if call(f'nft delete set inet sd_test {filter_name}') != 0:
print('## Tearing down NFT sets failed.')
self.fail()
- if call(f'nft delete table inet sd_test') != 0:
+ if call('nft delete table inet sd_test') != 0:
print('## Tearing down NFT table failed.')
self.fail()
if link_file:
self.assertRegex(output, rf'Link File: .*/{link_file}\.link')
-class NetworkctlTests(unittest.TestCase, Utilities):
+class NetworkctlTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.assertRegex(output, 'hogehogehogehogehogehoge')
def test_rename_to_altname(self):
- copy_network_unit('26-netdev-link-local-addressing-yes.network',
- '12-dummy.netdev', '12-dummy-rename-to-altname.link')
+ copy_network_unit(
+ '26-netdev-link-local-addressing-yes.network',
+ '12-dummy.netdev',
+ '12-dummy-rename-to-altname.link',
+ )
start_networkd()
self.wait_online('dummyalt:degraded')
self.assertIn('Network File: /run/systemd/network/11-test-unit-file.network', output)
self.assertIn('/run/systemd/network/11-test-unit-file.network.d/dropin.conf', output)
- self.check_networkd_log('test1: Configuring with /run/systemd/network/11-test-unit-file.network (dropins: /run/systemd/network/11-test-unit-file.network.d/dropin.conf).')
+ self.check_networkd_log(
+ 'test1: Configuring with /run/systemd/network/11-test-unit-file.network '
+ '(dropins: /run/systemd/network/11-test-unit-file.network.d/dropin.conf).'
+ )
output = networkctl_status('lo')
print(output)
def test_label(self):
networkctl('label')
-class NetworkdMatchTests(unittest.TestCase, Utilities):
+class NetworkdMatchTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
tear_down_common()
def test_match(self):
- copy_network_unit('12-dummy-mac.netdev',
- '12-dummy-match-mac-01.network',
- '12-dummy-match-mac-02.network',
- '12-dummy-match-renamed.network',
- '12-dummy-match-altname.network',
- '12-dummy-altname.link')
+ copy_network_unit(
+ '12-dummy-mac.netdev',
+ '12-dummy-match-mac-01.network',
+ '12-dummy-match-mac-02.network',
+ '12-dummy-match-renamed.network',
+ '12-dummy-match-altname.network',
+ '12-dummy-altname.link',
+ )
start_networkd()
self.wait_online('dummy98:routable')
self.assertIn('Network File: /run/systemd/network/12-dummy-match-altname.network', output)
def test_match_udev_property(self):
- copy_network_unit('12-dummy.netdev', '13-not-match-udev-property.network', '14-match-udev-property.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '13-not-match-udev-property.network',
+ '14-match-udev-property.network',
+ )
start_networkd()
self.wait_online('dummy98:routable')
print(output)
self.assertRegex(output, 'Network File: /run/systemd/network/14-match-udev-property')
-class WaitOnlineTests(unittest.TestCase, Utilities):
+class WaitOnlineTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
if network_dropin is not None:
network_dropin_path = os.path.join(
network_unit_dir,
- '25-dhcp-client-use-dns-ipv4.network.d/test.conf'
+ '25-dhcp-client-use-dns-ipv4.network.d/test.conf',
)
mkdir_p(os.path.dirname(network_dropin_path))
with open(network_dropin_path, 'w') as f:
copy_network_unit(
'25-veth.netdev',
'25-dhcp-client-use-dns-ipv4.network',
- '25-dhcp-server.network'
+ '25-dhcp-server.network',
)
start_networkd()
self.wait_online('veth-peer:routable')
resolved_dropin = '/run/systemd/resolved.conf.d/global-dns.conf'
mkdir_p(os.path.dirname(resolved_dropin))
with open(resolved_dropin, 'w') as f:
- f.write((
- '[Resolve]\n'
- f'DNS={global_dns}\n'
- f'FallbackDNS={fallback_dns}\n'
- ))
+ f.write(f'''
+[Resolve]
+DNS={global_dns}
+FallbackDNS={fallback_dns}
+''')
self.addCleanup(os.remove, resolved_dropin)
check_output('systemctl reload systemd-resolved')
if expect_timeout:
# The above should have thrown an exception.
- self.fail(
- 'Expected systemd-networkd-wait-online to time out'
- )
+ self.fail('Expected systemd-networkd-wait-online to time out')
except subprocess.CalledProcessError as e:
if expect_timeout:
self.assertRegex(
e.output,
- f'veth99: No link-specific DNS server is accessible',
- f'Missing expected log message:\n{e.output}'
+ 'veth99: No link-specific DNS server is accessible',
+ f'Missing expected log message:\n{e.output}',
)
else:
- self.fail(
- f'Command timed out:\n{e.output}'
- )
+ self.fail(f'Command timed out:\n{e.output}')
finally:
wait_online_env = wait_online_env_copy
def test_wait_online_dns(self):
- ''' test systemd-networkd-wait-online with --dns '''
+ """test systemd-networkd-wait-online with --dns"""
self.do_test_wait_online_dns()
def test_wait_online_dns_global(self):
- '''
+ """
test systemd-networkd-wait-online with --dns, expect pass due to global DNS
- '''
+ """
# Set UseDNS=no, and allow global DNS to be used.
self.do_test_wait_online_dns(
global_dns='192.168.5.1',
network_dropin=(
- '[DHCPv4]\n'
- 'UseDNS=no\n'
- )
+ '''
+[DHCPv4]
+UseDNS=no
+'''
+ ),
)
def test_wait_online_dns_expect_timeout(self):
- ''' test systemd-networkd-wait-online with --dns, and expect timeout '''
+ """test systemd-networkd-wait-online with --dns, and expect timeout"""
# Explicitly set DNSDefaultRoute=yes, and require link-specific DNS to be used.
self.do_test_wait_online_dns(
expect_timeout=True,
network_dropin=(
- '[Network]\n'
- 'DNSDefaultRoute=yes\n'
- '[DHCPv4]\n'
- 'UseDNS=no\n'
- )
+ '''
+[Network]
+DNSDefaultRoute=yes
+[DHCPv4]
+UseDNS=no
+'''
+ ),
)
def test_wait_online_dns_expect_timeout_global(self):
- '''
+ """
test systemd-networkd-wait-online with --dns, and expect timeout
despite global DNS
- '''
+ """
# Configure Domains=~., and expect timeout despite global DNS servers
# being available.
expect_timeout=True,
global_dns='192.168.5.1',
network_dropin=(
- '[Network]\n'
- 'Domains=~.\n'
- '[DHCPv4]\n'
- 'UseDNS=no\n'
- )
+ '''
+[Network]
+Domains=~.
+[DHCPv4]
+UseDNS=no
+'''
+ ),
)
class NetworkdNetDevTests(unittest.TestCase, Utilities):
-
def setUp(self):
setup_common()
self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'max_age')) / tick))
self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'forward_delay')) / tick))
self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'ageing_time')) / tick))
- self.assertEqual(9, int(read_link_attr('bridge99', 'bridge', 'priority')))
- self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_querier')))
- self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_snooping')))
- self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
- self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
- self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'no_linklocal_learn')))
+ self.assertEqual(9, int(read_link_attr('bridge99', 'bridge', 'priority')))
+ self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_querier')))
+ self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_snooping')))
+ self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
+ self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
+ self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'no_linklocal_learn')))
output = networkctl_status('bridge99')
print(output)
self.networkctl_check_unit('bond98', '25-bond-balanced-tlb')
self.networkctl_check_unit('bond97', '25-bond-property')
- self.check_link_attr('bond99', 'bonding', 'mode', '802.3ad 4')
- self.check_link_attr('bond99', 'bonding', 'xmit_hash_policy', 'layer3+4 1')
- self.check_link_attr('bond99', 'bonding', 'miimon', '1000')
- self.check_link_attr('bond99', 'bonding', 'lacp_rate', 'fast 1')
- self.check_link_attr('bond99', 'bonding', 'updelay', '2000')
- self.check_link_attr('bond99', 'bonding', 'downdelay', '2000')
- self.check_link_attr('bond99', 'bonding', 'resend_igmp', '4')
- self.check_link_attr('bond99', 'bonding', 'min_links', '1')
+ self.check_link_attr('bond99', 'bonding', 'mode', '802.3ad 4')
+ self.check_link_attr('bond99', 'bonding', 'xmit_hash_policy', 'layer3+4 1')
+ self.check_link_attr('bond99', 'bonding', 'miimon', '1000')
+ self.check_link_attr('bond99', 'bonding', 'lacp_rate', 'fast 1')
+ self.check_link_attr('bond99', 'bonding', 'updelay', '2000')
+ self.check_link_attr('bond99', 'bonding', 'downdelay', '2000')
+ self.check_link_attr('bond99', 'bonding', 'resend_igmp', '4')
+ self.check_link_attr('bond99', 'bonding', 'min_links', '1')
self.check_link_attr('bond99', 'bonding', 'ad_actor_sys_prio', '1218')
- self.check_link_attr('bond99', 'bonding', 'ad_user_port_key', '811')
- self.check_link_attr('bond99', 'bonding', 'ad_actor_system', '00:11:22:33:44:55')
+ self.check_link_attr('bond99', 'bonding', 'ad_user_port_key', '811')
+ self.check_link_attr('bond99', 'bonding', 'ad_actor_system', '00:11:22:33:44:55')
- self.check_link_attr('bond98', 'bonding', 'mode', 'balance-tlb 5')
- self.check_link_attr('bond98', 'bonding', 'tlb_dynamic_lb', '1')
+ self.check_link_attr('bond98', 'bonding', 'mode', 'balance-tlb 5')
+ self.check_link_attr('bond98', 'bonding', 'tlb_dynamic_lb', '1')
output = networkctl_status('bond99')
print(output)
output = networkctl_status('bond97')
print(output)
- self.check_link_attr('bond97', 'bonding', 'arp_missed_max', '10')
+ self.check_link_attr('bond97', 'bonding', 'arp_missed_max', '10')
self.check_link_attr('bond97', 'bonding', 'peer_notif_delay', '300000')
def check_vlan(self, id, flags):
self.assertRegex(output, 'inet 192.168.23.5/24 brd 192.168.23.255 scope global vlan99')
def test_vlan(self):
- copy_network_unit('21-vlan.netdev', '11-dummy.netdev',
- '21-vlan.network', '21-vlan-test1.network')
+ copy_network_unit(
+ '21-vlan.netdev',
+ '11-dummy.netdev',
+ '21-vlan.network',
+ '21-vlan-test1.network',
+ )
start_networkd()
self.check_vlan(id=99, flags=True)
# Test for reloading .netdev file. See issue #34907.
- with open(os.path.join(network_unit_dir, '21-vlan.netdev.d/override.conf'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '21-vlan.netdev.d/override.conf'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[VLAN]\nId=42\n')
# VLAN ID cannot be changed, so we need to remove the existing netdev.
- check_output("ip link del vlan99")
+ check_output('ip link del vlan99')
networkctl_reload()
self.check_vlan(id=42, flags=True)
- with open(os.path.join(network_unit_dir, '21-vlan.netdev.d/override.conf'), mode='a', encoding='utf-8') as f:
- f.write('[VLAN]\n'
- 'GVRP=no\n'
- 'MVRP=no\n'
- 'LooseBinding=no\n'
- 'ReorderHeader=no\n')
+ with open(
+ os.path.join(network_unit_dir, '21-vlan.netdev.d/override.conf'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[VLAN]
+GVRP=no
+MVRP=no
+LooseBinding=no
+ReorderHeader=no
+''')
# flags can be changed, hence it is not necessary to remove the existing netdev.
networkctl_reload()
# For issue #24377 (https://github.com/systemd/systemd/issues/24377),
# which is fixed by b05e52000b4eee764b383cc3031da0a3739e996e (PR#24020).
- copy_network_unit('21-bond-802.3ad.netdev', '21-bond-802.3ad.network',
- '21-vlan-on-bond.netdev', '21-vlan-on-bond.network')
+ copy_network_unit(
+ '21-bond-802.3ad.netdev',
+ '21-bond-802.3ad.network',
+ '21-vlan-on-bond.netdev',
+ '21-vlan-on-bond.network',
+ )
start_networkd()
self.wait_online('bond99:off')
self.wait_operstate('vlan99', operstate='off', setup_state='configuring', setup_timeout=10)
print(f'### test_macvtap(mode={mode})')
with self.subTest(mode=mode):
- copy_network_unit('21-macvtap.netdev', '26-netdev-link-local-addressing-yes.network',
- '11-dummy.netdev', '25-macvtap.network')
- with open(os.path.join(network_unit_dir, '21-macvtap.netdev'), mode='a', encoding='utf-8') as f:
+ copy_network_unit(
+ '21-macvtap.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '11-dummy.netdev',
+ '25-macvtap.network',
+ )
+ with open(
+ os.path.join(network_unit_dir, '21-macvtap.netdev'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[MACVTAP]\nMode=' + mode)
start_networkd()
- self.wait_online('macvtap99:degraded',
- 'test1:carrier' if mode == 'passthru' else 'test1:degraded')
+ self.wait_online(
+ 'macvtap99:degraded',
+ 'test1:carrier' if mode == 'passthru' else 'test1:degraded',
+ )
self.networkctl_check_unit('macvtap99', '21-macvtap', '26-netdev-link-local-addressing-yes')
self.networkctl_check_unit('test1', '11-dummy', '25-macvtap')
touch_network_unit('21-macvtap.netdev')
networkctl_reload()
- self.wait_online('macvtap99:degraded',
- 'test1:carrier' if mode == 'passthru' else 'test1:degraded')
+ self.wait_online(
+ 'macvtap99:degraded',
+ 'test1:carrier' if mode == 'passthru' else 'test1:degraded',
+ )
@expectedFailureIfModuleIsNotAvailable('macvlan')
def test_macvlan(self):
print(f'### test_macvlan(mode={mode})')
with self.subTest(mode=mode):
- copy_network_unit('21-macvlan.netdev', '26-netdev-link-local-addressing-yes.network',
- '11-dummy.netdev', '25-macvlan.network')
- with open(os.path.join(network_unit_dir, '21-macvlan.netdev'), mode='a', encoding='utf-8') as f:
+ copy_network_unit(
+ '21-macvlan.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '11-dummy.netdev',
+ '25-macvlan.network',
+ )
+ with open(
+ os.path.join(network_unit_dir, '21-macvlan.netdev'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[MACVLAN]\nMode=' + mode)
start_networkd()
- self.wait_online('macvlan99:degraded',
- 'test1:carrier' if mode == 'passthru' else 'test1:degraded')
+ self.wait_online(
+ 'macvlan99:degraded',
+ 'test1:carrier' if mode == 'passthru' else 'test1:degraded',
+ )
self.networkctl_check_unit('macvlan99', '21-macvlan', '26-netdev-link-local-addressing-yes')
self.networkctl_check_unit('test1', '11-dummy', '25-macvlan')
remove_link('test1')
time.sleep(1)
- check_output("ip link add test1 type dummy")
- self.wait_online('macvlan99:degraded',
- 'test1:carrier' if mode == 'passthru' else 'test1:degraded')
+ check_output('ip link add test1 type dummy')
+ self.wait_online(
+ 'macvlan99:degraded',
+ 'test1:carrier' if mode == 'passthru' else 'test1:degraded',
+ )
output = check_output('ip -d link show test1')
print(output)
self.assertIn(' mtu 2000 ', output)
self.assertIn(f' macvlan mode {mode} ', output)
self.assertIn(' bcqueuelen 1234 ', output)
- if ' bclim ' in output: # This is new in kernel and iproute2 v6.4
+ if ' bclim ' in output: # This is new in kernel and iproute2 v6.4
self.assertIn(' bclim 2147483647 ', output)
touch_network_unit('21-macvlan.netdev')
networkctl_reload()
- self.wait_online('macvlan99:degraded',
- 'test1:carrier' if mode == 'passthru' else 'test1:degraded')
+ self.wait_online(
+ 'macvlan99:degraded',
+ 'test1:carrier' if mode == 'passthru' else 'test1:degraded',
+ )
@expectedFailureIfModuleIsNotAvailable('ipvlan')
def test_ipvlan(self):
print(f'### test_ipvlan(mode={mode}, flag={flag})')
with self.subTest(mode=mode, flag=flag):
- copy_network_unit('25-ipvlan.netdev', '26-netdev-link-local-addressing-yes.network',
- '11-dummy.netdev', '25-ipvlan.network')
- with open(os.path.join(network_unit_dir, '25-ipvlan.netdev'), mode='a', encoding='utf-8') as f:
+ copy_network_unit(
+ '25-ipvlan.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '11-dummy.netdev',
+ '25-ipvlan.network',
+ )
+ with open(
+ os.path.join(network_unit_dir, '25-ipvlan.netdev'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[IPVLAN]\nMode=' + mode + '\nFlags=' + flag)
start_networkd()
print(f'### test_hsr(proto={proto}, supervision={supervision})')
with self.subTest(proto=proto, supervision=supervision):
- copy_network_unit('25-hsr.netdev', '25-hsr.network',
- '11-dummy.netdev', '11-dummy.network',
- '12-dummy.netdev', '12-dummy-no-address.network')
+ copy_network_unit(
+ '25-hsr.netdev',
+ '25-hsr.network',
+ '11-dummy.netdev',
+ '11-dummy.network',
+ '12-dummy.netdev',
+ '12-dummy-no-address.network',
+ )
with open(os.path.join(network_unit_dir, '25-hsr.netdev'), mode='a', encoding='utf-8') as f:
f.write('Protocol=' + proto + '\nSupervision=' + str(supervision))
print(f'### test_ipvtap(mode={mode}, flag={flag})')
with self.subTest(mode=mode, flag=flag):
- copy_network_unit('25-ipvtap.netdev', '26-netdev-link-local-addressing-yes.network',
- '11-dummy.netdev', '25-ipvtap.network')
- with open(os.path.join(network_unit_dir, '25-ipvtap.netdev'), mode='a', encoding='utf-8') as f:
+ copy_network_unit(
+ '25-ipvtap.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '11-dummy.netdev',
+ '25-ipvtap.network',
+ )
+ with open(
+ os.path.join(network_unit_dir, '25-ipvtap.netdev'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[IPVTAP]\nMode=' + mode + '\nFlags=' + flag)
start_networkd()
self.wait_online('ipvtap99:degraded', 'test1:degraded')
def test_veth(self):
- copy_network_unit('25-veth.netdev', '26-netdev-link-local-addressing-yes.network',
- '25-veth-mtu.netdev')
+ copy_network_unit(
+ '25-veth.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '25-veth-mtu.netdev',
+ )
start_networkd()
- self.wait_online('veth99:degraded', 'veth-peer:degraded', 'veth-mtu:degraded', 'veth-mtu-peer:degraded')
+ self.wait_online(
+ 'veth99:degraded',
+ 'veth-peer:degraded',
+ 'veth-mtu:degraded',
+ 'veth-mtu-peer:degraded',
+ )
self.networkctl_check_unit('veth99', '25-veth', '26-netdev-link-local-addressing-yes')
self.networkctl_check_unit('veth-peer', '25-veth', '26-netdev-link-local-addressing-yes')
self.networkctl_check_unit('veth-mtu', '25-veth-mtu', '26-netdev-link-local-addressing-yes')
touch_network_unit(
'25-veth.netdev',
'26-netdev-link-local-addressing-yes.network',
- '25-veth-mtu.netdev')
+ '25-veth-mtu.netdev',
+ )
networkctl_reload()
self.wait_online(
'veth99:degraded',
'veth-peer:degraded',
'veth-mtu:degraded',
- 'veth-mtu-peer:degraded')
+ 'veth-mtu-peer:degraded',
+ )
def check_tuntap(self, attached):
pid = networkd_pid()
output = check_output('ip -d -oneline tuntap show')
print(output)
+ # fmt: off
self.assertRegex(output, r'testtap99: tap pi (multi_queue |)vnet_hdr persist filter.*\tAttached to processes:')
self.assertRegex(output, r'testtun99: tun pi (multi_queue |)vnet_hdr persist filter.*\tAttached to processes:')
+ # fmt: on
if attached:
- self.assertRegex(output, fr'testtap99: .*{name}\({pid}\)')
- self.assertRegex(output, fr'testtun99: .*{name}\({pid}\)')
+ self.assertRegex(output, rf'testtap99: .*{name}\({pid}\)')
+ self.assertRegex(output, rf'testtun99: .*{name}\({pid}\)')
self.assertRegex(output, r'testtap99: .*systemd\(1\)')
self.assertRegex(output, r'testtun99: .*systemd\(1\)')
@expectedFailureIfModuleIsNotAvailable('vcan')
def test_vcan(self):
- copy_network_unit('25-vcan.netdev', '26-netdev-link-local-addressing-yes.network',
- '25-vcan98.netdev', '25-vcan98.network')
+ copy_network_unit(
+ '25-vcan.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '25-vcan98.netdev',
+ '25-vcan98.network',
+ )
start_networkd()
self.wait_online('vcan99:carrier', 'vcan98:carrier')
'25-vcan.netdev',
'26-netdev-link-local-addressing-yes.network',
'25-vcan98.netdev',
- '25-vcan98.network')
+ '25-vcan98.network',
+ )
networkctl_reload()
self.wait_online('vcan99:carrier', 'vcan98:carrier')
@expectedFailureIfModuleIsNotAvailable('wireguard')
def test_wireguard(self):
- copy_credential('25-wireguard-endpoint-peer0-cred.txt', 'network.wireguard.peer0.endpoint')
- copy_credential('25-wireguard-preshared-key-peer2-cred.txt', 'network.wireguard.peer2.psk')
- copy_credential('25-wireguard-no-peer-private-key-cred.txt', 'network.wireguard.private.25-wireguard-no-peer')
+ copy_credential(
+ '25-wireguard-endpoint-peer0-cred.txt',
+ 'network.wireguard.peer0.endpoint',
+ )
+ copy_credential(
+ '25-wireguard-preshared-key-peer2-cred.txt',
+ 'network.wireguard.peer2.psk',
+ )
+ copy_credential(
+ '25-wireguard-no-peer-private-key-cred.txt',
+ 'network.wireguard.private.25-wireguard-no-peer',
+ )
- copy_network_unit('25-wireguard.netdev', '25-wireguard.network',
- '25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
- '25-wireguard-public-key.txt', '25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt',
- '25-wireguard-no-peer.netdev', '25-wireguard-no-peer.network')
+ copy_network_unit(
+ '25-wireguard.netdev',
+ '25-wireguard.network',
+ '25-wireguard-23-peers.netdev',
+ '25-wireguard-23-peers.network',
+ '25-wireguard-public-key.txt',
+ '25-wireguard-preshared-key.txt',
+ '25-wireguard-private-key.txt',
+ '25-wireguard-no-peer.netdev',
+ '25-wireguard-no-peer.network',
+ )
start_networkd()
self.wait_online('wg99:routable', 'wg98:routable', 'wg97:carrier')
self.networkctl_check_unit('wg99', '25-wireguard', '25-wireguard')
output = check_output('wg show wg99 private-key')
self.assertEqual(output, 'EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=')
output = check_output('wg show wg99 allowed-ips')
+ # fmt: off
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t192.168.124.3/32', output)
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\t192.168.124.2/32', output)
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128', output)
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48', output)
+ # fmt: on
output = check_output('wg show wg99 persistent-keepalive')
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\toff', output)
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\toff', output)
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\t(none)', output)
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820', output)
output = check_output('wg show wg99 preshared-keys')
+ # fmt: off
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t6Fsg8XN0DE6aPQgAX4r2oazEYJOGqyHUz3QRH/jCB+I=', output)
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\tit7nd33chCT/tKT2ZZWfYyp43Zs+6oif72hexnSNMqA=', output)
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tcPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=', output)
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\tIIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=', output)
+ # fmt: on
output = check_output('wg show wg98 private-key')
self.assertEqual(output, 'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr+WHtZLZ90FU=')
self.assertEqual(output, '0x4d3')
touch_network_unit(
- '25-wireguard.netdev', '25-wireguard.network',
- '25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
- '25-wireguard-public-key.txt', '25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt',
- '25-wireguard-no-peer.netdev', '25-wireguard-no-peer.network')
+ '25-wireguard.netdev',
+ '25-wireguard.network',
+ '25-wireguard-23-peers.netdev',
+ '25-wireguard-23-peers.network',
+ '25-wireguard-public-key.txt',
+ '25-wireguard-preshared-key.txt',
+ '25-wireguard-private-key.txt',
+ '25-wireguard-no-peer.netdev',
+ '25-wireguard-no-peer.network',
+ )
networkctl_reload()
self.wait_online('wg99:routable', 'wg98:routable', 'wg97:carrier')
self.wait_online('geneve99:degraded')
def _test_ipip_tunnel(self, mode):
- copy_network_unit('12-dummy.netdev', '25-ipip.network',
- '25-ipip-tunnel.netdev', '25-tunnel.network',
- '25-ipip-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-ipip-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
- '25-ipip-tunnel-any-any.netdev', '25-tunnel-any-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-ipip.network',
+ '25-ipip-tunnel.netdev',
+ '25-tunnel.network',
+ '25-ipip-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-ipip-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ '25-ipip-tunnel-any-any.netdev',
+ '25-tunnel-any-any.network',
+ )
if mode:
- for netdev in ['25-ipip-tunnel.netdev',
- '25-ipip-tunnel-local-any.netdev',
- '25-ipip-tunnel-remote-any.netdev',
- '25-ipip-tunnel-any-any.netdev']:
+ for netdev in [
+ '25-ipip-tunnel.netdev',
+ '25-ipip-tunnel-local-any.netdev',
+ '25-ipip-tunnel-remote-any.netdev',
+ '25-ipip-tunnel-any-any.netdev',
+ ]:
with open(os.path.join(network_unit_dir, netdev), mode='a', encoding='utf-8') as f:
f.write(f'[Tunnel]\nMode={mode}\n')
else:
- mode = 'ipip' # kernel default
+ mode = 'ipip' # kernel default
start_networkd()
- self.wait_online('ipiptun99:routable', 'ipiptun98:routable', 'ipiptun97:routable', 'ipiptun96:routable', 'dummy98:degraded')
+ self.wait_online(
+ 'ipiptun99:routable',
+ 'ipiptun98:routable',
+ 'ipiptun97:routable',
+ 'ipiptun96:routable',
+ 'dummy98:degraded',
+ )
output = check_output('ip -d link show ipiptun99')
print(output)
'25-ipip-tunnel.netdev',
'25-ipip-tunnel-local-any.netdev',
'25-ipip-tunnel-remote-any.netdev',
- '25-ipip-tunnel-any-any.netdev')
+ '25-ipip-tunnel-any-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'ipiptun99:routable',
'ipiptun98:routable',
'ipiptun97:routable',
'ipiptun96:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_ipip_tunnel(self):
first = True
self._test_ipip_tunnel(mode)
def test_gre_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-gretun.network',
- '25-gre-tunnel.netdev', '25-tunnel.network',
- '25-gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
- '25-gre-tunnel-any-any.netdev', '25-tunnel-any-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-gretun.network',
+ '25-gre-tunnel.netdev',
+ '25-tunnel.network',
+ '25-gre-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-gre-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ '25-gre-tunnel-any-any.netdev',
+ '25-tunnel-any-any.network',
+ )
start_networkd()
- self.wait_online('gretun99:routable', 'gretun98:routable', 'gretun97:routable', 'gretun96:routable', 'dummy98:degraded')
+ self.wait_online(
+ 'gretun99:routable',
+ 'gretun98:routable',
+ 'gretun97:routable',
+ 'gretun96:routable',
+ 'dummy98:degraded',
+ )
self.networkctl_check_unit('gretun99', '25-gre-tunnel', '25-tunnel')
self.networkctl_check_unit('gretun98', '25-gre-tunnel-local-any', '25-tunnel-local-any')
self.networkctl_check_unit('gretun97', '25-gre-tunnel-remote-any', '25-tunnel-remote-any')
'25-gre-tunnel.netdev',
'25-gre-tunnel-local-any.netdev',
'25-gre-tunnel-remote-any.netdev',
- '25-gre-tunnel-any-any.netdev')
+ '25-gre-tunnel-any-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'gretun99:routable',
'gretun98:routable',
'gretun97:routable',
'gretun96:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_ip6gre_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-ip6gretun.network',
- '25-ip6gre-tunnel.netdev', '25-tunnel.network',
- '25-ip6gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-ip6gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
- '25-ip6gre-tunnel-any-any.netdev', '25-tunnel-any-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-ip6gretun.network',
+ '25-ip6gre-tunnel.netdev',
+ '25-tunnel.network',
+ '25-ip6gre-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-ip6gre-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ '25-ip6gre-tunnel-any-any.netdev',
+ '25-tunnel-any-any.network',
+ )
start_networkd()
self.wait_online(
output = check_output('ip -d link show ip6gretun99')
print(output)
- self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
+ self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98') # fmt: skip
output = check_output('ip -d link show ip6gretun98')
print(output)
self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local any dev dummy98')
'25-ip6gre-tunnel.netdev',
'25-ip6gre-tunnel-local-any.netdev',
'25-ip6gre-tunnel-remote-any.netdev',
- '25-ip6gre-tunnel-any-any.netdev')
+ '25-ip6gre-tunnel-any-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'ip6gretun99:routable',
)
def test_gretap_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-gretap.network',
- '25-gretap-tunnel.netdev', '25-tunnel.network',
- '25-gretap-tunnel-local-any.netdev', '25-tunnel-local-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-gretap.network',
+ '25-gretap-tunnel.netdev',
+ '25-tunnel.network',
+ '25-gretap-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ )
start_networkd()
self.wait_online('gretap99:routable', 'gretap98:routable', 'dummy98:degraded')
self.networkctl_check_unit('gretap99', '25-gretap-tunnel', '25-tunnel')
touch_network_unit(
'25-gretap-tunnel.netdev',
- '25-gretap-tunnel-local-any.netdev')
+ '25-gretap-tunnel-local-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'gretap99:routable',
'gretap98:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_ip6gretap_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-ip6gretap.network',
- '25-ip6gretap-tunnel.netdev', '25-tunnel.network',
- '25-ip6gretap-tunnel-local-any.netdev', '25-tunnel-local-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-ip6gretap.network',
+ '25-ip6gretap-tunnel.netdev',
+ '25-tunnel.network',
+ '25-ip6gretap-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ )
start_networkd()
self.wait_online('ip6gretap99:routable', 'ip6gretap98:routable', 'dummy98:degraded')
self.networkctl_check_unit('ip6gretap99', '25-ip6gretap-tunnel', '25-tunnel')
output = check_output('ip -d link show ip6gretap99')
print(output)
- self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
+ self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98') # fmt: skip
output = check_output('ip -d link show ip6gretap98')
print(output)
self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local any dev dummy98')
touch_network_unit(
'25-ip6gretap-tunnel.netdev',
- '25-ip6gretap-tunnel-local-any.netdev')
+ '25-ip6gretap-tunnel-local-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'ip6gretap99:routable',
'ip6gretap98:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_vti_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-vti.network',
- '25-vti-tunnel.netdev', '25-tunnel.network',
- '25-vti-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-vti-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
- '25-vti-tunnel-any-any.netdev', '25-tunnel-any-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-vti.network',
+ '25-vti-tunnel.netdev',
+ '25-tunnel.network',
+ '25-vti-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-vti-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ '25-vti-tunnel-any-any.netdev',
+ '25-tunnel-any-any.network',
+ )
start_networkd()
- self.wait_online('vtitun99:routable', 'vtitun98:routable', 'vtitun97:routable', 'vtitun96:routable', 'dummy98:degraded')
+ self.wait_online(
+ 'vtitun99:routable',
+ 'vtitun98:routable',
+ 'vtitun97:routable',
+ 'vtitun96:routable',
+ 'dummy98:degraded',
+ )
self.networkctl_check_unit('vtitun99', '25-vti-tunnel', '25-tunnel')
self.networkctl_check_unit('vtitun98', '25-vti-tunnel-local-any', '25-tunnel-local-any')
self.networkctl_check_unit('vtitun97', '25-vti-tunnel-remote-any', '25-tunnel-remote-any')
'25-vti-tunnel.netdev',
'25-vti-tunnel-local-any.netdev',
'25-vti-tunnel-remote-any.netdev',
- '25-vti-tunnel-any-any.netdev')
+ '25-vti-tunnel-any-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'vtitun99:routable',
'vtitun98:routable',
'vtitun97:routable',
'vtitun96:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_vti6_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-vti6.network',
- '25-vti6-tunnel.netdev', '25-tunnel.network',
- '25-vti6-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-vti6-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-vti6.network',
+ '25-vti6-tunnel.netdev',
+ '25-tunnel.network',
+ '25-vti6-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-vti6-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ )
start_networkd()
- self.wait_online('vti6tun99:routable', 'vti6tun98:routable', 'vti6tun97:routable', 'dummy98:degraded')
+ self.wait_online(
+ 'vti6tun99:routable',
+ 'vti6tun98:routable',
+ 'vti6tun97:routable',
+ 'dummy98:degraded',
+ )
self.networkctl_check_unit('vti6tun99', '25-vti6-tunnel', '25-tunnel')
self.networkctl_check_unit('vti6tun98', '25-vti6-tunnel-local-any', '25-tunnel-local-any')
self.networkctl_check_unit('vti6tun97', '25-vti6-tunnel-remote-any', '25-tunnel-remote-any')
output = check_output('ip -d link show vti6tun99')
print(output)
- 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') # fmt: skip
output = check_output('ip -d link show vti6tun98')
print(output)
self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
touch_network_unit(
'25-vti6-tunnel.netdev',
'25-vti6-tunnel-local-any.netdev',
- '25-vti6-tunnel-remote-any.netdev')
+ '25-vti6-tunnel-remote-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'vti6tun99:routable',
'vti6tun98:routable',
'vti6tun97:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def _test_ip6tnl_tunnel(self, mode):
- copy_network_unit('12-dummy.netdev', '25-ip6tnl.network',
- '25-ip6tnl-tunnel.netdev', '25-tunnel.network',
- '25-ip6tnl-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-ip6tnl-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
- '25-veth.netdev', '25-ip6tnl-slaac.network', '25-ipv6-prefix.network',
- '25-ip6tnl-tunnel-local-slaac.netdev', '25-ip6tnl-tunnel-local-slaac.network',
- '25-ip6tnl-tunnel-external.netdev', '26-netdev-link-local-addressing-yes.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-ip6tnl.network',
+ '25-ip6tnl-tunnel.netdev',
+ '25-tunnel.network',
+ '25-ip6tnl-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-ip6tnl-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ '25-veth.netdev',
+ '25-ip6tnl-slaac.network',
+ '25-ipv6-prefix.network',
+ '25-ip6tnl-tunnel-local-slaac.netdev',
+ '25-ip6tnl-tunnel-local-slaac.network',
+ '25-ip6tnl-tunnel-external.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ )
if mode:
- for netdev in ['25-ip6tnl-tunnel.netdev',
- '25-ip6tnl-tunnel-local-any.netdev',
- '25-ip6tnl-tunnel-remote-any.netdev',
- '25-ip6tnl-tunnel-local-slaac.netdev',
- '25-ip6tnl-tunnel-external.netdev']:
+ for netdev in [
+ '25-ip6tnl-tunnel.netdev',
+ '25-ip6tnl-tunnel-local-any.netdev',
+ '25-ip6tnl-tunnel-remote-any.netdev',
+ '25-ip6tnl-tunnel-local-slaac.netdev',
+ '25-ip6tnl-tunnel-external.netdev',
+ ]:
with open(os.path.join(network_unit_dir, netdev), mode='a', encoding='utf-8') as f:
f.write(f'[Tunnel]\nMode={mode}\n')
else:
- mode = 'any' # kernel default
-
- start_networkd()
- self.wait_online('ip6tnl99:routable', 'ip6tnl98:routable', 'ip6tnl97:routable',
- 'ip6tnl-slaac:degraded', 'ip6tnl-external:degraded',
- 'dummy98:degraded', 'veth99:routable', 'veth-peer:degraded')
- self.networkctl_check_unit('ip6tnl99', '25-ip6tnl-tunnel', '25-tunnel')
- self.networkctl_check_unit('ip6tnl98', '25-ip6tnl-tunnel-local-any', '25-tunnel-local-any')
- self.networkctl_check_unit('ip6tnl97', '25-ip6tnl-tunnel-remote-any', '25-tunnel-remote-any')
- self.networkctl_check_unit('ip6tnl-slaac', '25-ip6tnl-tunnel-local-slaac', '25-ip6tnl-tunnel-local-slaac')
- self.networkctl_check_unit('ip6tnl-external', '25-ip6tnl-tunnel-external', '26-netdev-link-local-addressing-yes')
- self.networkctl_check_unit('dummy98', '12-dummy', '25-ip6tnl')
- self.networkctl_check_unit('veth99', '25-veth', '25-ip6tnl-slaac')
- self.networkctl_check_unit('veth-peer', '25-veth', '25-ipv6-prefix')
+ mode = 'any' # kernel default
+
+ start_networkd()
+ self.wait_online(
+ 'ip6tnl99:routable',
+ 'ip6tnl98:routable',
+ 'ip6tnl97:routable',
+ 'ip6tnl-slaac:degraded',
+ 'ip6tnl-external:degraded',
+ 'dummy98:degraded',
+ 'veth99:routable',
+ 'veth-peer:degraded',
+ )
+ self.networkctl_check_unit(
+ 'ip6tnl99',
+ '25-ip6tnl-tunnel',
+ '25-tunnel',
+ )
+ self.networkctl_check_unit(
+ 'ip6tnl98',
+ '25-ip6tnl-tunnel-local-any',
+ '25-tunnel-local-any',
+ )
+ self.networkctl_check_unit(
+ 'ip6tnl97',
+ '25-ip6tnl-tunnel-remote-any',
+ '25-tunnel-remote-any',
+ )
+ self.networkctl_check_unit(
+ 'ip6tnl-slaac',
+ '25-ip6tnl-tunnel-local-slaac',
+ '25-ip6tnl-tunnel-local-slaac',
+ )
+ self.networkctl_check_unit(
+ 'ip6tnl-external',
+ '25-ip6tnl-tunnel-external',
+ '26-netdev-link-local-addressing-yes',
+ )
+ self.networkctl_check_unit(
+ 'dummy98',
+ '12-dummy',
+ '25-ip6tnl',
+ )
+ self.networkctl_check_unit(
+ 'veth99',
+ '25-veth',
+ '25-ip6tnl-slaac',
+ )
+ self.networkctl_check_unit(
+ 'veth-peer',
+ '25-veth',
+ '25-ipv6-prefix',
+ )
output = check_output('ip -d link show ip6tnl99')
print(output)
- self.assertIn(f'ip6tnl {mode} remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98', output)
+ self.assertIn(f'ip6tnl {mode} remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98', output) # fmt: skip
output = check_output('ip -d link show ip6tnl98')
print(output)
self.assertIn(f'ip6tnl {mode} remote 2001:473:fece:cafe::5179 local any dev dummy98', output)
self.assertIn('ip6tnl external ', output)
output = check_output('ip -d link show ip6tnl-slaac')
print(output)
- self.assertIn(f'ip6tnl {mode} remote 2001:473:fece:cafe::5179 local 2002:da8:1:0:1034:56ff:fe78:9abc dev veth99', output)
+ self.assertIn(f'ip6tnl {mode} remote 2001:473:fece:cafe::5179 local 2002:da8:1:0:1034:56ff:fe78:9abc dev veth99', output) # fmt: skip
output = check_output('ip -6 address show veth99')
print(output)
'25-ip6tnl-tunnel-local-any.netdev',
'25-ip6tnl-tunnel-remote-any.netdev',
'25-ip6tnl-tunnel-local-slaac.netdev',
- '25-ip6tnl-tunnel-external.netdev')
+ '25-ip6tnl-tunnel-external.netdev',
+ )
networkctl_reload()
self.wait_online(
'ip6tnl99:routable',
'ip6tnl-external:degraded',
'dummy98:degraded',
'veth99:routable',
- 'veth-peer:degraded')
+ 'veth-peer:degraded',
+ )
def test_ip6tnl_tunnel(self):
first = True
self._test_ip6tnl_tunnel(mode)
def _test_sit_tunnel(self, mode):
- copy_network_unit('12-dummy.netdev', '25-sit.network',
- '25-sit-tunnel.netdev', '25-tunnel.network',
- '25-sit-tunnel-local-any.netdev', '25-tunnel-local-any.network',
- '25-sit-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
- '25-sit-tunnel-any-any.netdev', '25-tunnel-any-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-sit.network',
+ '25-sit-tunnel.netdev',
+ '25-tunnel.network',
+ '25-sit-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ '25-sit-tunnel-remote-any.netdev',
+ '25-tunnel-remote-any.network',
+ '25-sit-tunnel-any-any.netdev',
+ '25-tunnel-any-any.network',
+ )
if mode:
- for netdev in ['25-sit-tunnel.netdev',
- '25-sit-tunnel-local-any.netdev',
- '25-sit-tunnel-remote-any.netdev',
- '25-sit-tunnel-any-any.netdev']:
+ for netdev in [
+ '25-sit-tunnel.netdev',
+ '25-sit-tunnel-local-any.netdev',
+ '25-sit-tunnel-remote-any.netdev',
+ '25-sit-tunnel-any-any.netdev',
+ ]:
with open(os.path.join(network_unit_dir, netdev), mode='a', encoding='utf-8') as f:
f.write(f'[Tunnel]\nMode={mode}\n')
else:
- mode = 'ip6ip' # kernel default
+ mode = 'ip6ip' # kernel default
start_networkd()
- self.wait_online('sittun99:routable', 'sittun98:routable', 'sittun97:routable', 'sittun96:routable', 'dummy98:degraded')
+ self.wait_online(
+ 'sittun99:routable',
+ 'sittun98:routable',
+ 'sittun97:routable',
+ 'sittun96:routable',
+ 'dummy98:degraded',
+ )
self.networkctl_check_unit('sittun99', '25-sit-tunnel', '25-tunnel')
self.networkctl_check_unit('sittun98', '25-sit-tunnel-local-any', '25-tunnel-local-any')
self.networkctl_check_unit('sittun97', '25-sit-tunnel-remote-any', '25-tunnel-remote-any')
'25-sit-tunnel.netdev',
'25-sit-tunnel-local-any.netdev',
'25-sit-tunnel-remote-any.netdev',
- '25-sit-tunnel-any-any.netdev')
+ '25-sit-tunnel-any-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'sittun99:routable',
'sittun98:routable',
'sittun97:routable',
'sittun96:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_sit_tunnel(self):
first = True
self._test_sit_tunnel(mode)
def test_isatap_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-isatap.network',
- '25-isatap-tunnel.netdev', '25-tunnel.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-isatap.network',
+ '25-isatap-tunnel.netdev',
+ '25-tunnel.network',
+ )
start_networkd()
self.wait_online('isataptun99:routable', 'dummy98:degraded')
self.networkctl_check_unit('isataptun99', '25-isatap-tunnel', '25-tunnel')
output = check_output('ip -d link show isataptun99')
print(output)
- self.assertRegex(output, "isatap ")
+ self.assertRegex(output, 'isatap ')
touch_network_unit('25-isatap-tunnel.netdev')
networkctl_reload()
self.wait_online('isataptun99:routable', 'dummy98:degraded')
def test_6rd_tunnel(self):
- copy_network_unit('12-dummy.netdev', '25-6rd.network',
- '25-6rd-tunnel.netdev', '25-tunnel.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-6rd.network',
+ '25-6rd-tunnel.netdev',
+ '25-tunnel.network',
+ )
start_networkd()
self.wait_online('sittun99:routable', 'dummy98:degraded')
self.networkctl_check_unit('sittun99', '25-6rd-tunnel', '25-tunnel')
self.wait_online('sittun99:routable', 'dummy98:degraded')
def test_erspan_tunnel_v0(self):
- copy_network_unit('12-dummy.netdev', '25-erspan.network',
- '25-erspan0-tunnel.netdev', '25-tunnel.network',
- '25-erspan0-tunnel-local-any.netdev', '25-tunnel-local-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-erspan.network',
+ '25-erspan0-tunnel.netdev',
+ '25-tunnel.network',
+ '25-erspan0-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ )
start_networkd()
self.wait_online('erspan99:routable', 'erspan98:routable', 'dummy98:degraded')
self.networkctl_check_unit('erspan99', '25-erspan0-tunnel', '25-tunnel')
touch_network_unit(
'25-erspan0-tunnel.netdev',
- '25-erspan0-tunnel-local-any.netdev')
+ '25-erspan0-tunnel-local-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'erspan99:routable',
'erspan98:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_erspan_tunnel_v1(self):
- copy_network_unit('12-dummy.netdev', '25-erspan.network',
- '25-erspan1-tunnel.netdev', '25-tunnel.network',
- '25-erspan1-tunnel-local-any.netdev', '25-tunnel-local-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-erspan.network',
+ '25-erspan1-tunnel.netdev',
+ '25-tunnel.network',
+ '25-erspan1-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ )
start_networkd()
self.wait_online('erspan99:routable', 'erspan98:routable', 'dummy98:degraded')
self.networkctl_check_unit('erspan99', '25-erspan1-tunnel', '25-tunnel')
touch_network_unit(
'25-erspan1-tunnel.netdev',
- '25-erspan1-tunnel-local-any.netdev')
+ '25-erspan1-tunnel-local-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'erspan99:routable',
'erspan98:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_erspan_tunnel_v2(self):
- copy_network_unit('12-dummy.netdev', '25-erspan.network',
- '25-erspan2-tunnel.netdev', '25-tunnel.network',
- '25-erspan2-tunnel-local-any.netdev', '25-tunnel-local-any.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-erspan.network',
+ '25-erspan2-tunnel.netdev',
+ '25-tunnel.network',
+ '25-erspan2-tunnel-local-any.netdev',
+ '25-tunnel-local-any.network',
+ )
start_networkd()
self.wait_online('erspan99:routable', 'erspan98:routable', 'dummy98:degraded')
self.networkctl_check_unit('erspan99', '25-erspan2-tunnel', '25-tunnel')
touch_network_unit(
'25-erspan2-tunnel.netdev',
- '25-erspan2-tunnel-local-any.netdev')
+ '25-erspan2-tunnel-local-any.netdev',
+ )
networkctl_reload()
self.wait_online(
'erspan99:routable',
'erspan98:routable',
- 'dummy98:degraded')
+ 'dummy98:degraded',
+ )
def test_tunnel_independent(self):
- copy_network_unit('25-ipip-tunnel-independent.netdev', '26-netdev-link-local-addressing-yes.network')
+ copy_network_unit(
+ '25-ipip-tunnel-independent.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ )
start_networkd()
self.wait_online('ipiptun99:carrier')
- self.networkctl_check_unit('ipiptun99', '25-ipip-tunnel-independent', '26-netdev-link-local-addressing-yes')
+ self.networkctl_check_unit(
+ 'ipiptun99',
+ '25-ipip-tunnel-independent',
+ '26-netdev-link-local-addressing-yes',
+ )
def test_tunnel_independent_loopback(self):
- copy_network_unit('25-ipip-tunnel-independent-loopback.netdev', '26-netdev-link-local-addressing-yes.network')
+ copy_network_unit(
+ '25-ipip-tunnel-independent-loopback.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ )
start_networkd()
self.wait_online('ipiptun99:carrier')
- self.networkctl_check_unit('ipiptun99', '25-ipip-tunnel-independent-loopback', '26-netdev-link-local-addressing-yes')
+ self.networkctl_check_unit(
+ 'ipiptun99',
+ '25-ipip-tunnel-independent-loopback',
+ '26-netdev-link-local-addressing-yes',
+ )
@expectedFailureIfModuleIsNotAvailable('xfrm_interface')
def test_xfrm(self):
- copy_network_unit('12-dummy.netdev', '25-xfrm.network',
- '25-xfrm.netdev', '25-xfrm-independent.netdev',
- '26-netdev-link-local-addressing-yes.network')
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-xfrm.network',
+ '25-xfrm.netdev',
+ '25-xfrm-independent.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ )
start_networkd()
self.wait_online('dummy98:degraded', 'xfrm98:degraded', 'xfrm99:degraded')
@expectedFailureIfModuleIsNotAvailable('fou')
def test_fou(self):
- copy_network_unit('25-fou-ipproto-ipip.netdev', '25-fou-ipproto-gre.netdev',
- '25-fou-ipip.netdev', '25-fou-sit.netdev',
- '25-fou-gre.netdev', '25-fou-gretap.netdev')
+ copy_network_unit(
+ '25-fou-ipproto-ipip.netdev',
+ '25-fou-ipproto-gre.netdev',
+ '25-fou-ipip.netdev',
+ '25-fou-sit.netdev',
+ '25-fou-gre.netdev',
+ '25-fou-gretap.netdev',
+ )
start_networkd()
- self.wait_online('ipiptun96:off', 'sittun96:off', 'gretun96:off', 'gretap96:off', setup_state='unmanaged')
+ self.wait_online(
+ 'ipiptun96:off',
+ 'sittun96:off',
+ 'gretun96:off',
+ 'gretap96:off',
+ setup_state='unmanaged',
+ )
self.networkctl_check_unit('ipiptun96', '25-fou-ipip')
self.networkctl_check_unit('sittun96', '25-fou-sit')
self.networkctl_check_unit('gretun96', '25-fou-gre')
self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55556')
touch_network_unit(
- '25-fou-ipproto-ipip.netdev', '25-fou-ipproto-gre.netdev',
- '25-fou-ipip.netdev', '25-fou-sit.netdev',
- '25-fou-gre.netdev', '25-fou-gretap.netdev')
+ '25-fou-ipproto-ipip.netdev',
+ '25-fou-ipproto-gre.netdev',
+ '25-fou-ipip.netdev',
+ '25-fou-sit.netdev',
+ '25-fou-gre.netdev',
+ '25-fou-gretap.netdev',
+ )
networkctl_reload()
- self.wait_online('ipiptun96:off', 'sittun96:off', 'gretun96:off', 'gretap96:off', setup_state='unmanaged')
+ self.wait_online(
+ 'ipiptun96:off',
+ 'sittun96:off',
+ 'gretun96:off',
+ 'gretap96:off',
+ setup_state='unmanaged',
+ )
def test_vxlan(self):
- copy_network_unit('11-dummy.netdev', '25-vxlan-test1.network',
- '25-vxlan.netdev', '25-vxlan.network',
- '25-vxlan-ipv6.netdev', '25-vxlan-ipv6.network',
- '25-vxlan-independent.netdev', '26-netdev-link-local-addressing-yes.network',
- '25-veth.netdev', '25-vxlan-veth99.network', '25-ipv6-prefix.network',
- '25-vxlan-local-slaac.netdev', '25-vxlan-local-slaac.network',
- '25-vxlan-external.netdev', '25-vxlan-external.network')
- start_networkd()
-
- self.wait_online('test1:degraded', 'veth99:routable', 'veth-peer:degraded',
- 'vxlan99:degraded', 'vxlan98:degraded', 'vxlan97:degraded', 'vxlan-slaac:degraded',
- 'vxlan-external:degraded')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '25-vxlan-test1.network',
+ '25-vxlan.netdev',
+ '25-vxlan.network',
+ '25-vxlan-ipv6.netdev',
+ '25-vxlan-ipv6.network',
+ '25-vxlan-independent.netdev',
+ '26-netdev-link-local-addressing-yes.network',
+ '25-veth.netdev',
+ '25-vxlan-veth99.network',
+ '25-ipv6-prefix.network',
+ '25-vxlan-local-slaac.netdev',
+ '25-vxlan-local-slaac.network',
+ '25-vxlan-external.netdev',
+ '25-vxlan-external.network',
+ )
+ start_networkd()
+
+ self.wait_online(
+ 'test1:degraded',
+ 'veth99:routable',
+ 'veth-peer:degraded',
+ 'vxlan99:degraded',
+ 'vxlan98:degraded',
+ 'vxlan97:degraded',
+ 'vxlan-slaac:degraded',
+ 'vxlan-external:degraded',
+ )
self.networkctl_check_unit('test1', '11-dummy', '25-vxlan-test1')
self.networkctl_check_unit('veth99', '25-veth', '25-vxlan-veth99')
self.networkctl_check_unit('veth-peer', '25-veth', '25-ipv6-prefix')
self.assertIn('external', output)
self.assertIn('vnifilter', output)
- @unittest.skipUnless(compare_kernel_version("6"), reason="Causes kernel panic on unpatched kernels: https://bugzilla.kernel.org/show_bug.cgi?id=208315")
+ @unittest.skipUnless(
+ compare_kernel_version('6'),
+ reason='Causes kernel panic on unpatched kernels: https://bugzilla.kernel.org/show_bug.cgi?id=208315',
+ )
def test_macsec(self):
- copy_network_unit('25-macsec.netdev', '25-macsec.network', '25-macsec.key',
- '26-macsec.network', '12-dummy.netdev')
+ copy_network_unit(
+ '25-macsec.netdev',
+ '25-macsec.network',
+ '25-macsec.key',
+ '26-macsec.network',
+ '12-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:degraded', 'macsec99:routable')
networkctl_reload()
self.wait_online('ifb99:degraded')
- @unittest.skipUnless(os.cpu_count() >= 2, reason="CPU count should be >= 2 to pass this test")
+ @unittest.skipUnless(os.cpu_count() >= 2, reason='CPU count should be >= 2 to pass this test')
def test_rps_cpu_1(self):
copy_network_unit('12-dummy.netdev', '12-dummy.network', '25-rps-cpu-1.link')
start_networkd()
print(output)
self.assertEqual(int(output.replace(',', ''), base=16), 2)
- @unittest.skipUnless(os.cpu_count() >= 2, reason="CPU count should be >= 2 to pass this test")
+ @unittest.skipUnless(os.cpu_count() >= 2, reason='CPU count should be >= 2 to pass this test')
def test_rps_cpu_0_1(self):
copy_network_unit('12-dummy.netdev', '12-dummy.network', '25-rps-cpu-0-1.link')
start_networkd()
print(output)
self.assertEqual(int(output.replace(',', ''), base=16), 3)
- @unittest.skipUnless(os.cpu_count() >= 4, reason="CPU count should be >= 4 to pass this test")
+ @unittest.skipUnless(os.cpu_count() >= 4, reason='CPU count should be >= 4 to pass this test')
def test_rps_cpu_multi(self):
copy_network_unit('12-dummy.netdev', '12-dummy.network', '25-rps-cpu-multi.link')
start_networkd()
self.networkctl_check_unit('dummy98', '12-dummy', '12-dummy', '25-rps-cpu-all')
output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
print(output)
- self.assertEqual(f"{int(output.replace(',', ''), base=16):x}", f'{(1 << cpu_count) - 1:x}')
+ self.assertEqual(f'{int(output.replace(",", ""), base=16):x}', f'{(1 << cpu_count) - 1:x}')
remove_network_unit('25-rps-cpu-all.link')
# disable
self.networkctl_check_unit('dummy98', '12-dummy', '12-dummy', '25-rps-cpu-all')
output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
print(output)
- self.assertEqual(f"{int(output.replace(',', ''), base=16):x}", f'{(1 << cpu_count) - 1:x}')
+ self.assertEqual(f'{int(output.replace(",", ""), base=16):x}', f'{(1 << cpu_count) - 1:x}')
remove_network_unit('25-rps-cpu-all.link')
# empty -> unchanged
self.networkctl_check_unit('dummy98', '12-dummy', '12-dummy', '24-rps-cpu-empty')
output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
print(output)
- self.assertEqual(f"{int(output.replace(',', ''), base=16):x}", f'{(1 << cpu_count) - 1:x}')
+ self.assertEqual(f'{int(output.replace(",", ""), base=16):x}', f'{(1 << cpu_count) - 1:x}')
remove_network_unit('24-rps-cpu-empty.link')
# 0, then empty -> unchanged
self.networkctl_check_unit('dummy98', '12-dummy', '12-dummy', '25-rps-cpu-0-empty')
output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
print(output)
- self.assertEqual(f"{int(output.replace(',', ''), base=16):x}", f'{(1 << cpu_count) - 1:x}')
+ self.assertEqual(f'{int(output.replace(",", ""), base=16):x}', f'{(1 << cpu_count) - 1:x}')
remove_network_unit('25-rps-cpu-0-empty.link')
# 0, then invalid -> 0
self.assertEqual(int(output.replace(',', ''), base=16), 1)
remove_network_unit('24-rps-cpu-invalid.link')
-class NetworkdL2TPTests(unittest.TestCase, Utilities):
+class NetworkdL2TPTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
@expectedFailureIfModuleIsNotAvailable('l2tp_eth', 'l2tp_netlink')
def test_l2tp_udp(self):
- copy_network_unit('11-dummy.netdev', '25-l2tp-dummy.network',
- '25-l2tp-udp.netdev', '25-l2tp.network')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '25-l2tp-dummy.network',
+ '25-l2tp-udp.netdev',
+ '25-l2tp.network',
+ )
start_networkd()
self.wait_online('test1:routable', 'l2tp-ses1:degraded', 'l2tp-ses2:degraded')
output = check_output('ip l2tp show tunnel tunnel_id 10')
print(output)
- self.assertRegex(output, "Tunnel 10, encap UDP")
- self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
- self.assertRegex(output, "Peer tunnel 11")
- self.assertRegex(output, "UDP source / dest ports: 3000/4000")
- self.assertRegex(output, "UDP checksum: enabled")
+ self.assertRegex(output, 'Tunnel 10, encap UDP')
+ self.assertRegex(output, 'From 192.168.30.100 to 192.168.30.101')
+ self.assertRegex(output, 'Peer tunnel 11')
+ self.assertRegex(output, 'UDP source / dest ports: 3000/4000')
+ self.assertRegex(output, 'UDP checksum: enabled')
output = check_output('ip l2tp show session tid 10 session_id 15')
print(output)
- self.assertRegex(output, "Session 15 in tunnel 10")
- self.assertRegex(output, "Peer session 16, tunnel 11")
- self.assertRegex(output, "interface name: l2tp-ses1")
+ self.assertRegex(output, 'Session 15 in tunnel 10')
+ self.assertRegex(output, 'Peer session 16, tunnel 11')
+ self.assertRegex(output, 'interface name: l2tp-ses1')
output = check_output('ip l2tp show session tid 10 session_id 17')
print(output)
- self.assertRegex(output, "Session 17 in tunnel 10")
- self.assertRegex(output, "Peer session 18, tunnel 11")
- self.assertRegex(output, "interface name: l2tp-ses2")
+ self.assertRegex(output, 'Session 17 in tunnel 10')
+ self.assertRegex(output, 'Peer session 18, tunnel 11')
+ self.assertRegex(output, 'interface name: l2tp-ses2')
touch_network_unit(
- '11-dummy.netdev', '25-l2tp-dummy.network',
- '25-l2tp-udp.netdev', '25-l2tp.network')
+ '11-dummy.netdev',
+ '25-l2tp-dummy.network',
+ '25-l2tp-udp.netdev',
+ '25-l2tp.network',
+ )
networkctl_reload()
self.wait_online('test1:routable', 'l2tp-ses1:degraded', 'l2tp-ses2:degraded')
@expectedFailureIfModuleIsNotAvailable('l2tp_eth', 'l2tp_ip', 'l2tp_netlink')
def test_l2tp_ip(self):
- copy_network_unit('11-dummy.netdev', '25-l2tp-dummy.network',
- '25-l2tp-ip.netdev', '25-l2tp.network')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '25-l2tp-dummy.network',
+ '25-l2tp-ip.netdev',
+ '25-l2tp.network',
+ )
start_networkd()
self.wait_online('test1:routable', 'l2tp-ses3:degraded', 'l2tp-ses4:degraded')
output = check_output('ip l2tp show tunnel tunnel_id 10')
print(output)
- self.assertRegex(output, "Tunnel 10, encap IP")
- self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
- self.assertRegex(output, "Peer tunnel 12")
+ self.assertRegex(output, 'Tunnel 10, encap IP')
+ self.assertRegex(output, 'From 192.168.30.100 to 192.168.30.101')
+ self.assertRegex(output, 'Peer tunnel 12')
output = check_output('ip l2tp show session tid 10 session_id 25')
print(output)
- self.assertRegex(output, "Session 25 in tunnel 10")
- self.assertRegex(output, "Peer session 26, tunnel 12")
- self.assertRegex(output, "interface name: l2tp-ses3")
+ self.assertRegex(output, 'Session 25 in tunnel 10')
+ self.assertRegex(output, 'Peer session 26, tunnel 12')
+ self.assertRegex(output, 'interface name: l2tp-ses3')
output = check_output('ip l2tp show session tid 10 session_id 27')
print(output)
- self.assertRegex(output, "Session 27 in tunnel 10")
- self.assertRegex(output, "Peer session 28, tunnel 12")
- self.assertRegex(output, "interface name: l2tp-ses4")
+ self.assertRegex(output, 'Session 27 in tunnel 10')
+ self.assertRegex(output, 'Peer session 28, tunnel 12')
+ self.assertRegex(output, 'interface name: l2tp-ses4')
touch_network_unit(
- '11-dummy.netdev', '25-l2tp-dummy.network',
- '25-l2tp-ip.netdev', '25-l2tp.network')
+ '11-dummy.netdev',
+ '25-l2tp-dummy.network',
+ '25-l2tp-ip.netdev',
+ '25-l2tp.network',
+ )
networkctl_reload()
self.wait_online('test1:routable', 'l2tp-ses3:degraded', 'l2tp-ses4:degraded')
-class NetworkdNetworkTests(unittest.TestCase, Utilities):
+class NetworkdNetworkTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.wait_online('test1:off', setup_state='unmanaged')
def verify_address_static(
- self,
- label1: str,
- label2: str,
- label3: str,
- broadcast1: str,
- broadcast2: str,
- broadcast3: str,
- peer1: str,
- peer2: str,
- peer3: str,
- peer4: str,
- peer5: str,
- peer6: str,
- scope1: str,
- scope2: str,
- deprecated1: str,
- deprecated2: str,
- deprecated3: str,
- deprecated4: str,
- route_metric: int,
- flag1: str,
- flag2: str,
- flag3: str,
- flag4: str,
- ip4_null_16: str,
- ip4_null_24: str,
- ip6_null_73: str,
- ip6_null_74: str,
+ self,
+ label1: str,
+ label2: str,
+ label3: str,
+ broadcast1: str,
+ broadcast2: str,
+ broadcast3: str,
+ peer1: str,
+ peer2: str,
+ peer3: str,
+ peer4: str,
+ peer5: str,
+ peer6: str,
+ scope1: str,
+ scope2: str,
+ deprecated1: str,
+ deprecated2: str,
+ deprecated3: str,
+ deprecated4: str,
+ route_metric: int,
+ flag1: str,
+ flag2: str,
+ flag3: str,
+ flag4: str,
+ ip4_null_16: str,
+ ip4_null_24: str,
+ ip6_null_73: str,
+ ip6_null_74: str,
):
output = check_output('ip address show dev dummy98')
print(output)
self.assertIn(f'inet6 2001:db8:0:f104::2/64 scope global{deprecated4}', output)
# route metric
- self.assertRegex(output, rf'inet 10.8.1.1/24 (metric {route_metric} |)brd 10.8.1.255 scope global dummy98')
+ self.assertRegex(output, rf'inet 10.8.1.1/24 (metric {route_metric} |)brd 10.8.1.255 scope global dummy98') # fmt: skip
self.assertRegex(output, rf'inet6 2001:db8:0:f105::1/64 (metric {route_metric} |)scope global')
output_route = check_output('ip -4 route show dev dummy98 10.8.1.0/24')
print(output_route)
- self.assertIn(f'10.8.1.0/24 proto kernel scope link src 10.8.1.1 metric {route_metric}', output_route)
+ self.assertIn(f'10.8.1.0/24 proto kernel scope link src 10.8.1.1 metric {route_metric}', output_route) # fmt: skip
output_route = check_output('ip -6 route show dev dummy98 2001:db8:0:f105::/64')
print(output_route)
# null address
self.assertTrue(ip4_null_16.endswith('.0.1'))
- prefix16 = ip4_null_16[:-len('.0.1')]
+ prefix16 = ip4_null_16[: -len('.0.1')]
self.assertTrue(ip4_null_24.endswith('.1'))
- prefix24 = ip4_null_24[:-len('.1')]
+ prefix24 = ip4_null_24[: -len('.1')]
self.assertIn(f'inet {ip4_null_16}/16 brd {prefix16}.255.255 scope global subnet16', output)
self.assertIn(f'inet {ip4_null_24}/24 brd {prefix24}.255 scope global subnet24', output)
self.assertIn(f'inet6 {ip6_null_73}/73 scope global', output)
@expectedFailureIfModuleIsNotAvailable('vrf')
def test_prefix_route(self):
- copy_network_unit('25-prefix-route-with-vrf.network', '12-dummy.netdev',
- '25-prefix-route-without-vrf.network', '11-dummy.netdev',
- '25-vrf.netdev', '25-vrf.network')
+ copy_network_unit(
+ '25-prefix-route-with-vrf.network',
+ '12-dummy.netdev',
+ '25-prefix-route-without-vrf.network',
+ '11-dummy.netdev',
+ '25-vrf.netdev',
+ '25-vrf.network',
+ )
for trial in range(2):
if trial == 0:
start_networkd()
if trial == 0:
# Kernel's bug?
self.assertRegex(output, 'local fdde:11:22::1 proto kernel metric 0 pref medium')
- #self.assertRegex(output, 'fdde:11:22::1 proto kernel metric 256 pref medium')
+ # self.assertRegex(output, 'fdde:11:22::1 proto kernel metric 256 pref medium')
self.assertRegex(output, 'local fdde:11:33::1 proto kernel metric 0 pref medium')
self.assertRegex(output, 'fdde:11:33::/64 proto kernel metric 256 pref medium')
self.assertRegex(output, 'local fdde:11:44::1 proto kernel metric 0 pref medium')
carrier_map = {'on': '1', 'off': '0'}
routable_map = {'on': 'routable', 'off': 'no-carrier'}
- for (carrier, have_config) in [('off', True), ('on', True), ('off', False)]:
+ for carrier, have_config in [('off', True), ('on', True), ('off', False)]:
with self.subTest(carrier=carrier, have_config=have_config):
if carrier_map[carrier] != read_link_attr('test1', 'carrier'):
check_output(f'ip link set dev test1 carrier {carrier}')
output = check_output('ip rule list iif test1 priority 111')
print(output)
- self.assertRegex(output, r'111: from 192.168.100.18 tos (0x08|throughput) iif test1 oif test1 lookup 7')
+ self.assertRegex(output, r'111: from 192.168.100.18 tos (0x08|throughput) iif test1 oif test1 lookup 7') # fmt: skip
output = check_output('ip -6 rule list iif test1 priority 100')
print(output)
output = check_output('ip rule list priority 112')
print(output)
- self.assertRegex(output, r'112: from 192.168.101.18 tos (0x08|throughput) iif dummy98 oif dummy98 lookup 8')
+ self.assertRegex(output, r'112: from 192.168.101.18 tos (0x08|throughput) iif dummy98 oif dummy98 lookup 8') # fmt: skip
def _test_routing_policy_rule(self, manage_foreign_routes):
if not manage_foreign_routes:
self._test_routing_policy_rule(manage_foreign_routes)
def test_routing_policy_rule_restart_and_reconfigure(self):
- copy_network_unit('25-routing-policy-rule-test1.network', '11-dummy.netdev',
- '25-routing-policy-rule-dummy98.network', '12-dummy.netdev')
+ copy_network_unit(
+ '25-routing-policy-rule-test1.network',
+ '11-dummy.netdev',
+ '25-routing-policy-rule-dummy98.network',
+ '12-dummy.netdev',
+ )
# For #11280 and #34068.
# For issue #36244.
copy_network_unit(
'11-dummy.netdev',
- '25-routing-policy-rule-manual.network')
+ '25-routing-policy-rule-manual.network',
+ )
start_networkd()
self.wait_operstate('test1', operstate='off', setup_state='configuring', setup_timeout=20)
if not manage_foreign_routes:
copy_networkd_conf_dropin('networkd-manage-foreign-routes-no.conf')
- copy_network_unit('25-route-static.network', '12-dummy.netdev',
- '25-route-static-test1.network', '11-dummy.netdev')
+ copy_network_unit(
+ '25-route-static.network',
+ '12-dummy.netdev',
+ '25-route-static-test1.network',
+ '11-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:routable', 'test1:routable')
self._check_route_static(test1_is_managed=True)
'25-route-static-issue-35047.network',
'25-route-static-issue-35047.network.d/step1.conf',
'12-dummy.netdev',
- copy_dropins=False)
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('dummy98:routable')
self.assertIn('198.51.100.0/24 via 192.0.2.2 proto static', output)
check_output('ip link set dev dummy98 down')
- self.wait_route_dropped('dummy98', '192.0.2.2 proto kernel scope link src 192.0.2.1', ipv='-4', table='all', timeout_sec=10)
- self.wait_route_dropped('dummy98', 'local 192.0.2.1 table local proto kernel scope host src 192.0.2.1', ipv='-4', table='all', timeout_sec=10)
- self.wait_route_dropped('dummy98', '198.51.100.0/24 via 192.0.2.2 proto static', ipv='-4', table='all', timeout_sec=10)
+ self.wait_route_dropped(
+ 'dummy98',
+ '192.0.2.2 proto kernel scope link src 192.0.2.1',
+ ipv='-4',
+ table='all',
+ timeout_sec=10,
+ )
+ self.wait_route_dropped(
+ 'dummy98',
+ 'local 192.0.2.1 table local proto kernel scope host src 192.0.2.1',
+ ipv='-4',
+ table='all',
+ timeout_sec=10,
+ )
+ self.wait_route_dropped(
+ 'dummy98',
+ '198.51.100.0/24 via 192.0.2.2 proto static',
+ ipv='-4',
+ table='all',
+ timeout_sec=10,
+ )
print('### ip -4 route show table all dev dummy98')
output = check_output('ip -4 route show table all dev dummy98')
print('### ip -4 route show table all dev dummy98')
output = check_output('ip -4 route show table all dev dummy98')
print(output)
+ # fmt: off
self.assertIn('default via 192.168.0.193 table 249 proto static src 192.168.0.227 metric 128 onlink', output)
self.assertIn('192.168.0.192/26 table 249 proto static scope link src 192.168.0.227 metric 128', output)
self.assertIn('10.1.2.2 via 192.168.0.193 proto static src 192.168.0.227 metric 128 onlink', output)
self.assertIn('192.168.0.193 proto static scope link src 192.168.0.227 metric 128', output)
self.assertIn('local 192.168.0.227 table local proto kernel scope host src 192.168.0.227', output)
self.assertIn('broadcast 192.168.0.255 table local proto kernel scope link src 192.168.0.227', output)
+ # fmt: on
print('### ip -6 route show table all dev dummy98')
output = check_output('ip -6 route show table all dev dummy98')
print(output)
+ # fmt: off
self.assertIn('2000:f00::/64 table 249 proto static src 2000:f00::227 metric 128 pref medium', output)
self.assertIn('default via 2000:f00::1 table 249 proto static src 2000:f00::227 metric 128 onlink pref medium', output)
self.assertIn('fe80::/64 proto kernel metric 256 pref medium', output)
self.assertIn('local 2000:f00::227 table local proto kernel metric 0 pref medium', output)
- self.assertRegex(output, 'local fe80:[a-f0-9:]* table local proto kernel metric 0 pref medium', output)
+ self.assertRegex(output, 'local fe80:[a-f0-9:]* table local proto kernel metric 0 pref medium')
self.assertIn('multicast ff00::/8 table local proto kernel metric 256 pref medium', output)
+ # fmt: on
def test_route_via_ipv6(self):
copy_network_unit('25-route-via-ipv6.network', '12-dummy.netdev')
@expectedFailureIfModuleIsNotAvailable('vrf')
def test_route_vrf(self):
- copy_network_unit('25-route-vrf.network', '12-dummy.netdev',
- '25-vrf.netdev', '25-vrf.network')
+ copy_network_unit(
+ '25-route-vrf.network',
+ '12-dummy.netdev',
+ '25-vrf.netdev',
+ '25-vrf.network',
+ )
start_networkd()
self.wait_online('dummy98:routable', 'vrf99:carrier')
# a dummy device does not make the addresses go through tentative state, so we
# reuse a bond from an earlier test, which does make the addresses go through
# tentative state, and do our test on that
- copy_network_unit('23-active-slave.network', '25-route-ipv6-src.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
+ copy_network_unit(
+ '23-active-slave.network',
+ '25-route-ipv6-src.network',
+ '25-bond-active-backup-slave.netdev',
+ '12-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:enslaved', 'bond199:routable')
output = check_output('ip -6 route list dev dummy98')
print(output)
- self.assertIn('abcd::/16 via 2001:1234:56:8f63::1:1 proto static src 2001:1234:56:8f63::1', output)
+ self.assertIn('abcd::/16 via 2001:1234:56:8f63::1:1 proto static src 2001:1234:56:8f63::1', output) # fmt: skip
output = check_output('ip -4 route list dev dummy98')
print(output)
self.assertRegex(output, f'2607:5300:203:5215:{i}::1 *proxy')
def test_ipv6_neigh_retrans_time(self):
- link='test25'
+ link = 'test25'
copy_network_unit('25-dummy.netdev', '25-dummy.network')
start_networkd()
remove_network_unit('25-ipv6-neigh-retrans-time-4s.network')
def test_neighbor(self):
- copy_network_unit('12-dummy.netdev', '25-neighbor-dummy.network', '25-neighbor-dummy.network.d/10-step1.conf',
- '25-gre-tunnel-remote-any.netdev', '25-neighbor-ip.network',
- '25-ip6gre-tunnel-remote-any.netdev', '25-neighbor-ipv6.network',
- copy_dropins=False)
+ copy_network_unit(
+ '12-dummy.netdev',
+ '25-neighbor-dummy.network',
+ '25-neighbor-dummy.network.d/10-step1.conf',
+ '25-gre-tunnel-remote-any.netdev',
+ '25-neighbor-ip.network',
+ '25-ip6gre-tunnel-remote-any.netdev',
+ '25-neighbor-ipv6.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('dummy98:degraded', 'gretun97:routable', 'ip6gretun97:routable')
print('### ip neigh list dev ip6gretun97')
output = check_output('ip neigh list dev ip6gretun97')
print(output)
- self.assertRegex(output, '2001:db8:0:f102::17 lladdr 2a:?00:ff:?de:45:?67:ed:?de:[0:]*:49:?88 PERMANENT')
+ self.assertRegex(output, '2001:db8:0:f102::17 lladdr 2a:?00:ff:?de:45:?67:ed:?de:[0:]*:49:?88 PERMANENT') # fmt: skip
self.assertNotIn('2001:db8:0:f102::18', output)
print('### ip neigh list dev dummy98')
check_json(networkctl_json())
- remove_network_unit('25-neighbor-dummy.network.d/10-step1.conf',
- '25-neighbor-dummy.network.d/10-step2.conf')
+ remove_network_unit(
+ '25-neighbor-dummy.network.d/10-step1.conf',
+ '25-neighbor-dummy.network.d/10-step2.conf',
+ )
copy_network_unit('25-neighbor-dummy.network.d/10-step3.conf')
networkctl_reload()
self.wait_online('dummy98:degraded')
self.assertNotIn('2004:da8:1::1', output)
def test_link_local_addressing(self):
- copy_network_unit('25-link-local-addressing-yes.network', '11-dummy.netdev',
- '25-link-local-addressing-no.network', '12-dummy.netdev')
+ copy_network_unit(
+ '25-link-local-addressing-yes.network',
+ '11-dummy.netdev',
+ '25-link-local-addressing-no.network',
+ '12-dummy.netdev',
+ )
start_networkd()
self.wait_online('test1:degraded', 'dummy98:carrier')
start_networkd()
always = test.startswith('always')
- initial_up = test != 'manual' and not test.endswith('down') # note: default is up
+ initial_up = test != 'manual' and not test.endswith('down') # note: default is up
expect_up = initial_up
next_up = not expect_up
else:
self.tearDown()
- print(f'### test_activation_policy_required_for_online(policy={policy}, required={required})')
+ print(f'### test_activation_policy_required_for_online(policy={policy}, required={required})') # fmt: skip
with self.subTest(policy=policy, required=required):
self._test_activation_policy_required_for_online(policy, required)
call('ip -6 addr add 2001:db8:9999:f101::15/64 dev unmanaged0')
# Wait for all addresses
+ # fmt: off
self.wait_address('unmanaged0', 'inet 10.20.30.40/32', scope='global', ipv='-4', timeout_sec=10)
self.wait_address('unmanaged0', 'inet6 2001:db8:9999:f101::15/64', scope='global', ipv='-6', timeout_sec=10)
self.wait_address('unmanaged0', 'inet6 fe80::[0-9a-f:]*/64', scope='link', ipv='-6', timeout_sec=10)
+ # fmt: on
# Wait for all routes
+ # fmt: off
self.wait_route('unmanaged0', 'local 10.20.30.40 proto kernel', table='local', ipv='-4', timeout_sec=10)
self.wait_route('unmanaged0', 'local fe80::[0-9a-f:]* proto kernel', table='local', ipv='-6', timeout_sec=10)
self.wait_route('unmanaged0', 'multicast ff00::/8 proto kernel', table='local', ipv='-6', timeout_sec=10)
self.wait_route('unmanaged0', '2001:db8:9999:f101::/64 proto kernel', table='main', ipv='-6', timeout_sec=10)
self.wait_route('unmanaged0', 'fe80::/64 proto kernel', table='main', ipv='-6', timeout_sec=10)
+ # fmt: on
# Start `ip monitor` with output to a temporary file
with tempfile.TemporaryFile(mode='r+', prefix='ip_monitor_u') as logfile_unmanaged:
- process_u = subprocess.Popen(['ip', 'monitor', 'dev', 'unmanaged0'], stdout=logfile_unmanaged, text=True)
+ process_u = subprocess.Popen(
+ ['ip', 'monitor', 'dev', 'unmanaged0'],
+ stdout=logfile_unmanaged,
+ text=True,
+ )
start_networkd()
self.check_keep_configuration_on_restart()
output = check_output('ip -6 route show dev veth99 2001:1234:5:8f62::1')
print(output)
+ # fmt: off
if first:
self.assertEqual('2001:1234:5:8f62::1 nhid 2 via 2001:1234:5:8f63::2 proto static metric 1024 pref medium', output)
else:
self.assertEqual('2001:1234:5:8f62::1 nhid 7 via 2001:1234:5:8f63::2 proto static metric 1024 pref medium', output)
+ # fmt: on
output = check_output('ip route show 10.10.10.13')
print(output)
output = check_output('ip -6 route show 2001:1234:5:8f62::2')
print(output)
+ # fmt: off
if first:
self.assertEqual('blackhole 2001:1234:5:8f62::2 nhid 7 dev lo proto static metric 1024 pref medium', output)
else:
self.assertEqual('blackhole 2001:1234:5:8f62::2 nhid 2 dev lo proto static metric 1024 pref medium', output)
+ # fmt: on
output = check_output('ip route show 10.10.10.14')
print(output)
check_output('ip address add 192.168.20.20/24 dev dummy98')
check_output('ip nexthop add id 42 via 192.168.20.2 dev dummy98')
- copy_network_unit('25-nexthop-1.network', '25-veth.netdev', '25-veth-peer.network',
- '12-dummy.netdev', '25-nexthop-dummy-1.network')
+ copy_network_unit(
+ '25-nexthop-1.network',
+ '25-veth.netdev',
+ '25-veth-peer.network',
+ '12-dummy.netdev',
+ '25-nexthop-dummy-1.network',
+ )
start_networkd()
self.check_nexthop(manage_foreign_nexthops, first=True)
# Of course, networkctl_reconfigure() below is unnecessary in normal operation, but it is intentional
# here to test reconfiguring with different .network files does not trigger race.
# See also comments in link_drop_requests().
- networkctl_reconfigure('dummy98') # reconfigured with 25-nexthop-dummy-2.network
- networkctl_reload() # reconfigured with 25-nexthop-dummy-1.network
+ # fmt: off
+ networkctl_reconfigure('dummy98') # reconfigured with 25-nexthop-dummy-2.network
+ networkctl_reload() # reconfigured with 25-nexthop-dummy-1.network
+ # fmt: on
self.check_nexthop(manage_foreign_nexthops, first=True)
with self.subTest(manage_foreign_nexthops=manage_foreign_nexthops):
self._test_nexthop(manage_foreign_nexthops)
-class NetworkdTCTests(unittest.TestCase, Utilities):
+class NetworkdTCTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
output = check_output('tc qdisc show dev dummy98')
print(output)
self.assertRegex(output, 'qdisc codel 33: root')
- self.assertRegex(output, 'limit 2000p target 10(.0)?ms ce_threshold 100(.0)?ms interval 50(.0)?ms ecn')
+ self.assertRegex(output, 'limit 2000p target 10(.0)?ms ce_threshold 100(.0)?ms interval 50(.0)?ms ecn') # fmt: skip
@expectedFailureIfModuleIsNotAvailable('sch_drr')
def test_qdisc_drr(self):
output = check_output('tc qdisc show dev dummy98')
print(output)
self.assertRegex(output, 'qdisc fq_codel 34: root')
- self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10(.0)?ms ce_threshold 100(.0)?ms interval 200(.0)?ms memory_limit 64Mb ecn')
+ self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10(.0)?ms ce_threshold 100(.0)?ms interval 200(.0)?ms memory_limit 64Mb ecn') # fmt: skip
@expectedFailureIfModuleIsNotAvailable('sch_fq_pie')
def test_qdisc_fq_pie(self):
@expectedFailureIfModuleIsNotAvailable('sch_ingress')
def test_qdisc_ingress(self):
- copy_network_unit('25-qdisc-clsact.network', '12-dummy.netdev',
- '25-qdisc-ingress.network', '11-dummy.netdev')
+ copy_network_unit(
+ '25-qdisc-clsact.network',
+ '12-dummy.netdev',
+ '25-qdisc-ingress.network',
+ '11-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:routable', 'test1:routable')
@expectedFailureIfModuleIsNotAvailable('sch_netem')
def test_qdisc_netem(self):
- copy_network_unit('25-qdisc-netem.network', '12-dummy.netdev',
- '25-qdisc-netem-compat.network', '11-dummy.netdev')
+ copy_network_unit(
+ '25-qdisc-netem.network',
+ '12-dummy.netdev',
+ '25-qdisc-netem-compat.network',
+ '11-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:routable', 'test1:routable')
output = check_output('tc qdisc show dev dummy98')
print(output)
self.assertRegex(output, 'qdisc tbf 35: root')
- self.assertRegex(output, 'rate 1Gbit burst 5000b peakrate 100Gbit minburst (987500b|999200b) lat 70(.0)?ms')
+ self.assertRegex(output, 'rate 1Gbit burst 5000b peakrate 100Gbit minburst (987500b|999200b) lat 70(.0)?ms') # fmt: skip
@expectedFailureIfModuleIsNotAvailable('sch_teql')
def test_qdisc_teql(self):
self.assertFalse(networkd_is_failed())
check_output('tc qdisc replace dev dummy98 root fq pacing')
self.assertFalse(networkd_is_failed())
- check_output('tc qdisc replace dev dummy98 handle 10: root tbf rate 0.5mbit burst 5kb latency 70ms peakrate 1mbit minburst 1540')
+ check_output('tc qdisc replace dev dummy98 handle 10: root tbf rate 0.5mbit burst 5kb latency 70ms peakrate 1mbit minburst 1540') # fmt: skip
self.assertFalse(networkd_is_failed())
check_output('tc qdisc add dev dummy98 parent 10:1 handle 100: sfq')
self.assertFalse(networkd_is_failed())
-class NetworkdStateFileTests(unittest.TestCase, Utilities):
+class NetworkdStateFileTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.assertIn('REQUIRED_FAMILY_FOR_ONLINE=both', output)
self.assertIn('ACTIVATION_POLICY=up', output)
self.assertIn('NETWORK_FILE=/run/systemd/network/25-state-file-tests.network', output)
- self.assertIn('DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com [1111:2222::3333]:1234#ccc.com', output)
+ self.assertIn('DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com [1111:2222::3333]:1234#ccc.com', output) # fmt: skip
self.assertIn('NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org', output)
self.assertIn('DOMAINS=hogehoge', output)
self.assertIn('ROUTE_DOMAINS=foofoo', output)
output = read_link_state_file('dummy98')
print(output)
- self.assertIn('DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com [1111:2222::3333]:1234#ccc.com', output)
+ self.assertIn('DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com [1111:2222::3333]:1234#ccc.com', output) # fmt: skip
self.assertIn('NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org', output)
self.assertIn('DOMAINS=hogehoge', output)
self.assertIn('ROUTE_DOMAINS=foofoo', output)
self.assertIn('IPV4_ADDRESS_STATE=off', output)
self.assertIn('IPV6_ADDRESS_STATE=routable', output)
-class NetworkdBondTests(unittest.TestCase, Utilities):
+class NetworkdBondTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.wait_online('dummy98:enslaved')
def test_bond_active_slave(self):
- copy_network_unit('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
+ copy_network_unit(
+ '23-active-slave.network',
+ '23-bond199.network',
+ '25-bond-active-backup-slave.netdev',
+ '12-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:enslaved', 'bond199:degraded')
'23-active-slave.network',
'23-bond199.network',
'25-bond-active-backup-slave.netdev',
- '12-dummy.netdev')
+ '12-dummy.netdev',
+ )
networkctl_reload()
self.wait_online('dummy98:enslaved', 'bond199:degraded')
def test_bond_primary_slave(self):
- copy_network_unit('23-primary-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
+ copy_network_unit(
+ '23-primary-slave.network',
+ '23-bond199.network',
+ '25-bond-active-backup-slave.netdev',
+ '12-dummy.netdev',
+ )
start_networkd()
self.wait_online('dummy98:enslaved', 'bond199:degraded')
# for issue #25627
mkdir_p(os.path.join(network_unit_dir, '23-bond199.network.d'))
for mac in ['00:11:22:33:44:55', '00:11:22:33:44:56']:
- with open(os.path.join(network_unit_dir, '23-bond199.network.d/mac.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '23-bond199.network.d/mac.conf'), mode='w', encoding='utf-8'
+ ) as f:
f.write(f'[Link]\nMACAddress={mac}\n')
networkctl_reload()
self.assertIn(f'link/ether {mac}', output)
def test_bond_operstate(self):
- copy_network_unit('25-bond.netdev', '11-dummy.netdev', '12-dummy.netdev',
- '25-bond99.network', '25-bond-slave.network')
+ copy_network_unit(
+ '25-bond.netdev',
+ '11-dummy.netdev',
+ '12-dummy.netdev',
+ '25-bond99.network',
+ '25-bond-slave.network',
+ )
start_networkd()
self.wait_online('dummy98:enslaved', 'test1:enslaved', 'bond99:routable')
print(output)
self.assertNotRegex(output, 'NO-CARRIER')
-class NetworkdBridgeTests(unittest.TestCase, Utilities):
+class NetworkdBridgeTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
tear_down_common()
def test_bridge_mac_none(self):
- copy_network_unit('12-dummy-mac.netdev', '26-bridge-mac-slave.network',
- '26-bridge-mac.netdev', '26-bridge-mac-master.network', '26-bridge-mac.link')
+ copy_network_unit(
+ '12-dummy-mac.netdev',
+ '26-bridge-mac-slave.network',
+ '26-bridge-mac.netdev',
+ '26-bridge-mac-master.network',
+ '26-bridge-mac.link',
+ )
start_networkd()
self.wait_online('dummy98:enslaved', 'bridge99:degraded')
self.assertIn('link/ether 12:34:56:78:9a:01', output)
def test_bridge_vlan(self):
- copy_network_unit('11-dummy.netdev', '26-bridge-vlan-slave.network',
- '26-bridge.netdev', '26-bridge-vlan-master.network',
- copy_dropins=False)
+ copy_network_unit(
+ '11-dummy.netdev',
+ '26-bridge-vlan-slave.network',
+ '26-bridge.netdev',
+ '26-bridge-vlan-master.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('test1:enslaved', 'bridge99:degraded')
self.assertNotIn(f'{i}', output)
# Change vlan IDs
- copy_network_unit('26-bridge-vlan-slave.network.d/10-override.conf',
- '26-bridge-vlan-master.network.d/10-override.conf')
+ copy_network_unit(
+ '26-bridge-vlan-slave.network.d/10-override.conf',
+ '26-bridge-vlan-master.network.d/10-override.conf',
+ )
networkctl_reload()
self.wait_online('test1:enslaved', 'bridge99:degraded')
self.assertNotIn(f'{i}', output)
# Remove several vlan IDs
- copy_network_unit('26-bridge-vlan-slave.network.d/20-override.conf',
- '26-bridge-vlan-master.network.d/20-override.conf')
+ copy_network_unit(
+ '26-bridge-vlan-slave.network.d/20-override.conf',
+ '26-bridge-vlan-master.network.d/20-override.conf',
+ )
networkctl_reload()
self.wait_online('test1:enslaved', 'bridge99:degraded')
self.assertNotIn(f'{i}', output)
# Remove all vlan IDs
- copy_network_unit('26-bridge-vlan-slave.network.d/30-override.conf',
- '26-bridge-vlan-master.network.d/30-override.conf')
+ copy_network_unit(
+ '26-bridge-vlan-slave.network.d/30-override.conf',
+ '26-bridge-vlan-master.network.d/30-override.conf',
+ )
networkctl_reload()
self.wait_online('test1:enslaved', 'bridge99:degraded')
self.assertNotIn(f'{i}', output)
def test_bridge_vlan_issue_20373(self):
- copy_network_unit('11-dummy.netdev', '26-bridge-vlan-slave-issue-20373.network',
- '26-bridge-issue-20373.netdev', '26-bridge-vlan-master-issue-20373.network',
- '21-vlan.netdev', '21-vlan.network')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '26-bridge-vlan-slave-issue-20373.network',
+ '26-bridge-issue-20373.netdev',
+ '26-bridge-vlan-master-issue-20373.network',
+ '21-vlan.netdev',
+ '21-vlan.network',
+ )
start_networkd()
self.wait_online('test1:enslaved', 'bridge99:degraded', 'vlan99:routable')
self.assertIn('600', output)
def test_bridge_mdb(self):
- copy_network_unit('11-dummy.netdev', '26-bridge-mdb-slave.network',
- '26-bridge.netdev', '26-bridge-mdb-master.network')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '26-bridge-mdb-slave.network',
+ '26-bridge.netdev',
+ '26-bridge-mdb-master.network',
+ )
start_networkd()
self.wait_online('test1:enslaved', 'bridge99:degraded')
self.assertRegex(output, 'dev bridge99 port bridge99 grp 224.0.1.2 temp *vid 4067')
# The kernels older than 955062b03fa62b802a1ee34fbb04e39f7a70ae73 (v5.11) do not support L2 bridge MDB entries
- if call_quiet('bridge mdb add dev bridge99 port bridge99 grp 01:80:c2:00:00:0f permanent vid 4070') == 0:
+ if call_quiet('bridge mdb add dev bridge99 port bridge99 grp 01:80:c2:00:00:0f permanent vid 4070') == 0: # fmt: skip
self.assertRegex(output, 'dev bridge99 port bridge99 grp 01:80:c2:00:00:0e permanent *vid 4069')
def test_bridge_keep_master(self):
output = check_output('bridge -d link show dummy98')
print(output)
- self.check_bridge_port_attr('bridge99', 'dummy98', 'path_cost', '400')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode', '1')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'path_cost', '400')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode', '1')
self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave', '1')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood', '1')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood', '1')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood', '0')
# CONFIG_BRIDGE_IGMP_SNOOPING=y
self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast', '1', allow_enoent=True)
- self.check_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress', '1', allow_enoent=True)
- self.check_bridge_port_attr('bridge99', 'dummy98', 'learning', '0')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'priority', '23')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard', '0')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'root_block', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress', '1', allow_enoent=True)
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'learning', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'priority', '23')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'root_block', '0')
def check_bridge_property(self):
self.wait_online('dummy98:enslaved', 'test1:enslaved', 'bridge99:routable')
output = check_output('bridge -d link show dummy98')
print(output)
- self.check_bridge_port_attr('bridge99', 'dummy98', 'path_cost', '400')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode', '1')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'isolated', '1')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'path_cost', '400')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode', '1')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'isolated', '1')
self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave', '1')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood', '1')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood', '1')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood', '0')
# CONFIG_BRIDGE_IGMP_SNOOPING=y
self.check_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast', '1', allow_enoent=True)
- self.check_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress', '1', allow_enoent=True)
- self.check_bridge_port_attr('bridge99', 'dummy98', 'learning', '0')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'priority', '23')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard', '0')
- self.check_bridge_port_attr('bridge99', 'dummy98', 'root_block', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress', '1', allow_enoent=True)
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'learning', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'priority', '23')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard', '0')
+ self.check_bridge_port_attr('bridge99', 'dummy98', 'root_block', '0')
output = check_output('bridge -d link show test1')
print(output)
- self.check_bridge_port_attr('bridge99', 'test1', 'priority', '0')
+ self.check_bridge_port_attr('bridge99', 'test1', 'priority', '0')
self.assertIn('locked on', output)
- if ' mab ' in output: # This is new in kernel and iproute2 v6.2
+ if ' mab ' in output: # This is new in kernel and iproute2 v6.2
self.assertIn('mab on', output)
def test_bridge_property(self):
- copy_network_unit('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
- '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
- '25-bridge99.network', '14-dummy.netdev', '26-bridge-vlan-tunnel.network')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '12-dummy.netdev',
+ '26-bridge.netdev',
+ '26-bridge-slave-interface-1.network',
+ '26-bridge-slave-interface-2.network',
+ '25-bridge99.network',
+ '14-dummy.netdev',
+ '26-bridge-vlan-tunnel.network',
+ )
start_networkd()
self.check_bridge_property()
'26-bridge-slave-interface-1.network',
'26-bridge-slave-interface-2.network',
'26-bridge-vlan-tunnel.network',
- '25-bridge99.network')
+ '25-bridge99.network',
+ )
networkctl_reload()
self.check_bridge_property()
output = check_output('ip address show bridge99')
print(output)
self.assertNotIn('192.168.0.15/24', output)
- self.assertIn('192.168.0.16/24', output) # foreign address is kept
+ self.assertIn('192.168.0.16/24', output) # foreign address is kept
print('### ip -6 route list table all dev bridge99')
output = check_output('ip -6 route list table all dev bridge99')
self.assertIn('mtu 9000 ', output)
def test_bridge_configure_without_carrier(self):
- copy_network_unit('26-bridge.netdev', '26-bridge-configure-without-carrier.network',
- '11-dummy.netdev')
+ copy_network_unit(
+ '26-bridge.netdev',
+ '26-bridge-configure-without-carrier.network',
+ '11-dummy.netdev',
+ )
start_networkd()
# With ConfigureWithoutCarrier=yes, the bridge should remain configured for all these situations
with self.subTest(test=test):
if test == 'no-slave':
# bridge has no slaves; it's up but *might* not have carrier
- self.wait_operstate('bridge99', operstate=r'(no-carrier|routable)', setup_state=None, setup_timeout=30)
+ self.wait_operstate(
+ 'bridge99',
+ operstate=r'(no-carrier|routable)',
+ setup_state=None,
+ setup_timeout=30,
+ )
# due to a bug in the kernel, newly-created bridges are brought up
# *with* carrier, unless they have had any setting changed; e.g.
# their mac set, priority set, etc. Then, they will lose carrier
# as soon as a (down) slave interface is added, and regain carrier
# again once the slave interface is brought up.
- #self.check_link_attr('bridge99', 'carrier', '0')
+ # self.check_link_attr('bridge99', 'carrier', '0')
elif test == 'add-slave':
# add slave to bridge, but leave it down; bridge is definitely no-carrier
self.check_link_attr('test1', 'operstate', 'down')
self.assertRegex(output, '10.1.2.1')
def test_bridge_ignore_carrier_loss(self):
- copy_network_unit('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
- '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
- '25-bridge99-ignore-carrier-loss.network')
+ copy_network_unit(
+ '11-dummy.netdev',
+ '12-dummy.netdev',
+ '26-bridge.netdev',
+ '26-bridge-slave-interface-1.network',
+ '26-bridge-slave-interface-2.network',
+ '25-bridge99-ignore-carrier-loss.network',
+ )
start_networkd()
self.wait_online('dummy98:enslaved', 'test1:enslaved', 'bridge99:routable')
self.assertRegex(output, 'inet 192.168.0.16/24 scope global secondary bridge99')
def test_bridge_ignore_carrier_loss_frequent_loss_and_gain(self):
- copy_network_unit('26-bridge.netdev', '26-bridge-slave-interface-1.network',
- '25-bridge99-ignore-carrier-loss.network')
+ copy_network_unit(
+ '26-bridge.netdev',
+ '26-bridge-slave-interface-1.network',
+ '25-bridge99-ignore-carrier-loss.network',
+ )
start_networkd()
self.wait_online('bridge99:no-carrier')
print(output)
self.assertIn('from all to 8.8.8.8 lookup 100', output)
-class NetworkdSRIOVTests(unittest.TestCase, Utilities):
+class NetworkdSRIOVTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
# Create VF.
if num_vfs > 0:
- with open(f'/sys/bus/netdevsim/devices/netdevsim{id}/sriov_numvfs', mode='w', encoding='utf-8') as f:
+ with open(
+ f'/sys/bus/netdevsim/devices/netdevsim{id}/sriov_numvfs', mode='w', encoding='utf-8'
+ ) as f:
f.write(f'{num_vfs}')
@expectedFailureIfModuleIsNotAvailable('netdevsim')
output = check_output('ip link show dev sim99')
print(output)
- self.assertRegex(output,
- 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
- 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
- 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off'
- )
+ self.assertRegex(
+ output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
+ 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off',
+ )
@expectedFailureIfModuleIsNotAvailable('netdevsim')
def test_sriov_udev(self):
output = check_output('ip link show dev sim99')
print(output)
- self.assertRegex(output,
- 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
- 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
- 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off'
- )
+ self.assertRegex(
+ output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
+ 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off',
+ )
self.assertNotIn('vf 3', output)
self.assertNotIn('vf 4', output)
output = check_output('ip link show dev sim99')
print(output)
- self.assertRegex(output,
- 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
- 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
- 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off\n *'
- 'vf 3'
- )
+ self.assertRegex(
+ output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
+ 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off\n *'
+ 'vf 3',
+ )
self.assertNotIn('vf 4', output)
with open(os.path.join(network_unit_dir, '25-sriov.link'), mode='a', encoding='utf-8') as f:
output = check_output('ip link show dev sim99')
print(output)
- self.assertRegex(output,
- 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
- 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
- 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off\n *'
- 'vf 3'
- )
+ self.assertRegex(
+ output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
+ 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off\n *'
+ 'vf 3',
+ )
self.assertNotIn('vf 4', output)
with open(os.path.join(network_unit_dir, '25-sriov.link'), mode='a', encoding='utf-8') as f:
output = check_output('ip link show dev sim99')
print(output)
- self.assertRegex(output,
- 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
- 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off'
- )
+ self.assertRegex(
+ output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off',
+ )
self.assertNotIn('vf 2', output)
self.assertNotIn('vf 3', output)
self.assertNotIn('vf 4', output)
output = check_output('ip link show dev sim99')
print(output)
- self.assertRegex(output,
- 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
- 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
- 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off'
- )
+ self.assertRegex(
+ output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
+ 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off',
+ )
self.assertNotIn('vf 3', output)
self.assertNotIn('vf 4', output)
-class NetworkdLLDPTests(unittest.TestCase, Utilities):
+class NetworkdLLDPTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.fail()
# With interface name
- output = networkctl('lldp', 'veth99');
+ output = networkctl('lldp', 'veth99')
print(output)
self.assertRegex(output, r'veth99 .* veth-peer .* .......a...')
# With interface name pattern
- output = networkctl('lldp', 've*9');
+ output = networkctl('lldp', 've*9')
print(output)
self.assertRegex(output, r'veth99 .* veth-peer .* .......a...')
self.fail()
# With interface name
- output = networkctl('lldp', 'veth99');
+ output = networkctl('lldp', 'veth99')
print(output)
self.assertRegex(output, r'veth99 .* veth-peer .* ....r......')
# With interface name pattern
- output = networkctl('lldp', 've*9');
+ output = networkctl('lldp', 've*9')
print(output)
self.assertRegex(output, r'veth99 .* veth-peer .* ....r......')
# Compare the json output from sender and receiver
sender_json = get_link_description('veth-peer')['LLDP']
- receiver_json = json.loads(networkctl('--json=short', 'lldp', 'veth99'))['Neighbors'][0]['Neighbors'][0]
+ receiver_json = json.loads(networkctl('--json=short', 'lldp', 'veth99'))['Neighbors'][0]['Neighbors'][0] # fmt: skip
print(sender_json)
print(receiver_json)
self.assertEqual(sender_json, receiver_json)
-class NetworkdRATests(unittest.TestCase, Utilities):
+class NetworkdRATests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.assertRegex(output, '2002:da8:2:0:fa:de:ca:fe')
def test_ipv6_token_static(self):
- copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-static.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6-prefix.network',
+ '25-ipv6-prefix-veth-token-static.network',
+ )
start_networkd()
self.check_ipv6_token_static()
def test_ndisc_redirect(self):
if not os.path.exists(test_ndisc_send):
- self.skipTest(f"{test_ndisc_send} does not exist.")
+ self.skipTest(f'{test_ndisc_send} does not exist.')
- copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-static.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6-prefix.network',
+ '25-ipv6-prefix-veth-token-static.network',
+ )
start_networkd()
self.check_ipv6_token_static()
# Introduce three redirect routes.
+ # fmt: off
check_output(f'{test_ndisc_send} --interface veth-peer --type redirect --target-address 2002:da8:1:1:1a:2b:3c:4d --redirect-destination 2002:da8:1:1:1a:2b:3c:4d')
check_output(f'{test_ndisc_send} --interface veth-peer --type redirect --target-address 2002:da8:1:2:1a:2b:3c:4d --redirect-destination 2002:da8:1:2:1a:2b:3c:4d')
check_output(f'{test_ndisc_send} --interface veth-peer --type redirect --target-address 2002:da8:1:3:1a:2b:3c:4d --redirect-destination 2002:da8:1:3:1a:2b:3c:4d')
+ # fmt: on
self.wait_route('veth99', '2002:da8:1:1:1a:2b:3c:4d proto redirect', ipv='-6', timeout_sec=10)
self.wait_route('veth99', '2002:da8:1:2:1a:2b:3c:4d proto redirect', ipv='-6', timeout_sec=10)
self.wait_route('veth99', '2002:da8:1:3:1a:2b:3c:4d proto redirect', ipv='-6', timeout_sec=10)
# Change the target address of the redirects.
+ # fmt: off
check_output(f'{test_ndisc_send} --interface veth-peer --type redirect --target-address fe80::1 --redirect-destination 2002:da8:1:1:1a:2b:3c:4d')
check_output(f'{test_ndisc_send} --interface veth-peer --type redirect --target-address fe80::2 --redirect-destination 2002:da8:1:2:1a:2b:3c:4d')
- self.wait_route_dropped('veth99', '2002:da8:1:1:1a:2b:3c:4d proto redirect', ipv='-6', timeout_sec=10)
- self.wait_route_dropped('veth99', '2002:da8:1:2:1a:2b:3c:4d proto redirect', ipv='-6', timeout_sec=10)
- self.wait_route('veth99', r'2002:da8:1:1:1a:2b:3c:4d nhid [0-9]* via fe80::1 proto redirect', ipv='-6', timeout_sec=10)
- self.wait_route('veth99', r'2002:da8:1:2:1a:2b:3c:4d nhid [0-9]* via fe80::2 proto redirect', ipv='-6', timeout_sec=10)
+ # fmt: on
+ self.wait_route_dropped(
+ 'veth99',
+ '2002:da8:1:1:1a:2b:3c:4d proto redirect',
+ ipv='-6',
+ timeout_sec=10,
+ )
+ self.wait_route_dropped(
+ 'veth99',
+ '2002:da8:1:2:1a:2b:3c:4d proto redirect',
+ ipv='-6',
+ timeout_sec=10,
+ )
+ self.wait_route(
+ 'veth99',
+ r'2002:da8:1:1:1a:2b:3c:4d nhid [0-9]* via fe80::1 proto redirect',
+ ipv='-6',
+ timeout_sec=10,
+ )
+ self.wait_route(
+ 'veth99',
+ r'2002:da8:1:2:1a:2b:3c:4d nhid [0-9]* via fe80::2 proto redirect',
+ ipv='-6',
+ timeout_sec=10,
+ )
- # Send Neighbor Advertisement without the router flag to announce the default router is not available anymore.
- # Then, verify that all redirect routes and the default route are dropped.
+ # Send Neighbor Advertisement without the router flag to announce the default router is not available
+ # anymore. Then, verify that all redirect routes and the default route are dropped.
output = check_output('ip -6 address show dev veth-peer scope link')
veth_peer_ipv6ll = re.search('fe80:[:0-9a-f]*', output).group()
print(f'veth-peer IPv6LL address: {veth_peer_ipv6ll}')
- check_output(f'{test_ndisc_send} --interface veth-peer --type neighbor-advertisement --target-address {veth_peer_ipv6ll} --is-router no')
+ check_output(f'{test_ndisc_send} --interface veth-peer --type neighbor-advertisement --target-address {veth_peer_ipv6ll} --is-router no') # fmt: skip
self.wait_route_dropped('veth99', 'proto ra', ipv='-6', timeout_sec=10)
self.wait_route_dropped('veth99', 'proto redirect', ipv='-6', timeout_sec=10)
# See https://github.com/systemd/systemd/pull/32267#discussion_r1566721306
since = datetime.datetime.now()
check_output(f'{test_ndisc_send} --interface veth-peer --type rs --dest {veth_peer_ipv6ll}')
- self.check_networkd_log('veth-peer: RADV: Received RS from the same interface, ignoring.', since=since)
+ self.check_networkd_log(
+ 'veth-peer: RADV: Received RS from the same interface, ignoring.',
+ since=since,
+ )
def check_ndisc_mtu(self, mtu):
for _ in range(20):
def test_ndisc_mtu(self):
if not os.path.exists(test_ndisc_send):
- self.skipTest(f"{test_ndisc_send} does not exist.")
+ self.skipTest(f'{test_ndisc_send} does not exist.')
- copy_network_unit('25-veth.netdev',
- '25-veth-peer-no-address.network',
- '25-ipv6-prefix-veth-token-static.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-veth-peer-no-address.network',
+ '25-ipv6-prefix-veth-token-static.network',
+ )
start_networkd()
self.wait_online('veth-peer:degraded')
self.check_ndisc_mtu(1700)
def test_ipv6_token_prefixstable(self):
- copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-prefixstable.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6-prefix.network',
+ '25-ipv6-prefix-veth-token-prefixstable.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:degraded')
output = check_output('ip -6 address show dev veth99')
print(output)
- self.assertIn('2002:da8:1:0:b47e:7975:fc7a:7d6e/64', output) # the 1st prefixstable
- self.assertIn('2002:da8:2:0:1034:56ff:fe78:9abc/64', output) # EUI64
+ self.assertIn('2002:da8:1:0:b47e:7975:fc7a:7d6e/64', output) # the 1st prefixstable
+ self.assertIn('2002:da8:2:0:1034:56ff:fe78:9abc/64', output) # EUI64
- with open(os.path.join(network_unit_dir, '25-ipv6-prefix-veth-token-prefixstable.network'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-ipv6-prefix-veth-token-prefixstable.network'),
+ mode='a',
+ encoding='utf-8',
+ ) as f:
f.write('\n[IPv6AcceptRA]\nPrefixAllowList=2002:da8:1:0::/64\n')
networkctl_reload()
output = check_output('ip -6 address show dev veth99')
print(output)
- self.assertIn('2002:da8:1:0:b47e:7975:fc7a:7d6e/64', output) # the 1st prefixstable
- self.assertNotIn('2002:da8:2:0:1034:56ff:fe78:9abc/64', output) # EUI64
+ self.assertIn('2002:da8:1:0:b47e:7975:fc7a:7d6e/64', output) # the 1st prefixstable
+ self.assertNotIn('2002:da8:2:0:1034:56ff:fe78:9abc/64', output) # EUI64
check_output('ip address del 2002:da8:1:0:b47e:7975:fc7a:7d6e/64 dev veth99')
check_output('ip address add 2002:da8:1:0:b47e:7975:fc7a:7d6e/64 dev veth-peer nodad')
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable')
- self.wait_address('veth99', '2002:da8:1:0:da5d:e50a:43fd:5d0f/64', ipv='-6', timeout_sec=10) # the 2nd prefixstable
- self.wait_address_dropped('veth99', '2002:da8:1:0:b47e:7975:fc7a:7d6e/64', ipv='-6', timeout_sec=10) # the 1st prefixstable
+ self.wait_address(
+ 'veth99',
+ '2002:da8:1:0:da5d:e50a:43fd:5d0f/64',
+ ipv='-6',
+ timeout_sec=10,
+ ) # the 2nd prefixstable
+ self.wait_address_dropped(
+ 'veth99',
+ '2002:da8:1:0:b47e:7975:fc7a:7d6e/64',
+ ipv='-6',
+ timeout_sec=10,
+ ) # the 1st prefixstable
check_output('ip address del 2002:da8:1:0:da5d:e50a:43fd:5d0f/64 dev veth99')
check_output('ip address add 2002:da8:1:0:da5d:e50a:43fd:5d0f/64 dev veth-peer nodad')
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable')
- self.wait_address('veth99', '2002:da8:1:0:c7e4:77ec:eb31:1b0d/64', ipv='-6', timeout_sec=10) # the 3rd prefixstable
- self.wait_address_dropped('veth99', '2002:da8:1:0:da5d:e50a:43fd:5d0f/64', ipv='-6', timeout_sec=10) # the 2nd prefixstable
- self.wait_address_dropped('veth99', '2002:da8:1:0:b47e:7975:fc7a:7d6e/64', ipv='-6', timeout_sec=10) # the 1st prefixstable
+ self.wait_address(
+ 'veth99',
+ '2002:da8:1:0:c7e4:77ec:eb31:1b0d/64',
+ ipv='-6',
+ timeout_sec=10,
+ ) # the 3rd prefixstable
+ self.wait_address_dropped(
+ 'veth99',
+ '2002:da8:1:0:da5d:e50a:43fd:5d0f/64',
+ ipv='-6',
+ timeout_sec=10,
+ ) # the 2nd prefixstable
+ self.wait_address_dropped(
+ 'veth99',
+ '2002:da8:1:0:b47e:7975:fc7a:7d6e/64',
+ ipv='-6',
+ timeout_sec=10,
+ ) # the 1st prefixstable
def test_ipv6_token_prefixstable_without_address(self):
- copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-prefixstable-without-address.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6-prefix.network',
+ '25-ipv6-prefix-veth-token-prefixstable-without-address.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:degraded')
self.assertIn('2002:da8:2:0:f689:561a:8eda:7443', output)
def test_router_hop_limit(self):
- copy_network_unit('25-veth-client.netdev',
- '25-veth-router.netdev',
- '26-bridge.netdev',
- '25-veth-bridge.network',
- '25-veth-client.network',
- '25-veth-router-hop-limit.network',
- '25-bridge99.network')
- start_networkd()
- self.wait_online('client:routable', 'client-p:enslaved',
- 'router:degraded', 'router-p:enslaved',
- 'bridge99:routable')
+ copy_network_unit(
+ '25-veth-client.netdev',
+ '25-veth-router.netdev',
+ '26-bridge.netdev',
+ '25-veth-bridge.network',
+ '25-veth-client.network',
+ '25-veth-router-hop-limit.network',
+ '25-bridge99.network',
+ )
+ start_networkd()
+ self.wait_online(
+ 'client:routable',
+ 'client-p:enslaved',
+ 'router:degraded',
+ 'router-p:enslaved',
+ 'bridge99:routable',
+ )
self.check_ipv6_sysctl_attr('client', 'hop_limit', '42')
- with open(os.path.join(network_unit_dir, '25-veth-router-hop-limit.network'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-hop-limit.network'), mode='a', encoding='utf-8'
+ ) as f:
f.write('\n[IPv6SendRA]\nHopLimit=43\n')
networkctl_reload()
self.wait_online('client:routable')
self.wait_address('client', f'2002:da8:1:99:1034:56ff:fe78:9a{suffix}/64', ipv='-6', timeout_sec=10)
self.wait_address('client', f'2002:da8:1:98:1034:56ff:fe78:9a{suffix}/64', ipv='-6', timeout_sec=10)
- self.wait_route('client', rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric {metric_1}', ipv='-6', timeout_sec=10)
- self.wait_route('client', rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric {metric_2}', ipv='-6', timeout_sec=10)
+ self.wait_route(
+ 'client',
+ rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric {metric_1}',
+ ipv='-6',
+ timeout_sec=10,
+ )
+ self.wait_route(
+ 'client',
+ rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric {metric_2}',
+ ipv='-6',
+ timeout_sec=10,
+ )
print('### ip -6 route show dev client default')
output = check_output('ip -6 route show dev client default')
print(output)
+ # fmt: off
self.assertRegex(output, rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric {metric_1} expires [0-9]*sec pref {preference_1}')
self.assertRegex(output, rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric {metric_2} expires [0-9]*sec pref {preference_2}')
+ # fmt: on
for i in [100, 200, 300, 512, 1024, 2048]:
if i not in [metric_1, metric_2]:
self.assertNotIn(f'pref {i}', output)
def test_router_preference(self):
- copy_network_unit('25-veth-client.netdev',
- '25-veth-router-high.netdev',
- '25-veth-router-low.netdev',
- '26-bridge.netdev',
- '25-veth-bridge.network',
- '25-veth-client.network',
- '25-veth-router-high.network',
- '25-veth-router-low.network',
- '25-bridge99.network')
- start_networkd()
- self.wait_online('client-p:enslaved',
- 'router-high:degraded', 'router-high-p:enslaved',
- 'router-low:degraded', 'router-low-p:enslaved',
- 'bridge99:routable')
+ copy_network_unit(
+ '25-veth-client.netdev',
+ '25-veth-router-high.netdev',
+ '25-veth-router-low.netdev',
+ '26-bridge.netdev',
+ '25-veth-bridge.network',
+ '25-veth-client.network',
+ '25-veth-router-high.network',
+ '25-veth-router-low.network',
+ '25-bridge99.network',
+ )
+ start_networkd()
+ self.wait_online(
+ 'client-p:enslaved',
+ 'router-high:degraded',
+ 'router-high-p:enslaved',
+ 'router-low:degraded',
+ 'router-low-p:enslaved',
+ 'bridge99:routable',
+ )
networkctl_reconfigure('client')
self.wait_online('client:routable')
# change the map from preference to metric.
with open(os.path.join(network_unit_dir, '25-veth-client.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[Link]\nMACAddress=12:34:56:78:9a:01\n[IPv6AcceptRA]\nRouteMetric=100:200:300\n')
+ f.write('''
+[Link]
+MACAddress=12:34:56:78:9a:01
+[IPv6AcceptRA]
+RouteMetric=100:200:300
+''')
networkctl_reload()
self.check_router_preference('01', 100, 'high', 300, 'low')
# swap the preference (for issue #28439)
- with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[IPv6SendRA]\nRouterPreference=low\n')
- with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[IPv6SendRA]\nRouterPreference=high\n')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[IPv6SendRA]
+RouterPreference=low
+''')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[IPv6SendRA]
+RouterPreference=high
+''')
networkctl_reload()
self.check_router_preference('01', 300, 'low', 100, 'high')
# Use the same preference, and check if the two routes are not coalesced. See issue #33470.
- with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[IPv6SendRA]\nRouterPreference=medium\n')
- with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[IPv6SendRA]\nRouterPreference=medium\n')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[IPv6SendRA]
+RouterPreference=medium
+''')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[IPv6SendRA]
+RouterPreference=medium
+''')
networkctl_reload()
self.check_router_preference('01', 200, 'medium', 200, 'medium')
# Use route options to configure default routes.
# The preference specified in the RA header should be ignored. See issue #33468.
- with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[IPv6SendRA]\nRouterPreference=high\n[IPv6RoutePrefix]\nRoute=::/0\nLifetimeSec=1200\n')
- with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[IPv6SendRA]\nRouterPreference=low\n[IPv6RoutePrefix]\nRoute=::/0\nLifetimeSec=1200\n')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[IPv6SendRA]
+RouterPreference=high
+[IPv6RoutePrefix]
+Route=::/0
+LifetimeSec=1200
+''')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+[IPv6SendRA]
+RouterPreference=low
+[IPv6RoutePrefix]
+Route=::/0
+LifetimeSec=1200
+''')
networkctl_reload()
self.check_router_preference('01', 200, 'medium', 200, 'medium')
# Set zero lifetime to the route options.
# The preference specified in the RA header should be used.
- with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
- f.write('LifetimeSec=0\n')
- with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
- f.write('LifetimeSec=0\n')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+LifetimeSec=0
+''')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+LifetimeSec=0
+''')
networkctl_reload()
self.check_router_preference('01', 100, 'high', 300, 'low')
# Use route options with preference to configure default routes.
- with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
- f.write('LifetimeSec=1200\nPreference=low\n')
- with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
- f.write('LifetimeSec=1200\nPreference=high\n')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+LifetimeSec=1200
+Preference=low
+''')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+LifetimeSec=1200
+Preference=high
+''')
networkctl_reload()
self.check_router_preference('01', 300, 'low', 100, 'high')
# Set zero lifetime again to the route options.
- with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
- f.write('LifetimeSec=0\n')
- with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
- f.write('LifetimeSec=0\n')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+LifetimeSec=0
+''')
+ with open(
+ os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8'
+ ) as f:
+ f.write('''
+LifetimeSec=0
+''')
networkctl_reload()
self.check_router_preference('01', 100, 'high', 300, 'low')
def _test_ndisc_vs_static_route(self, manage_foreign_nexthops):
if not manage_foreign_nexthops:
copy_networkd_conf_dropin('networkd-manage-foreign-nexthops-no.conf')
- copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-static-route.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6-prefix.network',
+ '25-ipv6-prefix-veth-static-route.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:degraded')
print(output)
self.assertIn('via fe80::1034:56ff:fe78:9abd proto static metric 256 pref medium', output)
if manage_foreign_nexthops:
- self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9abd proto ra metric 256 expires [0-9]*sec pref medium')
+ self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9abd proto ra metric 256 expires [0-9]*sec pref medium') # fmt: skip
else:
self.assertNotIn('proto ra', output)
output = check_output('ip -6 nexthop show dev veth99')
print(output)
if manage_foreign_nexthops:
- self.assertRegex(output, r'id [0-9]* via fe80::1034:56ff:fe78:9abd dev veth99 scope link proto ra')
+ self.assertRegex(output, r'id [0-9]* via fe80::1034:56ff:fe78:9abd dev veth99 scope link proto ra') # fmt: skip
else:
self.assertEqual(output, '')
# Also check if the static route is protected from RA with zero lifetime
with open(os.path.join(network_unit_dir, '25-ipv6-prefix.network'), mode='a', encoding='utf-8') as f:
- f.write('\n[Network]\nIPv6SendRA=no\n')
- networkctl_reload() # This makes veth-peer being reconfigured, and send RA with zero lifetime
- self.wait_route_dropped('veth99', r'default (nhid [0-9]* |)via fe80::1034:56ff:fe78:9abd proto ra metric 256', ipv='-6', timeout_sec=10)
+ f.write('''
+[Network]
+IPv6SendRA=no
+''')
+ networkctl_reload() # This makes veth-peer being reconfigured, and send RA with zero lifetime
+ self.wait_route_dropped(
+ 'veth99',
+ r'default (nhid [0-9]* |)via fe80::1034:56ff:fe78:9abd proto ra metric 256',
+ ipv='-6',
+ timeout_sec=10,
+ )
print('### ip -6 route show dev veth99 default')
output = check_output('ip -6 route show dev veth99 default')
# radvd supports captive portal since v2.20.
# https://github.com/radvd-project/radvd/commit/791179a7f730decbddb2290ef0e34aa85d71b1bc
- @unittest.skipUnless(radvd_check_config('captive-portal.conf'), "Installed radvd doesn't support captive portals")
+ @unittest.skipUnless(
+ radvd_check_config('captive-portal.conf'),
+ "Installed radvd doesn't support captive portals",
+ )
def test_captive_portal(self):
- copy_network_unit('25-veth-client.netdev',
- '25-veth-router-captive.netdev',
- '26-bridge.netdev',
- '25-veth-client-captive.network',
- '25-veth-router-captive.network',
- '25-veth-bridge-captive.network',
- '25-bridge99.network')
+ copy_network_unit(
+ '25-veth-client.netdev',
+ '25-veth-router-captive.netdev',
+ '26-bridge.netdev',
+ '25-veth-client-captive.network',
+ '25-veth-router-captive.network',
+ '25-veth-bridge-captive.network',
+ '25-bridge99.network',
+ )
start_networkd()
- self.wait_online('bridge99:routable', 'client-p:enslaved',
- 'router-captive:degraded', 'router-captivep:enslaved')
+ self.wait_online(
+ 'bridge99:routable',
+ 'client-p:enslaved',
+ 'router-captive:degraded',
+ 'router-captivep:enslaved',
+ )
start_radvd(config_file='captive-portal.conf')
networkctl_reconfigure('client')
print(output)
self.assertIn('Captive Portal: http://systemd.io', output)
- @unittest.skipUnless(radvd_check_config('captive-portal.conf'), "Installed radvd doesn't support captive portals")
+ @unittest.skipUnless(
+ radvd_check_config('captive-portal.conf'),
+ "Installed radvd doesn't support captive portals",
+ )
def test_invalid_captive_portal(self):
def radvd_write_config(captive_portal_uri):
- with open(os.path.join(networkd_ci_temp_dir, 'radvd/bogus-captive-portal.conf'), mode='w', encoding='utf-8') as f:
- f.write(f'interface router-captive {{ AdvSendAdvert on; AdvCaptivePortalAPI "{captive_portal_uri}"; prefix 2002:da8:1:99::/64 {{ AdvOnLink on; AdvAutonomous on; }}; }};')
+ with open(
+ os.path.join(networkd_ci_temp_dir, 'radvd/bogus-captive-portal.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
+ f.write(f'''
+interface router-captive {{
+ AdvSendAdvert on;
+ AdvCaptivePortalAPI "{captive_portal_uri}";
+ prefix 2002:da8:1:99::/64 {{
+ AdvOnLink on;
+ AdvAutonomous on;
+ }};
+}};
+''')
captive_portal_uris = [
- "42ěščěškd ěšč ě s",
- " ",
- "🤔",
+ '42ěščěškd ěšč ě s',
+ ' ',
+ '🤔',
]
- copy_network_unit('25-veth-client.netdev',
- '25-veth-router-captive.netdev',
- '26-bridge.netdev',
- '25-veth-client-captive.network',
- '25-veth-router-captive.network',
- '25-veth-bridge-captive.network',
- '25-bridge99.network')
+ copy_network_unit(
+ '25-veth-client.netdev',
+ '25-veth-router-captive.netdev',
+ '26-bridge.netdev',
+ '25-veth-client-captive.network',
+ '25-veth-router-captive.network',
+ '25-veth-bridge-captive.network',
+ '25-bridge99.network',
+ )
start_networkd()
- self.wait_online('bridge99:routable', 'client-p:enslaved',
- 'router-captive:degraded', 'router-captivep:enslaved')
+ self.wait_online(
+ 'bridge99:routable',
+ 'client-p:enslaved',
+ 'router-captive:degraded',
+ 'router-captivep:enslaved',
+ )
for uri in captive_portal_uris:
- print(f"Captive portal: {uri}")
+ print(f'Captive portal: {uri}')
radvd_write_config(uri)
stop_radvd()
start_radvd(config_file='bogus-captive-portal.conf')
print(output)
self.assertNotIn('Captive Portal:', output)
-class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
+class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
output = networkctl_status('veth-peer')
print(output)
- self.assertRegex(output, "Offered DHCP leases: 192.168.5.[0-9]*")
+ self.assertRegex(output, 'Offered DHCP leases: 192.168.5.[0-9]*')
self.assertEqual(get_dhcp_server_property('veth-peer', 'PoolSize'), 'u 50')
self.assertEqual(get_dhcp_server_property('veth-peer', 'PoolOffset'), 'u 10')
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth-peer', env=env)
if 'Offered DHCP leases: 192.168.5.' in output:
break
- time.sleep(.2)
+ time.sleep(0.2)
else:
self.fail()
self.check_dhcp_server(persist_leases='runtime')
def test_dhcp_server_null_server_address(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server-null-server-address.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client.network',
+ '25-dhcp-server-null-server-address.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
self.assertIn(f'Offered DHCP leases: {client_address}', output)
def test_dhcp_server_with_uplink(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server-downstream.network',
- '12-dummy.netdev', '25-dhcp-server-uplink.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client.network',
+ '25-dhcp-server-downstream.network',
+ '12-dummy.netdev',
+ '25-dhcp-server-uplink.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
self.assertIn('NTP: 192.168.5.1', output)
def test_emit_router_timezone(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-client-timezone-router.network', '25-dhcp-server-timezone-router.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client-timezone-router.network',
+ '25-dhcp-server-timezone-router.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
self.assertIn('Time Zone: Europe/Berlin', output)
def test_dhcp_server_static_lease_mac_by_network(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-client-static-lease.network', '25-dhcp-server-static-lease.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client-static-lease.network',
+ '25-dhcp-server-static-lease.network',
+ )
copy_networkd_conf_dropin('10-dhcp-client-id-duid.conf')
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
self.assertRegex(output, 'DHCPv4 Client ID: IAID:[0-9a-z]*/DUID')
def test_dhcp_server_static_lease_hostname_simple(self):
- copy_network_unit('25-veth.netdev',
- '25-dhcp-client-simple-hostname.network',
- '25-dhcp-server-static-hostname.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client-simple-hostname.network',
+ '25-dhcp-server-static-hostname.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
self.assertEqual(data['DHCPv4Client']['Lease']['Hostname'], 'simple-host')
def test_dhcp_server_static_lease_hostname_fqdn(self):
- copy_network_unit('25-veth.netdev',
- '25-dhcp-client-fqdn-hostname.network',
- '25-dhcp-server-static-hostname.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client-fqdn-hostname.network',
+ '25-dhcp-server-static-hostname.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
self.assertEqual(data['DHCPv4Client']['Lease']['Hostname'], 'fqdn.example.com')
def test_dhcp_server_resolve_hook(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-client-resolve-hook.network', '25-dhcp-server-resolve-hook.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-client-resolve-hook.network',
+ '25-dhcp-server-resolve-hook.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
class NetworkdDHCPServerRelayAgentTests(unittest.TestCase, Utilities):
-
def setUp(self):
setup_common()
tear_down_common()
def test_relay_agent(self):
- copy_network_unit('25-agent-veth-client.netdev',
- '25-agent-veth-server.netdev',
- '25-agent-client.network',
- '25-agent-server.network',
- '25-agent-client-peer.network',
- '25-agent-server-peer.network')
+ copy_network_unit(
+ '25-agent-veth-client.netdev',
+ '25-agent-veth-server.netdev',
+ '25-agent-client.network',
+ '25-agent-server.network',
+ '25-agent-client-peer.network',
+ '25-agent-server-peer.network',
+ )
start_networkd()
self.wait_online('client:routable')
self.assertRegex(output, r'Address: 192.168.5.150 \(DHCPv4 via 192.168.5.1\)')
def test_relay_agent_on_bridge(self):
- copy_network_unit('25-agent-bridge.netdev',
- '25-agent-veth-client.netdev',
- '25-agent-bridge.network',
- '25-agent-bridge-port.network',
- '25-agent-client.network')
+ copy_network_unit(
+ '25-agent-bridge.netdev',
+ '25-agent-veth-client.netdev',
+ '25-agent-bridge.network',
+ '25-agent-bridge-port.network',
+ '25-agent-client.network',
+ )
start_networkd()
self.wait_online('bridge-relay:routable', 'client-peer:enslaved')
# For issue #30763.
self.check_networkd_log('bridge-relay: DHCPv4 server: STARTED')
-class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
+class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
tear_down_common()
def test_dhcp_client_ipv6_only(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv6-only.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-ipv6-only.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
# information request mode
# The name ipv6-only option may not be supported by older dnsmasq
# start_dnsmasq('--dhcp-option=option:ipv6-only,300')
- start_dnsmasq('--dhcp-option=108,00:00:02:00',
- '--dhcp-option=option6:dns-server,[2600::ee]',
- '--dhcp-option=option6:ntp-server,[2600::ff]',
- ra_mode='ra-stateless')
+ start_dnsmasq(
+ '--dhcp-option=108,00:00:02:00',
+ '--dhcp-option=option6:dns-server,[2600::ee]',
+ '--dhcp-option=option6:ntp-server,[2600::ff]',
+ ra_mode='ra-stateless',
+ )
self.wait_online('veth99:routable', 'veth-peer:routable')
# DHCPv6 REPLY for INFORMATION-REQUEST may be received after the link entered configured state.
output = read_link_state_file('veth99')
if 'DNS=2600::ee' in output:
break
- time.sleep(.2)
+ time.sleep(0.2)
# Check link state file
print('## link state file')
# solicit mode
stop_dnsmasq()
- start_dnsmasq('--dhcp-option=108,00:00:02:00',
- '--dhcp-option=option6:dns-server,[2600::ee]',
- '--dhcp-option=option6:ntp-server,[2600::ff]')
+ start_dnsmasq(
+ '--dhcp-option=108,00:00:02:00',
+ '--dhcp-option=option6:dns-server,[2600::ee]',
+ '--dhcp-option=option6:ntp-server,[2600::ff]',
+ )
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable', 'veth-peer:routable')
check_json(networkctl_json('veth99'))
# Testing without rapid commit support
- with open(os.path.join(network_unit_dir, '25-dhcp-client-ipv6-only.network'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client-ipv6-only.network'), mode='a', encoding='utf-8'
+ ) as f:
f.write('\n[DHCPv6]\nRapidCommit=no\n')
stop_dnsmasq()
- start_dnsmasq('--dhcp-option=108,00:00:02:00',
- '--dhcp-option=option6:dns-server,[2600::ee]',
- '--dhcp-option=option6:ntp-server,[2600::ff]')
+ start_dnsmasq(
+ '--dhcp-option=108,00:00:02:00',
+ '--dhcp-option=option6:dns-server,[2600::ee]',
+ '--dhcp-option=option6:ntp-server,[2600::ff]',
+ )
networkctl_reload()
self.wait_online('veth99:routable', 'veth-peer:routable')
check_json(networkctl_json('veth99'))
def test_dhcp_client_ipv6_dbus_status(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv6-only.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-ipv6-only.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
# Note that at this point the DHCPv6 client has not been started because no RA (with managed
# bit set) has yet been received and the configuration does not include WithoutRA=true
state = get_dhcp6_client_state('veth99')
- print(f"DHCPv6 client state = {state}")
+ print(f'DHCPv6 client state = {state}')
self.assertEqual(state, 'stopped')
state = get_dhcp4_client_state('veth99')
- print(f"DHCPv4 client state = {state}")
+ print(f'DHCPv4 client state = {state}')
self.assertEqual(state, 'selecting')
start_dnsmasq('--dhcp-option=108,00:00:02:00')
self.wait_online('veth99:routable', 'veth-peer:routable')
state = get_dhcp6_client_state('veth99')
- print(f"DHCPv6 client state = {state}")
+ print(f'DHCPv6 client state = {state}')
self.assertEqual(state, 'bound')
# DHCPv4 client will stop after an DHCPOFFER message received, so we need to wait for a while.
state = get_dhcp4_client_state('veth99')
if state == 'stopped':
break
- time.sleep(.2)
+ time.sleep(0.2)
- print(f"DHCPv4 client state = {state}")
+ print(f'DHCPv4 client state = {state}')
self.assertEqual(state, 'stopped')
# restart dnsmasq to clear log
state = get_dhcp4_client_state('veth99')
if state == 'stopped':
break
- time.sleep(.2)
+ time.sleep(0.2)
- print(f"DHCPv4 client state = {state}")
+ print(f'DHCPv4 client state = {state}')
self.assertEqual(state, 'stopped')
print('## dnsmasq log')
self.assertNotIn('DHCPACK(veth-peer)', output)
def test_dhcp_client_ipv6_only_with_custom_client_identifier(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv6-only-custom-client-identifier.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-ipv6-only-custom-client-identifier.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
self.assertIn('sent size: 0 option: 14 rapid-commit', output)
def test_dhcp_client_ipv4_only(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv4-only.network',
- '25-sit-dhcp4.netdev', '25-sit-dhcp4.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-ipv4-only.network',
+ '25-sit-dhcp4.netdev',
+ '25-sit-dhcp4.network',
+ )
self.setup_nftset('addr4', 'ipv4_addr')
self.setup_nftset('network4', 'ipv4_addr', 'flags interval;')
start_networkd()
self.wait_online('veth-peer:carrier')
- start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7',
- '--dhcp-option=option:sip-server,192.168.5.21,192.168.5.22',
- '--dhcp-option=option:domain-search,example.com',
- '--dhcp-alternate-port=67,5555',
- ipv4_range='192.168.5.110,192.168.5.119')
+ start_dnsmasq(
+ '--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7',
+ '--dhcp-option=option:sip-server,192.168.5.21,192.168.5.22',
+ '--dhcp-option=option:domain-search,example.com',
+ '--dhcp-alternate-port=67,5555',
+ ipv4_range='192.168.5.110,192.168.5.119',
+ )
self.wait_online('veth99:routable', 'veth-peer:routable', 'sit-dhcp4:carrier')
self.wait_address('veth99', r'inet 192.168.5.11[0-9]*/24', ipv='-4')
print(output)
self.assertIn('mtu 1492', output)
self.assertIn('inet 192.168.5.250/24 brd 192.168.5.255 scope global veth99', output)
- self.assertRegex(output, r'inet 192.168.5.11[0-9]/24 metric 24 brd 192.168.5.255 scope global secondary dynamic noprefixroute test-label')
+ self.assertRegex(output, r'inet 192.168.5.11[0-9]/24 metric 24 brd 192.168.5.255 scope global secondary dynamic noprefixroute test-label') # fmt: skip
self.assertNotIn('2600::', output)
output = check_output('ip -4 --json address show dev veth99')
print('## tunnel')
output = check_output('ip -d link show sit-dhcp4')
print(output)
- self.assertRegex(output, fr'sit (ip6ip )?remote any local {address1} dev veth99')
+ self.assertRegex(output, rf'sit (ip6ip )?remote any local {address1} dev veth99')
print('## dnsmasq log')
output = read_dnsmasq_log_file()
# change address range, DNS servers, and Domains
stop_dnsmasq()
- start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1,192.168.5.7,192.168.5.8',
- '--dhcp-option=option:sip-server,192.168.5.23,192.168.5.24',
- '--dhcp-option=option:domain-search,foo.example.com',
- '--dhcp-alternate-port=67,5555',
- ipv4_range='192.168.5.120,192.168.5.129',)
+ start_dnsmasq(
+ '--dhcp-option=option:dns-server,192.168.5.1,192.168.5.7,192.168.5.8',
+ '--dhcp-option=option:sip-server,192.168.5.23,192.168.5.24',
+ '--dhcp-option=option:domain-search,foo.example.com',
+ '--dhcp-alternate-port=67,5555',
+ ipv4_range='192.168.5.120,192.168.5.129',
+ )
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
print('Wait for the DHCP lease to be expired')
self.assertIn('mtu 1492', output)
self.assertIn('inet 192.168.5.250/24 brd 192.168.5.255 scope global veth99', output)
self.assertNotIn(f'{address1}', output)
- self.assertRegex(output, r'inet 192.168.5.12[0-9]/24 metric 24 brd 192.168.5.255 scope global secondary dynamic noprefixroute test-label')
+ self.assertRegex(output, r'inet 192.168.5.12[0-9]/24 metric 24 brd 192.168.5.255 scope global secondary dynamic noprefixroute test-label') # fmt: skip
self.assertNotIn('2600::', output)
output = check_output('ip -4 --json address show dev veth99')
print('## tunnel')
output = check_output('ip -d link show sit-dhcp4')
print(output)
- self.assertRegex(output, fr'sit (ip6ip )?remote any local {address2} dev veth99')
+ self.assertRegex(output, rf'sit (ip6ip )?remote any local {address2} dev veth99')
print('## dnsmasq log')
output = read_dnsmasq_log_file()
try:
output = read_dnsmasq_log_file()
except FileNotFoundError:
- output = ""
+ output = ''
if 'DHCPRELEASE' in output:
success = True
break
self.fail('Timed out waiting for DHCPRELEASE in dnsmasq log (on bringing down interface)')
def test_dhcp_client_ipv4_dbus_status(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv4-only.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-ipv4-only.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
state = get_dhcp4_client_state('veth99')
- print(f"State = {state}")
+ print(f'State = {state}')
self.assertEqual(state, 'rebooting')
- start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7',
- '--dhcp-option=option:domain-search,example.com',
- '--dhcp-alternate-port=67,5555',
- ipv4_range='192.168.5.110,192.168.5.119')
+ start_dnsmasq(
+ '--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7',
+ '--dhcp-option=option:domain-search,example.com',
+ '--dhcp-alternate-port=67,5555',
+ ipv4_range='192.168.5.110,192.168.5.119',
+ )
self.wait_online('veth99:routable', 'veth-peer:routable')
self.wait_address('veth99', r'inet 192.168.5.11[0-9]*/24', ipv='-4')
state = get_dhcp4_client_state('veth99')
- print(f"State = {state}")
+ print(f'State = {state}')
self.assertEqual(state, 'bound')
def test_dhcp_client_allow_list(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-allow-list.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-allow-list.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
since = datetime.datetime.now()
start_dnsmasq()
- self.check_networkd_log('veth99: DHCPv4 server IP address 192.168.5.1 not found in allow-list, ignoring offer.', since=since)
+ self.check_networkd_log(
+ 'veth99: DHCPv4 server IP address 192.168.5.1 not found in allow-list, ignoring offer.',
+ since=since,
+ )
copy_network_unit('25-dhcp-client-allow-list.network.d/00-allow-list.conf')
since = datetime.datetime.now()
networkctl_reload()
- self.check_networkd_log('veth99: DHCPv4 server IP address 192.168.5.1 not found in allow-list, ignoring offer.', since=since)
+ self.check_networkd_log(
+ 'veth99: DHCPv4 server IP address 192.168.5.1 not found in allow-list, ignoring offer.',
+ since=since,
+ )
copy_network_unit('25-dhcp-client-allow-list.network.d/10-deny-list.conf')
since = datetime.datetime.now()
networkctl_reload()
- self.check_networkd_log('veth99: DHCPv4 server IP address 192.168.5.1 found in deny-list, ignoring offer.', since=since)
+ self.check_networkd_log(
+ 'veth99: DHCPv4 server IP address 192.168.5.1 found in deny-list, ignoring offer.',
+ since=since,
+ )
- @unittest.skipUnless("--dhcp-rapid-commit" in run("dnsmasq --help").stdout, reason="dnsmasq is missing dhcp-rapid-commit support")
+ @unittest.skipUnless(
+ '--dhcp-rapid-commit' in run('dnsmasq --help').stdout,
+ reason='dnsmasq is missing dhcp-rapid-commit support',
+ )
def test_dhcp_client_rapid_commit(self):
copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network')
start_networkd()
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24', ipv='-4')
state = get_dhcp4_client_state('veth99')
- print(f"DHCPv4 client state = {state}")
+ print(f'DHCPv4 client state = {state}')
self.assertEqual(state, 'bound')
output = read_dnsmasq_log_file()
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24')
state = get_dhcp4_client_state('veth99')
- print(f"DHCPv4 client state = {state}")
+ print(f'DHCPv4 client state = {state}')
self.assertEqual(state, 'bound')
if check_log:
networkctl_reload()
self.check_bootp_client(check_log=True)
- with open(os.path.join(network_unit_dir, '25-bootp-client.network'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-bootp-client.network'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[DHCPv4]\nBOOTP=no\n')
networkctl_reload()
self.assertIn('DHCPREQUEST(veth-peer)', output)
self.assertIn('DHCPACK(veth-peer)', output)
- with open(os.path.join(network_unit_dir, '25-bootp-client.network'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-bootp-client.network'), mode='a', encoding='utf-8'
+ ) as f:
f.write('[DHCPv4]\nBOOTP=yes\n')
since = datetime.datetime.now()
self.check_networkd_log('veth99: DHCPv4 client: RELEASE', since=since)
def test_dhcp_client_ipv6_only_mode_without_ipv6_connectivity(self):
- copy_network_unit('25-veth.netdev',
- '25-dhcp-server-ipv6-only-mode.network',
- '25-dhcp-client-ipv6-only-mode.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-ipv6-only-mode.network',
+ '25-dhcp-client-ipv6-only-mode.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable', timeout='40s')
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24', ipv='-4')
state = get_dhcp4_client_state('veth99')
- print(f"State = {state}")
+ print(f'State = {state}')
self.assertEqual(state, 'bound')
def test_dhcp_client_ipv4_use_routes_gateway(self):
first = True
- for (routes, gateway, dns_and_ntp_routes, classless) in itertools.product([True, False], repeat=4):
+ for routes, gateway, dns_and_ntp_routes, classless in itertools.product([True, False], repeat=4):
if first:
first = False
else:
self.tearDown()
+ # fmt: off
print(f'### test_dhcp_client_ipv4_use_routes_gateway(routes={routes}, gateway={gateway}, dns_and_ntp_routes={dns_and_ntp_routes}, classless={classless})')
with self.subTest(routes=routes, gateway=gateway, dns_and_ntp_routes=dns_and_ntp_routes, classless=classless):
self._test_dhcp_client_ipv4_use_routes_gateway(routes, gateway, dns_and_ntp_routes, classless)
+ # fmt: on
- def _test_dhcp_client_ipv4_use_routes_gateway(self, use_routes, use_gateway, dns_and_ntp_routes, classless):
+ def _test_dhcp_client_ipv4_use_routes_gateway(
+ self, use_routes, use_gateway, dns_and_ntp_routes, classless
+ ):
testunit = '25-dhcp-client-ipv4-use-routes-use-gateway.network'
testunits = ['25-veth.netdev', '25-dhcp-server-veth-peer.network', testunit]
testunits.append(f'{testunit}.d/use-routes-{use_routes}.conf')
additional_options = [
'--dhcp-option=option:dns-server,192.168.5.10,8.8.8.8',
'--dhcp-option=option:ntp-server,192.168.5.11,9.9.9.9',
- '--dhcp-option=option:static-route,192.168.6.100,192.168.5.2,8.8.8.8,192.168.5.3'
+ '--dhcp-option=option:static-route,192.168.6.100,192.168.5.2,8.8.8.8,192.168.5.3',
]
if classless:
additional_options += [
print(output)
# Check UseRoutes=
+ # fmt: off
if use_routes:
if classless:
self.assertRegex(output, r'default via 192.168.5.4 proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'8.0.0.0/8 via 192.168.5.3 proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'192.168.5.2 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'192.168.5.3 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
+ # fmt: on
# Check UseGateway=
if use_gateway and (not classless or not use_routes):
self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
else:
- self.assertNotRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
+ self.assertNotRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024') # fmt: skip
# Check route to gateway
if (use_gateway or dns_and_ntp_routes) and (not classless or not use_routes):
self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
else:
- self.assertNotRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
+ self.assertNotRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024') # fmt: skip
# Check RoutesToDNS= and RoutesToNTP=
+ # fmt: off
if dns_and_ntp_routes:
self.assertRegex(output, r'192.168.5.10 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertRegex(output, r'192.168.5.11 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'192.168.5.11 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'8.8.8.8 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
self.assertNotRegex(output, r'9.9.9.9 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
+ # fmt: on
check_json(networkctl_json())
def test_dhcp_client_settings_anonymize(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-anonymize.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-anonymize.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
start_dnsmasq()
self.assertNotIn('26:mtu', output)
def test_dhcp_keep_configuration_dynamic(self):
- copy_network_unit('25-veth.netdev',
- '25-dhcp-server-veth-peer.network',
- '25-dhcp-client-keep-configuration-dynamic.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-keep-configuration-dynamic.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
start_dnsmasq()
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *'
- 'valid_lft forever preferred_lft forever')
+ self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *valid_lft forever preferred_lft forever') # fmt: skip
# Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
stop_dnsmasq()
# The lease address should be kept after the lease expired
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *'
- 'valid_lft forever preferred_lft forever')
+ self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *valid_lft forever preferred_lft forever') # fmt: skip
stop_networkd()
# The lease address should be kept after networkd stopped
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *'
- 'valid_lft forever preferred_lft forever')
+ self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *valid_lft forever preferred_lft forever') # fmt: skip
- with open(os.path.join(network_unit_dir, '25-dhcp-client-keep-configuration-dynamic.network'), mode='a', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client-keep-configuration-dynamic.network'),
+ mode='a',
+ encoding='utf-8',
+ ) as f:
f.write('[Network]\nDHCP=no\n')
start_networkd()
# Still the lease address should be kept after networkd restarted
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *'
- 'valid_lft forever preferred_lft forever')
+ self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global veth99\n *valid_lft forever preferred_lft forever') # fmt: skip
def test_dhcp_keep_configuration_dynamic_on_stop(self):
- copy_network_unit('25-veth.netdev',
- '25-dhcp-server-veth-peer.network',
- '25-dhcp-client-keep-configuration-dynamic-on-stop.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-keep-configuration-dynamic-on-stop.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
start_dnsmasq()
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
+ self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99') # fmt: skip
stop_dnsmasq()
stop_networkd()
output = check_output('ip address show dev veth99 scope global')
print(output)
- self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
+ self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99') # fmt: skip
start_networkd()
self.wait_online('veth-peer:routable')
self.wait_online('veth99:routable', 'veth-peer:routable')
# link become 'routable' when at least one protocol provide an valid address.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
output = check_output('ip address show dev veth99 scope global')
ipv4_address = re.search(r'192.168.5.[0-9]*/24', output).group()
ipv6_address = re.search(r'2600::[0-9a-f:]*/128', output).group()
- static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address, 'Address=' + ipv6_address])
+ static_network = f'''
+[Match]
+Name=veth99
+[Network]
+IPv6AcceptRA=no
+Address={ipv4_address}
+Address={ipv6_address}
+'''
print(static_network)
remove_network_unit('25-dhcp-client.network')
output = check_output('ip -4 address show dev veth99 scope global')
print(output)
- self.assertRegex(output, f'inet {ipv4_address} brd 192.168.5.255 scope global veth99\n *'
- 'valid_lft forever preferred_lft forever')
+ self.assertRegex(output, f'inet {ipv4_address} brd 192.168.5.255 scope global veth99\n *valid_lft forever preferred_lft forever') # fmt: skip
output = check_output('ip -6 address show dev veth99 scope global')
print(output)
- self.assertRegex(output, f'inet6 {ipv6_address} scope global *\n *'
- 'valid_lft forever preferred_lft forever')
+ self.assertRegex(output, f'inet6 {ipv6_address} scope global *\n *valid_lft forever preferred_lft forever') # fmt: skip
@expectedFailureIfModuleIsNotAvailable('vrf')
def test_dhcp_client_vrf(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-vrf.network',
- '25-vrf.netdev', '25-vrf.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-vrf.network',
+ '25-vrf.netdev',
+ '25-vrf.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
start_dnsmasq()
self.wait_online('veth99:routable', 'veth-peer:routable', 'vrf99:carrier')
# link become 'routable' when at least one protocol provide an valid address.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
print('## ip -d link show dev vrf99')
output = check_output('ip -d link show dev vrf99')
print('## ip address show vrf vrf99')
output = check_output('ip address show vrf vrf99')
print(output)
+ # fmt: off
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 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 .* scope link')
+ # fmt: on
print('## ip address show dev veth99')
output = check_output('ip address show dev veth99')
print(output)
+ # fmt: off
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 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 .* scope link')
+ # fmt: on
print('## ip route show vrf vrf99')
output = check_output('ip route show vrf vrf99')
self.assertEqual(output, '')
def test_dhcp_client_gateway_onlink_implicit(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network',
- '25-dhcp-client-gateway-onlink-implicit.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-gateway-onlink-implicit.network',
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
start_dnsmasq()
self.assertRegex(output, 'onlink')
def test_dhcp_client_with_ipv4ll(self):
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network',
- '25-dhcp-client-with-ipv4ll.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client-with-ipv4ll.network',
+ )
start_networkd()
# we need to increase timeout above default, as this will need to wait for
# systemd-networkd to get the dhcpv4 transient failure event
start_dnsmasq()
print('Wait for a DHCP lease to be acquired and the IPv4LL address to be dropped')
- self.wait_address('veth99', r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic', ipv='-4')
- self.wait_address_dropped('veth99', r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link', scope='link', ipv='-4')
+ self.wait_address(
+ 'veth99',
+ r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic',
+ ipv='-4',
+ )
+ self.wait_address_dropped(
+ 'veth99',
+ r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link',
+ scope='link',
+ ipv='-4',
+ )
self.wait_online('veth99:routable')
output = check_output('ip -4 address show dev veth99')
print(output)
- self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
+ self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99') # fmt: skip
self.assertNotIn('169.254.', output)
self.assertNotIn('scope link', output)
stop_dnsmasq()
print('Wait for the DHCP lease to be expired and an IPv4LL address to be acquired')
- self.wait_address_dropped('veth99', r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic', ipv='-4', timeout_sec=130)
- self.wait_address('veth99', r'inet 169\.254\.133\.11/16 metric 2048 brd 169\.254\.255\.255 scope link', scope='link', ipv='-4')
+ self.wait_address_dropped(
+ 'veth99',
+ r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic',
+ ipv='-4',
+ timeout_sec=130,
+ )
+ self.wait_address(
+ 'veth99',
+ r'inet 169\.254\.133\.11/16 metric 2048 brd 169\.254\.255\.255 scope link',
+ scope='link',
+ ipv='-4',
+ )
output = check_output('ip -4 address show dev veth99')
print(output)
def test_dhcp_client_use_dns(self):
def check(self, ipv4, ipv6, needs_reconfigure=False):
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
- with open(os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
f.write('[DHCPv4]\nUseDNS=')
f.write('yes' if ipv4 else 'no')
f.write('\n[DHCPv6]\nUseDNS=')
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable')
- # link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
+ # link becomes 'routable' when at least one protocol provide an valid address.
+ # Hence, we need to explicitly wait for both addresses.
+ self.wait_address(
+ 'veth99',
+ r'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
# make resolved re-read the link state file
resolvectl('revert', 'veth99')
check_json(networkctl_json())
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
- start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1',
- '--dhcp-option=option6:dns-server,[2600::1]')
+ start_dnsmasq(
+ '--dhcp-option=option:dns-server,192.168.5.1',
+ '--dhcp-option=option6:dns-server,[2600::1]',
+ )
check(self, True, True)
check(self, True, False)
def test_dhcp_client_default_use_domains(self):
def check(self, common, ipv4, ipv6):
mkdir_p(networkd_conf_dropin_dir)
- with open(os.path.join(networkd_conf_dropin_dir, 'default_use_domains.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(networkd_conf_dropin_dir, 'default_use_domains.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
f.write('[Network]\nUseDomains=')
f.write('yes\n' if common else 'no\n')
f.write('[DHCPv4]\nUseDomains=')
restart_networkd()
self.wait_online('veth-peer:carrier')
- start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1',
- '--dhcp-option=option6:dns-server,[2600::1]',
- '--dhcp-option=option:domain-search,example.com',
- '--dhcp-option=option6:domain-search,example.com')
+ start_dnsmasq(
+ '--dhcp-option=option:dns-server,192.168.5.1',
+ '--dhcp-option=option6:dns-server,[2600::1]',
+ '--dhcp-option=option:domain-search,example.com',
+ '--dhcp-option=option6:domain-search,example.com',
+ )
self.wait_online('veth99:routable')
- # link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
+ # link becomes 'routable' when at least one protocol provide an valid address.
+ # Hence, we need to explicitly wait for both addresses.
+ self.wait_address(
+ 'veth99',
+ r'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
for _ in range(20):
output = resolvectl('domain', 'veth99')
stop_dnsmasq()
remove_networkd_conf_dropin('default_use_domains.conf')
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client.network',
+ copy_dropins=False,
+ )
check(self, True, False, False)
check(self, False, True, True)
check(self, False, True, False)
def test_dhcp_client_use_dnr(self):
def check(self, ipv4, ipv6, needs_reconfigure=False):
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
- with open(os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
f.write('[DHCPv4]\nUseDNS=')
f.write('yes' if ipv4 else 'no')
f.write('\n[DHCPv6]\nUseDNS=')
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable')
- # link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
+ # link becomes 'routable' when at least one protocol provide an valid address.
+ # Hence, we need to explicitly wait for both addresses.
+ self.wait_address(
+ 'veth99',
+ r'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
# make resolved re-read the link state file
resolvectl('revert', 'veth99')
check_json(networkctl_json())
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
- dnr_v4 = dnr_v4_instance_data(adn = "dns.google", addrs = ["8.8.8.8", "8.8.4.4"])
- dnr_v4 += dnr_v4_instance_data(adn = "homer.simpson", addrs = ["0.7.4.2"], alpns = ("dot","h2","h3"), dohpath = "/springfield{?dns}")
- dnr_v6 = dnr_v6_instance_data(adn = "dns.google", addrs = ["2001:4860:4860::8888", "2001:4860:4860::8844"])
- masq = lambda bs: ':'.join(f"{b:02x}" for b in bs)
- start_dnsmasq(f'--dhcp-option=162,{masq(dnr_v4)}',
- f'--dhcp-option=option6:144,{masq(dnr_v6)}')
+ dnr_v4 = dnr_v4_instance_data(
+ adn='dns.google',
+ addrs=['8.8.8.8', '8.8.4.4'],
+ )
+ dnr_v4 += dnr_v4_instance_data(
+ adn='homer.simpson',
+ addrs=['0.7.4.2'],
+ alpns=('dot', 'h2', 'h3'),
+ dohpath='/springfield{?dns}',
+ )
+ dnr_v6 = dnr_v6_instance_data(
+ adn='dns.google',
+ addrs=['2001:4860:4860::8888', '2001:4860:4860::8844'],
+ )
+ masq = lambda bs: ':'.join(f'{b:02x}' for b in bs)
+ start_dnsmasq(f'--dhcp-option=162,{masq(dnr_v4)}', f'--dhcp-option=option6:144,{masq(dnr_v6)}')
check(self, True, True)
check(self, True, False)
def test_dhcp_client_use_sip(self):
def check(self, ipv4, ipv6, needs_reconfigure=False):
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
- with open(os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
f.write('[DHCPv4]\nUseSIP=')
f.write('yes' if ipv4 else 'no')
f.write('\n[DHCPv6]\nUseSIP=')
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable')
- # link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
+ # link becomes 'routable' when at least one protocol provide an valid address.
+ # Hence, we need to explicitly wait for both addresses.
+ self.wait_address(
+ 'veth99',
+ r'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
output = networkctl_status('veth99')
print(output)
check_json(networkctl_json())
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
- start_dnsmasq('--dhcp-option=option:sip-server,192.168.5.1',
- '--dhcp-option=option6:sip-server,[2600::1]',
- '--dhcp-option=option6:sip-server-domain,foo.example.com')
+ start_dnsmasq(
+ '--dhcp-option=option:sip-server,192.168.5.1',
+ '--dhcp-option=option6:sip-server,[2600::1]',
+ '--dhcp-option=option6:sip-server-domain,foo.example.com',
+ )
check(self, True, True)
check(self, True, False)
def test_dhcp_client_use_captive_portal(self):
def check(self, ipv4, ipv6, needs_reconfigure=False):
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
- with open(os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
f.write('[DHCPv4]\nUseCaptivePortal=')
f.write('yes' if ipv4 else 'no')
f.write('\n[DHCPv6]\nUseCaptivePortal=')
networkctl_reconfigure('veth99')
self.wait_online('veth99:routable')
- # link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
+ # link becomes 'routable' when at least one protocol provide an valid address.
+ # Hence, we need to explicitly wait for both addresses.
+ self.wait_address(
+ 'veth99',
+ r'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
output = networkctl_status('veth99')
print(output)
check_json(networkctl_json())
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
- start_dnsmasq('--dhcp-option=114,http://systemd.io',
- '--dhcp-option=option6:103,http://systemd.io')
+ start_dnsmasq(
+ '--dhcp-option=114,http://systemd.io',
+ '--dhcp-option=option6:103,http://systemd.io',
+ )
check(self, True, True)
check(self, True, False)
def test_dhcp_client_reject_captive_portal(self):
def check(self, ipv4, ipv6):
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
- with open(os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'), mode='w', encoding='utf-8') as f:
+ with open(
+ os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'),
+ mode='w',
+ encoding='utf-8',
+ ) as f:
f.write('[DHCPv4]\nUseCaptivePortal=')
f.write('yes' if ipv4 else 'no')
f.write('\n[DHCPv6]\nUseCaptivePortal=')
networkctl_reload()
self.wait_online('veth99:routable')
- # link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
- self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 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')
+ # link becomes 'routable' when at least one protocol provide an valid address.
+ # Hence, we need to explicitly wait for both addresses.
+ self.wait_address(
+ 'veth99',
+ r'inet 192.168.5.[0-9]*/24 metric 1024 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',
+ )
output = networkctl_status('veth99')
print(output)
check_json(networkctl_json())
- copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp-server-veth-peer.network',
+ '25-dhcp-client.network',
+ copy_dropins=False,
+ )
start_networkd()
self.wait_online('veth-peer:carrier')
- start_dnsmasq('--dhcp-option=114,http://|invalid/url',
- '--dhcp-option=option6:103,http://|invalid/url')
+ start_dnsmasq(
+ '--dhcp-option=114,http://|invalid/url',
+ '--dhcp-option=option6:103,http://|invalid/url',
+ )
check(self, True, True)
check(self, True, False)
check(self, False, True)
check(self, False, False)
-class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
+class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.assertGreater(prefixInfo[0]['PreferredLifetimeUSec'], 0)
self.assertGreater(prefixInfo[0]['ValidLifetimeUSec'], 0)
- @unittest.skipUnless(shutil.which('dhcpd'), reason="dhcpd is not available")
+ @unittest.skipUnless(shutil.which('dhcpd'), reason='dhcpd is not available')
def test_dhcp6pd_no_address(self):
# For issue #29979.
- copy_network_unit('25-veth.netdev', '25-dhcp6pd-server.network', '25-dhcp6pd-upstream-no-address.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp6pd-server.network',
+ '25-dhcp6pd-upstream-no-address.network',
+ )
start_networkd()
self.wait_online('veth-peer:routable')
self.check_dhcp6_prefix('veth99')
- @unittest.skipUnless(shutil.which('dhcpd'), reason="dhcpd is not available")
+ @unittest.skipUnless(shutil.which('dhcpd'), reason='dhcpd is not available')
def test_dhcp6pd_no_assign(self):
# Similar to test_dhcp6pd_no_assign(), but in this case UseAddress=yes (default),
# However, the server does not provide IA_NA. For issue #31349.
- copy_network_unit('25-veth.netdev', '25-dhcp6pd-server.network', '25-dhcp6pd-upstream-no-assign.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp6pd-server.network',
+ '25-dhcp6pd-upstream-no-assign.network',
+ )
start_networkd()
self.wait_online('veth-peer:routable')
self.check_dhcp6_prefix('veth99')
- @unittest.skipUnless(shutil.which('dhcpd'), reason="dhcpd is not available")
+ @unittest.skipUnless(shutil.which('dhcpd'), reason='dhcpd is not available')
def test_dhcp6pd(self):
- copy_network_unit('25-veth.netdev', '25-dhcp6pd-server.network', '25-dhcp6pd-upstream.network',
- '25-veth-downstream-veth97.netdev', '25-dhcp-pd-downstream-veth97.network', '25-dhcp-pd-downstream-veth97-peer.network',
- '25-veth-downstream-veth98.netdev', '25-dhcp-pd-downstream-veth98.network', '25-dhcp-pd-downstream-veth98-peer.network',
- '11-dummy.netdev', '25-dhcp-pd-downstream-test1.network',
- '25-dhcp-pd-downstream-dummy97.network',
- '12-dummy.netdev', '25-dhcp-pd-downstream-dummy98.network',
- '13-dummy.netdev', '25-dhcp-pd-downstream-dummy99.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp6pd-server.network',
+ '25-dhcp6pd-upstream.network',
+ '25-veth-downstream-veth97.netdev',
+ '25-dhcp-pd-downstream-veth97.network',
+ '25-dhcp-pd-downstream-veth97-peer.network',
+ '25-veth-downstream-veth98.netdev',
+ '25-dhcp-pd-downstream-veth98.network',
+ '25-dhcp-pd-downstream-veth98-peer.network',
+ '11-dummy.netdev',
+ '25-dhcp-pd-downstream-test1.network',
+ '25-dhcp-pd-downstream-dummy97.network',
+ '12-dummy.netdev',
+ '25-dhcp-pd-downstream-dummy98.network',
+ '13-dummy.netdev',
+ '25-dhcp-pd-downstream-dummy99.network',
+ )
start_networkd()
self.wait_online('veth-peer:routable')
start_isc_dhcpd(conf_file='isc-dhcpd-dhcp6pd.conf', ipv='-6')
- self.wait_online('veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded',
- 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable')
+ self.wait_online(
+ 'veth99:routable',
+ 'test1:routable',
+ 'dummy98:routable',
+ 'dummy99:degraded',
+ 'veth97:routable',
+ 'veth97-peer:routable',
+ 'veth98:routable',
+ 'veth98-peer:routable',
+ )
self.setup_nftset('addr6', 'ipv6_addr')
self.setup_nftset('network6', 'ipv6_addr', 'flags interval;')
print('### ip -6 address show dev veth99 scope global')
output = check_output('ip -6 address show dev veth99 scope global')
print(output)
+ # fmt: off
# IA_NA
self.assertRegex(output, 'inet6 3ffe:501:ffff:100::[0-9]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
# address in IA_PD (Token=static)
self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic')
# address in IA_PD (Token=eui64)
self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic')
+ # fmt: on
# address in IA_PD (temporary)
# Note that the temporary addresses may appear after the link enters configured state
- self.wait_address('veth99', 'inet6 3ffe:501:ffff:[2-9a-f]10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth99',
+ 'inet6 3ffe:501:ffff:[2-9a-f]10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev test1 scope global')
output = check_output('ip -6 address show dev test1 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('test1', 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'test1',
+ 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev dummy98 scope global')
output = check_output('ip -6 address show dev dummy98 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('dummy98', 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'dummy98',
+ 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev veth97 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (Token=eui64)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1034:56ff:fe78:9ace/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1034:56ff:fe78:9ace/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('veth97', 'inet6 3ffe:501:ffff:[2-9a-f]08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth97',
+ 'inet6 3ffe:501:ffff:[2-9a-f]08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev veth97-peer scope global')
output = check_output('ip -6 address show dev veth97-peer scope global')
print(output)
# NDisc address (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (Token=eui64)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1034:56ff:fe78:9acf/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]08:1034:56ff:fe78:9acf/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (temporary)
- self.wait_address('veth97-peer', 'inet6 3ffe:501:ffff:[2-9a-f]08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth97-peer',
+ 'inet6 3ffe:501:ffff:[2-9a-f]08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev veth98 scope global')
output = check_output('ip -6 address show dev veth98 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (Token=eui64)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1034:56ff:fe78:9abe/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1034:56ff:fe78:9abe/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('veth98', 'inet6 3ffe:501:ffff:[2-9a-f]09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth98',
+ 'inet6 3ffe:501:ffff:[2-9a-f]09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev veth98-peer scope global')
output = check_output('ip -6 address show dev veth98-peer scope global')
print(output)
# NDisc address (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (Token=eui64)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1034:56ff:fe78:9abf/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]09:1034:56ff:fe78:9abf/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (temporary)
- self.wait_address('veth98-peer', 'inet6 3ffe:501:ffff:[2-9a-f]09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth98-peer',
+ 'inet6 3ffe:501:ffff:[2-9a-f]09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 route show type unreachable')
output = check_output('ip -6 route show type unreachable')
output = check_output('ip -6 address show dev dummy97 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]01:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]01:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('dummy97', 'inet6 3ffe:501:ffff:[2-9a-f]01:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'dummy97',
+ 'inet6 3ffe:501:ffff:[2-9a-f]01:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 route show dev dummy97')
output = check_output('ip -6 route show dev dummy97')
output = check_output('ip -6 address show dev dummy98 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 3ffe:501:ffff:[2-9a-f]00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('dummy98', 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'dummy98',
+ 'inet6 3ffe:501:ffff:[2-9a-f]00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev dummy99 scope global')
print('### ip -4 address show dev veth99 scope global')
output = check_output('ip -4 address show dev veth99 scope global')
print(output)
- self.assertRegex(output, fr'inet {address_prefix}[0-9]*/8 (metric 1024 |)brd 10.255.255.255 scope global dynamic veth99')
+ self.assertRegex(output, rf'inet {address_prefix}[0-9]*/8 (metric 1024 |)brd 10.255.255.255 scope global dynamic veth99') # fmt: skip
print('### ip -6 address show dev veth99 scope global')
output = check_output('ip -6 address show dev veth99 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (Token=eui64)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
# Note that the temporary addresses may appear after the link enters configured state
- self.wait_address('veth99', 'inet6 2001:db8:6464:[0-9a-f]+10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth99',
+ 'inet6 2001:db8:6464:[0-9a-f]+10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev test1 scope global')
output = check_output('ip -6 address show dev test1 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('test1', 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'test1',
+ 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev dummy98 scope global')
output = check_output('ip -6 address show dev dummy98 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('dummy98', 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'dummy98',
+ 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev dummy99 scope global')
output = check_output('ip -6 address show dev veth97 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (Token=eui64)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9ace/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9ace/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('veth97', 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth97',
+ 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev veth97-peer scope global')
output = check_output('ip -6 address show dev veth97-peer scope global')
print(output)
# NDisc address (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (Token=eui64)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9acf/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9acf/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (temporary)
- self.wait_address('veth97-peer', 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth97-peer',
+ 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev veth98 scope global')
output = check_output('ip -6 address show dev veth98 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (Token=eui64)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abe/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abe/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('veth98', 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth98',
+ 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 address show dev veth98-peer scope global')
output = check_output('ip -6 address show dev veth98-peer scope global')
print(output)
# NDisc address (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (Token=eui64)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abf/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abf/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# NDisc address (temporary)
- self.wait_address('veth98-peer', 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'veth98-peer',
+ 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 route show type unreachable')
output = check_output('ip -6 route show type unreachable')
output = check_output('ip -6 address show dev dummy97 scope global')
print(output)
# address in IA_PD (Token=static)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+01:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+01:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') # fmt: skip
# address in IA_PD (temporary)
- self.wait_address('dummy97', 'inet6 2001:db8:6464:[0-9a-f]+01:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+ self.wait_address(
+ 'dummy97',
+ 'inet6 2001:db8:6464:[0-9a-f]+01:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic',
+ ipv='-6',
+ )
print('### ip -6 route show dev dummy97')
output = check_output('ip -6 route show dev dummy97')
print(f'### ip -6 address show dev {tunnel_name}')
output = check_output(f'ip -6 address show dev {tunnel_name}')
print(output)
- self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+0[23]:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global dynamic')
- self.assertRegex(output, fr'inet6 ::{address_prefix_re}/96 scope global')
+ self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+0[23]:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global dynamic') # fmt: skip
+ self.assertRegex(output, rf'inet6 ::{address_prefix_re}/96 scope global')
print(f'### ip -6 route show dev {tunnel_name}')
output = check_output(f'ip -6 route show dev {tunnel_name}')
output = check_output('ip -6 route show default')
print(output)
self.assertIn('default', output)
- self.assertRegex(output, fr'via ::{border_router} dev {tunnel_name}')
+ self.assertRegex(output, rf'via ::{border_router} dev {tunnel_name}')
def test_dhcp4_6rd(self):
def get_dhcp_6rd_prefix(link):
return prefixInfo
- copy_network_unit('25-veth.netdev', '25-dhcp4-6rd-server.network', '25-dhcp4-6rd-upstream.network',
- '25-veth-downstream-veth97.netdev', '25-dhcp-pd-downstream-veth97.network', '25-dhcp-pd-downstream-veth97-peer.network',
- '25-veth-downstream-veth98.netdev', '25-dhcp-pd-downstream-veth98.network', '25-dhcp-pd-downstream-veth98-peer.network',
- '11-dummy.netdev', '25-dhcp-pd-downstream-test1.network',
- '25-dhcp-pd-downstream-dummy97.network',
- '12-dummy.netdev', '25-dhcp-pd-downstream-dummy98.network',
- '13-dummy.netdev', '25-dhcp-pd-downstream-dummy99.network',
- '80-6rd-tunnel.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-dhcp4-6rd-server.network',
+ '25-dhcp4-6rd-upstream.network',
+ '25-veth-downstream-veth97.netdev',
+ '25-dhcp-pd-downstream-veth97.network',
+ '25-dhcp-pd-downstream-veth97-peer.network',
+ '25-veth-downstream-veth98.netdev',
+ '25-dhcp-pd-downstream-veth98.network',
+ '25-dhcp-pd-downstream-veth98-peer.network',
+ '11-dummy.netdev',
+ '25-dhcp-pd-downstream-test1.network',
+ '25-dhcp-pd-downstream-dummy97.network',
+ '12-dummy.netdev',
+ '25-dhcp-pd-downstream-dummy98.network',
+ '13-dummy.netdev',
+ '25-dhcp-pd-downstream-dummy99.network',
+ '80-6rd-tunnel.network',
+ )
start_networkd()
self.wait_online('veth-peer:routable')
# 6rd-prefix: 2001:db8::/32
# br-address: 10.0.0.1
- start_dnsmasq('--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:01',
- ipv4_range='10.100.100.100,10.100.100.200',
- ipv4_router='10.0.0.1')
- self.wait_online('veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded',
- 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable')
+ start_dnsmasq(
+ '--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:01',
+ ipv4_range='10.100.100.100,10.100.100.200',
+ ipv4_router='10.0.0.1',
+ )
+ self.wait_online(
+ 'veth99:routable',
+ 'test1:routable',
+ 'dummy98:routable',
+ 'dummy99:degraded',
+ 'veth97:routable',
+ 'veth97-peer:routable',
+ 'veth98:routable',
+ 'veth98-peer:routable',
+ )
# Check the DBus interface for assigned prefix information
prefixInfo = get_dhcp_6rd_prefix('veth99')
- self.assertEqual(prefixInfo['Prefix'], [32,1,13,184,0,0,0,0,0,0,0,0,0,0,0,0]) # 2001:db8::
+ self.assertEqual(prefixInfo['Prefix'], [32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) # 2001:db8:: # fmt: skip
self.assertEqual(prefixInfo['PrefixLength'], 32)
self.assertEqual(prefixInfo['IPv4MaskLength'], 8)
- self.assertEqual(prefixInfo['BorderRouters'], [[10,0,0,1]])
+ self.assertEqual(prefixInfo['BorderRouters'], [[10, 0, 0, 1]])
# Test case for a downstream which appears later
check_output('ip link add dummy97 type dummy')
self.wait_online(f'{tunnel_name}:routable')
- self.verify_dhcp4_6rd(tunnel_name, '10.100.100.1', '(10.100.100.1[0-9][0-9]|a64:64[6-9a-c][0-9a-f])', '(10.0.0.1|a00:1)')
+ self.verify_dhcp4_6rd(
+ tunnel_name,
+ '10.100.100.1',
+ '(10.100.100.1[0-9][0-9]|a64:64[6-9a-c][0-9a-f])',
+ '(10.0.0.1|a00:1)',
+ )
# Test case for reconfigure
networkctl_reconfigure('dummy98', 'dummy99')
self.wait_online('dummy98:routable', 'dummy99:degraded')
- self.verify_dhcp4_6rd(tunnel_name, '10.100.100.1', '(10.100.100.1[0-9][0-9]|a64:64[6-9a-c][0-9a-f])', '(10.0.0.1|a00:1)')
+ self.verify_dhcp4_6rd(
+ tunnel_name,
+ '10.100.100.1',
+ '(10.100.100.1[0-9][0-9]|a64:64[6-9a-c][0-9a-f])',
+ '(10.0.0.1|a00:1)',
+ )
# Change the address range and (border) router, then if check the same tunnel is reused.
stop_dnsmasq()
- start_dnsmasq('--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:02',
- ipv4_range='10.100.100.200,10.100.100.250',
- ipv4_router='10.0.0.2')
+ start_dnsmasq(
+ '--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:02',
+ ipv4_range='10.100.100.200,10.100.100.250',
+ ipv4_router='10.0.0.2',
+ )
print('Wait for the DHCP lease to be renewed/rebind')
time.sleep(120)
- self.wait_online('veth99:routable', 'test1:routable', 'dummy97:routable', 'dummy98:routable', 'dummy99:degraded',
- 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable')
+ self.wait_online(
+ 'veth99:routable',
+ 'test1:routable',
+ 'dummy97:routable',
+ 'dummy98:routable',
+ 'dummy99:degraded',
+ 'veth97:routable',
+ 'veth97-peer:routable',
+ 'veth98:routable',
+ 'veth98-peer:routable',
+ )
+
+ self.verify_dhcp4_6rd(
+ tunnel_name,
+ '10.100.100.2',
+ '(10.100.100.2[0-5][0-9]|a64:64[c-f][0-9a-f])',
+ '(10.0.0.2|a00:2)',
+ )
- self.verify_dhcp4_6rd(tunnel_name, '10.100.100.2', '(10.100.100.2[0-5][0-9]|a64:64[c-f][0-9a-f])', '(10.0.0.2|a00:2)')
class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
-
def setUp(self):
setup_common()
tear_down_common()
def test_ipv6_route_prefix(self):
- copy_network_unit('25-veth.netdev', '25-ipv6ra-prefix-client.network', '25-ipv6ra-prefix.network',
- '12-dummy.netdev', '25-ipv6ra-uplink.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6ra-prefix-client.network',
+ '25-ipv6ra-prefix.network',
+ '12-dummy.netdev',
+ '25-ipv6ra-uplink.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable', 'dummy98:routable')
print('### ip -6 nexthop show dev veth-peer')
output = check_output('ip -6 nexthop show dev veth-peer')
print(output)
- self.assertRegex(output, r'id [0-9]* via fe80::1034:56ff:fe78:9abc dev veth-peer scope link proto ra')
+ self.assertRegex(output, r'id [0-9]* via fe80::1034:56ff:fe78:9abc dev veth-peer scope link proto ra') # fmt: skip
print('### ip -6 address show dev veth99')
output = check_output('ip -6 address show dev veth99')
self.assertEqual(prefix_length, 96)
def test_ipv6_route_prefix_deny_list(self):
- copy_network_unit('25-veth.netdev', '25-ipv6ra-prefix-client-deny-list.network', '25-ipv6ra-prefix.network',
- '12-dummy.netdev', '25-ipv6ra-uplink.network')
+ copy_network_unit(
+ '25-veth.netdev',
+ '25-ipv6ra-prefix-client-deny-list.network',
+ '25-ipv6ra-prefix.network',
+ '12-dummy.netdev',
+ '25-ipv6ra-uplink.network',
+ )
start_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable', 'dummy98:routable')
print('### ip -6 nexthop show dev veth-peer')
output = check_output('ip -6 nexthop show dev veth-peer')
print(output)
- self.assertRegex(output, r'id [0-9]* via fe80::1034:56ff:fe78:9abc dev veth-peer scope link proto ra')
+ self.assertRegex(output, r'id [0-9]* via fe80::1034:56ff:fe78:9abc dev veth-peer scope link proto ra') # fmt: skip
print('### ip -6 address show dev veth99')
output = check_output('ip -6 address show dev veth99')
print(output)
self.assertIn('example.com', output)
-class NetworkdMTUTests(unittest.TestCase, Utilities):
+class NetworkdMTUTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
self.reset_check_mtu(mtu, ipv6_mtu)
def reset_check_mtu(self, mtu, ipv6_mtu=None):
- ''' test setting mtu/ipv6_mtu with interface already up '''
+ """test setting mtu/ipv6_mtu with interface already up"""
stop_networkd()
# note - changing the device mtu resets the ipv6 mtu
self.check_mtu('1600', reset=False)
def test_ipv6_mtu(self):
- ''' set ipv6 mtu without setting device mtu '''
+ """set ipv6 mtu without setting device mtu"""
copy_network_unit('12-dummy.netdev', '12-dummy.network.d/ipv6-mtu-1400.conf')
self.check_mtu('1500', '1400')
def test_ipv6_mtu_toolarge(self):
- ''' try set ipv6 mtu over device mtu (it shouldn't work) '''
+ """try set ipv6 mtu over device mtu (it shouldn't work)"""
copy_network_unit('12-dummy.netdev', '12-dummy.network.d/ipv6-mtu-1550.conf')
self.check_mtu('1500', '1500')
def test_mtu_network_ipv6_mtu(self):
- ''' set ipv6 mtu and set device mtu via network file '''
- copy_network_unit('12-dummy.netdev', '12-dummy.network.d/mtu.conf', '12-dummy.network.d/ipv6-mtu-1550.conf')
+ """set ipv6 mtu and set device mtu via network file"""
+ copy_network_unit(
+ '12-dummy.netdev',
+ '12-dummy.network.d/mtu.conf',
+ '12-dummy.network.d/ipv6-mtu-1550.conf',
+ )
self.check_mtu('1600', '1550')
def test_mtu_netdev_ipv6_mtu(self):
- ''' set ipv6 mtu and set device mtu via netdev file '''
+ """set ipv6 mtu and set device mtu via netdev file"""
copy_network_unit('12-dummy-mtu.netdev', '12-dummy.network.d/ipv6-mtu-1550.conf')
self.check_mtu('1600', '1550', reset=False)
def test_mtu_link_ipv6_mtu(self):
- ''' set ipv6 mtu and set device mtu via link file '''
+ """set ipv6 mtu and set device mtu via link file"""
copy_network_unit('12-dummy.netdev', '12-dummy-mtu.link', '12-dummy.network.d/ipv6-mtu-1550.conf')
self.check_mtu('1600', '1550', reset=False)
-class NetworkdSysctlTest(unittest.TestCase, Utilities):
+class NetworkdSysctlTest(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
def tearDown(self):
tear_down_common()
- @unittest.skipUnless(compare_kernel_version("6.12"), reason="On kernels <= 6.12, bpf_current_task_under_cgroup() isn't available for program types BPF_PROG_TYPE_CGROUP_SYSCTL")
+ @unittest.skipUnless(
+ compare_kernel_version('6.12'),
+ reason='On kernels <= 6.12, bpf_current_task_under_cgroup() is not available for program types BPF_PROG_TYPE_CGROUP_SYSCTL',
+ )
def test_sysctl_monitor(self):
copy_network_unit('12-dummy.network', '12-dummy.netdev', '12-dummy.link')
start_networkd()
call('sysctl -w net.ipv6.conf.dummy98.hop_limit=4')
call('sysctl -w net.ipv6.conf.dummy98.max_addresses=10')
- log=read_networkd_log()
+ log = read_networkd_log()
+ # fmt: off
self.assertRegex(log, r"Foreign process 'sysctl\[\d+\]' changed sysctl '/proc/sys/net/ipv6/conf/dummy98/accept_ra' from '0' to '1', conflicting with our setting to '0'")
self.assertRegex(log, r"Foreign process 'sysctl\[\d+\]' changed sysctl '/proc/sys/net/ipv6/conf/dummy98/mtu' from '1550' to '1360', conflicting with our setting to '1550'")
self.assertRegex(log, r"Foreign process 'sysctl\[\d+\]' changed sysctl '/proc/sys/net/ipv4/conf/dummy98/promote_secondaries' from '1' to '0', conflicting with our setting to '1'")
self.assertRegex(log, r"Foreign process 'sysctl\[\d+\]' changed sysctl '/proc/sys/net/ipv6/conf/dummy98/proxy_ndp' from '0' to '1', conflicting with our setting to '0'")
+ # fmt: on
self.assertNotIn("changed sysctl '/proc/sys/net/ipv6/conf/dummy98/hop_limit'", log)
self.assertNotIn("changed sysctl '/proc/sys/net/ipv6/conf/dummy98/max_addresses'", log)
- self.assertNotIn("Sysctl monitor BPF returned error", log)
+ self.assertNotIn('Sysctl monitor BPF returned error', log)
-class NetworkdWWANTests(unittest.TestCase, Utilities):
+class NetworkdWWANTests(unittest.TestCase, Utilities):
def setUp(self):
setup_common()
'--ipv6-address', '2001:db8::1',
'--ipv6-gateway', '2001:db8::2',
'--ipv6-prefix', '64',
- )
+ ) # fmt: skip
except (subprocess.CalledProcessError, PermissionError, OSError) as e:
self.skipTest(f'Failed to start mock ModemManager: {e}')
start_networkd()
print(output)
self.assertIn('default via 2001:db8::2', output)
+
if __name__ == '__main__':
parser = argparse.ArgumentParser()
- parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
- parser.add_argument('--source-dir', help='Path to source dir/git tree', dest='source_dir')
- parser.add_argument('--valgrind', help='Enable valgrind', dest='use_valgrind', type=bool, nargs='?', const=True, default=use_valgrind)
- parser.add_argument('--debug', help='Generate debugging logs', dest='enable_debug', type=bool, nargs='?', const=True, default=enable_debug)
- parser.add_argument('--asan-options', help='ASAN options', dest='asan_options')
- parser.add_argument('--lsan-options', help='LSAN options', dest='lsan_options')
- parser.add_argument('--ubsan-options', help='UBSAN options', dest='ubsan_options')
- parser.add_argument('--with-coverage', help='Loosen certain sandbox restrictions to make gcov happy', dest='with_coverage', type=bool, nargs='?', const=True, default=with_coverage)
- parser.add_argument('--no-journal', help='Do not show journal of systemd-networkd on stop', dest='show_journal', action='store_false')
+ parser.add_argument(
+ '--build-dir',
+ help='Path to build dir',
+ dest='build_dir',
+ )
+ parser.add_argument(
+ '--source-dir',
+ help='Path to source dir/git tree',
+ dest='source_dir',
+ )
+ parser.add_argument(
+ '--valgrind',
+ help='Enable valgrind',
+ dest='use_valgrind',
+ type=bool,
+ nargs='?',
+ const=True,
+ default=use_valgrind,
+ )
+ parser.add_argument(
+ '--debug',
+ help='Generate debugging logs',
+ dest='enable_debug',
+ type=bool,
+ nargs='?',
+ const=True,
+ default=enable_debug,
+ )
+ parser.add_argument(
+ '--asan-options',
+ help='ASAN options',
+ dest='asan_options',
+ )
+ parser.add_argument(
+ '--lsan-options',
+ help='LSAN options',
+ dest='lsan_options',
+ )
+ parser.add_argument(
+ '--ubsan-options',
+ help='UBSAN options',
+ dest='ubsan_options',
+ )
+ parser.add_argument(
+ '--with-coverage',
+ help='Loosen certain sandbox restrictions to make gcov happy',
+ dest='with_coverage',
+ type=bool,
+ nargs='?',
+ const=True,
+ default=with_coverage,
+ )
+ parser.add_argument(
+ '--no-journal',
+ help='Do not show journal of systemd-networkd on stop',
+ dest='show_journal',
+ action='store_false',
+ )
ns, unknown_args = parser.parse_known_args(namespace=unittest)
if ns.build_dir:
udevadm_bin = os.path.join(ns.build_dir, 'udevadm')
build_dir = ns.build_dir
+ # fmt: off
if ns.source_dir:
source_dir = ns.source_dir
- assert os.path.exists(os.path.join(source_dir, "meson_options.txt")), f"{source_dir} doesn't appear to be a systemd source tree."
- elif os.path.exists(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../meson_options.txt"))):
- source_dir = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../"))
+ assert os.path.exists(os.path.join(source_dir, 'meson_options.txt')), f"{source_dir} doesn't appear to be a systemd source tree."
+ elif os.path.exists(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../meson_options.txt'))):
+ source_dir = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
else:
source_dir = None
+ # fmt: on
if networkd_bin is None or resolved_bin is None or timesyncd_bin is None:
- print("networkd tests require networkd/resolved/timesyncd to be enabled")
+ print('networkd tests require networkd/resolved/timesyncd to be enabled')
sys.exit(77)
use_valgrind = ns.use_valgrind
asan_options = ns.asan_options
lsan_options = ns.lsan_options
ubsan_options = ns.ubsan_options
- with_coverage = ns.with_coverage or "COVERAGE_BUILD_DIR" in os.environ
+ with_coverage = ns.with_coverage or 'COVERAGE_BUILD_DIR' in os.environ
show_journal = ns.show_journal
if use_valgrind:
argv=[
sys.argv[0],
*unknown_args,
- *(["-k", match] if (match := os.getenv("TEST_MATCH_TESTCASE")) else [])
+ *(['-k', match] if (match := os.getenv('TEST_MATCH_TESTCASE')) else []),
],
)