]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
test: expand configure-without-carrier test
[thirdparty/systemd.git] / test / test-network / systemd-networkd-tests.py
CommitLineData
1f0e3109
SS
1#!/usr/bin/env python3
2# SPDX-License-Identifier: LGPL-2.1+
3# systemd-networkd tests
4
9c1ae484 5import argparse
7c0d36ff 6import itertools
1f0e3109 7import os
201bf07f 8import re
1f0e3109
SS
9import shutil
10import signal
a9bc5e37
YW
11import subprocess
12import sys
a9bc5e37
YW
13import time
14import unittest
1f0e3109
SS
15from shutil import copytree
16
d486a2d0 17network_unit_file_path='/run/systemd/network'
bad4969b 18networkd_runtime_directory='/run/systemd/netif'
d486a2d0 19networkd_ci_path='/run/networkd-ci'
1f0e3109
SS
20network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
21network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
22
d486a2d0
YW
23dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
24dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
1f0e3109 25
7471bcb0
DS
26systemd_lib_paths=['/usr/lib/systemd', '/lib/systemd']
27which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':').split(':'))
28
29networkd_bin=shutil.which('systemd-networkd', path=which_paths)
30resolved_bin=shutil.which('systemd-resolved', path=which_paths)
641aa412 31udevd_bin=shutil.which('systemd-udevd', path=which_paths)
7471bcb0
DS
32wait_online_bin=shutil.which('systemd-networkd-wait-online', path=which_paths)
33networkctl_bin=shutil.which('networkctl', path=which_paths)
34resolvectl_bin=shutil.which('resolvectl', path=which_paths)
35timedatectl_bin=shutil.which('timedatectl', path=which_paths)
36
9c1ae484 37use_valgrind=False
aaae5713 38enable_debug=True
9c1ae484 39env = {}
94c03122 40asan_options=None
fa4c6095 41lsan_options=None
94c03122 42ubsan_options=None
5aa58329 43
2225e7fd
YW
44running_units = []
45
371810d1
ZJS
46def check_output(*command, **kwargs):
47 # This replaces both check_output and check_call (output can be ignored)
48 command = command[0].split() + list(command[1:])
49 return subprocess.check_output(command, universal_newlines=True, **kwargs).rstrip()
50
51def call(*command, **kwargs):
52 command = command[0].split() + list(command[1:])
53 return subprocess.call(command, universal_newlines=True, **kwargs)
54
55def run(*command, **kwargs):
56 command = command[0].split() + list(command[1:])
57 return subprocess.run(command, universal_newlines=True, **kwargs)
58
7a0a37b2 59def is_module_available(module_name):
371810d1
ZJS
60 lsmod_output = check_output('lsmod')
61 module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE)
856423f1 62 return module_re.search(lsmod_output) or not call('modprobe', module_name, stderr=subprocess.DEVNULL)
7a0a37b2
EV
63
64def expectedFailureIfModuleIsNotAvailable(module_name):
65 def f(func):
66 if not is_module_available(module_name):
67 return unittest.expectedFailure(func)
68 return func
69
70 return f
71
7bea7f9b
SS
72def expectedFailureIfERSPANModuleIsNotAvailable():
73 def f(func):
856423f1 74 rc = call('ip link add dev erspan99 type erspan seq key 30 local 192.168.1.4 remote 192.168.1.1 erspan_ver 1 erspan 123', stderr=subprocess.DEVNULL)
7bea7f9b 75 if rc == 0:
371810d1 76 call('ip link del erspan99')
7bea7f9b
SS
77 return func
78 else:
79 return unittest.expectedFailure(func)
80
81 return f
82
d586a2c3
YW
83def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
84 def f(func):
856423f1 85 rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7', stderr=subprocess.DEVNULL)
d586a2c3 86 if rc == 0:
371810d1 87 call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
d586a2c3
YW
88 return func
89 else:
90 return unittest.expectedFailure(func)
91
92 return f
93
94def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
95 def f(func):
856423f1 96 rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7', stderr=subprocess.DEVNULL)
d586a2c3 97 if rc == 0:
371810d1 98 call('ip rule del not from 192.168.100.19 ipproto tcp table 7')
d586a2c3
YW
99 return func
100 else:
101 return unittest.expectedFailure(func)
102
103 return f
104
6be8e78e
YW
105def expectedFailureIfRoutingPolicyUIDRangeIsNotAvailable():
106 def f(func):
107 support = False
108 rc = call('ip rule add from 192.168.100.19 table 7 uidrange 200-300', stderr=subprocess.DEVNULL)
109 if rc == 0:
110 ret = run('ip rule list from 192.168.100.19 table 7', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
111 if ret.returncode == 0 and 'uidrange 200-300' in ret.stdout.rstrip():
112 support = True
113 call('ip rule del from 192.168.100.19 table 7 uidrange 200-300')
114
115 if support:
116 return func
117 else:
118 return unittest.expectedFailure(func)
119
120 return f
121
e28fd95f
YW
122def expectedFailureIfLinkFileFieldIsNotSet():
123 def f(func):
124 support = False
856423f1 125 rc = call('ip link add name dummy99 type dummy', stderr=subprocess.DEVNULL)
e28fd95f
YW
126 if rc == 0:
127 ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
128 if ret.returncode == 0 and 'E: ID_NET_LINK_FILE=' in ret.stdout.rstrip():
129 support = True
130 call('ip link del dummy99')
131
132 if support:
133 return func
134 else:
135 return unittest.expectedFailure(func)
136
137 return f
138
086bcf5d
YW
139def expectedFailureIfNexthopIsNotAvailable():
140 def f(func):
856423f1 141 rc = call('ip nexthop list', stderr=subprocess.DEVNULL)
086bcf5d
YW
142 if rc == 0:
143 return func
144 else:
145 return unittest.expectedFailure(func)
146
147 return f
148
6934ace0
YW
149def expectedFailureIfAlternativeNameIsNotAvailable():
150 def f(func):
151 call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
152 rc = call('ip link prop add dev dummy98 altname hogehogehogehogehoge', stderr=subprocess.DEVNULL)
834ea1a4 153 call('ip link del dummy98', stderr=subprocess.DEVNULL)
6934ace0
YW
154 if rc == 0:
155 return func
156 else:
157 return unittest.expectedFailure(func)
158
159 return f
160
f6c6af38
YW
161def expectedFailureIfCAKEIsNotAvailable():
162 def f(func):
163 call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
164 rc = call('tc qdisc add dev dummy98 parent root cake', stderr=subprocess.DEVNULL)
165 call('ip link del dummy98', stderr=subprocess.DEVNULL)
166 if rc == 0:
167 return func
168 else:
169 return unittest.expectedFailure(func)
170
171 return f
172
be94e591
YW
173def expectedFailureIfPIEIsNotAvailable():
174 def f(func):
175 call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
176 rc = call('tc qdisc add dev dummy98 parent root pie', stderr=subprocess.DEVNULL)
177 call('ip link del dummy98', stderr=subprocess.DEVNULL)
178 if rc == 0:
179 return func
180 else:
181 return unittest.expectedFailure(func)
182
183 return f
184
970ab1fc
YW
185def expectedFailureIfHHFIsNotAvailable():
186 def f(func):
187 call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
188 rc = call('tc qdisc add dev dummy98 parent root hhf', stderr=subprocess.DEVNULL)
189 call('ip link del dummy98', stderr=subprocess.DEVNULL)
190 if rc == 0:
191 return func
192 else:
193 return unittest.expectedFailure(func)
194
195 return f
196
1f0e3109 197def setUpModule():
2225e7fd
YW
198 global running_units
199
1f0e3109
SS
200 os.makedirs(network_unit_file_path, exist_ok=True)
201 os.makedirs(networkd_ci_path, exist_ok=True)
202
203 shutil.rmtree(networkd_ci_path)
6aea9276 204 copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
1f0e3109 205
f7ada4b8
YW
206 for u in ['systemd-networkd.socket', 'systemd-networkd.service', 'systemd-resolved.service',
207 'systemd-udevd-kernel.socket', 'systemd-udevd-control.socket', 'systemd-udevd.service',
208 'firewalld.service']:
2225e7fd
YW
209 if call(f'systemctl is-active --quiet {u}') == 0:
210 check_output(f'systemctl stop {u}')
211 running_units.append(u)
c0bf6733 212
9c1ae484 213 drop_in = [
3e821525
DS
214 '[Unit]',
215 'StartLimitIntervalSec=0',
9c1ae484
YW
216 '[Service]',
217 'Restart=no',
218 'ExecStart=',
219 ]
220 if use_valgrind:
221 drop_in += [
222 'ExecStart=!!valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ' + networkd_bin,
94c03122 223 'PrivateTmp=yes'
9c1ae484
YW
224 ]
225 else:
226 drop_in += ['ExecStart=!!' + networkd_bin]
227 if enable_debug:
228 drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
94c03122
YW
229 if asan_options:
230 drop_in += ['Environment=ASAN_OPTIONS="' + asan_options + '"']
fa4c6095
YW
231 if lsan_options:
232 drop_in += ['Environment=LSAN_OPTIONS="' + lsan_options + '"']
94c03122
YW
233 if ubsan_options:
234 drop_in += ['Environment=UBSAN_OPTIONS="' + ubsan_options + '"']
78690bb5
YW
235 if asan_options or lsan_options or ubsan_options:
236 drop_in += ['SystemCallFilter=']
fa4c6095 237 if use_valgrind or asan_options or lsan_options or ubsan_options:
94c03122 238 drop_in += ['MemoryDenyWriteExecute=no']
9c1ae484 239
9c1ae484
YW
240 os.makedirs('/run/systemd/system/systemd-networkd.service.d', exist_ok=True)
241 with open('/run/systemd/system/systemd-networkd.service.d/00-override.conf', mode='w') as f:
72917fcc 242 f.write('\n'.join(drop_in))
9c1ae484 243
b6d587d1
YW
244 drop_in = [
245 '[Service]',
246 'Restart=no',
247 'ExecStart=',
248 ]
249 if use_valgrind:
250 drop_in += ['ExecStart=!!valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ' + resolved_bin]
251 else:
252 drop_in += ['ExecStart=!!' + resolved_bin]
253 if enable_debug:
254 drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
255 if asan_options:
256 drop_in += ['Environment=ASAN_OPTIONS="' + asan_options + '"']
257 if lsan_options:
258 drop_in += ['Environment=LSAN_OPTIONS="' + lsan_options + '"']
259 if ubsan_options:
260 drop_in += ['Environment=UBSAN_OPTIONS="' + ubsan_options + '"']
261 if asan_options or lsan_options or ubsan_options:
262 drop_in += ['SystemCallFilter=']
263 if use_valgrind or asan_options or lsan_options or ubsan_options:
264 drop_in += ['MemoryDenyWriteExecute=no']
265
266 os.makedirs('/run/systemd/system/systemd-resolved.service.d', exist_ok=True)
267 with open('/run/systemd/system/systemd-resolved.service.d/00-override.conf', mode='w') as f:
268 f.write('\n'.join(drop_in))
269
641aa412
YW
270 drop_in = [
271 '[Service]',
272 'ExecStart=',
273 'ExecStart=!!' + udevd_bin,
274 ]
275
276 os.makedirs('/run/systemd/system/systemd-udevd.service.d', exist_ok=True)
277 with open('/run/systemd/system/systemd-udevd.service.d/00-override.conf', mode='w') as f:
278 f.write('\n'.join(drop_in))
279
371810d1
ZJS
280 check_output('systemctl daemon-reload')
281 print(check_output('systemctl cat systemd-networkd.service'))
b6d587d1 282 print(check_output('systemctl cat systemd-resolved.service'))
641aa412 283 print(check_output('systemctl cat systemd-udevd.service'))
b6d587d1 284 check_output('systemctl restart systemd-resolved')
641aa412 285 check_output('systemctl restart systemd-udevd')
9c1ae484 286
1f0e3109 287def tearDownModule():
2225e7fd
YW
288 global running_units
289
1f0e3109 290 shutil.rmtree(networkd_ci_path)
d4fda2a5 291
f7ada4b8 292 for u in ['systemd-networkd.service', 'systemd-resolved.service']:
2225e7fd 293 check_output(f'systemctl stop {u}')
d4fda2a5 294
9c1ae484 295 shutil.rmtree('/run/systemd/system/systemd-networkd.service.d')
b6d587d1 296 shutil.rmtree('/run/systemd/system/systemd-resolved.service.d')
641aa412 297 shutil.rmtree('/run/systemd/system/systemd-udevd.service.d')
371810d1 298 check_output('systemctl daemon-reload')
f7ada4b8 299 check_output('systemctl restart systemd-udevd.service')
1f0e3109 300
2225e7fd
YW
301 for u in running_units:
302 check_output(f'systemctl start {u}')
c0bf6733 303
befd4b8b
DS
304def read_link_attr(*args):
305 with open(os.path.join('/sys/class/net/', *args)) as f:
ec38833c
ZJS
306 return f.readline().strip()
307
308def read_bridge_port_attr(bridge, link, attribute):
309 path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
310 path_port = 'lower_' + link + '/brport'
311 path = os.path.join(path_bridge, path_port)
312
313 with open(os.path.join(path, attribute)) as f:
314 return f.readline().strip()
315
316def link_exists(link):
317 return os.path.exists(os.path.join('/sys/class/net', link))
318
319def remove_links(links):
320 for link in links:
321 if link_exists(link):
322 call('ip link del dev', link)
323 time.sleep(1)
324
325def remove_fou_ports(ports):
326 for port in ports:
5239d7b3 327 call('ip fou del port', port, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
ec38833c
ZJS
328
329def remove_routing_policy_rule_tables(tables):
330 for table in tables:
4ef39b49
YW
331 rc = 0
332 while rc == 0:
333 rc = call('ip rule del table', table, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
ec38833c
ZJS
334
335def remove_routes(routes):
336 for route_type, addr in routes:
5239d7b3 337 call('ip route del', route_type, addr, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
ec38833c 338
ad78d7b0 339def remove_l2tp_tunnels(tunnel_ids):
ec38833c
ZJS
340 output = check_output('ip l2tp show tunnel')
341 for tid in tunnel_ids:
342 words='Tunnel ' + tid + ', encap'
343 if words in output:
344 call('ip l2tp del tunnel tid', tid)
345 time.sleep(1)
346
347def read_ipv6_sysctl_attr(link, attribute):
348 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
349 return f.readline().strip()
350
351def read_ipv4_sysctl_attr(link, attribute):
352 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
353 return f.readline().strip()
354
9dfc1a93
DS
355def copy_unit_to_networkd_unit_path(*units, dropins=True):
356 """Copy networkd unit files into the testbed.
357
358 Any networkd unit file type can be specified, as well as drop-in files.
359
360 By default, all drop-ins for a specified unit file are copied in;
361 to avoid that specify dropins=False.
362
363 When a drop-in file is specified, its unit file is also copied in automatically.
364 """
ec38833c
ZJS
365 print()
366 for unit in units:
9dfc1a93 367 if dropins and os.path.exists(os.path.join(networkd_ci_path, unit + '.d')):
ec38833c 368 copytree(os.path.join(networkd_ci_path, unit + '.d'), os.path.join(network_unit_file_path, unit + '.d'))
9dfc1a93
DS
369 if unit.endswith('.conf'):
370 dropin = unit
371 dropindir = os.path.join(network_unit_file_path, os.path.dirname(dropin))
372 os.makedirs(dropindir, exist_ok=True)
373 shutil.copy(os.path.join(networkd_ci_path, dropin), dropindir)
374 unit = os.path.dirname(dropin).rstrip('.d')
375 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
ec38833c
ZJS
376
377def remove_unit_from_networkd_path(units):
9dfc1a93
DS
378 """Remove previously copied unit files from the testbed.
379
380 Drop-ins will be removed automatically.
381 """
ec38833c
ZJS
382 for unit in units:
383 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
384 os.remove(os.path.join(network_unit_file_path, unit))
385 if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
386 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
387
ec38833c 388def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'):
ec38833c
ZJS
389 dnsmasq_command = f'dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --dhcp-option=33,192.168.5.4,192.168.5.5 --port=0 ' + additional_options
390 check_output(dnsmasq_command)
391
392def stop_dnsmasq(pid_file):
393 if os.path.exists(pid_file):
394 with open(pid_file, 'r') as f:
395 pid = f.read().rstrip(' \t\r\n\0')
396 os.kill(int(pid), signal.SIGTERM)
397
398 os.remove(pid_file)
399
400def search_words_in_dnsmasq_log(words, show_all=False):
401 if os.path.exists(dnsmasq_log_file):
402 with open (dnsmasq_log_file) as in_file:
403 contents = in_file.read()
404 if show_all:
405 print(contents)
406 for line in contents.splitlines():
407 if words in line:
408 in_file.close()
409 print("%s, %s" % (words, line))
410 return True
411 return False
412
413def remove_lease_file():
414 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
415 os.remove(os.path.join(networkd_ci_path, 'lease'))
416
417def remove_log_file():
418 if os.path.exists(dnsmasq_log_file):
419 os.remove(dnsmasq_log_file)
420
aaae5713
YW
421def remove_networkd_state_files():
422 if os.path.exists(os.path.join(networkd_runtime_directory, 'state')):
ec38833c 423 os.remove(os.path.join(networkd_runtime_directory, 'state'))
aaae5713
YW
424
425def stop_networkd(show_logs=True, remove_state_files=True):
426 if show_logs:
427 invocation_id = check_output('systemctl show systemd-networkd -p InvocationID --value')
428 check_output('systemctl stop systemd-networkd')
429 if show_logs:
430 print(check_output('journalctl _SYSTEMD_INVOCATION_ID=' + invocation_id))
431 if remove_state_files:
432 remove_networkd_state_files()
433
434def start_networkd(sleep_sec=0):
435 check_output('systemctl start systemd-networkd')
ec38833c
ZJS
436 if sleep_sec > 0:
437 time.sleep(sleep_sec)
438
aaae5713
YW
439def restart_networkd(sleep_sec=0, show_logs=True, remove_state_files=True):
440 stop_networkd(show_logs, remove_state_files)
441 start_networkd(sleep_sec)
442
1f0e3109 443
ec38833c 444class Utilities():
e39cc445 445 def check_link_exists(self, link):
ec38833c 446 self.assertTrue(link_exists(link))
2be0b6fc 447
a4632dc7
DS
448 def wait_operstate(self, link, operstate='degraded', setup_state='configured', setup_timeout=5, fail_assert=True):
449 """Wait for the link to reach the specified operstate and/or setup state.
450
451 Specify None or '' for either operstate or setup_state to ignore that state.
452 This will recheck until the state conditions are met or the timeout expires.
453
454 If the link successfully matches the requested state, this returns True.
455 If this times out waiting for the link to match, the behavior depends on the
456 'fail_assert' parameter; if True, this causes a test assertion failure,
457 otherwise this returns False. The default is to cause assertion failure.
458
459 Note that this function matches on *exactly* the given operstate and setup_state.
460 To wait for a link to reach *or exceed* a given operstate, use wait_online().
461 """
462 if not operstate:
463 operstate = r'\S+'
464 if not setup_state:
465 setup_state = r'\S+'
466
467 for secs in range(setup_timeout + 1):
468 output = check_output(*networkctl_cmd, '-n', '0', 'status', link, env=env)
469 print(output)
470 if re.search(rf'(?m)^\s*State:\s+{operstate}\s+\({setup_state}\)\s*$', output):
471 return True
472 # don't bother sleeping if time is up
473 if secs < setup_timeout:
474 time.sleep(1)
475 if fail_assert:
476 self.fail(f'Timed out waiting for {link} to reach state {operstate}/{setup_state}')
477 return False
2be0b6fc 478
fd372b1a 479 def wait_online(self, links_with_operstate, timeout='20s', bool_any=False, setup_state='configured', setup_timeout=5):
0c020321
DS
480 """Wait for the link(s) to reach the specified operstate and/or setup state.
481
482 This is similar to wait_operstate() but can be used for multiple links,
483 and it also calls systemd-networkd-wait-online to wait for the given operstate.
484 The operstate should be specified in the link name, like 'eth0:degraded'.
485 If just a link name is provided, wait-online's default operstate to wait for is degraded.
486
487 The 'timeout' parameter controls the systemd-networkd-wait-online timeout, and the
488 'setup_timeout' controls the per-link timeout waiting for the setup_state.
489
490 Set 'bool_any' to True to wait for any (instead of all) of the given links.
491 If this is set, no setup_state checks are done.
492
493 Note that this function waits for the link(s) to reach *or exceed* the given operstate.
494 However, the setup_state, if specified, must be matched *exactly*.
495
496 This returns if the link(s) reached the requested operstate/setup_state; otherwise it
497 raises CalledProcessError or fails test assertion.
498 """
e2aea43f
YW
499 args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate]
500 if bool_any:
501 args += ['--any']
502 try:
503 check_output(*args, env=env)
504 except subprocess.CalledProcessError:
505 for link in links_with_operstate:
fc79e6ff 506 output = check_output(*networkctl_cmd, '-n', '0', 'status', link.split(':')[0], env=env)
e2aea43f
YW
507 print(output)
508 raise
fd372b1a 509 if not bool_any and setup_state:
0c020321
DS
510 for link in links_with_operstate:
511 self.wait_operstate(link.split(':')[0], None, setup_state, setup_timeout)
e2aea43f 512
53c32c2b 513 def wait_address(self, link, address_regex, scope='global', ipv='', timeout_sec=100):
2629df47
YW
514 for i in range(timeout_sec):
515 if i > 0:
516 time.sleep(1)
371810d1 517 output = check_output(f'ip {ipv} address show dev {link} scope {scope}')
2629df47
YW
518 if re.search(address_regex, output):
519 break
520 else:
521 self.assertRegex(output, address_regex)
522
1ca44d7d
YW
523class NetworkctlTests(unittest.TestCase, Utilities):
524
525 links = [
dcd9f07c 526 'dummy98',
1ca44d7d
YW
527 'test1',
528 'veth99',
529 ]
530
531 units = [
532 '11-dummy.netdev',
6d5b4efe 533 '11-dummy-mtu.netdev',
1ca44d7d 534 '11-dummy.network',
dcd9f07c 535 '12-dummy.netdev',
6934ace0 536 '12-dummy.link',
dcd9f07c 537 '25-address-static.network',
1ca44d7d
YW
538 '25-veth.netdev',
539 'netdev-link-local-addressing-yes.network',
540 ]
541
542 def setUp(self):
ec38833c 543 remove_links(self.links)
aaae5713 544 stop_networkd(show_logs=False)
1ca44d7d
YW
545
546 def tearDown(self):
ec38833c
ZJS
547 remove_links(self.links)
548 remove_unit_from_networkd_path(self.units)
aaae5713 549 stop_networkd(show_logs=True)
1ca44d7d 550
6934ace0
YW
551 @expectedFailureIfAlternativeNameIsNotAvailable()
552 def test_altname(self):
553 copy_unit_to_networkd_unit_path('netdev-link-local-addressing-yes.network', '12-dummy.netdev', '12-dummy.link')
554 check_output('udevadm control --reload')
555 start_networkd()
556 self.wait_online(['dummy98:degraded'])
557
fc79e6ff 558 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
6934ace0
YW
559 self.assertRegex(output, 'hogehogehogehogehogehoge')
560
dcd9f07c
YW
561 def test_reconfigure(self):
562 copy_unit_to_networkd_unit_path('25-address-static.network', '12-dummy.netdev')
563 start_networkd()
564 self.wait_online(['dummy98:routable'])
565
566 output = check_output('ip -4 address show dev dummy98')
567 print(output)
568 self.assertRegex(output, 'inet 10.1.2.3/16 brd 10.1.255.255 scope global dummy98')
569 self.assertRegex(output, 'inet 10.1.2.4/16 brd 10.1.255.255 scope global secondary dummy98')
570 self.assertRegex(output, 'inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98')
571
572 check_output('ip address del 10.1.2.3/16 dev dummy98')
573 check_output('ip address del 10.1.2.4/16 dev dummy98')
574 check_output('ip address del 10.2.2.4/16 dev dummy98')
575
576 check_output(*networkctl_cmd, 'reconfigure', 'dummy98', env=env)
577 self.wait_online(['dummy98:routable'])
578
579 output = check_output('ip -4 address show dev dummy98')
580 print(output)
581 self.assertRegex(output, 'inet 10.1.2.3/16 brd 10.1.255.255 scope global dummy98')
582 self.assertRegex(output, 'inet 10.1.2.4/16 brd 10.1.255.255 scope global secondary dummy98')
583 self.assertRegex(output, 'inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98')
584
66de8671
YW
585 def test_reload(self):
586 start_networkd(3)
587
588 copy_unit_to_networkd_unit_path('11-dummy.netdev')
589 check_output(*networkctl_cmd, 'reload', env=env)
19cf3143 590 self.wait_operstate('test1', 'off', setup_state='unmanaged')
66de8671
YW
591
592 copy_unit_to_networkd_unit_path('11-dummy.network')
593 check_output(*networkctl_cmd, 'reload', env=env)
594 self.wait_online(['test1:degraded'])
595
596 remove_unit_from_networkd_path(['11-dummy.network'])
597 check_output(*networkctl_cmd, 'reload', env=env)
19cf3143 598 self.wait_operstate('test1', 'degraded', setup_state='unmanaged')
66de8671
YW
599
600 remove_unit_from_networkd_path(['11-dummy.netdev'])
601 check_output(*networkctl_cmd, 'reload', env=env)
19cf3143 602 self.wait_operstate('test1', 'degraded', setup_state='unmanaged')
66de8671
YW
603
604 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
605 check_output(*networkctl_cmd, 'reload', env=env)
19cf3143 606 self.wait_operstate('test1', 'degraded')
66de8671 607
1ca44d7d 608 def test_glob(self):
ec38833c 609 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
2cf6fdff 610 start_networkd()
1ca44d7d 611
e2aea43f 612 self.wait_online(['test1:degraded'])
1ca44d7d 613
371810d1 614 output = check_output(*networkctl_cmd, 'list', env=env)
1ca44d7d
YW
615 self.assertRegex(output, '1 lo ')
616 self.assertRegex(output, 'test1')
617
371810d1 618 output = check_output(*networkctl_cmd, 'list', 'test1', env=env)
1ca44d7d
YW
619 self.assertNotRegex(output, '1 lo ')
620 self.assertRegex(output, 'test1')
621
371810d1 622 output = check_output(*networkctl_cmd, 'list', 'te*', env=env)
1ca44d7d
YW
623 self.assertNotRegex(output, '1 lo ')
624 self.assertRegex(output, 'test1')
625
fc79e6ff 626 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'te*', env=env)
1ca44d7d
YW
627 self.assertNotRegex(output, '1: lo ')
628 self.assertRegex(output, 'test1')
629
fc79e6ff 630 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'tes[a-z][0-9]', env=env)
1ca44d7d
YW
631 self.assertNotRegex(output, '1: lo ')
632 self.assertRegex(output, 'test1')
633
6d5b4efe 634 def test_mtu(self):
ec38833c 635 copy_unit_to_networkd_unit_path('11-dummy-mtu.netdev', '11-dummy.network')
2cf6fdff 636 start_networkd()
6d5b4efe 637
e2aea43f 638 self.wait_online(['test1:degraded'])
6d5b4efe 639
fc79e6ff 640 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
6d5b4efe
YW
641 self.assertRegex(output, 'MTU: 1600')
642
e28fd95f
YW
643 def test_type(self):
644 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
645 start_networkd()
e2aea43f 646 self.wait_online(['test1:degraded'])
e28fd95f 647
fc79e6ff 648 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
e28fd95f
YW
649 print(output)
650 self.assertRegex(output, 'Type: ether')
651
fc79e6ff 652 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'lo', env=env)
e28fd95f
YW
653 print(output)
654 self.assertRegex(output, 'Type: loopback')
655
656 @expectedFailureIfLinkFileFieldIsNotSet()
657 def test_udev_link_file(self):
658 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
659 start_networkd()
e2aea43f 660 self.wait_online(['test1:degraded'])
e28fd95f 661
fc79e6ff 662 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
e28fd95f 663 print(output)
426654d7 664 self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
e28fd95f
YW
665 self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
666
fc79e6ff 667 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'lo', env=env)
e28fd95f 668 print(output)
426654d7 669 self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
e28fd95f
YW
670 self.assertRegex(output, r'Network File: n/a')
671
bee692fd 672 def test_delete_links(self):
ec38833c
ZJS
673 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network',
674 '25-veth.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 675 start_networkd()
bee692fd 676
e2aea43f 677 self.wait_online(['test1:degraded', 'veth99:degraded', 'veth-peer:degraded'])
bee692fd 678
7a2f6fb6 679 check_output(*networkctl_cmd, 'delete', 'test1', 'veth99', env=env)
ec38833c
ZJS
680 self.assertFalse(link_exists('test1'))
681 self.assertFalse(link_exists('veth99'))
682 self.assertFalse(link_exists('veth-peer'))
bee692fd 683
1f0e3109
SS
684class NetworkdNetDevTests(unittest.TestCase, Utilities):
685
e64dc406
YW
686 links_remove_earlier = [
687 'xfrm99',
688 ]
689
690 links = [
09ea6724
YW
691 '6rdtun99',
692 'bond99',
693 'bridge99',
694 'dropin-test',
695 'dummy98',
6a97a864
YW
696 'erspan98',
697 'erspan99',
09ea6724 698 'geneve99',
4b6a6d1e 699 'gretap96',
6a97a864 700 'gretap98',
09ea6724 701 'gretap99',
4b6a6d1e 702 'gretun96',
6a97a864
YW
703 'gretun97',
704 'gretun98',
09ea6724 705 'gretun99',
b076d5d7 706 'ifb99',
6a97a864 707 'ip6gretap98',
09ea6724 708 'ip6gretap99',
42a29fcb 709 'ip6gretun96',
6a97a864
YW
710 'ip6gretun97',
711 'ip6gretun98',
712 'ip6gretun99',
713 'ip6tnl97',
714 'ip6tnl98',
09ea6724 715 'ip6tnl99',
4b6a6d1e 716 'ipiptun96',
6a97a864
YW
717 'ipiptun97',
718 'ipiptun98',
09ea6724
YW
719 'ipiptun99',
720 'ipvlan99',
956c8fec 721 'ipvtap99',
09ea6724
YW
722 'isataptun99',
723 'macvlan99',
724 'macvtap99',
811f33d0 725 'nlmon99',
4b6a6d1e 726 'sittun96',
6a97a864
YW
727 'sittun97',
728 'sittun98',
09ea6724
YW
729 'sittun99',
730 'tap99',
731 'test1',
732 'tun99',
733 'vcan99',
734 'veth99',
735 'vlan99',
736 'vrf99',
6a97a864
YW
737 'vti6tun97',
738 'vti6tun98',
09ea6724 739 'vti6tun99',
42a29fcb 740 'vtitun96',
6a97a864
YW
741 'vtitun97',
742 'vtitun98',
09ea6724 743 'vtitun99',
f63b14d3 744 'vxcan99',
09ea6724 745 'vxlan99',
da44fb8a 746 'wg98',
e64dc406
YW
747 'wg99',
748 ]
09ea6724
YW
749
750 units = [
751 '10-dropin-test.netdev',
752 '11-dummy.netdev',
03db80b2 753 '11-dummy.network',
09ea6724 754 '12-dummy.netdev',
6b9518a0
YW
755 '13-not-match-udev-property.network',
756 '14-match-udev-property.network',
753e0a24 757 '15-name-conflict-test.netdev',
09ea6724
YW
758 '21-macvlan.netdev',
759 '21-macvtap.netdev',
7f45d738 760 '21-vlan-test1.network',
09ea6724
YW
761 '21-vlan.netdev',
762 '21-vlan.network',
763 '25-6rd-tunnel.netdev',
764 '25-bond.netdev',
fde60a42 765 '25-bond-balanced-tlb.netdev',
09ea6724 766 '25-bridge.netdev',
1285edf3 767 '25-bridge-configure-without-carrier.network',
03db80b2 768 '25-bridge.network',
6a97a864 769 '25-erspan-tunnel-local-any.netdev',
09ea6724 770 '25-erspan-tunnel.netdev',
4b6a6d1e
YW
771 '25-fou-gretap.netdev',
772 '25-fou-gre.netdev',
773 '25-fou-ipip.netdev',
774 '25-fou-ipproto-gre.netdev',
775 '25-fou-ipproto-ipip.netdev',
776 '25-fou-sit.netdev',
09ea6724 777 '25-geneve.netdev',
6a97a864 778 '25-gretap-tunnel-local-any.netdev',
09ea6724 779 '25-gretap-tunnel.netdev',
42a29fcb 780 '25-gre-tunnel-any-any.netdev',
6a97a864
YW
781 '25-gre-tunnel-local-any.netdev',
782 '25-gre-tunnel-remote-any.netdev',
09ea6724 783 '25-gre-tunnel.netdev',
b076d5d7 784 '25-ifb.netdev',
6a97a864
YW
785 '25-ip6gretap-tunnel-local-any.netdev',
786 '25-ip6gretap-tunnel.netdev',
42a29fcb 787 '25-ip6gre-tunnel-any-any.netdev',
6a97a864
YW
788 '25-ip6gre-tunnel-local-any.netdev',
789 '25-ip6gre-tunnel-remote-any.netdev',
09ea6724 790 '25-ip6gre-tunnel.netdev',
42a29fcb 791 '25-ip6tnl-tunnel-any-any.netdev',
6a97a864 792 '25-ip6tnl-tunnel-local-any.netdev',
42a29fcb 793 '25-ip6tnl-tunnel-remote-any.netdev',
09ea6724 794 '25-ip6tnl-tunnel.netdev',
42a29fcb 795 '25-ipip-tunnel-any-any.netdev',
09ea6724 796 '25-ipip-tunnel-independent.netdev',
95082dbe 797 '25-ipip-tunnel-independent-loopback.netdev',
6a97a864
YW
798 '25-ipip-tunnel-local-any.netdev',
799 '25-ipip-tunnel-remote-any.netdev',
09ea6724
YW
800 '25-ipip-tunnel.netdev',
801 '25-ipvlan.netdev',
956c8fec 802 '25-ipvtap.netdev',
09ea6724 803 '25-isatap-tunnel.netdev',
02849d8b
YW
804 '25-macsec.key',
805 '25-macsec.netdev',
806 '25-macsec.network',
811f33d0 807 '25-nlmon.netdev',
42a29fcb 808 '25-sit-tunnel-any-any.netdev',
6a97a864
YW
809 '25-sit-tunnel-local-any.netdev',
810 '25-sit-tunnel-remote-any.netdev',
09ea6724
YW
811 '25-sit-tunnel.netdev',
812 '25-tap.netdev',
813 '25-tun.netdev',
11309591
YW
814 '25-tunnel-local-any.network',
815 '25-tunnel-remote-any.network',
816 '25-tunnel.network',
09ea6724
YW
817 '25-vcan.netdev',
818 '25-veth.netdev',
819 '25-vrf.netdev',
42a29fcb 820 '25-vti6-tunnel-any-any.netdev',
6a97a864
YW
821 '25-vti6-tunnel-local-any.netdev',
822 '25-vti6-tunnel-remote-any.netdev',
09ea6724 823 '25-vti6-tunnel.netdev',
42a29fcb 824 '25-vti-tunnel-any-any.netdev',
6a97a864
YW
825 '25-vti-tunnel-local-any.netdev',
826 '25-vti-tunnel-remote-any.netdev',
09ea6724 827 '25-vti-tunnel.netdev',
f63b14d3 828 '25-vxcan.netdev',
09ea6724 829 '25-vxlan.netdev',
da44fb8a
YW
830 '25-wireguard-23-peers.netdev',
831 '25-wireguard-23-peers.network',
9e5d79e7 832 '25-wireguard-preshared-key.txt',
39bcff3b 833 '25-wireguard-private-key.txt',
09ea6724 834 '25-wireguard.netdev',
5a0bd90b 835 '25-wireguard.network',
e64dc406
YW
836 '25-xfrm.netdev',
837 '25-xfrm-independent.netdev',
09ea6724 838 '6rd.network',
6730a1f3 839 'erspan.network',
09ea6724
YW
840 'gre.network',
841 'gretap.network',
842 'gretun.network',
843 'ip6gretap.network',
6a97a864 844 'ip6gretun.network',
09ea6724
YW
845 'ip6tnl.network',
846 'ipip.network',
847 'ipvlan.network',
956c8fec 848 'ipvtap.network',
09ea6724 849 'isatap.network',
02849d8b 850 'macsec.network',
09ea6724
YW
851 'macvlan.network',
852 'macvtap.network',
077f9abc 853 'netdev-link-local-addressing-yes.network',
09ea6724
YW
854 'sit.network',
855 'vti6.network',
856 'vti.network',
1c862fe0 857 'vxlan-test1.network',
e64dc406
YW
858 'vxlan.network',
859 'xfrm.network',
860 ]
1f0e3109 861
def9fc0d
YW
862 fou_ports = [
863 '55555',
864 '55556']
865
1f0e3109 866 def setUp(self):
ec38833c 867 remove_fou_ports(self.fou_ports)
e64dc406 868 remove_links(self.links_remove_earlier)
ec38833c 869 remove_links(self.links)
aaae5713 870 stop_networkd(show_logs=False)
1f0e3109
SS
871
872 def tearDown(self):
ec38833c 873 remove_fou_ports(self.fou_ports)
e64dc406 874 remove_links(self.links_remove_earlier)
ec38833c
ZJS
875 remove_links(self.links)
876 remove_unit_from_networkd_path(self.units)
aaae5713 877 stop_networkd(show_logs=True)
1f0e3109 878
1ca44d7d 879 def test_dropin_and_name_conflict(self):
ec38833c 880 copy_unit_to_networkd_unit_path('10-dropin-test.netdev', '15-name-conflict-test.netdev')
2cf6fdff 881 start_networkd()
d80734f7 882
e2aea43f 883 self.wait_online(['dropin-test:off'], setup_state='unmanaged')
d80734f7 884
371810d1 885 output = check_output('ip link show dropin-test')
d80734f7
YW
886 print(output)
887 self.assertRegex(output, '00:50:56:c0:00:28')
888
6b9518a0
YW
889 def test_match_udev_property(self):
890 copy_unit_to_networkd_unit_path('12-dummy.netdev', '13-not-match-udev-property.network', '14-match-udev-property.network')
891 start_networkd()
e2aea43f 892 self.wait_online(['dummy98:routable'])
6b9518a0 893
fc79e6ff 894 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
6b9518a0
YW
895 print(output)
896 self.assertRegex(output, 'Network File: /run/systemd/network/14-match-udev-property')
897
03db80b2 898 def test_wait_online_any(self):
ec38833c 899 copy_unit_to_networkd_unit_path('25-bridge.netdev', '25-bridge.network', '11-dummy.netdev', '11-dummy.network')
2cf6fdff 900 start_networkd()
03db80b2 901
e2aea43f 902 self.wait_online(['bridge99', 'test1:degraded'], bool_any=True)
03db80b2 903
19cf3143
DS
904 self.wait_operstate('bridge99', '(off|no-carrier)', setup_state='configuring')
905 self.wait_operstate('test1', 'degraded')
03db80b2 906
1f0e3109 907 def test_bridge(self):
1285edf3 908 copy_unit_to_networkd_unit_path('25-bridge.netdev', '25-bridge-configure-without-carrier.network')
2cf6fdff 909 start_networkd()
1f0e3109 910
e2aea43f 911 self.wait_online(['bridge99:no-carrier'])
1f0e3109 912
3d165124 913 tick = os.sysconf('SC_CLK_TCK')
ec38833c
ZJS
914 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'hello_time')) / tick))
915 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'max_age')) / tick))
c9047092
YW
916 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'forward_delay')) / tick))
917 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'ageing_time')) / tick))
918 self.assertEqual(9, int(read_link_attr('bridge99', 'bridge', 'priority')))
919 self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_querier')))
920 self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_snooping')))
921 self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
922 self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
1f0e3109 923
fc79e6ff 924 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'bridge99', env=env)
36bc2ffb
YW
925 print(output)
926 self.assertRegex(output, 'Priority: 9')
927 self.assertRegex(output, 'STP: yes')
928 self.assertRegex(output, 'Multicast IGMP Version: 3')
929
1f0e3109 930 def test_bond(self):
ec38833c 931 copy_unit_to_networkd_unit_path('25-bond.netdev', '25-bond-balanced-tlb.netdev')
2cf6fdff 932 start_networkd()
ec38833c 933
e2aea43f 934 self.wait_online(['bond99:off', 'bond98:off'], setup_state='unmanaged')
ec38833c
ZJS
935
936 self.assertEqual('802.3ad 4', read_link_attr('bond99', 'bonding', 'mode'))
937 self.assertEqual('layer3+4 1', read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
938 self.assertEqual('1000', read_link_attr('bond99', 'bonding', 'miimon'))
939 self.assertEqual('fast 1', read_link_attr('bond99', 'bonding', 'lacp_rate'))
940 self.assertEqual('2000', read_link_attr('bond99', 'bonding', 'updelay'))
941 self.assertEqual('2000', read_link_attr('bond99', 'bonding', 'downdelay'))
942 self.assertEqual('4', read_link_attr('bond99', 'bonding', 'resend_igmp'))
943 self.assertEqual('1', read_link_attr('bond99', 'bonding', 'min_links'))
944 self.assertEqual('1218', read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
945 self.assertEqual('811', read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
946 self.assertEqual('00:11:22:33:44:55', read_link_attr('bond99', 'bonding', 'ad_actor_system'))
947
948 self.assertEqual('balance-tlb 5', read_link_attr('bond98', 'bonding', 'mode'))
949 self.assertEqual('1', read_link_attr('bond98', 'bonding', 'tlb_dynamic_lb'))
fde60a42 950
1f0e3109 951 def test_vlan(self):
ec38833c
ZJS
952 copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev',
953 '21-vlan.network', '21-vlan-test1.network')
2cf6fdff 954 start_networkd()
1f0e3109 955
e2aea43f 956 self.wait_online(['test1:degraded', 'vlan99:routable'])
1f0e3109 957
371810d1 958 output = check_output('ip -d link show test1')
72b7f1b9 959 print(output)
7d7be1b9 960 self.assertRegex(output, ' mtu 2000 ')
72b7f1b9 961
371810d1 962 output = check_output('ip -d link show vlan99')
14ecd604 963 print(output)
06895a1d
YW
964 self.assertRegex(output, ' mtu 2000 ')
965 self.assertRegex(output, 'REORDER_HDR')
966 self.assertRegex(output, 'LOOSE_BINDING')
967 self.assertRegex(output, 'GVRP')
968 self.assertRegex(output, 'MVRP')
969 self.assertRegex(output, ' id 99 ')
1f0e3109 970
371810d1 971 output = check_output('ip -4 address show dev test1')
7f45d738
YW
972 print(output)
973 self.assertRegex(output, 'inet 192.168.24.5/24 brd 192.168.24.255 scope global test1')
974 self.assertRegex(output, 'inet 192.168.25.5/24 brd 192.168.25.255 scope global test1')
975
371810d1 976 output = check_output('ip -4 address show dev vlan99')
7f45d738
YW
977 print(output)
978 self.assertRegex(output, 'inet 192.168.23.5/24 brd 192.168.23.255 scope global vlan99')
979
1f0e3109 980 def test_macvtap(self):
460feb61
YW
981 for mode in ['private', 'vepa', 'bridge', 'passthru']:
982 with self.subTest(mode=mode):
983 if mode != 'private':
984 self.tearDown()
ec38833c
ZJS
985 copy_unit_to_networkd_unit_path('21-macvtap.netdev', 'netdev-link-local-addressing-yes.network',
986 '11-dummy.netdev', 'macvtap.network')
460feb61
YW
987 with open(os.path.join(network_unit_file_path, '21-macvtap.netdev'), mode='a') as f:
988 f.write('[MACVTAP]\nMode=' + mode)
2cf6fdff 989 start_networkd()
1f0e3109 990
e2aea43f 991 self.wait_online(['macvtap99:degraded', 'test1:degraded'])
460feb61 992
371810d1 993 output = check_output('ip -d link show macvtap99')
460feb61
YW
994 print(output)
995 self.assertRegex(output, 'macvtap mode ' + mode + ' ')
1f0e3109
SS
996
997 def test_macvlan(self):
dff9792b
YW
998 for mode in ['private', 'vepa', 'bridge', 'passthru']:
999 with self.subTest(mode=mode):
1000 if mode != 'private':
1001 self.tearDown()
ec38833c
ZJS
1002 copy_unit_to_networkd_unit_path('21-macvlan.netdev', 'netdev-link-local-addressing-yes.network',
1003 '11-dummy.netdev', 'macvlan.network')
dff9792b
YW
1004 with open(os.path.join(network_unit_file_path, '21-macvlan.netdev'), mode='a') as f:
1005 f.write('[MACVLAN]\nMode=' + mode)
2cf6fdff 1006 start_networkd()
dff9792b 1007
e2aea43f 1008 self.wait_online(['macvlan99:degraded', 'test1:degraded'])
dff9792b 1009
371810d1 1010 output = check_output('ip -d link show test1')
dff9792b
YW
1011 print(output)
1012 self.assertRegex(output, ' mtu 2000 ')
72b7f1b9 1013
371810d1 1014 output = check_output('ip -d link show macvlan99')
dff9792b
YW
1015 print(output)
1016 self.assertRegex(output, ' mtu 2000 ')
1017 self.assertRegex(output, 'macvlan mode ' + mode + ' ')
72b7f1b9 1018
7a0a37b2 1019 @expectedFailureIfModuleIsNotAvailable('ipvlan')
1f0e3109 1020 def test_ipvlan(self):
bc6dff6e
YW
1021 for mode, flag in [['L2', 'private'], ['L3', 'vepa'], ['L3S', 'bridge']]:
1022 with self.subTest(mode=mode, flag=flag):
1023 if mode != 'L2':
1024 self.tearDown()
ec38833c
ZJS
1025 copy_unit_to_networkd_unit_path('25-ipvlan.netdev', 'netdev-link-local-addressing-yes.network',
1026 '11-dummy.netdev', 'ipvlan.network')
bc6dff6e
YW
1027 with open(os.path.join(network_unit_file_path, '25-ipvlan.netdev'), mode='a') as f:
1028 f.write('[IPVLAN]\nMode=' + mode + '\nFlags=' + flag)
1f0e3109 1029
2cf6fdff 1030 start_networkd()
e2aea43f 1031 self.wait_online(['ipvlan99:degraded', 'test1:degraded'])
bc6dff6e 1032
371810d1 1033 output = check_output('ip -d link show ipvlan99')
bc6dff6e
YW
1034 print(output)
1035 self.assertRegex(output, 'ipvlan *mode ' + mode.lower() + ' ' + flag)
1f0e3109 1036
956c8fec
YW
1037 @expectedFailureIfModuleIsNotAvailable('ipvtap')
1038 def test_ipvtap(self):
40921f08
YW
1039 for mode, flag in [['L2', 'private'], ['L3', 'vepa'], ['L3S', 'bridge']]:
1040 with self.subTest(mode=mode, flag=flag):
1041 if mode != 'L2':
1042 self.tearDown()
ec38833c
ZJS
1043 copy_unit_to_networkd_unit_path('25-ipvtap.netdev', 'netdev-link-local-addressing-yes.network',
1044 '11-dummy.netdev', 'ipvtap.network')
40921f08
YW
1045 with open(os.path.join(network_unit_file_path, '25-ipvtap.netdev'), mode='a') as f:
1046 f.write('[IPVTAP]\nMode=' + mode + '\nFlags=' + flag)
1047
2cf6fdff 1048 start_networkd()
e2aea43f 1049 self.wait_online(['ipvtap99:degraded', 'test1:degraded'])
956c8fec 1050
371810d1 1051 output = check_output('ip -d link show ipvtap99')
40921f08
YW
1052 print(output)
1053 self.assertRegex(output, 'ipvtap *mode ' + mode.lower() + ' ' + flag)
956c8fec 1054
1f0e3109 1055 def test_veth(self):
ec38833c 1056 copy_unit_to_networkd_unit_path('25-veth.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1057 start_networkd()
1f0e3109 1058
e2aea43f 1059 self.wait_online(['veth99:degraded', 'veth-peer:degraded'])
671dacdf 1060
371810d1 1061 output = check_output('ip -d link show veth99')
671dacdf
YW
1062 print(output)
1063 self.assertRegex(output, 'link/ether 12:34:56:78:9a:bc')
371810d1 1064 output = check_output('ip -d link show veth-peer')
671dacdf
YW
1065 print(output)
1066 self.assertRegex(output, 'link/ether 12:34:56:78:9a:bd')
1f0e3109 1067
1f0e3109 1068 def test_tun(self):
ec38833c 1069 copy_unit_to_networkd_unit_path('25-tun.netdev')
2cf6fdff 1070 start_networkd()
1f0e3109 1071
e2aea43f 1072 self.wait_online(['tun99:off'], setup_state='unmanaged')
1f0e3109 1073
371810d1 1074 output = check_output('ip -d link show tun99')
2746d307
YW
1075 print(output)
1076 # Old ip command does not support IFF_ flags
426654d7 1077 self.assertRegex(output, 'tun (type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
2746d307 1078
1f0e3109 1079 def test_tap(self):
ec38833c 1080 copy_unit_to_networkd_unit_path('25-tap.netdev')
2cf6fdff 1081 start_networkd()
1f0e3109 1082
e2aea43f 1083 self.wait_online(['tap99:off'], setup_state='unmanaged')
1f0e3109 1084
371810d1 1085 output = check_output('ip -d link show tap99')
2746d307
YW
1086 print(output)
1087 # Old ip command does not support IFF_ flags
426654d7 1088 self.assertRegex(output, 'tun (type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
2746d307 1089
7a0a37b2 1090 @expectedFailureIfModuleIsNotAvailable('vrf')
1f0e3109 1091 def test_vrf(self):
ec38833c 1092 copy_unit_to_networkd_unit_path('25-vrf.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1093 start_networkd()
1f0e3109 1094
e2aea43f 1095 self.wait_online(['vrf99:carrier'])
1f0e3109 1096
7a0a37b2 1097 @expectedFailureIfModuleIsNotAvailable('vcan')
1f0e3109 1098 def test_vcan(self):
ec38833c 1099 copy_unit_to_networkd_unit_path('25-vcan.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1100 start_networkd()
1f0e3109 1101
e2aea43f 1102 self.wait_online(['vcan99:carrier'])
1f0e3109 1103
f63b14d3
YW
1104 @expectedFailureIfModuleIsNotAvailable('vxcan')
1105 def test_vxcan(self):
ec38833c 1106 copy_unit_to_networkd_unit_path('25-vxcan.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1107 start_networkd()
f63b14d3 1108
e2aea43f 1109 self.wait_online(['vxcan99:carrier', 'vxcan-peer:carrier'])
f63b14d3 1110
7a3bc5a8
EV
1111 @expectedFailureIfModuleIsNotAvailable('wireguard')
1112 def test_wireguard(self):
ec38833c
ZJS
1113 copy_unit_to_networkd_unit_path('25-wireguard.netdev', '25-wireguard.network',
1114 '25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
1115 '25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt')
2cf6fdff 1116 start_networkd()
e2aea43f 1117 self.wait_online(['wg99:carrier', 'wg98:routable'])
5a0bd90b 1118
7a3bc5a8 1119 if shutil.which('wg'):
371810d1 1120 call('wg')
5a0bd90b 1121
371810d1 1122 output = check_output('wg show wg99 listen-port')
06895a1d 1123 self.assertRegex(output, '51820')
371810d1 1124 output = check_output('wg show wg99 fwmark')
06895a1d 1125 self.assertRegex(output, '0x4d2')
371810d1 1126 output = check_output('wg show wg99 allowed-ips')
88aaf89e
ZJS
1127 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
1128 self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128')
371810d1 1129 output = check_output('wg show wg99 persistent-keepalive')
88aaf89e 1130 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t20')
371810d1 1131 output = check_output('wg show wg99 endpoints')
88aaf89e 1132 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.27.3:51820')
371810d1 1133 output = check_output('wg show wg99 private-key')
88aaf89e 1134 self.assertRegex(output, r'EEGlnEPYJV//kbvvIqxKkQwOiS\+UENyPncC4bF46ong=')
371810d1 1135 output = check_output('wg show wg99 preshared-keys')
88aaf89e
ZJS
1136 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA= IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=')
1137 self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc= cPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=')
7a3bc5a8 1138
371810d1 1139 output = check_output('wg show wg98 private-key')
88aaf89e 1140 self.assertRegex(output, r'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr\+WHtZLZ90FU=')
da44fb8a 1141
1f0e3109 1142 def test_geneve(self):
ec38833c 1143 copy_unit_to_networkd_unit_path('25-geneve.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1144 start_networkd()
1f0e3109 1145
e2aea43f 1146 self.wait_online(['geneve99:degraded'])
1f0e3109 1147
371810d1 1148 output = check_output('ip -d link show geneve99')
14ecd604 1149 print(output)
06895a1d
YW
1150 self.assertRegex(output, '192.168.22.1')
1151 self.assertRegex(output, '6082')
1152 self.assertRegex(output, 'udpcsum')
1153 self.assertRegex(output, 'udp6zerocsumrx')
1f0e3109
SS
1154
1155 def test_ipip_tunnel(self):
ec38833c
ZJS
1156 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ipip.network',
1157 '25-ipip-tunnel.netdev', '25-tunnel.network',
1158 '25-ipip-tunnel-local-any.netdev', '25-tunnel-local-any.network',
42a29fcb
YW
1159 '25-ipip-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
1160 '25-ipip-tunnel-any-any.netdev', '25-tunnel-any-any.network')
2cf6fdff 1161 start_networkd()
e2aea43f 1162 self.wait_online(['ipiptun99:routable', 'ipiptun98:routable', 'ipiptun97:routable', 'ipiptun96:routable', 'dummy98:degraded'])
6a97a864 1163
371810d1 1164 output = check_output('ip -d link show ipiptun99')
6a97a864 1165 print(output)
426654d7 1166 self.assertRegex(output, 'ipip (ipip )?remote 192.169.224.239 local 192.168.223.238 dev dummy98')
371810d1 1167 output = check_output('ip -d link show ipiptun98')
6a97a864 1168 print(output)
426654d7 1169 self.assertRegex(output, 'ipip (ipip )?remote 192.169.224.239 local any dev dummy98')
371810d1 1170 output = check_output('ip -d link show ipiptun97')
6a97a864 1171 print(output)
426654d7 1172 self.assertRegex(output, 'ipip (ipip )?remote any local 192.168.223.238 dev dummy98')
42a29fcb
YW
1173 output = check_output('ip -d link show ipiptun96')
1174 print(output)
426654d7 1175 self.assertRegex(output, 'ipip (ipip )?remote any local any dev dummy98')
1f0e3109
SS
1176
1177 def test_gre_tunnel(self):
ec38833c
ZJS
1178 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network',
1179 '25-gre-tunnel.netdev', '25-tunnel.network',
1180 '25-gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
42a29fcb
YW
1181 '25-gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
1182 '25-gre-tunnel-any-any.netdev', '25-tunnel-any-any.network')
2cf6fdff 1183 start_networkd()
e2aea43f 1184 self.wait_online(['gretun99:routable', 'gretun98:routable', 'gretun97:routable', 'gretun96:routable', 'dummy98:degraded'])
6a97a864 1185
371810d1 1186 output = check_output('ip -d link show gretun99')
6a97a864
YW
1187 print(output)
1188 self.assertRegex(output, 'gre remote 10.65.223.239 local 10.65.223.238 dev dummy98')
38f4bb44
YW
1189 self.assertRegex(output, 'ikey 1.2.3.103')
1190 self.assertRegex(output, 'okey 1.2.4.103')
1191 self.assertRegex(output, 'iseq')
1192 self.assertRegex(output, 'oseq')
371810d1 1193 output = check_output('ip -d link show gretun98')
6a97a864
YW
1194 print(output)
1195 self.assertRegex(output, 'gre remote 10.65.223.239 local any dev dummy98')
38f4bb44
YW
1196 self.assertRegex(output, 'ikey 0.0.0.104')
1197 self.assertRegex(output, 'okey 0.0.0.104')
1198 self.assertNotRegex(output, 'iseq')
1199 self.assertNotRegex(output, 'oseq')
371810d1 1200 output = check_output('ip -d link show gretun97')
6a97a864
YW
1201 print(output)
1202 self.assertRegex(output, 'gre remote any local 10.65.223.238 dev dummy98')
38f4bb44
YW
1203 self.assertRegex(output, 'ikey 0.0.0.105')
1204 self.assertRegex(output, 'okey 0.0.0.105')
1205 self.assertNotRegex(output, 'iseq')
1206 self.assertNotRegex(output, 'oseq')
42a29fcb
YW
1207 output = check_output('ip -d link show gretun96')
1208 print(output)
1209 self.assertRegex(output, 'gre remote any local any dev dummy98')
1210 self.assertRegex(output, 'ikey 0.0.0.106')
1211 self.assertRegex(output, 'okey 0.0.0.106')
1212 self.assertNotRegex(output, 'iseq')
1213 self.assertNotRegex(output, 'oseq')
6a97a864
YW
1214
1215 def test_ip6gre_tunnel(self):
ec38833c
ZJS
1216 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6gretun.network',
1217 '25-ip6gre-tunnel.netdev', '25-tunnel.network',
1218 '25-ip6gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
42a29fcb
YW
1219 '25-ip6gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
1220 '25-ip6gre-tunnel-any-any.netdev', '25-tunnel-any-any.network')
01943d43 1221 start_networkd(5)
6a97a864 1222
17bcf0a0
YW
1223 # Old kernels seem not to support IPv6LL address on ip6gre tunnel, So please do not use wait_online() here.
1224
e39cc445
YW
1225 self.check_link_exists('dummy98')
1226 self.check_link_exists('ip6gretun99')
1227 self.check_link_exists('ip6gretun98')
1228 self.check_link_exists('ip6gretun97')
42a29fcb 1229 self.check_link_exists('ip6gretun96')
6a97a864 1230
371810d1 1231 output = check_output('ip -d link show ip6gretun99')
6a97a864
YW
1232 print(output)
1233 self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1234 output = check_output('ip -d link show ip6gretun98')
6a97a864
YW
1235 print(output)
1236 self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local any dev dummy98')
371810d1 1237 output = check_output('ip -d link show ip6gretun97')
6a97a864
YW
1238 print(output)
1239 self.assertRegex(output, 'ip6gre remote any local 2a00:ffde:4567:edde::4987 dev dummy98')
42a29fcb
YW
1240 output = check_output('ip -d link show ip6gretun96')
1241 print(output)
1242 self.assertRegex(output, 'ip6gre remote any local any dev dummy98')
1f0e3109 1243
11309591 1244 def test_gretap_tunnel(self):
ec38833c
ZJS
1245 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretap.network',
1246 '25-gretap-tunnel.netdev', '25-tunnel.network',
1247 '25-gretap-tunnel-local-any.netdev', '25-tunnel-local-any.network')
2cf6fdff 1248 start_networkd()
e2aea43f 1249 self.wait_online(['gretap99:routable', 'gretap98:routable', 'dummy98:degraded'])
6a97a864 1250
371810d1 1251 output = check_output('ip -d link show gretap99')
6a97a864
YW
1252 print(output)
1253 self.assertRegex(output, 'gretap remote 10.65.223.239 local 10.65.223.238 dev dummy98')
38f4bb44
YW
1254 self.assertRegex(output, 'ikey 0.0.0.106')
1255 self.assertRegex(output, 'okey 0.0.0.106')
1256 self.assertRegex(output, 'iseq')
1257 self.assertRegex(output, 'oseq')
371810d1 1258 output = check_output('ip -d link show gretap98')
6a97a864
YW
1259 print(output)
1260 self.assertRegex(output, 'gretap remote 10.65.223.239 local any dev dummy98')
38f4bb44
YW
1261 self.assertRegex(output, 'ikey 0.0.0.107')
1262 self.assertRegex(output, 'okey 0.0.0.107')
1263 self.assertRegex(output, 'iseq')
1264 self.assertRegex(output, 'oseq')
1f0e3109
SS
1265
1266 def test_ip6gretap_tunnel(self):
ec38833c
ZJS
1267 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6gretap.network',
1268 '25-ip6gretap-tunnel.netdev', '25-tunnel.network',
1269 '25-ip6gretap-tunnel-local-any.netdev', '25-tunnel-local-any.network')
2cf6fdff 1270 start_networkd()
e2aea43f 1271 self.wait_online(['ip6gretap99:routable', 'ip6gretap98:routable', 'dummy98:degraded'])
6a97a864 1272
371810d1 1273 output = check_output('ip -d link show ip6gretap99')
6a97a864
YW
1274 print(output)
1275 self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1276 output = check_output('ip -d link show ip6gretap98')
6a97a864
YW
1277 print(output)
1278 self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local any dev dummy98')
1f0e3109
SS
1279
1280 def test_vti_tunnel(self):
ec38833c
ZJS
1281 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'vti.network',
1282 '25-vti-tunnel.netdev', '25-tunnel.network',
1283 '25-vti-tunnel-local-any.netdev', '25-tunnel-local-any.network',
42a29fcb
YW
1284 '25-vti-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
1285 '25-vti-tunnel-any-any.netdev', '25-tunnel-any-any.network')
2cf6fdff 1286 start_networkd()
e2aea43f 1287 self.wait_online(['vtitun99:routable', 'vtitun98:routable', 'vtitun97:routable', 'vtitun96:routable', 'dummy98:degraded'])
6a97a864 1288
371810d1 1289 output = check_output('ip -d link show vtitun99')
6a97a864
YW
1290 print(output)
1291 self.assertRegex(output, 'vti remote 10.65.223.239 local 10.65.223.238 dev dummy98')
371810d1 1292 output = check_output('ip -d link show vtitun98')
6a97a864
YW
1293 print(output)
1294 self.assertRegex(output, 'vti remote 10.65.223.239 local any dev dummy98')
371810d1 1295 output = check_output('ip -d link show vtitun97')
6a97a864
YW
1296 print(output)
1297 self.assertRegex(output, 'vti remote any local 10.65.223.238 dev dummy98')
42a29fcb
YW
1298 output = check_output('ip -d link show vtitun96')
1299 print(output)
1300 self.assertRegex(output, 'vti remote any local any dev dummy98')
1f0e3109
SS
1301
1302 def test_vti6_tunnel(self):
ec38833c
ZJS
1303 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'vti6.network',
1304 '25-vti6-tunnel.netdev', '25-tunnel.network',
1305 '25-vti6-tunnel-local-any.netdev', '25-tunnel-local-any.network',
1306 '25-vti6-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 1307 start_networkd()
e2aea43f 1308 self.wait_online(['vti6tun99:routable', 'vti6tun98:routable', 'vti6tun97:routable', 'dummy98:degraded'])
6a97a864 1309
371810d1 1310 output = check_output('ip -d link show vti6tun99')
6a97a864
YW
1311 print(output)
1312 self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1313 output = check_output('ip -d link show vti6tun98')
6a97a864 1314 print(output)
426654d7 1315 self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
371810d1 1316 output = check_output('ip -d link show vti6tun97')
6a97a864 1317 print(output)
426654d7 1318 self.assertRegex(output, 'vti6 remote (any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
1f0e3109
SS
1319
1320 def test_ip6tnl_tunnel(self):
ec38833c
ZJS
1321 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network',
1322 '25-ip6tnl-tunnel.netdev', '25-tunnel.network',
1323 '25-ip6tnl-tunnel-local-any.netdev', '25-tunnel-local-any.network',
1324 '25-ip6tnl-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 1325 start_networkd()
e2aea43f 1326 self.wait_online(['ip6tnl99:routable', 'ip6tnl98:routable', 'ip6tnl97:routable', 'dummy98:degraded'])
6a97a864 1327
371810d1 1328 output = check_output('ip -d link show ip6tnl99')
6a97a864
YW
1329 print(output)
1330 self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1331 output = check_output('ip -d link show ip6tnl98')
6a97a864 1332 print(output)
426654d7 1333 self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (any|::) dev dummy98')
371810d1 1334 output = check_output('ip -d link show ip6tnl97')
6a97a864 1335 print(output)
426654d7 1336 self.assertRegex(output, 'ip6tnl ip6ip6 remote (any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
1f0e3109
SS
1337
1338 def test_sit_tunnel(self):
ec38833c
ZJS
1339 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network',
1340 '25-sit-tunnel.netdev', '25-tunnel.network',
1341 '25-sit-tunnel-local-any.netdev', '25-tunnel-local-any.network',
42a29fcb
YW
1342 '25-sit-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
1343 '25-sit-tunnel-any-any.netdev', '25-tunnel-any-any.network')
2cf6fdff 1344 start_networkd()
e2aea43f 1345 self.wait_online(['sittun99:routable', 'sittun98:routable', 'sittun97:routable', 'sittun96:routable', 'dummy98:degraded'])
6a97a864 1346
371810d1 1347 output = check_output('ip -d link show sittun99')
6a97a864 1348 print(output)
426654d7 1349 self.assertRegex(output, "sit (ip6ip )?remote 10.65.223.239 local 10.65.223.238 dev dummy98")
371810d1 1350 output = check_output('ip -d link show sittun98')
6a97a864 1351 print(output)
426654d7 1352 self.assertRegex(output, "sit (ip6ip )?remote 10.65.223.239 local any dev dummy98")
371810d1 1353 output = check_output('ip -d link show sittun97')
6a97a864 1354 print(output)
426654d7 1355 self.assertRegex(output, "sit (ip6ip )?remote any local 10.65.223.238 dev dummy98")
42a29fcb
YW
1356 output = check_output('ip -d link show sittun96')
1357 print(output)
426654d7 1358 self.assertRegex(output, "sit (ip6ip )?remote any local any dev dummy98")
1f0e3109 1359
d0e728b6 1360 def test_isatap_tunnel(self):
ec38833c
ZJS
1361 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network',
1362 '25-isatap-tunnel.netdev', '25-tunnel.network')
2cf6fdff 1363 start_networkd()
e2aea43f 1364 self.wait_online(['isataptun99:routable', 'dummy98:degraded'])
d0e728b6 1365
371810d1 1366 output = check_output('ip -d link show isataptun99')
14ecd604 1367 print(output)
d0e728b6
SS
1368 self.assertRegex(output, "isatap ")
1369
d29dc4f1 1370 def test_6rd_tunnel(self):
ec38833c
ZJS
1371 copy_unit_to_networkd_unit_path('12-dummy.netdev', '6rd.network',
1372 '25-6rd-tunnel.netdev', '25-tunnel.network')
2cf6fdff 1373 start_networkd()
e2aea43f 1374 self.wait_online(['sittun99:routable', 'dummy98:degraded'])
d29dc4f1 1375
371810d1 1376 output = check_output('ip -d link show sittun99')
6a97a864
YW
1377 print(output)
1378 self.assertRegex(output, '6rd-prefix 2602::/24')
1379
7bea7f9b 1380 @expectedFailureIfERSPANModuleIsNotAvailable()
2266864b 1381 def test_erspan_tunnel(self):
ec38833c
ZJS
1382 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'erspan.network',
1383 '25-erspan-tunnel.netdev', '25-tunnel.network',
1384 '25-erspan-tunnel-local-any.netdev', '25-tunnel-local-any.network')
2cf6fdff 1385 start_networkd()
e2aea43f 1386 self.wait_online(['erspan99:routable', 'erspan98:routable', 'dummy98:degraded'])
2266864b 1387
371810d1 1388 output = check_output('ip -d link show erspan99')
6a97a864
YW
1389 print(output)
1390 self.assertRegex(output, 'erspan remote 172.16.1.100 local 172.16.1.200')
38f4bb44
YW
1391 self.assertRegex(output, 'ikey 0.0.0.101')
1392 self.assertRegex(output, 'okey 0.0.0.101')
1393 self.assertRegex(output, 'iseq')
1394 self.assertRegex(output, 'oseq')
371810d1 1395 output = check_output('ip -d link show erspan98')
2266864b 1396 print(output)
6a97a864
YW
1397 self.assertRegex(output, 'erspan remote 172.16.1.100 local any')
1398 self.assertRegex(output, '102')
38f4bb44
YW
1399 self.assertRegex(output, 'ikey 0.0.0.102')
1400 self.assertRegex(output, 'okey 0.0.0.102')
1401 self.assertRegex(output, 'iseq')
1402 self.assertRegex(output, 'oseq')
2266864b 1403
1f0e3109 1404 def test_tunnel_independent(self):
ec38833c 1405 copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1406 start_networkd()
e40a58b5 1407
e2aea43f 1408 self.wait_online(['ipiptun99:carrier'])
1f0e3109 1409
95082dbe
YW
1410 def test_tunnel_independent_loopback(self):
1411 copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent-loopback.netdev', 'netdev-link-local-addressing-yes.network')
1412 start_networkd()
1413
e2aea43f 1414 self.wait_online(['ipiptun99:carrier'])
95082dbe 1415
e64dc406
YW
1416 @expectedFailureIfModuleIsNotAvailable('xfrm_interface')
1417 def test_xfrm(self):
1418 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'xfrm.network',
1419 '25-xfrm.netdev', 'netdev-link-local-addressing-yes.network')
1420 start_networkd()
1421
e2aea43f 1422 self.wait_online(['xfrm99:degraded', 'dummy98:degraded'])
e64dc406
YW
1423
1424 output = check_output('ip link show dev xfrm99')
1425 print(output)
1426
1427 @expectedFailureIfModuleIsNotAvailable('xfrm_interface')
1428 def test_xfrm_independent(self):
1429 copy_unit_to_networkd_unit_path('25-xfrm-independent.netdev', 'netdev-link-local-addressing-yes.network')
1430 start_networkd()
1431
e2aea43f 1432 self.wait_online(['xfrm99:degraded'])
e64dc406 1433
4b6a6d1e
YW
1434 @expectedFailureIfModuleIsNotAvailable('fou')
1435 def test_fou(self):
1436 # The following redundant check is necessary for CentOS CI.
1437 # Maybe, error handling in lookup_id() in sd-netlink/generic-netlink.c needs to be updated.
1438 self.assertTrue(is_module_available('fou'))
1439
ec38833c
ZJS
1440 copy_unit_to_networkd_unit_path('25-fou-ipproto-ipip.netdev', '25-fou-ipproto-gre.netdev',
1441 '25-fou-ipip.netdev', '25-fou-sit.netdev',
1442 '25-fou-gre.netdev', '25-fou-gretap.netdev')
2cf6fdff 1443 start_networkd()
4b6a6d1e 1444
e2aea43f 1445 self.wait_online(['ipiptun96:off', 'sittun96:off', 'gretun96:off', 'gretap96:off'], setup_state='unmanaged')
4b6a6d1e 1446
371810d1 1447 output = check_output('ip fou show')
4b6a6d1e
YW
1448 print(output)
1449 self.assertRegex(output, 'port 55555 ipproto 4')
1450 self.assertRegex(output, 'port 55556 ipproto 47')
1451
371810d1 1452 output = check_output('ip -d link show ipiptun96')
4b6a6d1e
YW
1453 print(output)
1454 self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55555')
371810d1 1455 output = check_output('ip -d link show sittun96')
4b6a6d1e
YW
1456 print(output)
1457 self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55555')
371810d1 1458 output = check_output('ip -d link show gretun96')
4b6a6d1e
YW
1459 print(output)
1460 self.assertRegex(output, 'encap fou encap-sport 1001 encap-dport 55556')
371810d1 1461 output = check_output('ip -d link show gretap96')
4b6a6d1e
YW
1462 print(output)
1463 self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55556')
1464
1f0e3109 1465 def test_vxlan(self):
ec38833c
ZJS
1466 copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network',
1467 '11-dummy.netdev', 'vxlan-test1.network')
2cf6fdff 1468 start_networkd()
1f0e3109 1469
e2aea43f 1470 self.wait_online(['test1:degraded', 'vxlan99:degraded'])
1f0e3109 1471
371810d1 1472 output = check_output('ip -d link show vxlan99')
14ecd604 1473 print(output)
1c862fe0 1474 self.assertRegex(output, '999')
1f0e3109
SS
1475 self.assertRegex(output, '5555')
1476 self.assertRegex(output, 'l2miss')
1477 self.assertRegex(output, 'l3miss')
1478 self.assertRegex(output, 'udpcsum')
1479 self.assertRegex(output, 'udp6zerocsumtx')
1480 self.assertRegex(output, 'udp6zerocsumrx')
1481 self.assertRegex(output, 'remcsumtx')
1482 self.assertRegex(output, 'remcsumrx')
1483 self.assertRegex(output, 'gbp')
1484
371810d1 1485 output = check_output('bridge fdb show dev vxlan99')
1c862fe0
YW
1486 print(output)
1487 self.assertRegex(output, '00:11:22:33:44:55 dst 10.0.0.5 self permanent')
1488 self.assertRegex(output, '00:11:22:33:44:66 dst 10.0.0.6 self permanent')
1489 self.assertRegex(output, '00:11:22:33:44:77 dst 10.0.0.7 self permanent')
1490
fc79e6ff 1491 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'vxlan99', env=env)
36bc2ffb
YW
1492 print(output)
1493 self.assertRegex(output, 'VNI: 999')
1494 self.assertRegex(output, 'Destination Port: 5555')
1495 self.assertRegex(output, 'Underlying Device: test1')
1496
02849d8b 1497 def test_macsec(self):
ec38833c
ZJS
1498 copy_unit_to_networkd_unit_path('25-macsec.netdev', '25-macsec.network', '25-macsec.key',
1499 'macsec.network', '12-dummy.netdev')
2cf6fdff 1500 start_networkd()
02849d8b 1501
e2aea43f 1502 self.wait_online(['dummy98:degraded', 'macsec99:routable'])
02849d8b 1503
371810d1 1504 output = check_output('ip -d link show macsec99')
02849d8b
YW
1505 print(output)
1506 self.assertRegex(output, 'macsec99@dummy98')
1507 self.assertRegex(output, 'macsec sci [0-9a-f]*000b')
1508 self.assertRegex(output, 'encrypt on')
1509
371810d1 1510 output = check_output('ip macsec show macsec99')
02849d8b
YW
1511 print(output)
1512 self.assertRegex(output, 'encrypt on')
1513 self.assertRegex(output, 'TXSC: [0-9a-f]*000b on SA 1')
1514 self.assertRegex(output, '0: PN [0-9]*, state on, key 01000000000000000000000000000000')
1515 self.assertRegex(output, '1: PN [0-9]*, state on, key 02030000000000000000000000000000')
1516 self.assertRegex(output, 'RXSC: c619528fe6a00100, state on')
1517 self.assertRegex(output, '0: PN [0-9]*, state on, key 02030405000000000000000000000000')
1518 self.assertRegex(output, '1: PN [0-9]*, state on, key 02030405060000000000000000000000')
1519 self.assertRegex(output, '2: PN [0-9]*, state off, key 02030405060700000000000000000000')
1520 self.assertRegex(output, '3: PN [0-9]*, state off, key 02030405060708000000000000000000')
1521 self.assertNotRegex(output, 'key 02030405067080900000000000000000')
1522 self.assertRegex(output, 'RXSC: 8c16456c83a90002, state on')
1523 self.assertRegex(output, '0: PN [0-9]*, state off, key 02030400000000000000000000000000')
1524
811f33d0 1525 def test_nlmon(self):
ec38833c 1526 copy_unit_to_networkd_unit_path('25-nlmon.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1527 start_networkd()
811f33d0 1528
e2aea43f 1529 self.wait_online(['nlmon99:carrier'])
02849d8b 1530
b076d5d7
YW
1531 @expectedFailureIfModuleIsNotAvailable('ifb')
1532 def test_ifb(self):
1533 copy_unit_to_networkd_unit_path('25-ifb.netdev', 'netdev-link-local-addressing-yes.network')
1534 start_networkd()
1535
1536 self.wait_online(['ifb99:degraded'])
1537
cff83db9
YW
1538class NetworkdL2TPTests(unittest.TestCase, Utilities):
1539
1540 links =[
1541 'l2tp-ses1',
1542 'l2tp-ses2',
1543 'l2tp-ses3',
1544 'l2tp-ses4',
1545 'test1']
1546
1547 units = [
1548 '11-dummy.netdev',
1549 '25-l2tp-dummy.network',
e2aea43f 1550 '25-l2tp.network',
cff83db9
YW
1551 '25-l2tp-ip.netdev',
1552 '25-l2tp-udp.netdev']
1553
1554 l2tp_tunnel_ids = [ '10' ]
1555
1556 def setUp(self):
ad78d7b0 1557 remove_l2tp_tunnels(self.l2tp_tunnel_ids)
ec38833c 1558 remove_links(self.links)
aaae5713 1559 stop_networkd(show_logs=False)
cff83db9
YW
1560
1561 def tearDown(self):
ad78d7b0 1562 remove_l2tp_tunnels(self.l2tp_tunnel_ids)
ec38833c
ZJS
1563 remove_links(self.links)
1564 remove_unit_from_networkd_path(self.units)
aaae5713 1565 stop_networkd(show_logs=True)
cff83db9
YW
1566
1567 @expectedFailureIfModuleIsNotAvailable('l2tp_eth')
1568 def test_l2tp_udp(self):
e2aea43f
YW
1569 copy_unit_to_networkd_unit_path('11-dummy.netdev', '25-l2tp-dummy.network',
1570 '25-l2tp-udp.netdev', '25-l2tp.network')
2cf6fdff 1571 start_networkd()
cff83db9 1572
e2aea43f 1573 self.wait_online(['test1:routable', 'l2tp-ses1:degraded', 'l2tp-ses2:degraded'])
cff83db9 1574
371810d1 1575 output = check_output('ip l2tp show tunnel tunnel_id 10')
cff83db9
YW
1576 print(output)
1577 self.assertRegex(output, "Tunnel 10, encap UDP")
1578 self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
1579 self.assertRegex(output, "Peer tunnel 11")
1580 self.assertRegex(output, "UDP source / dest ports: 3000/4000")
1581 self.assertRegex(output, "UDP checksum: enabled")
1582
371810d1 1583 output = check_output('ip l2tp show session tid 10 session_id 15')
cff83db9
YW
1584 print(output)
1585 self.assertRegex(output, "Session 15 in tunnel 10")
1586 self.assertRegex(output, "Peer session 16, tunnel 11")
1587 self.assertRegex(output, "interface name: l2tp-ses1")
1588
371810d1 1589 output = check_output('ip l2tp show session tid 10 session_id 17')
cff83db9
YW
1590 print(output)
1591 self.assertRegex(output, "Session 17 in tunnel 10")
1592 self.assertRegex(output, "Peer session 18, tunnel 11")
1593 self.assertRegex(output, "interface name: l2tp-ses2")
1594
1595 @expectedFailureIfModuleIsNotAvailable('l2tp_ip')
1596 def test_l2tp_ip(self):
e2aea43f
YW
1597 copy_unit_to_networkd_unit_path('11-dummy.netdev', '25-l2tp-dummy.network',
1598 '25-l2tp-ip.netdev', '25-l2tp.network')
2cf6fdff 1599 start_networkd()
cff83db9 1600
e2aea43f 1601 self.wait_online(['test1:routable', 'l2tp-ses3:degraded', 'l2tp-ses4:degraded'])
cff83db9 1602
371810d1 1603 output = check_output('ip l2tp show tunnel tunnel_id 10')
cff83db9
YW
1604 print(output)
1605 self.assertRegex(output, "Tunnel 10, encap IP")
1606 self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
1607 self.assertRegex(output, "Peer tunnel 12")
1608
371810d1 1609 output = check_output('ip l2tp show session tid 10 session_id 25')
cff83db9
YW
1610 print(output)
1611 self.assertRegex(output, "Session 25 in tunnel 10")
1612 self.assertRegex(output, "Peer session 26, tunnel 12")
1613 self.assertRegex(output, "interface name: l2tp-ses3")
1614
371810d1 1615 output = check_output('ip l2tp show session tid 10 session_id 27')
cff83db9
YW
1616 print(output)
1617 self.assertRegex(output, "Session 27 in tunnel 10")
1618 self.assertRegex(output, "Peer session 28, tunnel 12")
1619 self.assertRegex(output, "interface name: l2tp-ses4")
1620
be68c2c9 1621class NetworkdNetworkTests(unittest.TestCase, Utilities):
09ea6724
YW
1622 links = [
1623 'bond199',
1624 'dummy98',
cd65d067 1625 'dummy99',
74761cf3 1626 'gretun97',
fb2ba330 1627 'ip6gretun97',
086bcf5d
YW
1628 'test1',
1629 'veth99',
40afe491 1630 'vrf99',
74761cf3 1631 ]
09ea6724
YW
1632
1633 units = [
1634 '11-dummy.netdev',
1635 '12-dummy.netdev',
1636 '23-active-slave.network',
1e498853 1637 '24-keep-configuration-static.network',
fdcd1ec5 1638 '24-search-domain.network',
dc7d3c5f
YW
1639 '25-address-dad-veth-peer.network',
1640 '25-address-dad-veth99.network',
09ea6724 1641 '25-address-link-section.network',
e4783b54 1642 '25-address-preferred-lifetime-zero.network',
b8102725 1643 '25-address-static.network',
cd65d067 1644 '25-bind-carrier.network',
09ea6724
YW
1645 '25-bond-active-backup-slave.netdev',
1646 '25-fibrule-invert.network',
1647 '25-fibrule-port-range.network',
6be8e78e 1648 '25-fibrule-uidrange.network',
74761cf3 1649 '25-gre-tunnel-remote-any.netdev',
fb2ba330 1650 '25-ip6gre-tunnel-remote-any.netdev',
09ea6724 1651 '25-ipv6-address-label-section.network',
ef3c8a92
YW
1652 '25-link-local-addressing-no.network',
1653 '25-link-local-addressing-yes.network',
1654 '25-link-section-unmanaged.network',
e4a71bf3 1655 '25-neighbor-section.network',
d1bdafd2 1656 '25-neighbor-next.network',
fb2ba330 1657 '25-neighbor-ipv6.network',
74761cf3
YW
1658 '25-neighbor-ip-dummy.network',
1659 '25-neighbor-ip.network',
086bcf5d 1660 '25-nexthop.network',
f6c6af38 1661 '25-qdisc-cake.network',
f1de1eb3 1662 '25-qdisc-clsact-and-htb.network',
557fa421 1663 '25-qdisc-drr.network',
970ab1fc 1664 '25-qdisc-hhf.network',
ab9dc1db 1665 '25-qdisc-ingress-netem-compat.network',
be94e591 1666 '25-qdisc-pie.network',
20ca06a6 1667 '25-route-ipv6-src.network',
0ef830cf 1668 '25-route-static.network',
40afe491 1669 '25-route-vrf.network',
0b1cd3e2
WKI
1670 '25-gateway-static.network',
1671 '25-gateway-next-static.network',
4da33154 1672 '25-sysctl-disable-ipv6.network',
09ea6724 1673 '25-sysctl.network',
9bacf431 1674 '25-test1.network',
086bcf5d
YW
1675 '25-veth-peer.network',
1676 '25-veth.netdev',
40afe491 1677 '25-vrf.netdev',
7b3770a7 1678 '26-link-local-addressing-ipv6.network',
b677774d 1679 'routing-policy-rule-dummy98.network',
b8102725 1680 'routing-policy-rule-test1.network']
1f0e3109 1681
65c24cd0 1682 routing_policy_rule_tables = ['7', '8', '9']
5f68a6a4 1683 routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
95c74b0a 1684
1f0e3109 1685 def setUp(self):
ec38833c
ZJS
1686 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
1687 remove_routes(self.routes)
1688 remove_links(self.links)
aaae5713 1689 stop_networkd(show_logs=False)
1f0e3109
SS
1690
1691 def tearDown(self):
ec38833c
ZJS
1692 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
1693 remove_routes(self.routes)
1694 remove_links(self.links)
1695 remove_unit_from_networkd_path(self.units)
aaae5713 1696 stop_networkd(show_logs=True)
1f0e3109 1697
b8102725 1698 def test_address_static(self):
ec38833c 1699 copy_unit_to_networkd_unit_path('25-address-static.network', '12-dummy.netdev')
2cf6fdff 1700 start_networkd()
b8102725 1701
e2aea43f 1702 self.wait_online(['dummy98:routable'])
b8102725 1703
371810d1 1704 output = check_output('ip -4 address show dev dummy98')
b8102725
YW
1705 print(output)
1706 self.assertRegex(output, 'inet 10.1.2.3/16 brd 10.1.255.255 scope global dummy98')
1707 self.assertRegex(output, 'inet 10.1.2.4/16 brd 10.1.255.255 scope global secondary dummy98')
1708 self.assertRegex(output, 'inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98')
1709
1710 # invalid sections
1711 self.assertNotRegex(output, '10.10.0.1/16')
1712 self.assertNotRegex(output, '10.10.0.2/16')
1713
371810d1 1714 output = check_output('ip -4 address show dev dummy98 label 32')
b8102725
YW
1715 self.assertRegex(output, 'inet 10.3.2.3/16 brd 10.3.255.255 scope global 32')
1716
371810d1 1717 output = check_output('ip -4 address show dev dummy98 label 33')
b8102725
YW
1718 self.assertRegex(output, 'inet 10.4.2.3 peer 10.4.2.4/16 scope global 33')
1719
371810d1 1720 output = check_output('ip -4 address show dev dummy98 label 34')
b8102725
YW
1721 self.assertRegex(output, 'inet 192.168.[0-9]*.1/24 brd 192.168.[0-9]*.255 scope global 34')
1722
371810d1 1723 output = check_output('ip -4 address show dev dummy98 label 35')
b8102725
YW
1724 self.assertRegex(output, 'inet 172.[0-9]*.0.1/16 brd 172.[0-9]*.255.255 scope global 35')
1725
371810d1 1726 output = check_output('ip -6 address show dev dummy98')
b8102725
YW
1727 print(output)
1728 self.assertRegex(output, 'inet6 2001:db8:0:f101::15/64 scope global')
1729 self.assertRegex(output, 'inet6 2001:db8:0:f101::16/64 scope global')
1730 self.assertRegex(output, 'inet6 2001:db8:0:f102::15/64 scope global')
1731 self.assertRegex(output, 'inet6 2001:db8:0:f102::16/64 scope global')
1732 self.assertRegex(output, 'inet6 2001:db8:0:f103::20 peer 2001:db8:0:f103::10/128 scope global')
1733 self.assertRegex(output, 'inet6 fd[0-9a-f:]*1/64 scope global')
1734
1735 def test_address_preferred_lifetime_zero_ipv6(self):
e4783b54 1736 copy_unit_to_networkd_unit_path('25-address-preferred-lifetime-zero.network', '12-dummy.netdev')
01943d43 1737 start_networkd(5)
1f0e3109 1738
e4783b54 1739 self.wait_online(['dummy98:routable'])
b8102725 1740
371810d1 1741 output = check_output('ip address show dummy98')
b8102725
YW
1742 print(output)
1743 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
1744 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
1f0e3109 1745
e4783b54
YW
1746 output = check_output('ip route show dev dummy98')
1747 print(output)
1748 self.assertRegex(output, 'default via 20.20.20.1 proto static')
1749
dc7d3c5f
YW
1750 def test_address_dad(self):
1751 copy_unit_to_networkd_unit_path('25-address-dad-veth99.network', '25-address-dad-veth-peer.network',
1752 '25-veth.netdev')
1753 start_networkd()
1754 self.wait_online(['veth99:routable', 'veth-peer:degraded'])
1755
1756 output = check_output('ip -4 address show dev veth99')
1757 print(output)
1758 self.assertRegex(output, '192.168.100.10/24')
1759
1760 output = check_output('ip -4 address show dev veth-peer')
1761 print(output)
1762 self.assertNotRegex(output, '192.168.100.10/24')
1763
1f0e3109 1764 def test_configure_without_carrier(self):
9bacf431 1765 copy_unit_to_networkd_unit_path('11-dummy.netdev')
2cf6fdff 1766 start_networkd()
9bacf431
DS
1767 self.wait_operstate('test1', 'off', '')
1768 check_output('ip link set dev test1 up carrier off')
1769
1770 copy_unit_to_networkd_unit_path('25-test1.network.d/configure-without-carrier.conf', dropins=False)
1771 restart_networkd()
1772 self.wait_online(['test1:no-carrier'])
1773
1774 carrier_map = {'on': '1', 'off': '0'}
1775 routable_map = {'on': 'routable', 'off': 'no-carrier'}
1776 for carrier in ['off', 'on', 'off']:
1777 with self.subTest(carrier=carrier):
1778 if carrier_map[carrier] != read_link_attr('test1', 'carrier'):
1779 check_output(f'ip link set dev test1 carrier {carrier}')
1780 self.wait_online([f'test1:{routable_map[carrier]}'])
1781
1782 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
1783 print(output)
1784 self.assertRegex(output, '192.168.0.15')
1785 self.assertRegex(output, '192.168.0.1')
1786 self.assertRegex(output, routable_map[carrier])
e40a58b5 1787
9bacf431
DS
1788 def test_configure_without_carrier_yes_ignore_carrier_loss_no(self):
1789 copy_unit_to_networkd_unit_path('11-dummy.netdev')
1790 start_networkd()
1791 self.wait_operstate('test1', 'off', '')
1792 check_output('ip link set dev test1 up carrier off')
1793
1794 copy_unit_to_networkd_unit_path('25-test1.network')
1795 restart_networkd()
1796 self.wait_online(['test1:no-carrier'])
1797
1798 carrier_map = {'on': '1', 'off': '0'}
1799 routable_map = {'on': 'routable', 'off': 'no-carrier'}
1800 for (carrier, have_config) in [('off', True), ('on', True), ('off', False)]:
1801 with self.subTest(carrier=carrier, have_config=have_config):
1802 if carrier_map[carrier] != read_link_attr('test1', 'carrier'):
1803 check_output(f'ip link set dev test1 carrier {carrier}')
1804 self.wait_online([f'test1:{routable_map[carrier]}'])
1805
1806 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
1807 print(output)
1808 if have_config:
1809 self.assertRegex(output, '192.168.0.15')
1810 self.assertRegex(output, '192.168.0.1')
1811 else:
1812 self.assertNotRegex(output, '192.168.0.15')
1813 self.assertNotRegex(output, '192.168.0.1')
1814 self.assertRegex(output, routable_map[carrier])
1f0e3109 1815
1f0e3109 1816 def test_routing_policy_rule(self):
ec38833c 1817 copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev')
2cf6fdff 1818 start_networkd()
e2aea43f 1819 self.wait_online(['test1:degraded'])
e40a58b5 1820
65c24cd0 1821 output = check_output('ip rule list iif test1 priority 111')
1f0e3109 1822 print(output)
65c24cd0 1823 self.assertRegex(output, '111:')
1f0e3109 1824 self.assertRegex(output, 'from 192.168.100.18')
426654d7 1825 self.assertRegex(output, r'tos (0x08|throughput)\s')
1f0e3109
SS
1826 self.assertRegex(output, 'iif test1')
1827 self.assertRegex(output, 'oif test1')
1828 self.assertRegex(output, 'lookup 7')
1829
65c24cd0
YW
1830 output = check_output('ip rule list iif test1 priority 101')
1831 print(output)
1832 self.assertRegex(output, '101:')
1833 self.assertRegex(output, 'from all')
1834 self.assertRegex(output, 'iif test1')
1835 self.assertRegex(output, 'lookup 9')
1836
1837 output = check_output('ip -6 rule list iif test1 priority 100')
1838 print(output)
1839 self.assertRegex(output, '100:')
1840 self.assertRegex(output, 'from all')
1841 self.assertRegex(output, 'iif test1')
1842 self.assertRegex(output, 'lookup 8')
1843
1844 output = check_output('ip -6 rule list iif test1 priority 101')
1845 print(output)
1846 self.assertRegex(output, '101:')
1847 self.assertRegex(output, 'from all')
1848 self.assertRegex(output, 'iif test1')
1849 self.assertRegex(output, 'lookup 9')
1850
b677774d 1851 def test_routing_policy_rule_issue_11280(self):
ec38833c
ZJS
1852 copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev',
1853 'routing-policy-rule-dummy98.network', '12-dummy.netdev')
b677774d 1854
b677774d
YW
1855 for trial in range(3):
1856 # Remove state files only first time
e2aea43f
YW
1857 start_networkd(3)
1858 self.wait_online(['test1:degraded', 'dummy98:degraded'])
df7f9afa 1859 time.sleep(1)
b677774d 1860
371810d1 1861 output = check_output('ip rule list table 7')
b677774d 1862 print(output)
426654d7 1863 self.assertRegex(output, '111: from 192.168.100.18 tos (0x08|throughput) iif test1 oif test1 lookup 7')
b677774d 1864
371810d1 1865 output = check_output('ip rule list table 8')
b677774d 1866 print(output)
426654d7 1867 self.assertRegex(output, '112: from 192.168.101.18 tos (0x08|throughput) iif dummy98 oif dummy98 lookup 8')
b677774d 1868
aaae5713
YW
1869 stop_networkd(remove_state_files=False)
1870
d586a2c3 1871 @expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
926062f0 1872 def test_routing_policy_rule_port_range(self):
ec38833c 1873 copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
2cf6fdff 1874 start_networkd()
e2aea43f 1875 self.wait_online(['test1:degraded'])
e40a58b5 1876
371810d1 1877 output = check_output('ip rule')
926062f0
SS
1878 print(output)
1879 self.assertRegex(output, '111')
1880 self.assertRegex(output, 'from 192.168.100.18')
1881 self.assertRegex(output, '1123-1150')
1882 self.assertRegex(output, '3224-3290')
1883 self.assertRegex(output, 'tcp')
1884 self.assertRegex(output, 'lookup 7')
1f0e3109 1885
d586a2c3 1886 @expectedFailureIfRoutingPolicyIPProtoIsNotAvailable()
efecf9cd 1887 def test_routing_policy_rule_invert(self):
ec38833c 1888 copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
2cf6fdff 1889 start_networkd()
e2aea43f 1890 self.wait_online(['test1:degraded'])
e40a58b5 1891
371810d1 1892 output = check_output('ip rule')
efecf9cd 1893 print(output)
efecf9cd
SS
1894 self.assertRegex(output, '111')
1895 self.assertRegex(output, 'not.*?from.*?192.168.100.18')
1896 self.assertRegex(output, 'tcp')
1897 self.assertRegex(output, 'lookup 7')
1898
6be8e78e
YW
1899 @expectedFailureIfRoutingPolicyUIDRangeIsNotAvailable()
1900 def test_routing_policy_rule_uidrange(self):
1901 copy_unit_to_networkd_unit_path('25-fibrule-uidrange.network', '11-dummy.netdev')
1902 start_networkd()
1903 self.wait_online(['test1:degraded'])
1904
1905 output = check_output('ip rule')
1906 print(output)
1907 self.assertRegex(output, '111')
1908 self.assertRegex(output, 'from 192.168.100.18')
1909 self.assertRegex(output, 'lookup 7')
1910 self.assertRegex(output, 'uidrange 100-200')
1911
0ef830cf 1912 def test_route_static(self):
ec38833c 1913 copy_unit_to_networkd_unit_path('25-route-static.network', '12-dummy.netdev')
2cf6fdff 1914 start_networkd()
e2aea43f
YW
1915 self.wait_online(['dummy98:routable'])
1916
fc79e6ff 1917 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
e2aea43f 1918 print(output)
0d34228f 1919
6d60f9db 1920 print('### ip -6 route show dev dummy98')
371810d1 1921 output = check_output('ip -6 route show dev dummy98')
0d34228f 1922 print(output)
0ef830cf
YW
1923 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff proto static')
1924 self.assertRegex(output, '2001:1234:5:8f63::1 proto kernel')
1f0e3109 1925
6d60f9db 1926 print('### ip -6 route show dev dummy98 default')
371810d1 1927 output = check_output('ip -6 route show dev dummy98 default')
6d60f9db 1928 print(output)
0ef830cf 1929 self.assertRegex(output, 'default via 2001:1234:5:8fff:ff:ff:ff:ff proto static metric 1024 pref medium')
1f0e3109 1930
6d60f9db 1931 print('### ip -4 route show dev dummy98')
371810d1 1932 output = check_output('ip -4 route show dev dummy98')
1f0e3109 1933 print(output)
0ef830cf
YW
1934 self.assertRegex(output, '149.10.124.48/28 proto kernel scope link src 149.10.124.58')
1935 self.assertRegex(output, '149.10.124.64 proto static scope link')
2b00dff8 1936 self.assertRegex(output, '169.254.0.0/16 proto static scope link metric 2048')
0ef830cf
YW
1937 self.assertRegex(output, '192.168.1.1 proto static initcwnd 20')
1938 self.assertRegex(output, '192.168.1.2 proto static initrwnd 30')
6d60f9db 1939 self.assertRegex(output, 'multicast 149.10.123.4 proto static')
1f0e3109 1940
6d60f9db 1941 print('### ip -4 route show dev dummy98 default')
371810d1 1942 output = check_output('ip -4 route show dev dummy98 default')
6d60f9db 1943 print(output)
0ef830cf
YW
1944 self.assertRegex(output, 'default via 149.10.125.65 proto static onlink')
1945 self.assertRegex(output, 'default via 149.10.124.64 proto static')
6543b7fd 1946 self.assertRegex(output, 'default proto static')
1f0e3109 1947
6d60f9db
YW
1948 print('### ip -4 route show table local dev dummy98')
1949 output = check_output('ip -4 route show table local dev dummy98')
1950 print(output)
1951 self.assertRegex(output, 'local 149.10.123.1 proto static scope host')
1952 self.assertRegex(output, 'anycast 149.10.123.2 proto static scope link')
1953 self.assertRegex(output, 'broadcast 149.10.123.3 proto static scope link')
1954
1955 print('### ip route show type blackhole')
371810d1 1956 output = check_output('ip route show type blackhole')
1f0e3109 1957 print(output)
0ef830cf 1958 self.assertRegex(output, 'blackhole 202.54.1.2 proto static')
f5050e48 1959
6d60f9db 1960 print('### ip route show type unreachable')
371810d1 1961 output = check_output('ip route show type unreachable')
f5050e48 1962 print(output)
0ef830cf 1963 self.assertRegex(output, 'unreachable 202.54.1.3 proto static')
f5050e48 1964
6d60f9db 1965 print('### ip route show type prohibit')
371810d1 1966 output = check_output('ip route show type prohibit')
f5050e48 1967 print(output)
0ef830cf 1968 self.assertRegex(output, 'prohibit 202.54.1.4 proto static')
f5050e48 1969
a0ce990e
YW
1970 print('### ip route show 192.168.10.1')
1971 output = check_output('ip route show 192.168.10.1')
1972 print(output)
1973 self.assertRegex(output, '192.168.10.1 proto static')
1974 self.assertRegex(output, 'nexthop via 149.10.124.59 dev dummy98 weight 10')
1975 self.assertRegex(output, 'nexthop via 149.10.124.60 dev dummy98 weight 5')
1976
1977 print('### ip route show 192.168.10.2')
1978 output = check_output('ip route show 192.168.10.2')
1979 print(output)
1980 # old ip command does not show IPv6 gateways...
1981 self.assertRegex(output, '192.168.10.2 proto static')
1982 self.assertRegex(output, 'nexthop')
1983 self.assertRegex(output, 'dev dummy98 weight 10')
1984 self.assertRegex(output, 'dev dummy98 weight 5')
1985
1986 print('### ip -6 route show 2001:1234:5:7fff:ff:ff:ff:ff')
1987 output = check_output('ip -6 route show 2001:1234:5:7fff:ff:ff:ff:ff')
1988 print(output)
1989 # old ip command does not show 'nexthop' keyword and weight...
1990 self.assertRegex(output, '2001:1234:5:7fff:ff:ff:ff:ff')
1991 self.assertRegex(output, 'via 2001:1234:5:8fff:ff:ff:ff:ff dev dummy98')
1992 self.assertRegex(output, 'via 2001:1234:5:9fff:ff:ff:ff:ff dev dummy98')
1993
40afe491
YW
1994 @expectedFailureIfModuleIsNotAvailable('vrf')
1995 def test_route_vrf(self):
1996 copy_unit_to_networkd_unit_path('25-route-vrf.network', '12-dummy.netdev',
1997 '25-vrf.netdev', '25-vrf.network')
1998 start_networkd()
1999 self.wait_online(['dummy98:routable', 'vrf99:carrier'])
2000
2001 output = check_output('ip route show vrf vrf99')
2002 print(output)
2003 self.assertRegex(output, 'default via 192.168.100.1')
2004
2005 output = check_output('ip route show')
2006 print(output)
2007 self.assertNotRegex(output, 'default via 192.168.100.1')
2008
0b1cd3e2
WKI
2009 def test_gateway_reconfigure(self):
2010 copy_unit_to_networkd_unit_path('25-gateway-static.network', '12-dummy.netdev')
2011 start_networkd()
2012 self.wait_online(['dummy98:routable'])
2013 print('### ip -4 route show dev dummy98 default')
2014 output = check_output('ip -4 route show dev dummy98 default')
2015 print(output)
2016 self.assertRegex(output, 'default via 149.10.124.59 proto static')
2017 self.assertNotRegex(output, '149.10.124.60')
2018
2019 remove_unit_from_networkd_path(['25-gateway-static.network'])
2020 copy_unit_to_networkd_unit_path('25-gateway-next-static.network')
2021 restart_networkd(3)
2022 self.wait_online(['dummy98:routable'])
2023 print('### ip -4 route show dev dummy98 default')
2024 output = check_output('ip -4 route show dev dummy98 default')
2025 print(output)
2026 self.assertNotRegex(output, '149.10.124.59')
2027 self.assertRegex(output, 'default via 149.10.124.60 proto static')
2028
20ca06a6
DA
2029 def test_ip_route_ipv6_src_route(self):
2030 # a dummy device does not make the addresses go through tentative state, so we
2031 # reuse a bond from an earlier test, which does make the addresses go through
2032 # tentative state, and do our test on that
ec38833c 2033 copy_unit_to_networkd_unit_path('23-active-slave.network', '25-route-ipv6-src.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
2cf6fdff 2034 start_networkd()
e2aea43f 2035 self.wait_online(['dummy98:enslaved', 'bond199:routable'])
20ca06a6 2036
371810d1 2037 output = check_output('ip -6 route list dev bond199')
20ca06a6
DA
2038 print(output)
2039 self.assertRegex(output, 'abcd::/16')
2040 self.assertRegex(output, 'src')
2041 self.assertRegex(output, '2001:1234:56:8f63::2')
2042
1f0e3109 2043 def test_ip_link_mac_address(self):
ec38833c 2044 copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
2cf6fdff 2045 start_networkd()
e2aea43f 2046 self.wait_online(['dummy98:degraded'])
1f0e3109 2047
371810d1 2048 output = check_output('ip link show dummy98')
1f0e3109
SS
2049 print(output)
2050 self.assertRegex(output, '00:01:02:aa:bb:cc')
2051
2052 def test_ip_link_unmanaged(self):
ec38833c 2053 copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
df7f9afa 2054 start_networkd(5)
1f0e3109 2055
e39cc445 2056 self.check_link_exists('dummy98')
1f0e3109 2057
19cf3143 2058 self.wait_operstate('dummy98', 'off', setup_state='unmanaged')
1f0e3109
SS
2059
2060 def test_ipv6_address_label(self):
ec38833c 2061 copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
2cf6fdff 2062 start_networkd()
e2aea43f 2063 self.wait_online(['dummy98:degraded'])
1f0e3109 2064
371810d1 2065 output = check_output('ip addrlabel list')
1f0e3109
SS
2066 print(output)
2067 self.assertRegex(output, '2004:da8:1::/64')
2068
d86f5c19 2069 def test_neighbor_section(self):
ec38833c 2070 copy_unit_to_networkd_unit_path('25-neighbor-section.network', '12-dummy.netdev')
2cf6fdff 2071 start_networkd()
e2aea43f 2072 self.wait_online(['dummy98:degraded'], timeout='40s')
e4a71bf3 2073
d1bdafd2 2074 print('### ip neigh list dev dummy98')
df7f9afa 2075 output = check_output('ip neigh list dev dummy98')
e4a71bf3
WKI
2076 print(output)
2077 self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
094b5479 2078 self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
e4a71bf3 2079
d1bdafd2
WKI
2080 def test_neighbor_reconfigure(self):
2081 copy_unit_to_networkd_unit_path('25-neighbor-section.network', '12-dummy.netdev')
2082 start_networkd()
2083 self.wait_online(['dummy98:degraded'], timeout='40s')
2084
2085 print('### ip neigh list dev dummy98')
2086 output = check_output('ip neigh list dev dummy98')
2087 print(output)
2088 self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
2089 self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
2090
2091 remove_unit_from_networkd_path(['25-neighbor-section.network'])
2092 copy_unit_to_networkd_unit_path('25-neighbor-next.network')
2093 restart_networkd(3)
2094 self.wait_online(['dummy98:degraded'], timeout='40s')
2095 print('### ip neigh list dev dummy98')
2096 output = check_output('ip neigh list dev dummy98')
2097 print(output)
2098 self.assertNotRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
2099 self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:66.*PERMANENT')
2100 self.assertNotRegex(output, '2004:da8:1::1.*PERMANENT')
2101
74761cf3 2102 def test_neighbor_gre(self):
fb2ba330
YW
2103 copy_unit_to_networkd_unit_path('25-neighbor-ip.network', '25-neighbor-ipv6.network', '25-neighbor-ip-dummy.network',
2104 '12-dummy.netdev', '25-gre-tunnel-remote-any.netdev', '25-ip6gre-tunnel-remote-any.netdev')
74761cf3 2105 start_networkd()
fb2ba330 2106 self.wait_online(['dummy98:degraded', 'gretun97:routable', 'ip6gretun97:routable'], timeout='40s')
74761cf3
YW
2107
2108 output = check_output('ip neigh list dev gretun97')
2109 print(output)
2110 self.assertRegex(output, '10.0.0.22 lladdr 10.65.223.239 PERMANENT')
fb2ba330
YW
2111
2112 output = check_output('ip neigh list dev ip6gretun97')
2113 print(output)
2114 self.assertRegex(output, '2001:db8:0:f102::17 lladdr 2a:?00:ff:?de:45:?67:ed:?de:[0:]*:49:?88 PERMANENT')
74761cf3 2115
05514ae1 2116 def test_link_local_addressing(self):
ec38833c
ZJS
2117 copy_unit_to_networkd_unit_path('25-link-local-addressing-yes.network', '11-dummy.netdev',
2118 '25-link-local-addressing-no.network', '12-dummy.netdev')
2cf6fdff 2119 start_networkd()
e2aea43f 2120 self.wait_online(['test1:degraded', 'dummy98:carrier'])
05514ae1 2121
371810d1 2122 output = check_output('ip address show dev test1')
05514ae1
YW
2123 print(output)
2124 self.assertRegex(output, 'inet .* scope link')
2125 self.assertRegex(output, 'inet6 .* scope link')
2126
371810d1 2127 output = check_output('ip address show dev dummy98')
05514ae1
YW
2128 print(output)
2129 self.assertNotRegex(output, 'inet6* .* scope link')
2130
05514ae1
YW
2131 '''
2132 Documentation/networking/ip-sysctl.txt
2133
2134 addr_gen_mode - INTEGER
2135 Defines how link-local and autoconf addresses are generated.
2136
2137 0: generate address based on EUI64 (default)
2138 1: do no generate a link-local address, use EUI64 for addresses generated
2139 from autoconf
2140 2: generate stable privacy addresses, using the secret from
2141 stable_secret (RFC7217)
2142 3: generate stable privacy addresses, using a random secret if unset
2143 '''
2144
2145 test1_addr_gen_mode = ''
2146 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')):
2147 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')) as f:
2148 try:
2149 f.readline()
2150 except IOError:
2151 # if stable_secret is unset, then EIO is returned
2152 test1_addr_gen_mode = '0'
2153 else:
2154 test1_addr_gen_mode = '2'
2155 else:
2156 test1_addr_gen_mode = '0'
2157
2158 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'addr_gen_mode')):
ec38833c 2159 self.assertEqual(read_ipv6_sysctl_attr('test1', 'addr_gen_mode'), test1_addr_gen_mode)
05514ae1
YW
2160
2161 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'dummy98'), 'addr_gen_mode')):
ec38833c 2162 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'addr_gen_mode'), '1')
05514ae1 2163
7b3770a7
YW
2164 def test_link_local_addressing_remove_ipv6ll(self):
2165 copy_unit_to_networkd_unit_path('26-link-local-addressing-ipv6.network', '12-dummy.netdev')
2166 start_networkd()
2167 self.wait_online(['dummy98:degraded'])
2168
2169 output = check_output('ip address show dev dummy98')
2170 print(output)
2171 self.assertRegex(output, 'inet6 .* scope link')
2172
2173 copy_unit_to_networkd_unit_path('25-link-local-addressing-no.network')
2174 restart_networkd(1)
2175 self.wait_online(['dummy98:carrier'])
2176
2177 output = check_output('ip address show dev dummy98')
2178 print(output)
2179 self.assertNotRegex(output, 'inet6* .* scope link')
2180
1f0e3109 2181 def test_sysctl(self):
ec38833c 2182 copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
2cf6fdff 2183 start_networkd()
e2aea43f 2184 self.wait_online(['dummy98:degraded'])
ec38833c
ZJS
2185
2186 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
2187 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
2188 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
2189 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
2190 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
2191 self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
2192 self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
1f0e3109 2193
4da33154 2194 def test_sysctl_disable_ipv6(self):
ec38833c 2195 copy_unit_to_networkd_unit_path('25-sysctl-disable-ipv6.network', '12-dummy.netdev')
4da33154
YW
2196
2197 print('## Disable ipv6')
cefd6b3d
ZJS
2198 check_output('sysctl net.ipv6.conf.all.disable_ipv6=1')
2199 check_output('sysctl net.ipv6.conf.default.disable_ipv6=1')
4da33154 2200
2cf6fdff 2201 start_networkd()
e2aea43f 2202 self.wait_online(['dummy98:routable'])
4da33154 2203
371810d1 2204 output = check_output('ip -4 address show dummy98')
4da33154
YW
2205 print(output)
2206 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
371810d1 2207 output = check_output('ip -6 address show dummy98')
4da33154 2208 print(output)
57ad7607
ZJS
2209 self.assertRegex(output, 'inet6 2607:5300:203:3906::/64 scope global')
2210 self.assertRegex(output, 'inet6 .* scope link')
4933b97d
YW
2211 output = check_output('ip -4 route show dev dummy98')
2212 print(output)
2213 self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
2214 output = check_output('ip -6 route show dev dummy98')
2215 print(output)
57ad7607 2216 self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
4da33154 2217
cefd6b3d 2218 check_output('ip link del dummy98')
4da33154
YW
2219
2220 print('## Enable ipv6')
cefd6b3d
ZJS
2221 check_output('sysctl net.ipv6.conf.all.disable_ipv6=0')
2222 check_output('sysctl net.ipv6.conf.default.disable_ipv6=0')
4da33154 2223
e2aea43f
YW
2224 restart_networkd(3)
2225 self.wait_online(['dummy98:routable'])
4da33154 2226
371810d1 2227 output = check_output('ip -4 address show dummy98')
4da33154
YW
2228 print(output)
2229 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
371810d1 2230 output = check_output('ip -6 address show dummy98')
4da33154 2231 print(output)
4933b97d 2232 self.assertRegex(output, 'inet6 2607:5300:203:3906::/64 scope global')
4da33154 2233 self.assertRegex(output, 'inet6 .* scope link')
4933b97d
YW
2234 output = check_output('ip -4 route show dev dummy98')
2235 print(output)
2236 self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
2237 output = check_output('ip -6 route show dev dummy98')
2238 print(output)
2239 self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
4da33154 2240
cd65d067 2241 def test_bind_carrier(self):
bc942f69
YW
2242 check_output('ip link add dummy98 type dummy')
2243 check_output('ip link set dummy98 up')
2244 time.sleep(2)
2245
ec38833c 2246 copy_unit_to_networkd_unit_path('25-bind-carrier.network', '11-dummy.netdev')
2cf6fdff 2247 start_networkd()
e2aea43f 2248 self.wait_online(['test1:routable'])
cd65d067 2249
371810d1 2250 output = check_output('ip address show test1')
cd65d067
YW
2251 print(output)
2252 self.assertRegex(output, 'UP,LOWER_UP')
2253 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
19cf3143 2254 self.wait_operstate('test1', 'routable')
cd65d067 2255
cefd6b3d
ZJS
2256 check_output('ip link add dummy99 type dummy')
2257 check_output('ip link set dummy99 up')
b117044c 2258 time.sleep(2)
371810d1 2259 output = check_output('ip address show test1')
cd65d067
YW
2260 print(output)
2261 self.assertRegex(output, 'UP,LOWER_UP')
2262 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
19cf3143 2263 self.wait_operstate('test1', 'routable')
cd65d067 2264
cefd6b3d 2265 check_output('ip link del dummy98')
b117044c 2266 time.sleep(2)
371810d1 2267 output = check_output('ip address show test1')
cd65d067
YW
2268 print(output)
2269 self.assertRegex(output, 'UP,LOWER_UP')
2270 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
19cf3143 2271 self.wait_operstate('test1', 'routable')
cd65d067 2272
bc942f69 2273 check_output('ip link set dummy99 down')
b117044c 2274 time.sleep(2)
371810d1 2275 output = check_output('ip address show test1')
cd65d067
YW
2276 print(output)
2277 self.assertNotRegex(output, 'UP,LOWER_UP')
2278 self.assertRegex(output, 'DOWN')
2279 self.assertNotRegex(output, '192.168.10')
19cf3143 2280 self.wait_operstate('test1', 'off')
cd65d067 2281
bc942f69 2282 check_output('ip link set dummy99 up')
b117044c 2283 time.sleep(2)
371810d1 2284 output = check_output('ip address show test1')
cd65d067
YW
2285 print(output)
2286 self.assertRegex(output, 'UP,LOWER_UP')
2287 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
19cf3143 2288 self.wait_operstate('test1', 'routable')
cd65d067 2289
fdcd1ec5 2290 def test_domain(self):
ec38833c 2291 copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network')
2cf6fdff 2292 start_networkd()
e2aea43f 2293 self.wait_online(['dummy98:routable'])
fdcd1ec5 2294
fc79e6ff 2295 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
fdcd1ec5
YW
2296 print(output)
2297 self.assertRegex(output, 'Address: 192.168.42.100')
2298 self.assertRegex(output, 'DNS: 192.168.42.1')
2299 self.assertRegex(output, 'Search Domains: one')
2300
1e498853
YW
2301 def test_keep_configuration_static(self):
2302 check_output('systemctl stop systemd-networkd')
2303
2304 check_output('ip link add name dummy98 type dummy')
2305 check_output('ip address add 10.1.2.3/16 dev dummy98')
2306 check_output('ip address add 10.2.3.4/16 dev dummy98 valid_lft 600 preferred_lft 500')
2307 output = check_output('ip address show dummy98')
2308 print(output)
2309 self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
2310 self.assertRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
2311 output = check_output('ip route show dev dummy98')
2312 print(output)
2313
2314 copy_unit_to_networkd_unit_path('24-keep-configuration-static.network')
2cf6fdff 2315 start_networkd()
e2aea43f 2316 self.wait_online(['dummy98:routable'])
1e498853
YW
2317
2318 output = check_output('ip address show dummy98')
2319 print(output)
2320 self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
2321 self.assertNotRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
2322
086bcf5d
YW
2323 @expectedFailureIfNexthopIsNotAvailable()
2324 def test_nexthop(self):
2325 copy_unit_to_networkd_unit_path('25-nexthop.network', '25-veth.netdev', '25-veth-peer.network')
2326 start_networkd()
2327 self.wait_online(['veth99:routable', 'veth-peer:routable'])
2328
2329 output = check_output('ip nexthop list dev veth99')
2330 print(output)
2331 self.assertRegex(output, '192.168.5.1')
2332
ef3c8a92 2333 def test_qdisc(self):
f1de1eb3
YW
2334 copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
2335 '25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
2336 check_output('modprobe sch_teql max_equalizers=2')
ef3c8a92
YW
2337 start_networkd()
2338
1b628c4f 2339 self.wait_online(['dummy98:routable', 'test1:routable'])
ef3c8a92 2340
f1de1eb3
YW
2341 output = check_output('tc qdisc show dev test1')
2342 print(output)
2343 self.assertRegex(output, 'qdisc netem')
2344 self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%')
2345 self.assertRegex(output, 'qdisc ingress')
2346
ef3c8a92
YW
2347 output = check_output('tc qdisc show dev dummy98')
2348 print(output)
f1de1eb3
YW
2349 self.assertRegex(output, 'qdisc clsact')
2350
2351 self.assertRegex(output, 'qdisc htb 2: root')
2352 self.assertRegex(output, r'default (0x30|30)')
2353
2354 self.assertRegex(output, 'qdisc netem 30: parent 2:30')
ef3c8a92 2355 self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%')
40821c2a 2356 self.assertRegex(output, 'qdisc fq_codel')
9401e488 2357 self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10.0ms ce_threshold 100.0ms interval 200.0ms memory_limit 64Mb ecn')
ef3c8a92 2358
f1de1eb3 2359 self.assertRegex(output, 'qdisc teql1 31: parent 2:31')
0baddbd5 2360
f1de1eb3 2361 self.assertRegex(output, 'qdisc fq 32: parent 2:32')
a05a6e8b
YW
2362 self.assertRegex(output, 'limit 1000p flow_limit 200p buckets 512 orphan_mask 511')
2363 self.assertRegex(output, 'quantum 1500')
2364 self.assertRegex(output, 'initial_quantum 13000')
2365 self.assertRegex(output, 'maxrate 1Mbit')
ab9dc1db 2366
f1de1eb3 2367 self.assertRegex(output, 'qdisc codel 33: parent 2:33')
a3d35654 2368 self.assertRegex(output, 'limit 2000p target 10.0ms ce_threshold 100.0ms interval 50.0ms ecn')
ab9dc1db 2369
f1de1eb3
YW
2370 self.assertRegex(output, 'qdisc fq_codel 34: parent 2:34')
2371 self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10.0ms ce_threshold 100.0ms interval 200.0ms memory_limit 64Mb ecn')
ab9dc1db 2372
f1de1eb3
YW
2373 self.assertRegex(output, 'qdisc tbf 35: parent 2:35')
2374 self.assertRegex(output, 'rate 1Gbit burst 5000b peakrate 100Gbit minburst 987500b lat 70.0ms')
ab9dc1db 2375
f1de1eb3
YW
2376 self.assertRegex(output, 'qdisc sfq 36: parent 2:36')
2377 self.assertRegex(output, 'perturb 5sec')
3d55b5a9 2378
bc0769c9
YW
2379 self.assertRegex(output, 'qdisc pfifo 37: parent 2:37')
2380 self.assertRegex(output, 'limit 100000p')
2381
95edcf3f
YW
2382 self.assertRegex(output, 'qdisc gred 38: parent 2:38')
2383 self.assertRegex(output, 'vqs 12 default 10 grio')
2384
f2c5c129
YW
2385 self.assertRegex(output, 'qdisc sfb 39: parent 2:39')
2386 self.assertRegex(output, 'limit 200000')
2387
7b1a31a3
YW
2388 self.assertRegex(output, 'qdisc bfifo 3a: parent 2:3a')
2389 self.assertRegex(output, 'limit 1000000')
2390
73136507
YW
2391 self.assertRegex(output, 'qdisc pfifo_head_drop 3b: parent 2:3b')
2392 self.assertRegex(output, 'limit 1023p')
2393
41bb371b
YW
2394 self.assertRegex(output, 'qdisc pfifo_fast 3c: parent 2:3c')
2395
f1de1eb3 2396 output = check_output('tc class show dev dummy98')
ab9dc1db 2397 print(output)
f1de1eb3
YW
2398 self.assertRegex(output, 'class htb 2:30 root leaf 30:')
2399 self.assertRegex(output, 'class htb 2:31 root leaf 31:')
2400 self.assertRegex(output, 'class htb 2:32 root leaf 32:')
2401 self.assertRegex(output, 'class htb 2:33 root leaf 33:')
2402 self.assertRegex(output, 'class htb 2:34 root leaf 34:')
2403 self.assertRegex(output, 'class htb 2:35 root leaf 35:')
2404 self.assertRegex(output, 'class htb 2:36 root leaf 36:')
bc0769c9 2405 self.assertRegex(output, 'class htb 2:37 root leaf 37:')
95edcf3f 2406 self.assertRegex(output, 'class htb 2:38 root leaf 38:')
f2c5c129 2407 self.assertRegex(output, 'class htb 2:39 root leaf 39:')
7b1a31a3 2408 self.assertRegex(output, 'class htb 2:3a root leaf 3a:')
73136507 2409 self.assertRegex(output, 'class htb 2:3b root leaf 3b:')
41bb371b 2410 self.assertRegex(output, 'class htb 2:3c root leaf 3c:')
f1de1eb3 2411 self.assertRegex(output, 'prio 1 rate 1Mbit ceil 500Kbit')
0baddbd5 2412
557fa421
YW
2413 def test_qdisc2(self):
2414 copy_unit_to_networkd_unit_path('25-qdisc-drr.network', '12-dummy.netdev')
2415 start_networkd()
2416
2417 self.wait_online(['dummy98:routable'])
2418
2419 output = check_output('tc qdisc show dev dummy98')
2420 print(output)
2421 self.assertRegex(output, 'qdisc drr 2: root')
2422 output = check_output('tc class show dev dummy98')
2423 print(output)
2424 self.assertRegex(output, 'class drr 2:30 root quantum 2000b')
2425
f6c6af38
YW
2426 @expectedFailureIfCAKEIsNotAvailable()
2427 def test_qdisc_cake(self):
2428 copy_unit_to_networkd_unit_path('25-qdisc-cake.network', '12-dummy.netdev')
3d55b5a9 2429 start_networkd()
3d55b5a9
YW
2430 self.wait_online(['dummy98:routable'])
2431
2432 output = check_output('tc qdisc show dev dummy98')
2433 print(output)
f6c6af38
YW
2434 self.assertRegex(output, 'qdisc cake 3a: root')
2435 self.assertRegex(output, 'bandwidth 500Mbit')
2436 self.assertRegex(output, 'overhead 128')
3d55b5a9 2437
be94e591
YW
2438 @expectedFailureIfPIEIsNotAvailable()
2439 def test_qdisc_pie(self):
2440 copy_unit_to_networkd_unit_path('25-qdisc-pie.network', '12-dummy.netdev')
2441 start_networkd()
2442 self.wait_online(['dummy98:routable'])
2443
2444 output = check_output('tc qdisc show dev dummy98')
2445 print(output)
2446 self.assertRegex(output, 'qdisc pie 3a: root')
2447 self.assertRegex(output, 'limit 200000')
2448
970ab1fc
YW
2449 @expectedFailureIfHHFIsNotAvailable()
2450 def test_qdisc_hhf(self):
2451 copy_unit_to_networkd_unit_path('25-qdisc-hhf.network', '12-dummy.netdev')
2452 start_networkd()
2453 self.wait_online(['dummy98:routable'])
2454
2455 output = check_output('tc qdisc show dev dummy98')
2456 print(output)
2457 self.assertRegex(output, 'qdisc hhf 3a: root')
2458 self.assertRegex(output, 'limit 1022p')
2459
336d18f0
YW
2460class NetworkdStateFileTests(unittest.TestCase, Utilities):
2461 links = [
2462 'dummy98',
2463 ]
2464
2465 units = [
2466 '12-dummy.netdev',
2467 'state-file-tests.network',
2468 ]
2469
2470 def setUp(self):
2471 remove_links(self.links)
2472 stop_networkd(show_logs=False)
2473
2474 def tearDown(self):
2475 remove_links(self.links)
2476 remove_unit_from_networkd_path(self.units)
2477 stop_networkd(show_logs=True)
2478
2479 def test_state_file(self):
2480 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'state-file-tests.network')
2481 start_networkd()
2482 self.wait_online(['dummy98:routable'])
2483
2484 output = check_output(*networkctl_cmd, '--no-legend', 'list', 'dummy98', env=env)
2485 print(output)
2486 ifindex = output.split()[0]
2487
2488 path = os.path.join('/run/systemd/netif/links/', ifindex)
2489 self.assertTrue(os.path.exists(path))
2490 time.sleep(2)
2491
2492 with open(path) as f:
2493 data = f.read()
2494 self.assertRegex(data, r'ADMIN_STATE=configured')
2495 self.assertRegex(data, r'OPER_STATE=routable')
2496 self.assertRegex(data, r'REQUIRED_FOR_ONLINE=yes')
2497 self.assertRegex(data, r'REQUIRED_OPER_STATE_FOR_ONLINE=routable')
2498 self.assertRegex(data, r'NETWORK_FILE=/run/systemd/network/state-file-tests.network')
2499 self.assertRegex(data, r'DNS=10.10.10.10 10.10.10.11')
2500 self.assertRegex(data, r'NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org')
2501 self.assertRegex(data, r'DOMAINS=hogehoge')
2502 self.assertRegex(data, r'ROUTE_DOMAINS=foofoo')
2503 self.assertRegex(data, r'LLMNR=no')
2504 self.assertRegex(data, r'MDNS=yes')
2505 self.assertRegex(data, r'DNSSEC=no')
426654d7 2506 self.assertRegex(data, r'ADDRESSES=192.168.(10.10|12.12)/24 192.168.(12.12|10.10)/24')
336d18f0
YW
2507
2508 check_output(*resolvectl_cmd, 'dns', 'dummy98', '10.10.10.12', '10.10.10.13', env=env)
2509 check_output(*resolvectl_cmd, 'domain', 'dummy98', 'hogehogehoge', '~foofoofoo', env=env)
2510 check_output(*resolvectl_cmd, 'llmnr', 'dummy98', 'yes', env=env)
2511 check_output(*resolvectl_cmd, 'mdns', 'dummy98', 'no', env=env)
2512 check_output(*resolvectl_cmd, 'dnssec', 'dummy98', 'yes', env=env)
2513 check_output(*timedatectl_cmd, 'ntp-servers', 'dummy98', '2.fedora.pool.ntp.org', '3.fedora.pool.ntp.org', env=env)
2514 time.sleep(2)
2515
2516 with open(path) as f:
2517 data = f.read()
2518 self.assertRegex(data, r'DNS=10.10.10.12 10.10.10.13')
2519 self.assertRegex(data, r'NTP=2.fedora.pool.ntp.org 3.fedora.pool.ntp.org')
2520 self.assertRegex(data, r'DOMAINS=hogehogehoge')
2521 self.assertRegex(data, r'ROUTE_DOMAINS=foofoofoo')
2522 self.assertRegex(data, r'LLMNR=yes')
2523 self.assertRegex(data, r'MDNS=no')
2524 self.assertRegex(data, r'DNSSEC=yes')
2525
2526 check_output(*timedatectl_cmd, 'revert', 'dummy98', env=env)
2527 time.sleep(2)
2528
2529 with open(path) as f:
2530 data = f.read()
2531 self.assertRegex(data, r'DNS=10.10.10.12 10.10.10.13')
2532 self.assertRegex(data, r'NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org')
2533 self.assertRegex(data, r'DOMAINS=hogehogehoge')
2534 self.assertRegex(data, r'ROUTE_DOMAINS=foofoofoo')
2535 self.assertRegex(data, r'LLMNR=yes')
2536 self.assertRegex(data, r'MDNS=no')
2537 self.assertRegex(data, r'DNSSEC=yes')
2538
2539 check_output(*resolvectl_cmd, 'revert', 'dummy98', env=env)
2540 time.sleep(2)
2541
2542 with open(path) as f:
2543 data = f.read()
2544 self.assertRegex(data, r'DNS=10.10.10.10 10.10.10.11')
2545 self.assertRegex(data, r'NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org')
2546 self.assertRegex(data, r'DOMAINS=hogehoge')
2547 self.assertRegex(data, r'ROUTE_DOMAINS=foofoo')
2548 self.assertRegex(data, r'LLMNR=no')
2549 self.assertRegex(data, r'MDNS=yes')
2550 self.assertRegex(data, r'DNSSEC=no')
2551
be68c2c9 2552class NetworkdBondTests(unittest.TestCase, Utilities):
c3a8853f 2553 links = [
c2990ec3 2554 'bond199',
c3a8853f 2555 'bond99',
cc3e488c
YW
2556 'dummy98',
2557 'test1']
c3a8853f
YW
2558
2559 units = [
cc3e488c
YW
2560 '11-dummy.netdev',
2561 '12-dummy.netdev',
c2990ec3
YW
2562 '23-active-slave.network',
2563 '23-bond199.network',
2564 '23-primary-slave.network',
c2990ec3 2565 '25-bond-active-backup-slave.netdev',
c3a8853f 2566 '25-bond.netdev',
c3a8853f 2567 'bond99.network',
cc3e488c 2568 'bond-slave.network']
c3a8853f
YW
2569
2570 def setUp(self):
ec38833c 2571 remove_links(self.links)
aaae5713 2572 stop_networkd(show_logs=False)
c3a8853f
YW
2573
2574 def tearDown(self):
ec38833c
ZJS
2575 remove_links(self.links)
2576 remove_unit_from_networkd_path(self.units)
aaae5713 2577 stop_networkd(show_logs=True)
c3a8853f 2578
c2990ec3 2579 def test_bond_active_slave(self):
ec38833c 2580 copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
2cf6fdff 2581 start_networkd()
e2aea43f 2582 self.wait_online(['dummy98:enslaved', 'bond199:degraded'])
c2990ec3 2583
371810d1 2584 output = check_output('ip -d link show bond199')
c2990ec3
YW
2585 print(output)
2586 self.assertRegex(output, 'active_slave dummy98')
2587
2588 def test_bond_primary_slave(self):
35a78c51 2589 copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
2cf6fdff 2590 start_networkd()
e2aea43f 2591 self.wait_online(['dummy98:enslaved', 'bond199:degraded'])
c2990ec3 2592
371810d1 2593 output = check_output('ip -d link show bond199')
c2990ec3 2594 print(output)
35a78c51 2595 self.assertRegex(output, 'primary dummy98')
c2990ec3 2596
cc3e488c 2597 def test_bond_operstate(self):
ec38833c
ZJS
2598 copy_unit_to_networkd_unit_path('25-bond.netdev', '11-dummy.netdev', '12-dummy.netdev',
2599 'bond99.network','bond-slave.network')
2cf6fdff 2600 start_networkd()
e2aea43f 2601 self.wait_online(['dummy98:enslaved', 'test1:enslaved', 'bond99:routable'])
c3a8853f 2602
371810d1 2603 output = check_output('ip -d link show dummy98')
c3a8853f 2604 print(output)
cc3e488c 2605 self.assertRegex(output, 'SLAVE,UP,LOWER_UP')
c3a8853f 2606
371810d1 2607 output = check_output('ip -d link show test1')
c3a8853f
YW
2608 print(output)
2609 self.assertRegex(output, 'SLAVE,UP,LOWER_UP')
2610
371810d1 2611 output = check_output('ip -d link show bond99')
c3a8853f
YW
2612 print(output)
2613 self.assertRegex(output, 'MASTER,UP,LOWER_UP')
2614
19cf3143
DS
2615 self.wait_operstate('dummy98', 'enslaved')
2616 self.wait_operstate('test1', 'enslaved')
2617 self.wait_operstate('bond99', 'routable')
c3a8853f 2618
cefd6b3d 2619 check_output('ip link set dummy98 down')
c3a8853f 2620
19cf3143
DS
2621 self.wait_operstate('dummy98', 'off')
2622 self.wait_operstate('test1', 'enslaved')
2623 self.wait_operstate('bond99', 'degraded-carrier')
c3a8853f 2624
cefd6b3d 2625 check_output('ip link set dummy98 up')
c3a8853f 2626
19cf3143
DS
2627 self.wait_operstate('dummy98', 'enslaved')
2628 self.wait_operstate('test1', 'enslaved')
2629 self.wait_operstate('bond99', 'routable')
c3a8853f 2630
cefd6b3d
ZJS
2631 check_output('ip link set dummy98 down')
2632 check_output('ip link set test1 down')
cc3e488c 2633
19cf3143
DS
2634 self.wait_operstate('dummy98', 'off')
2635 self.wait_operstate('test1', 'off')
2700d2c7 2636
a4632dc7 2637 if not self.wait_operstate('bond99', 'no-carrier', setup_timeout=30, fail_assert=False):
2700d2c7
YW
2638 # Huh? Kernel does not recognize that all slave interfaces are down?
2639 # Let's confirm that networkd's operstate is consistent with ip's result.
2640 self.assertNotRegex(output, 'NO-CARRIER')
cc3e488c 2641
be68c2c9 2642class NetworkdBridgeTests(unittest.TestCase, Utilities):
09ea6724
YW
2643 links = [
2644 'bridge99',
2645 'dummy98',
2646 'test1']
2647
2648 units = [
2649 '11-dummy.netdev',
2650 '12-dummy.netdev',
2651 '26-bridge.netdev',
2652 '26-bridge-slave-interface-1.network',
2653 '26-bridge-slave-interface-2.network',
6f943798
YW
2654 '26-bridge-vlan-master.network',
2655 '26-bridge-vlan-slave.network',
804b6cd2 2656 'bridge99-ignore-carrier-loss.network',
09ea6724 2657 'bridge99.network']
1f0e3109 2658
8d17c386
YW
2659 routing_policy_rule_tables = ['100']
2660
1f0e3109 2661 def setUp(self):
8d17c386 2662 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
ec38833c 2663 remove_links(self.links)
aaae5713 2664 stop_networkd(show_logs=False)
1f0e3109
SS
2665
2666 def tearDown(self):
8d17c386 2667 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
ec38833c
ZJS
2668 remove_links(self.links)
2669 remove_unit_from_networkd_path(self.units)
aaae5713 2670 stop_networkd(show_logs=True)
1f0e3109 2671
6f943798
YW
2672 def test_bridge_vlan(self):
2673 copy_unit_to_networkd_unit_path('11-dummy.netdev', '26-bridge-vlan-slave.network',
2674 '26-bridge.netdev', '26-bridge-vlan-master.network')
2675 start_networkd()
e2aea43f 2676 self.wait_online(['test1:enslaved', 'bridge99:degraded'])
6f943798
YW
2677
2678 output = check_output('bridge vlan show dev test1')
2679 print(output)
2680 self.assertNotRegex(output, '4063')
2681 for i in range(4064, 4095):
2682 self.assertRegex(output, f'{i}')
2683 self.assertNotRegex(output, '4095')
2684
2685 output = check_output('bridge vlan show dev bridge99')
2686 print(output)
2687 self.assertNotRegex(output, '4059')
2688 for i in range(4060, 4095):
2689 self.assertRegex(output, f'{i}')
2690 self.assertNotRegex(output, '4095')
2691
1f0e3109 2692 def test_bridge_property(self):
ec38833c
ZJS
2693 copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
2694 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
2695 'bridge99.network')
2cf6fdff 2696 start_networkd()
e2aea43f 2697 self.wait_online(['dummy98:enslaved', 'test1:enslaved', 'bridge99:routable'])
1f0e3109 2698
371810d1 2699 output = check_output('ip -d link show test1')
1f0e3109
SS
2700 print(output)
2701 self.assertRegex(output, 'master')
2702 self.assertRegex(output, 'bridge')
2703
371810d1 2704 output = check_output('ip -d link show dummy98')
1f0e3109
SS
2705 print(output)
2706 self.assertRegex(output, 'master')
2707 self.assertRegex(output, 'bridge')
2708
371810d1 2709 output = check_output('ip addr show bridge99')
1f0e3109 2710 print(output)
2be6c5d2 2711 self.assertRegex(output, '192.168.0.15/24')
1f0e3109 2712
371810d1 2713 output = check_output('bridge -d link show dummy98')
1f0e3109 2714 print(output)
ec38833c 2715 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
5424fd95
YW
2716 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
2717 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
ec38833c
ZJS
2718 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
2719 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood'), '0')
5424fd95
YW
2720 # CONFIG_BRIDGE_IGMP_SNOOPING=y
2721 if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
2722 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
7f15b714 2723 if (os.path.exists('/sys/devices/virtual/net/bridge99/lower_dummy98/brport/neigh_suppress')):
ec38833c
ZJS
2724 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress'), '1')
2725 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'learning'), '0')
5424fd95
YW
2726 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'priority'), '23')
2727 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard'), '1')
2728 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'root_block'), '1')
4d7ed14f 2729
5424fd95
YW
2730 output = check_output('bridge -d link show test1')
2731 print(output)
2732 self.assertEqual(read_bridge_port_attr('bridge99', 'test1', 'priority'), '0')
1f0e3109 2733
371810d1 2734 check_output('ip address add 192.168.0.16/24 dev bridge99')
804b6cd2
YW
2735 time.sleep(1)
2736
371810d1 2737 output = check_output('ip addr show bridge99')
2be6c5d2
YW
2738 print(output)
2739 self.assertRegex(output, '192.168.0.16/24')
2740
e3cbaeab
YW
2741 # for issue #6088
2742 print('### ip -6 route list table all dev bridge99')
2743 output = check_output('ip -6 route list table all dev bridge99')
2744 print(output)
2745 self.assertRegex(output, 'ff00::/8 table local metric 256 pref medium')
2746
371810d1 2747 self.assertEqual(call('ip link del test1'), 0)
2be6c5d2 2748
19cf3143 2749 self.wait_operstate('bridge99', 'degraded-carrier')
2be6c5d2 2750
cefd6b3d 2751 check_output('ip link del dummy98')
804b6cd2 2752
19cf3143 2753 self.wait_operstate('bridge99', 'no-carrier')
2be6c5d2 2754
371810d1 2755 output = check_output('ip address show bridge99')
804b6cd2
YW
2756 print(output)
2757 self.assertRegex(output, 'NO-CARRIER')
2758 self.assertNotRegex(output, '192.168.0.15/24')
2759 self.assertNotRegex(output, '192.168.0.16/24')
2760
e3cbaeab
YW
2761 print('### ip -6 route list table all dev bridge99')
2762 output = check_output('ip -6 route list table all dev bridge99')
2763 print(output)
426654d7 2764 self.assertRegex(output, 'ff00::/8 table local metric 256 (linkdown )?pref medium')
e3cbaeab 2765
804b6cd2 2766 def test_bridge_ignore_carrier_loss(self):
ec38833c
ZJS
2767 copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
2768 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
2769 'bridge99-ignore-carrier-loss.network')
2cf6fdff 2770 start_networkd()
e2aea43f 2771 self.wait_online(['dummy98:enslaved', 'test1:enslaved', 'bridge99:routable'])
804b6cd2 2772
371810d1 2773 check_output('ip address add 192.168.0.16/24 dev bridge99')
804b6cd2
YW
2774 time.sleep(1)
2775
371810d1
ZJS
2776 check_output('ip link del test1')
2777 check_output('ip link del dummy98')
804b6cd2
YW
2778 time.sleep(3)
2779
371810d1 2780 output = check_output('ip address show bridge99')
804b6cd2
YW
2781 print(output)
2782 self.assertRegex(output, 'NO-CARRIER')
2783 self.assertRegex(output, 'inet 192.168.0.15/24 brd 192.168.0.255 scope global bridge99')
2784 self.assertRegex(output, 'inet 192.168.0.16/24 scope global secondary bridge99')
2785
6609924c 2786 def test_bridge_ignore_carrier_loss_frequent_loss_and_gain(self):
ec38833c
ZJS
2787 copy_unit_to_networkd_unit_path('26-bridge.netdev', '26-bridge-slave-interface-1.network',
2788 'bridge99-ignore-carrier-loss.network')
2cf6fdff 2789 start_networkd()
e2aea43f 2790 self.wait_online(['bridge99:no-carrier'])
6609924c 2791
90e3bcbd
YW
2792 for trial in range(4):
2793 check_output('ip link add dummy98 type dummy')
2794 check_output('ip link set dummy98 up')
2795 if trial < 3:
2796 check_output('ip link del dummy98')
6609924c 2797
e2aea43f 2798 self.wait_online(['bridge99:routable', 'dummy98:enslaved'])
6609924c 2799
371810d1 2800 output = check_output('ip address show bridge99')
6609924c
YW
2801 print(output)
2802 self.assertRegex(output, 'inet 192.168.0.15/24 brd 192.168.0.255 scope global bridge99')
2803
371810d1 2804 output = check_output('ip rule list table 100')
6609924c
YW
2805 print(output)
2806 self.assertEqual(output, '0: from all to 8.8.8.8 lookup 100')
2807
be68c2c9 2808class NetworkdLLDPTests(unittest.TestCase, Utilities):
1f0e3109
SS
2809 links = ['veth99']
2810
09ea6724
YW
2811 units = [
2812 '23-emit-lldp.network',
2813 '24-lldp.network',
2814 '25-veth.netdev']
1f0e3109
SS
2815
2816 def setUp(self):
ec38833c 2817 remove_links(self.links)
aaae5713 2818 stop_networkd(show_logs=False)
1f0e3109
SS
2819
2820 def tearDown(self):
ec38833c
ZJS
2821 remove_links(self.links)
2822 remove_unit_from_networkd_path(self.units)
aaae5713 2823 stop_networkd(show_logs=True)
1f0e3109
SS
2824
2825 def test_lldp(self):
ec38833c 2826 copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
2cf6fdff 2827 start_networkd()
e2aea43f 2828 self.wait_online(['veth99:degraded', 'veth-peer:degraded'])
1f0e3109 2829
371810d1 2830 output = check_output(*networkctl_cmd, 'lldp', env=env)
1f0e3109
SS
2831 print(output)
2832 self.assertRegex(output, 'veth-peer')
2833 self.assertRegex(output, 'veth99')
2834
be68c2c9 2835class NetworkdRATests(unittest.TestCase, Utilities):
1f0e3109
SS
2836 links = ['veth99']
2837
09ea6724
YW
2838 units = [
2839 '25-veth.netdev',
2840 'ipv6-prefix.network',
87bbebea 2841 'ipv6-prefix-veth.network',
e2c4070e 2842 'ipv6-prefix-veth-token-static.network',
b241fa00 2843 'ipv6-prefix-veth-token-static-explicit.network',
c24c83dc 2844 'ipv6-prefix-veth-token-static-multiple.network',
87bbebea 2845 'ipv6-prefix-veth-token-prefixstable.network']
1f0e3109
SS
2846
2847 def setUp(self):
ec38833c 2848 remove_links(self.links)
aaae5713 2849 stop_networkd(show_logs=False)
1f0e3109
SS
2850
2851 def tearDown(self):
ec38833c
ZJS
2852 remove_links(self.links)
2853 remove_unit_from_networkd_path(self.units)
aaae5713 2854 stop_networkd(show_logs=True)
1f0e3109
SS
2855
2856 def test_ipv6_prefix_delegation(self):
ec38833c 2857 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
2cf6fdff 2858 start_networkd()
e2aea43f 2859 self.wait_online(['veth99:routable', 'veth-peer:degraded'])
1f0e3109 2860
41fd8fe7
YW
2861 output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
2862 print(output)
2863 self.assertRegex(output, 'fe80::')
2864 self.assertRegex(output, '2002:da8:1::1')
2865
fc79e6ff 2866 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109
SS
2867 print(output)
2868 self.assertRegex(output, '2002:da8:1:0')
2869
e2c4070e
YW
2870 def test_ipv6_token_static(self):
2871 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-static.network')
87bbebea 2872 start_networkd()
b241fa00
KF
2873 self.wait_online(['veth99:routable', 'veth-peer:degraded'])
2874
2875 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
2876 print(output)
2877 self.assertRegex(output, '2002:da8:1:0:1a:2b:3c:4d')
2878
2879 def test_ipv6_token_static_explicit(self):
2880 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-static-explicit.network')
2881 start_networkd()
87bbebea
YW
2882 self.wait_online(['veth99:routable', 'veth-peer:degraded'])
2883
2884 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
2885 print(output)
2886 self.assertRegex(output, '2002:da8:1:0:1a:2b:3c:4d')
2887
c24c83dc
KF
2888 def test_ipv6_token_static_multiple(self):
2889 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-static-multiple.network')
2890 start_networkd()
2891 self.wait_online(['veth99:routable', 'veth-peer:degraded'])
2892
2893 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
2894 print(output)
2895 self.assertRegex(output, '2002:da8:1:0:1a:2b:3c:4d')
2896 self.assertRegex(output, '2002:da8:1:0:fa:de:ca:fe')
2897
87bbebea
YW
2898 def test_ipv6_token_prefixstable(self):
2899 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-prefixstable.network')
2900 start_networkd()
2901 self.wait_online(['veth99:routable', 'veth-peer:degraded'])
2902
2903 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
2904 print(output)
2905 self.assertRegex(output, '2002:da8:1:0')
2906
be68c2c9 2907class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
fdcd1ec5 2908 links = ['veth99']
09ea6724
YW
2909
2910 units = [
09ea6724
YW
2911 '25-veth.netdev',
2912 'dhcp-client.network',
2913 'dhcp-client-timezone-router.network',
2914 'dhcp-server.network',
2915 'dhcp-server-timezone-router.network']
1f0e3109
SS
2916
2917 def setUp(self):
ec38833c 2918 remove_links(self.links)
aaae5713 2919 stop_networkd(show_logs=False)
1f0e3109
SS
2920
2921 def tearDown(self):
ec38833c
ZJS
2922 remove_links(self.links)
2923 remove_unit_from_networkd_path(self.units)
aaae5713 2924 stop_networkd(show_logs=True)
1f0e3109
SS
2925
2926 def test_dhcp_server(self):
ec38833c 2927 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
2cf6fdff 2928 start_networkd()
e2aea43f 2929 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2930
fc79e6ff 2931 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109
SS
2932 print(output)
2933 self.assertRegex(output, '192.168.5.*')
2934 self.assertRegex(output, 'Gateway: 192.168.5.1')
2935 self.assertRegex(output, 'DNS: 192.168.5.1')
2936 self.assertRegex(output, 'NTP: 192.168.5.1')
2937
1f0e3109 2938 def test_emit_router_timezone(self):
ec38833c 2939 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
2cf6fdff 2940 start_networkd()
e2aea43f 2941 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2942
fc79e6ff 2943 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109
SS
2944 print(output)
2945 self.assertRegex(output, 'Gateway: 192.168.5.*')
2946 self.assertRegex(output, '192.168.5.*')
2947 self.assertRegex(output, 'Europe/Berlin')
2948
be68c2c9 2949class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
09ea6724 2950 links = [
18c613dc
YW
2951 'veth99',
2952 'vrf99']
09ea6724
YW
2953
2954 units = [
2955 '25-veth.netdev',
18c613dc
YW
2956 '25-vrf.netdev',
2957 '25-vrf.network',
09ea6724 2958 'dhcp-client-anonymize.network',
0fd8b718 2959 'dhcp-client-decline.network',
214c5bae
YW
2960 'dhcp-client-gateway-ipv4.network',
2961 'dhcp-client-gateway-ipv6.network',
af3b1498 2962 'dhcp-client-gateway-onlink-implicit.network',
09ea6724
YW
2963 'dhcp-client-ipv4-dhcp-settings.network',
2964 'dhcp-client-ipv4-only-ipv6-disabled.network',
2965 'dhcp-client-ipv4-only.network',
7c0d36ff 2966 'dhcp-client-ipv4-use-routes-use-gateway.network',
09ea6724
YW
2967 'dhcp-client-ipv6-only.network',
2968 'dhcp-client-ipv6-rapid-commit.network',
1e498853
YW
2969 'dhcp-client-keep-configuration-dhcp-on-stop.network',
2970 'dhcp-client-keep-configuration-dhcp.network',
09ea6724 2971 'dhcp-client-listen-port.network',
c1b01a62
YW
2972 'dhcp-client-reassign-static-routes-ipv4.network',
2973 'dhcp-client-reassign-static-routes-ipv6.network',
09ea6724
YW
2974 'dhcp-client-route-metric.network',
2975 'dhcp-client-route-table.network',
e2d5aab3
YW
2976 'dhcp-client-use-dns-ipv4-and-ra.network',
2977 'dhcp-client-use-dns-ipv4.network',
2978 'dhcp-client-use-dns-no.network',
2979 'dhcp-client-use-dns-yes.network',
e0c1341d 2980 'dhcp-client-use-domains.network',
18c613dc 2981 'dhcp-client-vrf.network',
117a55c7
YW
2982 'dhcp-client-with-ipv4ll-fallback-with-dhcp-server.network',
2983 'dhcp-client-with-ipv4ll-fallback-without-dhcp-server.network',
4c882c16 2984 'dhcp-client-with-static-address.network',
3e9d5552 2985 'dhcp-client.network',
0fd8b718 2986 'dhcp-server-decline.network',
09ea6724 2987 'dhcp-server-veth-peer.network',
30d3b54e
YW
2988 'dhcp-v4-server-veth-peer.network',
2989 'static.network']
1f0e3109
SS
2990
2991 def setUp(self):
ec38833c
ZJS
2992 stop_dnsmasq(dnsmasq_pid_file)
2993 remove_links(self.links)
aaae5713 2994 stop_networkd(show_logs=False)
1f0e3109
SS
2995
2996 def tearDown(self):
ec38833c
ZJS
2997 stop_dnsmasq(dnsmasq_pid_file)
2998 remove_lease_file()
2999 remove_log_file()
3000 remove_links(self.links)
3001 remove_unit_from_networkd_path(self.units)
aaae5713 3002 stop_networkd(show_logs=True)
1f0e3109
SS
3003
3004 def test_dhcp_client_ipv6_only(self):
ec38833c 3005 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
1f0e3109 3006
2cf6fdff 3007 start_networkd()
e2aea43f 3008 self.wait_online(['veth-peer:carrier'])
ec38833c 3009 start_dnsmasq()
e2aea43f 3010 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 3011
fc79e6ff 3012 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109
SS
3013 print(output)
3014 self.assertRegex(output, '2600::')
3015 self.assertNotRegex(output, '192.168.5')
3016
3a956d38 3017 # Confirm that ipv6 token is not set in the kernel
371810d1 3018 output = check_output('ip token show dev veth99')
3a956d38
YW
3019 print(output)
3020 self.assertRegex(output, 'token :: dev veth99')
3021
1f0e3109 3022 def test_dhcp_client_ipv4_only(self):
ec38833c 3023 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-only-ipv6-disabled.network')
1f0e3109 3024
2cf6fdff 3025 start_networkd()
e2aea43f 3026 self.wait_online(['veth-peer:carrier'])
195a18c1 3027 start_dnsmasq(additional_options='--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7', lease_time='2m')
e2aea43f 3028 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 3029
fc79e6ff 3030 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109
SS
3031 print(output)
3032 self.assertNotRegex(output, '2600::')
3033 self.assertRegex(output, '192.168.5')
195a18c1
YW
3034 self.assertRegex(output, '192.168.5.6')
3035 self.assertRegex(output, '192.168.5.7')
3036
3037 # checking routes to DNS servers
3038 output = check_output('ip route show dev veth99')
3039 print(output)
3040 self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.181 metric 1024')
3041 self.assertRegex(output, r'192.168.5.6 proto dhcp scope link src 192.168.5.181 metric 1024')
3042 self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
3043
3044 stop_dnsmasq(dnsmasq_pid_file)
3045 start_dnsmasq(additional_options='--dhcp-option=option:dns-server,192.168.5.1,192.168.5.7,192.168.5.8', lease_time='2m')
3046
3047 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
3048 print('Wait for the dynamic address to be renewed')
3049 time.sleep(125)
3050
3051 self.wait_online(['veth99:routable', 'veth-peer:routable'])
3052
fc79e6ff 3053 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
195a18c1
YW
3054 print(output)
3055 self.assertNotRegex(output, '2600::')
3056 self.assertRegex(output, '192.168.5')
3057 self.assertNotRegex(output, '192.168.5.6')
3058 self.assertRegex(output, '192.168.5.7')
3059 self.assertRegex(output, '192.168.5.8')
3060
3061 # checking routes to DNS servers
3062 output = check_output('ip route show dev veth99')
3063 print(output)
3064 self.assertNotRegex(output, r'192.168.5.6')
3065 self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.181 metric 1024')
3066 self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
3067 self.assertRegex(output, r'192.168.5.8 proto dhcp scope link src 192.168.5.181 metric 1024')
1f0e3109 3068
7c0d36ff 3069 def test_dhcp_client_ipv4_use_routes_gateway(self):
06c2b0c7 3070 for (routes, gateway, dnsroutes) in itertools.product([True, False, None], repeat=3):
7c0d36ff 3071 self.setUp()
06c2b0c7
DS
3072 with self.subTest(routes=routes, gateway=gateway, dnsroutes=dnsroutes):
3073 self._test_dhcp_client_ipv4_use_routes_gateway(routes, gateway, dnsroutes)
7c0d36ff
DS
3074 self.tearDown()
3075
06c2b0c7 3076 def _test_dhcp_client_ipv4_use_routes_gateway(self, routes, gateway, dnsroutes):
7c0d36ff
DS
3077 testunit = 'dhcp-client-ipv4-use-routes-use-gateway.network'
3078 testunits = ['25-veth.netdev', 'dhcp-server-veth-peer.network', testunit]
3079 if routes != None:
3080 testunits.append(f'{testunit}.d/use-routes-{routes}.conf');
3081 if gateway != None:
3082 testunits.append(f'{testunit}.d/use-gateway-{gateway}.conf');
06c2b0c7
DS
3083 if dnsroutes != None:
3084 testunits.append(f'{testunit}.d/use-dns-routes-{dnsroutes}.conf');
7c0d36ff 3085 copy_unit_to_networkd_unit_path(*testunits, dropins=False)
4c2e1833
YW
3086
3087 start_networkd()
3088 self.wait_online(['veth-peer:carrier'])
3089 start_dnsmasq(additional_options='--dhcp-option=option:dns-server,192.168.5.6,192.168.5.7', lease_time='2m')
3090 self.wait_online(['veth99:routable', 'veth-peer:routable'])
3091
3092 output = check_output('ip route show dev veth99')
3093 print(output)
4c2e1833 3094
7c0d36ff
DS
3095 # UseRoutes= defaults to true
3096 useroutes = routes in [True, None]
3097 # UseGateway= defaults to useroutes
3098 usegateway = useroutes if gateway == None else gateway
0d7bd445 3099
7c0d36ff
DS
3100 # Check UseRoutes=
3101 if useroutes:
3102 self.assertRegex(output, r'192.168.5.0/24 via 192.168.5.5 proto dhcp src 192.168.5.181 metric 1024')
3103 else:
3104 self.assertNotRegex(output, r'192.168.5.5')
0d7bd445 3105
7c0d36ff
DS
3106 # Check UseGateway=
3107 if usegateway:
3108 self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.181 metric 1024')
3109 else:
3110 self.assertNotRegex(output, r'default via 192.168.5.1')
3111
06c2b0c7
DS
3112 # Check RoutesToDNS=, which defaults to false
3113 if dnsroutes:
7c0d36ff
DS
3114 self.assertRegex(output, r'192.168.5.6 proto dhcp scope link src 192.168.5.181 metric 1024')
3115 self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
3116 else:
3117 self.assertNotRegex(output, r'192.168.5.6')
3118 self.assertNotRegex(output, r'192.168.5.7')
0d7bd445 3119
1f0e3109 3120 def test_dhcp_client_ipv4_ipv6(self):
ec38833c
ZJS
3121 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
3122 'dhcp-client-ipv4-only.network')
2cf6fdff 3123 start_networkd()
e2aea43f 3124 self.wait_online(['veth-peer:carrier'])
ec38833c 3125 start_dnsmasq()
e2aea43f 3126 self.wait_online(['veth99:routable', 'veth-peer:routable'])
2629df47
YW
3127
3128 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79 3129 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3130 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
1f0e3109 3131
fc79e6ff 3132 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109
SS
3133 print(output)
3134 self.assertRegex(output, '2600::')
3135 self.assertRegex(output, '192.168.5')
3136
3137 def test_dhcp_client_settings(self):
ec38833c 3138 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
1f0e3109 3139
2cf6fdff 3140 start_networkd()
e2aea43f 3141 self.wait_online(['veth-peer:carrier'])
ec38833c 3142 start_dnsmasq()
e2aea43f 3143 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 3144
0ae7a66d 3145 print('## ip address show dev veth99')
371810d1 3146 output = check_output('ip address show dev veth99')
1f0e3109
SS
3147 print(output)
3148 self.assertRegex(output, '12:34:56:78:9a:bc')
3149 self.assertRegex(output, '192.168.5')
3150 self.assertRegex(output, '1492')
3151
0ae7a66d 3152 print('## ip route show table main dev veth99')
371810d1 3153 output = check_output('ip route show table main dev veth99')
1f0e3109 3154 print(output)
156ddf8d 3155 # See issue #8726
dd9b10c8
YW
3156 main_table_is_empty = output == ''
3157 if not main_table_is_empty:
3158 self.assertNotRegex(output, 'proto dhcp')
1f0e3109 3159
0ae7a66d 3160 print('## ip route show table 211 dev veth99')
371810d1 3161 output = check_output('ip route show table 211 dev veth99')
0ae7a66d
YW
3162 print(output)
3163 self.assertRegex(output, 'default via 192.168.5.1 proto dhcp')
dd9b10c8
YW
3164 if main_table_is_empty:
3165 self.assertRegex(output, '192.168.5.0/24 proto dhcp')
0ae7a66d
YW
3166 self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 proto dhcp')
3167 self.assertRegex(output, '192.168.5.1 proto dhcp scope link')
3168
3169 print('## dnsmasq log')
ec38833c
ZJS
3170 self.assertTrue(search_words_in_dnsmasq_log('vendor class: SusantVendorTest', True))
3171 self.assertTrue(search_words_in_dnsmasq_log('DHCPDISCOVER(veth-peer) 12:34:56:78:9a:bc'))
3172 self.assertTrue(search_words_in_dnsmasq_log('client provides name: test-hostname'))
3173 self.assertTrue(search_words_in_dnsmasq_log('26:mtu'))
1f0e3109
SS
3174
3175 def test_dhcp6_client_settings_rapidcommit_true(self):
ec38833c 3176 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
2cf6fdff 3177 start_networkd()
e2aea43f 3178 self.wait_online(['veth-peer:carrier'])
ec38833c 3179 start_dnsmasq()
e2aea43f 3180 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 3181
371810d1 3182 output = check_output('ip address show dev veth99')
1f0e3109
SS
3183 print(output)
3184 self.assertRegex(output, '12:34:56:78:9a:bc')
ec38833c 3185 self.assertTrue(search_words_in_dnsmasq_log('14:rapid-commit', True))
1f0e3109
SS
3186
3187 def test_dhcp6_client_settings_rapidcommit_false(self):
ec38833c 3188 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
2cf6fdff 3189 start_networkd()
e2aea43f 3190 self.wait_online(['veth-peer:carrier'])
ec38833c 3191 start_dnsmasq()
e2aea43f 3192 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 3193
371810d1 3194 output = check_output('ip address show dev veth99')
1f0e3109
SS
3195 print(output)
3196 self.assertRegex(output, '12:34:56:78:9a:bc')
ec38833c 3197 self.assertFalse(search_words_in_dnsmasq_log('14:rapid-commit', True))
1f0e3109
SS
3198
3199 def test_dhcp_client_settings_anonymize(self):
ec38833c 3200 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
2cf6fdff 3201 start_networkd()
e2aea43f 3202 self.wait_online(['veth-peer:carrier'])
ec38833c 3203 start_dnsmasq()
e2aea43f 3204 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 3205
ec38833c
ZJS
3206 self.assertFalse(search_words_in_dnsmasq_log('VendorClassIdentifier=SusantVendorTest', True))
3207 self.assertFalse(search_words_in_dnsmasq_log('test-hostname'))
3208 self.assertFalse(search_words_in_dnsmasq_log('26:mtu'))
1f0e3109
SS
3209
3210 def test_dhcp_client_listen_port(self):
ec38833c 3211 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
2cf6fdff 3212 start_networkd()
e2aea43f 3213 self.wait_online(['veth-peer:carrier'])
ec38833c 3214 start_dnsmasq('--dhcp-alternate-port=67,5555')
e2aea43f 3215 self.wait_online(['veth99:routable', 'veth-peer:routable'])
2629df47 3216
371810d1 3217 output = check_output('ip -4 address show dev veth99')
b412fce8
YW
3218 print(output)
3219 self.assertRegex(output, '192.168.5.* dynamic')
1f0e3109 3220
4c882c16
YW
3221 def test_dhcp_client_with_static_address(self):
3222 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network',
3223 'dhcp-client-with-static-address.network')
3224 start_networkd()
e2aea43f 3225 self.wait_online(['veth-peer:carrier'])
4c882c16 3226 start_dnsmasq()
e2aea43f 3227 self.wait_online(['veth99:routable', 'veth-peer:routable'])
4c882c16
YW
3228
3229 output = check_output('ip address show dev veth99 scope global')
3230 print(output)
3231 self.assertRegex(output, r'inet 192.168.5.250/24 brd 192.168.5.255 scope global veth99')
3232 self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global secondary dynamic veth99')
3233
3234 output = check_output('ip route show dev veth99')
3235 print(output)
3236 self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
3237 self.assertRegex(output, r'192.168.5.0/24 proto kernel scope link src 192.168.5.250')
3238 self.assertRegex(output, r'192.168.5.0/24 via 192.168.5.5 proto dhcp src 192.168.5.[0-9]* metric 1024')
3239 self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
3240
1f0e3109 3241 def test_dhcp_route_table_id(self):
ec38833c 3242 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
2cf6fdff 3243 start_networkd()
e2aea43f 3244 self.wait_online(['veth-peer:carrier'])
ec38833c 3245 start_dnsmasq()
e2aea43f 3246 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 3247
371810d1 3248 output = check_output('ip route show table 12')
1f0e3109 3249 print(output)
1f0e3109
SS
3250 self.assertRegex(output, 'veth99 proto dhcp')
3251 self.assertRegex(output, '192.168.5.1')
3252
3253 def test_dhcp_route_metric(self):
ec38833c 3254 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
2cf6fdff 3255 start_networkd()
e2aea43f 3256 self.wait_online(['veth-peer:carrier'])
ec38833c 3257 start_dnsmasq()
e2aea43f 3258 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 3259
371810d1 3260 output = check_output('ip route show dev veth99')
1f0e3109 3261 print(output)
1f0e3109
SS
3262 self.assertRegex(output, 'metric 24')
3263
c1b01a62 3264 def test_dhcp_client_reassign_static_routes_ipv4(self):
c38d2d4d 3265 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
c1b01a62 3266 'dhcp-client-reassign-static-routes-ipv4.network')
c38d2d4d 3267 start_networkd()
e2aea43f 3268 self.wait_online(['veth-peer:carrier'])
c38d2d4d 3269 start_dnsmasq(lease_time='2m')
e2aea43f 3270 self.wait_online(['veth99:routable', 'veth-peer:routable'])
c38d2d4d
YW
3271
3272 output = check_output('ip address show dev veth99 scope global')
3273 print(output)
3274 self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
3275
3276 output = check_output('ip route show dev veth99')
3277 print(output)
3278 self.assertRegex(output, r'192.168.5.0/24 proto kernel scope link src 192.168.5.[0-9]*')
3279 self.assertRegex(output, r'192.168.5.0/24 proto static')
3280 self.assertRegex(output, r'192.168.6.0/24 proto static')
3281 self.assertRegex(output, r'192.168.7.0/24 proto static')
3282
c1b01a62
YW
3283 stop_dnsmasq(dnsmasq_pid_file)
3284 start_dnsmasq(ipv4_range='192.168.5.210,192.168.5.220', lease_time='2m')
3285
c38d2d4d
YW
3286 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
3287 print('Wait for the dynamic address to be renewed')
3288 time.sleep(125)
3289
e2aea43f 3290 self.wait_online(['veth99:routable'])
c38d2d4d
YW
3291
3292 output = check_output('ip route show dev veth99')
3293 print(output)
3294 self.assertRegex(output, r'192.168.5.0/24 proto kernel scope link src 192.168.5.[0-9]*')
3295 self.assertRegex(output, r'192.168.5.0/24 proto static')
3296 self.assertRegex(output, r'192.168.6.0/24 proto static')
3297 self.assertRegex(output, r'192.168.7.0/24 proto static')
3298
c1b01a62
YW
3299 def test_dhcp_client_reassign_static_routes_ipv6(self):
3300 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3301 'dhcp-client-reassign-static-routes-ipv6.network')
3302 start_networkd()
e2aea43f 3303 self.wait_online(['veth-peer:carrier'])
c1b01a62 3304 start_dnsmasq(lease_time='2m')
e2aea43f 3305 self.wait_online(['veth99:routable', 'veth-peer:routable'])
c1b01a62
YW
3306
3307 output = check_output('ip address show dev veth99 scope global')
3308 print(output)
426654d7 3309 self.assertRegex(output, r'inet6 2600::[0-9a-f]*/128 scope global (noprefixroute dynamic|dynamic noprefixroute)')
c1b01a62
YW
3310
3311 output = check_output('ip -6 route show dev veth99')
3312 print(output)
3313 self.assertRegex(output, r'2600::/64 proto ra metric 1024')
3314 self.assertRegex(output, r'2600:0:0:1::/64 proto static metric 1024 pref medium')
3315
3316 stop_dnsmasq(dnsmasq_pid_file)
3317 start_dnsmasq(ipv6_range='2600::30,2600::40', lease_time='2m')
3318
3319 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
3320 print('Wait for the dynamic address to be renewed')
3321 time.sleep(125)
3322
e2aea43f 3323 self.wait_online(['veth99:routable'])
c1b01a62
YW
3324
3325 output = check_output('ip -6 route show dev veth99')
3326 print(output)
3327 self.assertRegex(output, r'2600::/64 proto ra metric 1024')
3328 self.assertRegex(output, r'2600:0:0:1::/64 proto static metric 1024 pref medium')
3329
1e498853
YW
3330 def test_dhcp_keep_configuration_dhcp(self):
3331 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp.network')
2cf6fdff 3332 start_networkd()
e2aea43f 3333 self.wait_online(['veth-peer:carrier'])
1e498853 3334 start_dnsmasq(lease_time='2m')
e2aea43f 3335 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 3336
1e498853
YW
3337 output = check_output('ip address show dev veth99 scope global')
3338 print(output)
3339 self.assertRegex(output, r'192.168.5.*')
3340
fc79e6ff 3341 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109 3342 print(output)
1e498853 3343 self.assertRegex(output, r'192.168.5.*')
e40a58b5 3344
5238e957 3345 # Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
ec38833c 3346 stop_dnsmasq(dnsmasq_pid_file)
1f0e3109
SS
3347
3348 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
1e498853 3349 print('Wait for the dynamic address to be expired')
1f0e3109
SS
3350 time.sleep(125)
3351
1e498853
YW
3352 print('The lease address should be kept after lease expired')
3353 output = check_output('ip address show dev veth99 scope global')
3354 print(output)
3355 self.assertRegex(output, r'192.168.5.*')
3356
fc79e6ff 3357 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1f0e3109 3358 print(output)
1e498853
YW
3359 self.assertRegex(output, r'192.168.5.*')
3360
3361 check_output('systemctl stop systemd-networkd')
3362
3363 print('The lease address should be kept after networkd stopped')
3364 output = check_output('ip address show dev veth99 scope global')
3365 print(output)
3366 self.assertRegex(output, r'192.168.5.*')
3367
fc79e6ff 3368 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1e498853
YW
3369 print(output)
3370 self.assertRegex(output, r'192.168.5.*')
3371
e2aea43f
YW
3372 start_networkd(3)
3373 self.wait_online(['veth-peer:routable'])
1e498853
YW
3374
3375 print('Still the lease address should be kept after networkd restarted')
3376 output = check_output('ip address show dev veth99 scope global')
3377 print(output)
3378 self.assertRegex(output, r'192.168.5.*')
3379
fc79e6ff 3380 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
1e498853
YW
3381 print(output)
3382 self.assertRegex(output, r'192.168.5.*')
3383
3384 def test_dhcp_keep_configuration_dhcp_on_stop(self):
3385 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp-on-stop.network')
2cf6fdff 3386 start_networkd()
e2aea43f 3387 self.wait_online(['veth-peer:carrier'])
1e498853 3388 start_dnsmasq(lease_time='2m')
e2aea43f 3389 self.wait_online(['veth99:routable', 'veth-peer:routable'])
1e498853
YW
3390
3391 output = check_output('ip address show dev veth99 scope global')
3392 print(output)
3393 self.assertRegex(output, r'192.168.5.*')
3394
3395 stop_dnsmasq(dnsmasq_pid_file)
3396 check_output('systemctl stop systemd-networkd')
3397
3398 output = check_output('ip address show dev veth99 scope global')
3399 print(output)
3400 self.assertRegex(output, r'192.168.5.*')
3401
e2aea43f
YW
3402 restart_networkd(3)
3403 self.wait_online(['veth-peer:routable'])
1e498853
YW
3404
3405 output = check_output('ip address show dev veth99 scope global')
3406 print(output)
3407 self.assertNotRegex(output, r'192.168.5.*')
1f0e3109 3408
30d3b54e 3409 def test_dhcp_client_reuse_address_as_static(self):
ec38833c 3410 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
2cf6fdff 3411 start_networkd()
e2aea43f 3412 self.wait_online(['veth-peer:carrier'])
ec38833c 3413 start_dnsmasq()
e2aea43f 3414 self.wait_online(['veth99:routable', 'veth-peer:routable'])
2629df47
YW
3415
3416 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79 3417 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3418 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
30d3b54e 3419
371810d1 3420 output = check_output('ip address show dev veth99 scope global')
30d3b54e
YW
3421 print(output)
3422 self.assertRegex(output, '192.168.5')
3423 self.assertRegex(output, '2600::')
3424
2629df47
YW
3425 ipv4_address = re.search(r'192.168.5.[0-9]*/24', output)
3426 ipv6_address = re.search(r'2600::[0-9a-f:]*/128', output)
30d3b54e
YW
3427 static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address.group(), 'Address=' + ipv6_address.group()])
3428 print(static_network)
3429
ec38833c 3430 remove_unit_from_networkd_path(['dhcp-client.network'])
30d3b54e
YW
3431
3432 with open(os.path.join(network_unit_file_path, 'static.network'), mode='w') as f:
3433 f.write(static_network)
3434
2629df47
YW
3435 # When networkd started, the links are already configured, so let's wait for 5 seconds
3436 # the links to be re-configured.
aaae5713 3437 restart_networkd(5)
e2aea43f 3438 self.wait_online(['veth99:routable', 'veth-peer:routable'])
30d3b54e 3439
371810d1 3440 output = check_output('ip -4 address show dev veth99 scope global')
30d3b54e
YW
3441 print(output)
3442 self.assertRegex(output, '192.168.5')
3443 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
3444
371810d1 3445 output = check_output('ip -6 address show dev veth99 scope global')
30d3b54e
YW
3446 print(output)
3447 self.assertRegex(output, '2600::')
3448 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
3449
18c613dc
YW
3450 @expectedFailureIfModuleIsNotAvailable('vrf')
3451 def test_dhcp_client_vrf(self):
ec38833c
ZJS
3452 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-vrf.network',
3453 '25-vrf.netdev', '25-vrf.network')
2cf6fdff 3454 start_networkd()
e2aea43f 3455 self.wait_online(['veth-peer:carrier'])
ec38833c 3456 start_dnsmasq()
e2aea43f 3457 self.wait_online(['veth99:routable', 'veth-peer:routable', 'vrf99:carrier'])
2629df47
YW
3458
3459 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79 3460 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3461 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
18c613dc
YW
3462
3463 print('## ip -d link show dev vrf99')
371810d1 3464 output = check_output('ip -d link show dev vrf99')
18c613dc
YW
3465 print(output)
3466 self.assertRegex(output, 'vrf table 42')
3467
3468 print('## ip address show vrf vrf99')
371810d1 3469 output = check_output('ip address show vrf vrf99')
d90f4f7d
YW
3470 print(output)
3471 self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
3472 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
426654d7 3473 self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
d90f4f7d 3474 self.assertRegex(output, 'inet6 .* scope link')
18c613dc
YW
3475
3476 print('## ip address show dev veth99')
371810d1 3477 output = check_output('ip address show dev veth99')
18c613dc 3478 print(output)
18c613dc
YW
3479 self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
3480 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
426654d7 3481 self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
18c613dc
YW
3482 self.assertRegex(output, 'inet6 .* scope link')
3483
3484 print('## ip route show vrf vrf99')
371810d1 3485 output = check_output('ip route show vrf vrf99')
18c613dc
YW
3486 print(output)
3487 self.assertRegex(output, 'default via 192.168.5.1 dev veth99 proto dhcp src 192.168.5.')
18c613dc
YW
3488 self.assertRegex(output, '169.254.0.0/16 dev veth99 proto kernel scope link src 169.254')
3489 self.assertRegex(output, '192.168.5.0/24 dev veth99 proto kernel scope link src 192.168.5')
3490 self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 dev veth99 proto dhcp')
3491 self.assertRegex(output, '192.168.5.1 dev veth99 proto dhcp scope link src 192.168.5')
3492
3493 print('## ip route show table main dev veth99')
371810d1 3494 output = check_output('ip route show table main dev veth99')
18c613dc
YW
3495 print(output)
3496 self.assertEqual(output, '')
3497
214c5bae
YW
3498 def test_dhcp_client_gateway_ipv4(self):
3499 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3500 'dhcp-client-gateway-ipv4.network')
3501 start_networkd()
3502 self.wait_online(['veth-peer:carrier'])
3503 start_dnsmasq()
3504 self.wait_online(['veth99:routable', 'veth-peer:routable'])
3505
3506 output = check_output('ip route list dev veth99 10.0.0.0/8')
3507 print(output)
3508 self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto static')
3509
3510 def test_dhcp_client_gateway_ipv6(self):
3511 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3512 'dhcp-client-gateway-ipv6.network')
3513 start_networkd()
3514 self.wait_online(['veth-peer:carrier'])
3515 start_dnsmasq()
3516 self.wait_online(['veth99:routable', 'veth-peer:routable'])
3517
3518 output = check_output('ip -6 route list dev veth99 2001:1234:5:9fff:ff:ff:ff:ff')
3519 print(output)
3520 self.assertRegex(output, 'via fe80::1034:56ff:fe78:9abd')
3521
af3b1498 3522 def test_dhcp_client_gateway_onlink_implicit(self):
ec38833c
ZJS
3523 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3524 'dhcp-client-gateway-onlink-implicit.network')
2cf6fdff 3525 start_networkd()
e2aea43f 3526 self.wait_online(['veth-peer:carrier'])
ec38833c 3527 start_dnsmasq()
e2aea43f 3528 self.wait_online(['veth99:routable', 'veth-peer:routable'])
af3b1498 3529
fc79e6ff 3530 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
af3b1498
YW
3531 print(output)
3532 self.assertRegex(output, '192.168.5')
3533
371810d1 3534 output = check_output('ip route list dev veth99 10.0.0.0/8')
af3b1498
YW
3535 print(output)
3536 self.assertRegex(output, 'onlink')
371810d1 3537 output = check_output('ip route list dev veth99 192.168.100.0/24')
af3b1498
YW
3538 print(output)
3539 self.assertRegex(output, 'onlink')
3540
117a55c7 3541 def test_dhcp_client_with_ipv4ll_fallback_with_dhcp_server(self):
ec38833c
ZJS
3542 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3543 'dhcp-client-with-ipv4ll-fallback-with-dhcp-server.network')
2cf6fdff 3544 start_networkd()
e2aea43f 3545 self.wait_online(['veth-peer:carrier'])
ec38833c 3546 start_dnsmasq(lease_time='2m')
e2aea43f 3547 self.wait_online(['veth99:routable', 'veth-peer:routable'])
63c598ed 3548
371810d1 3549 output = check_output('ip address show dev veth99')
63c598ed
YW
3550 print(output)
3551
371810d1 3552 output = check_output('ip -6 address show dev veth99 scope global dynamic')
63c598ed 3553 self.assertNotRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic')
371810d1 3554 output = check_output('ip -6 address show dev veth99 scope link')
63c598ed 3555 self.assertRegex(output, 'inet6 .* scope link')
371810d1 3556 output = check_output('ip -4 address show dev veth99 scope global dynamic')
63c598ed 3557 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
371810d1 3558 output = check_output('ip -4 address show dev veth99 scope link')
63c598ed
YW
3559 self.assertNotRegex(output, 'inet .* scope link')
3560
3561 print('Wait for the dynamic address to be expired')
3562 time.sleep(130)
3563
371810d1 3564 output = check_output('ip address show dev veth99')
63c598ed
YW
3565 print(output)
3566
371810d1 3567 output = check_output('ip -6 address show dev veth99 scope global dynamic')
63c598ed 3568 self.assertNotRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic')
371810d1 3569 output = check_output('ip -6 address show dev veth99 scope link')
63c598ed 3570 self.assertRegex(output, 'inet6 .* scope link')
371810d1 3571 output = check_output('ip -4 address show dev veth99 scope global dynamic')
63c598ed 3572 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
371810d1 3573 output = check_output('ip -4 address show dev veth99 scope link')
63c598ed
YW
3574 self.assertNotRegex(output, 'inet .* scope link')
3575
ec38833c 3576 search_words_in_dnsmasq_log('DHCPOFFER', show_all=True)
63c598ed 3577
117a55c7 3578 def test_dhcp_client_with_ipv4ll_fallback_without_dhcp_server(self):
ec38833c
ZJS
3579 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3580 'dhcp-client-with-ipv4ll-fallback-without-dhcp-server.network')
2cf6fdff 3581 start_networkd()
e2aea43f 3582 self.wait_online(['veth99:degraded', 'veth-peer:routable'])
117a55c7 3583
371810d1 3584 output = check_output('ip address show dev veth99')
117a55c7
YW
3585 print(output)
3586
371810d1 3587 output = check_output('ip -6 address show dev veth99 scope global dynamic')
117a55c7 3588 self.assertNotRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic')
371810d1 3589 output = check_output('ip -6 address show dev veth99 scope link')
117a55c7 3590 self.assertRegex(output, 'inet6 .* scope link')
371810d1 3591 output = check_output('ip -4 address show dev veth99 scope global dynamic')
117a55c7 3592 self.assertNotRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
371810d1 3593 output = check_output('ip -4 address show dev veth99 scope link')
117a55c7
YW
3594 self.assertRegex(output, 'inet .* scope link')
3595
b6efd661 3596 def test_dhcp_client_route_remove_on_renew(self):
ec38833c
ZJS
3597 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
3598 'dhcp-client-ipv4-only-ipv6-disabled.network')
2cf6fdff 3599 start_networkd()
e2aea43f 3600 self.wait_online(['veth-peer:carrier'])
ec38833c 3601 start_dnsmasq(ipv4_range='192.168.5.100,192.168.5.199', lease_time='2m')
e2aea43f 3602 self.wait_online(['veth99:routable', 'veth-peer:routable'])
b6efd661
YW
3603
3604 # test for issue #12490
3605
371810d1 3606 output = check_output('ip -4 address show dev veth99 scope global dynamic')
b6efd661
YW
3607 print(output)
3608 self.assertRegex(output, 'inet 192.168.5.1[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
3609 address1=None
3610 for line in output.splitlines():
3611 if 'brd 192.168.5.255 scope global dynamic veth99' in line:
3612 address1 = line.split()[1].split('/')[0]
3613 break
3614
371810d1 3615 output = check_output('ip -4 route show dev veth99')
b6efd661
YW
3616 print(output)
3617 self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address1} metric 1024')
3618 self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address1} metric 1024')
3619
ec38833c
ZJS
3620 stop_dnsmasq(dnsmasq_pid_file)
3621 start_dnsmasq(ipv4_range='192.168.5.200,192.168.5.250', lease_time='2m')
b6efd661
YW
3622
3623 print('Wait for the dynamic address to be expired')
3624 time.sleep(130)
3625
371810d1 3626 output = check_output('ip -4 address show dev veth99 scope global dynamic')
b6efd661
YW
3627 print(output)
3628 self.assertRegex(output, 'inet 192.168.5.2[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
3629 address2=None
3630 for line in output.splitlines():
3631 if 'brd 192.168.5.255 scope global dynamic veth99' in line:
3632 address2 = line.split()[1].split('/')[0]
3633 break
3634
3635 self.assertNotEqual(address1, address2)
3636
371810d1 3637 output = check_output('ip -4 route show dev veth99')
b6efd661
YW
3638 print(output)
3639 self.assertNotRegex(output, f'default via 192.168.5.1 proto dhcp src {address1} metric 1024')
3640 self.assertNotRegex(output, f'192.168.5.1 proto dhcp scope link src {address1} metric 1024')
3641 self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address2} metric 1024')
3642 self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address2} metric 1024')
3643
e2d5aab3
YW
3644 def test_dhcp_client_use_dns_yes(self):
3645 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-yes.network')
3646
3647 start_networkd()
e2aea43f 3648 self.wait_online(['veth-peer:carrier'])
e2d5aab3 3649 start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
e2aea43f 3650 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e2d5aab3
YW
3651
3652 # link become 'routable' when at least one protocol provide an valid address.
3653 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3654 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
e2d5aab3 3655
693283cd 3656 time.sleep(3)
e2d5aab3
YW
3657 output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
3658 print(output)
3659 self.assertRegex(output, '192.168.5.1')
3660 self.assertRegex(output, '2600::1')
3661
3662 def test_dhcp_client_use_dns_no(self):
3663 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-no.network')
3664
3665 start_networkd()
e2aea43f 3666 self.wait_online(['veth-peer:carrier'])
e2d5aab3 3667 start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
e2aea43f 3668 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e2d5aab3
YW
3669
3670 # link become 'routable' when at least one protocol provide an valid address.
3671 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3672 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
e2d5aab3 3673
693283cd 3674 time.sleep(3)
e2d5aab3
YW
3675 output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
3676 print(output)
3677 self.assertNotRegex(output, '192.168.5.1')
3678 self.assertNotRegex(output, '2600::1')
3679
3680 def test_dhcp_client_use_dns_ipv4(self):
3681 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-ipv4.network')
3682
3683 start_networkd()
e2aea43f 3684 self.wait_online(['veth-peer:carrier'])
e2d5aab3 3685 start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
e2aea43f 3686 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e2d5aab3
YW
3687
3688 # link become 'routable' when at least one protocol provide an valid address.
3689 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3690 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
e2d5aab3 3691
693283cd 3692 time.sleep(3)
e2d5aab3
YW
3693 output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
3694 print(output)
3695 self.assertRegex(output, '192.168.5.1')
3696 self.assertNotRegex(output, '2600::1')
3697
3698 def test_dhcp_client_use_dns_ipv4_and_ra(self):
3699 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-dns-ipv4-and-ra.network')
3700
3701 start_networkd()
e2aea43f 3702 self.wait_online(['veth-peer:carrier'])
e2d5aab3 3703 start_dnsmasq('--dhcp-option=option:dns-server,192.168.5.1 --dhcp-option=option6:dns-server,[2600::1]')
e2aea43f 3704 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e2d5aab3
YW
3705
3706 # link become 'routable' when at least one protocol provide an valid address.
3707 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
426654d7 3708 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
e2d5aab3 3709
693283cd 3710 time.sleep(3)
e2d5aab3
YW
3711 output = check_output(*resolvectl_cmd, 'dns', 'veth99', env=env)
3712 print(output)
3713 self.assertRegex(output, '192.168.5.1')
3714 self.assertRegex(output, '2600::1')
3715
e0c1341d
YW
3716 def test_dhcp_client_use_domains(self):
3717 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-use-domains.network')
3718
3719 start_networkd()
e2aea43f 3720 self.wait_online(['veth-peer:carrier'])
e0c1341d 3721 start_dnsmasq('--dhcp-option=option:domain-search,example.com')
e2aea43f 3722 self.wait_online(['veth99:routable', 'veth-peer:routable'])
e0c1341d 3723
fc79e6ff 3724 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
e0c1341d
YW
3725 print(output)
3726 self.assertRegex(output, 'Search Domains: example.com')
3727
3728 time.sleep(3)
3729 output = check_output(*resolvectl_cmd, 'domain', 'veth99', env=env)
3730 print(output)
3731 self.assertRegex(output, 'example.com')
3732
0fd8b718
YW
3733 def test_dhcp_client_decline(self):
3734 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-decline.network', 'dhcp-client-decline.network')
3735
3736 start_networkd()
3737 self.wait_online(['veth-peer:carrier'])
3738 rc = call(*wait_online_cmd, '--timeout=10s', '--interface=veth99:routable', env=env)
3739 self.assertTrue(rc == 1)
3740
9633f977
SS
3741class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
3742 links = ['veth99']
3743
3744 units = [
3745 '25-veth.netdev',
3746 'ipv6ra-prefix-client.network',
3747 'ipv6ra-prefix.network'
3748 ]
3749
3750 def setUp(self):
3751 remove_links(self.links)
3752 stop_networkd(show_logs=False)
3753
3754 def tearDown(self):
3755 remove_log_file()
3756 remove_links(self.links)
3757 remove_unit_from_networkd_path(self.units)
3758 stop_networkd(show_logs=True)
3759
3760 def test_ipv6_route_prefix(self):
3761 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6ra-prefix-client.network', 'ipv6ra-prefix.network')
3762
3763 start_networkd()
9633f977
SS
3764 self.wait_online(['veth99:routable', 'veth-peer:routable'])
3765
3c874fd7 3766 output = check_output('ip -6 route show dev veth-peer')
9633f977
SS
3767 print(output)
3768 self.assertRegex(output, '2001:db8:0:1::/64 proto ra')
3769
3c874fd7
YW
3770 output = check_output('ip addr show dev veth99')
3771 print(output)
3772 self.assertNotRegex(output, '2001:db8:0:1')
3773 self.assertRegex(output, '2001:db8:0:2')
3774
7db05447
DS
3775class NetworkdMTUTests(unittest.TestCase, Utilities):
3776 links = ['dummy98']
3777
3778 units = [
3779 '12-dummy.netdev',
3780 '12-dummy-mtu.netdev',
3781 '12-dummy-mtu.link',
3782 '12-dummy.network',
3783 ]
3784
3785 def setUp(self):
3786 remove_links(self.links)
3787 stop_networkd(show_logs=False)
3788
3789 def tearDown(self):
3790 remove_log_file()
3791 remove_links(self.links)
3792 remove_unit_from_networkd_path(self.units)
3793 stop_networkd(show_logs=True)
3794
3795 def check_mtu(self, mtu, ipv6_mtu=None, reset=True):
3796 if not ipv6_mtu:
3797 ipv6_mtu = mtu
3798
3799 # test normal start
3800 start_networkd()
3801 self.wait_online(['dummy98:routable'])
3802 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'mtu'), ipv6_mtu)
3803 self.assertEqual(read_link_attr('dummy98', 'mtu'), mtu)
3804
3805 # test normal restart
3806 restart_networkd()
3807 self.wait_online(['dummy98:routable'])
3808 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'mtu'), ipv6_mtu)
3809 self.assertEqual(read_link_attr('dummy98', 'mtu'), mtu)
3810
3811 if reset:
3812 self.reset_check_mtu(mtu, ipv6_mtu)
3813
3814 def reset_check_mtu(self, mtu, ipv6_mtu=None):
3815 ''' test setting mtu/ipv6_mtu with interface already up '''
3816 stop_networkd()
3817
3818 # note - changing the device mtu resets the ipv6 mtu
3819 run('ip link set up mtu 1501 dev dummy98')
3820 run('ip link set up mtu 1500 dev dummy98')
3821 self.assertEqual(read_link_attr('dummy98', 'mtu'), '1500')
3822 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'mtu'), '1500')
3823
3824 self.check_mtu(mtu, ipv6_mtu, reset=False)
3825
3826 def test_mtu_network(self):
3827 copy_unit_to_networkd_unit_path('12-dummy.netdev', '12-dummy.network.d/mtu.conf')
3828 self.check_mtu('1600')
3829
3830 def test_mtu_netdev(self):
3831 copy_unit_to_networkd_unit_path('12-dummy-mtu.netdev', '12-dummy.network', dropins=False)
3832 # note - MTU set by .netdev happens ONLY at device creation!
3833 self.check_mtu('1600', reset=False)
3834
3835 def test_mtu_link(self):
3836 copy_unit_to_networkd_unit_path('12-dummy.netdev', '12-dummy-mtu.link', '12-dummy.network', dropins=False)
3837 # must reload udev because it only picks up new files after 3 second delay
3838 call('udevadm control --reload')
3839 # note - MTU set by .link happens ONLY at udev processing of device 'add' uevent!
3840 self.check_mtu('1600', reset=False)
3841
3842 def test_ipv6_mtu(self):
3843 ''' set ipv6 mtu without setting device mtu '''
3844 copy_unit_to_networkd_unit_path('12-dummy.netdev', '12-dummy.network.d/ipv6-mtu-1400.conf')
3845 self.check_mtu('1500', '1400')
3846
3847 def test_ipv6_mtu_toolarge(self):
3848 ''' try set ipv6 mtu over device mtu (it shouldn't work) '''
3849 copy_unit_to_networkd_unit_path('12-dummy.netdev', '12-dummy.network.d/ipv6-mtu-1550.conf')
3850 self.check_mtu('1500', '1500')
3851
3852 def test_mtu_network_ipv6_mtu(self):
3853 ''' set ipv6 mtu and set device mtu via network file '''
3854 copy_unit_to_networkd_unit_path('12-dummy.netdev', '12-dummy.network.d/mtu.conf', '12-dummy.network.d/ipv6-mtu-1550.conf')
3855 self.check_mtu('1600', '1550')
3856
3857 def test_mtu_netdev_ipv6_mtu(self):
3858 ''' set ipv6 mtu and set device mtu via netdev file '''
3859 copy_unit_to_networkd_unit_path('12-dummy-mtu.netdev', '12-dummy.network.d/ipv6-mtu-1550.conf')
3860 self.check_mtu('1600', '1550', reset=False)
3861
3862 def test_mtu_link_ipv6_mtu(self):
3863 ''' set ipv6 mtu and set device mtu via link file '''
3864 copy_unit_to_networkd_unit_path('12-dummy.netdev', '12-dummy-mtu.link', '12-dummy.network.d/ipv6-mtu-1550.conf')
3865 # must reload udev because it only picks up new files after 3 second delay
3866 call('udevadm control --reload')
3867 self.check_mtu('1600', '1550', reset=False)
3868
3869
1f0e3109 3870if __name__ == '__main__':
9c1ae484
YW
3871 parser = argparse.ArgumentParser()
3872 parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
3873 parser.add_argument('--networkd', help='Path to systemd-networkd', dest='networkd_bin')
b6d587d1 3874 parser.add_argument('--resolved', help='Path to systemd-resolved', dest='resolved_bin')
641aa412 3875 parser.add_argument('--udevd', help='Path to systemd-udevd', dest='udevd_bin')
9c1ae484
YW
3876 parser.add_argument('--wait-online', help='Path to systemd-networkd-wait-online', dest='wait_online_bin')
3877 parser.add_argument('--networkctl', help='Path to networkctl', dest='networkctl_bin')
b6d587d1
YW
3878 parser.add_argument('--resolvectl', help='Path to resolvectl', dest='resolvectl_bin')
3879 parser.add_argument('--timedatectl', help='Path to timedatectl', dest='timedatectl_bin')
9c1ae484
YW
3880 parser.add_argument('--valgrind', help='Enable valgrind', dest='use_valgrind', type=bool, nargs='?', const=True, default=use_valgrind)
3881 parser.add_argument('--debug', help='Generate debugging logs', dest='enable_debug', type=bool, nargs='?', const=True, default=enable_debug)
94c03122 3882 parser.add_argument('--asan-options', help='ASAN options', dest='asan_options')
fa4c6095 3883 parser.add_argument('--lsan-options', help='LSAN options', dest='lsan_options')
94c03122 3884 parser.add_argument('--ubsan-options', help='UBSAN options', dest='ubsan_options')
9c1ae484
YW
3885 ns, args = parser.parse_known_args(namespace=unittest)
3886
3887 if ns.build_dir:
641aa412 3888 if ns.networkd_bin or ns.resolved_bin or ns.udevd_bin or ns.wait_online_bin or ns.networkctl_bin or ns.resolvectl_bin or ns.timedatectl_bin:
b6d587d1 3889 print('WARNING: --networkd, --resolved, --wait-online, --networkctl, --resolvectl, or --timedatectl options are ignored when --build-dir is specified.')
9c1ae484 3890 networkd_bin = os.path.join(ns.build_dir, 'systemd-networkd')
b6d587d1 3891 resolved_bin = os.path.join(ns.build_dir, 'systemd-resolved')
641aa412 3892 udevd_bin = os.path.join(ns.build_dir, 'systemd-udevd')
9c1ae484
YW
3893 wait_online_bin = os.path.join(ns.build_dir, 'systemd-networkd-wait-online')
3894 networkctl_bin = os.path.join(ns.build_dir, 'networkctl')
b6d587d1
YW
3895 resolvectl_bin = os.path.join(ns.build_dir, 'resolvectl')
3896 timedatectl_bin = os.path.join(ns.build_dir, 'timedatectl')
9c1ae484
YW
3897 else:
3898 if ns.networkd_bin:
3899 networkd_bin = ns.networkd_bin
b6d587d1
YW
3900 if ns.resolved_bin:
3901 resolved_bin = ns.resolved_bin
641aa412
YW
3902 if ns.udevd_bin:
3903 udevd_bin = ns.udevd_bin
9c1ae484
YW
3904 if ns.wait_online_bin:
3905 wait_online_bin = ns.wait_online_bin
3906 if ns.networkctl_bin:
3907 networkctl_bin = ns.networkctl_bin
b6d587d1
YW
3908 if ns.resolvectl_bin:
3909 resolvectl_bin = ns.resolvectl_bin
3910 if ns.timedatectl_bin:
3911 timedatectl_bin = ns.timedatectl_bin
9c1ae484
YW
3912
3913 use_valgrind = ns.use_valgrind
3914 enable_debug = ns.enable_debug
94c03122 3915 asan_options = ns.asan_options
fa4c6095 3916 lsan_options = ns.lsan_options
94c03122 3917 ubsan_options = ns.ubsan_options
9c1ae484
YW
3918
3919 if use_valgrind:
3920 networkctl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', networkctl_bin]
b6d587d1
YW
3921 resolvectl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', resolvectl_bin]
3922 timedatectl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', timedatectl_bin]
9c1ae484
YW
3923 wait_online_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', wait_online_bin]
3924 else:
3925 networkctl_cmd = [networkctl_bin]
b6d587d1
YW
3926 resolvectl_cmd = [resolvectl_bin]
3927 timedatectl_cmd = [timedatectl_bin]
9c1ae484
YW
3928 wait_online_cmd = [wait_online_bin]
3929
3930 if enable_debug:
3931 env.update({ 'SYSTEMD_LOG_LEVEL' : 'debug' })
94c03122
YW
3932 if asan_options:
3933 env.update({ 'ASAN_OPTIONS' : asan_options })
fa4c6095
YW
3934 if lsan_options:
3935 env.update({ 'LSAN_OPTIONS' : lsan_options })
94c03122
YW
3936 if ubsan_options:
3937 env.update({ 'UBSAN_OPTIONS' : ubsan_options })
9c1ae484
YW
3938
3939 sys.argv[1:] = args
1f0e3109
SS
3940 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
3941 verbosity=3))