]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
network: fix issue found by UBSan
[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
1f0e3109 6import os
201bf07f 7import re
1f0e3109
SS
8import shutil
9import signal
a9bc5e37
YW
10import subprocess
11import sys
a9bc5e37
YW
12import time
13import unittest
1f0e3109
SS
14from shutil import copytree
15
d486a2d0 16network_unit_file_path='/run/systemd/network'
bad4969b 17networkd_runtime_directory='/run/systemd/netif'
d486a2d0 18networkd_ci_path='/run/networkd-ci'
1f0e3109
SS
19network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
20network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
21
d486a2d0
YW
22dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
23dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
1f0e3109 24
9c1ae484 25networkd_bin='/usr/lib/systemd/systemd-networkd'
5aa58329 26wait_online_bin='/usr/lib/systemd/systemd-networkd-wait-online'
9c1ae484
YW
27networkctl_bin='/usr/bin/networkctl'
28use_valgrind=False
aaae5713 29enable_debug=True
9c1ae484 30env = {}
94c03122 31asan_options=None
fa4c6095 32lsan_options=None
94c03122 33ubsan_options=None
5aa58329 34
371810d1
ZJS
35def check_output(*command, **kwargs):
36 # This replaces both check_output and check_call (output can be ignored)
37 command = command[0].split() + list(command[1:])
38 return subprocess.check_output(command, universal_newlines=True, **kwargs).rstrip()
39
40def call(*command, **kwargs):
41 command = command[0].split() + list(command[1:])
42 return subprocess.call(command, universal_newlines=True, **kwargs)
43
44def run(*command, **kwargs):
45 command = command[0].split() + list(command[1:])
46 return subprocess.run(command, universal_newlines=True, **kwargs)
47
7a0a37b2 48def is_module_available(module_name):
371810d1
ZJS
49 lsmod_output = check_output('lsmod')
50 module_re = re.compile(rf'^{re.escape(module_name)}\b', re.MULTILINE)
51 return module_re.search(lsmod_output) or not call('modprobe', module_name)
7a0a37b2
EV
52
53def expectedFailureIfModuleIsNotAvailable(module_name):
54 def f(func):
55 if not is_module_available(module_name):
56 return unittest.expectedFailure(func)
57 return func
58
59 return f
60
7bea7f9b
SS
61def expectedFailureIfERSPANModuleIsNotAvailable():
62 def f(func):
371810d1 63 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')
7bea7f9b 64 if rc == 0:
371810d1 65 call('ip link del erspan99')
7bea7f9b
SS
66 return func
67 else:
68 return unittest.expectedFailure(func)
69
70 return f
71
d586a2c3
YW
72def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
73 def f(func):
371810d1 74 rc = call('ip rule add from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
d586a2c3 75 if rc == 0:
371810d1 76 call('ip rule del from 192.168.100.19 sport 1123-1150 dport 3224-3290 table 7')
d586a2c3
YW
77 return func
78 else:
79 return unittest.expectedFailure(func)
80
81 return f
82
83def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
84 def f(func):
371810d1 85 rc = call('ip rule add not from 192.168.100.19 ipproto tcp table 7')
d586a2c3 86 if rc == 0:
371810d1 87 call('ip rule del not from 192.168.100.19 ipproto tcp table 7')
d586a2c3
YW
88 return func
89 else:
90 return unittest.expectedFailure(func)
91
92 return f
93
e28fd95f
YW
94def expectedFailureIfLinkFileFieldIsNotSet():
95 def f(func):
96 support = False
97 rc = call('ip link add name dummy99 type dummy')
98 if rc == 0:
99 ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
100 if ret.returncode == 0 and 'E: ID_NET_LINK_FILE=' in ret.stdout.rstrip():
101 support = True
102 call('ip link del dummy99')
103
104 if support:
105 return func
106 else:
107 return unittest.expectedFailure(func)
108
109 return f
110
1ca44d7d
YW
111def expectedFailureIfEthtoolDoesNotSupportDriver():
112 def f(func):
113 support = False
371810d1 114 rc = call('ip link add name dummy99 type dummy')
1ca44d7d 115 if rc == 0:
371810d1 116 ret = run('udevadm info -w10s /sys/class/net/dummy99', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1ca44d7d
YW
117 if ret.returncode == 0 and 'E: ID_NET_DRIVER=dummy' in ret.stdout.rstrip():
118 support = True
371810d1 119 call('ip link del dummy99')
1ca44d7d
YW
120
121 if support:
122 return func
123 else:
124 return unittest.expectedFailure(func)
125
126 return f
127
1f0e3109 128def setUpModule():
1f0e3109
SS
129 os.makedirs(network_unit_file_path, exist_ok=True)
130 os.makedirs(networkd_ci_path, exist_ok=True)
131
132 shutil.rmtree(networkd_ci_path)
6aea9276 133 copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
1f0e3109 134
371810d1
ZJS
135 check_output('systemctl stop systemd-networkd.socket')
136 check_output('systemctl stop systemd-networkd.service')
c0bf6733 137
9c1ae484
YW
138 drop_in = [
139 '[Service]',
140 'Restart=no',
141 'ExecStart=',
142 ]
143 if use_valgrind:
144 drop_in += [
145 'ExecStart=!!valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ' + networkd_bin,
94c03122 146 'PrivateTmp=yes'
9c1ae484
YW
147 ]
148 else:
149 drop_in += ['ExecStart=!!' + networkd_bin]
150 if enable_debug:
151 drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
94c03122
YW
152 if asan_options:
153 drop_in += ['Environment=ASAN_OPTIONS="' + asan_options + '"']
fa4c6095
YW
154 if lsan_options:
155 drop_in += ['Environment=LSAN_OPTIONS="' + lsan_options + '"']
94c03122
YW
156 if ubsan_options:
157 drop_in += ['Environment=UBSAN_OPTIONS="' + ubsan_options + '"']
78690bb5
YW
158 if asan_options or lsan_options or ubsan_options:
159 drop_in += ['SystemCallFilter=']
fa4c6095 160 if use_valgrind or asan_options or lsan_options or ubsan_options:
94c03122 161 drop_in += ['MemoryDenyWriteExecute=no']
9c1ae484 162
9c1ae484
YW
163 os.makedirs('/run/systemd/system/systemd-networkd.service.d', exist_ok=True)
164 with open('/run/systemd/system/systemd-networkd.service.d/00-override.conf', mode='w') as f:
72917fcc 165 f.write('\n'.join(drop_in))
9c1ae484 166
371810d1
ZJS
167 check_output('systemctl daemon-reload')
168 print(check_output('systemctl cat systemd-networkd.service'))
9c1ae484 169
1f0e3109
SS
170def tearDownModule():
171 shutil.rmtree(networkd_ci_path)
d4fda2a5 172
371810d1 173 check_output('systemctl stop systemd-networkd.service')
d4fda2a5 174
9c1ae484 175 shutil.rmtree('/run/systemd/system/systemd-networkd.service.d')
371810d1 176 check_output('systemctl daemon-reload')
1f0e3109 177
371810d1
ZJS
178 check_output('systemctl start systemd-networkd.socket')
179 check_output('systemctl start systemd-networkd.service')
c0bf6733 180
ec38833c
ZJS
181def read_link_attr(link, dev, attribute):
182 with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
183 return f.readline().strip()
184
185def read_bridge_port_attr(bridge, link, attribute):
186 path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
187 path_port = 'lower_' + link + '/brport'
188 path = os.path.join(path_bridge, path_port)
189
190 with open(os.path.join(path, attribute)) as f:
191 return f.readline().strip()
192
193def link_exists(link):
194 return os.path.exists(os.path.join('/sys/class/net', link))
195
196def remove_links(links):
197 for link in links:
198 if link_exists(link):
199 call('ip link del dev', link)
200 time.sleep(1)
201
202def remove_fou_ports(ports):
203 for port in ports:
5239d7b3 204 call('ip fou del port', port, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
ec38833c
ZJS
205
206def remove_routing_policy_rule_tables(tables):
207 for table in tables:
4ef39b49
YW
208 rc = 0
209 while rc == 0:
210 rc = call('ip rule del table', table, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
ec38833c
ZJS
211
212def remove_routes(routes):
213 for route_type, addr in routes:
5239d7b3 214 call('ip route del', route_type, addr, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
ec38833c 215
ad78d7b0 216def remove_l2tp_tunnels(tunnel_ids):
ec38833c
ZJS
217 output = check_output('ip l2tp show tunnel')
218 for tid in tunnel_ids:
219 words='Tunnel ' + tid + ', encap'
220 if words in output:
221 call('ip l2tp del tunnel tid', tid)
222 time.sleep(1)
223
224def read_ipv6_sysctl_attr(link, attribute):
225 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
226 return f.readline().strip()
227
228def read_ipv4_sysctl_attr(link, attribute):
229 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
230 return f.readline().strip()
231
232def copy_unit_to_networkd_unit_path(*units):
233 print()
234 for unit in units:
235 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
236 if (os.path.exists(os.path.join(networkd_ci_path, unit + '.d'))):
237 copytree(os.path.join(networkd_ci_path, unit + '.d'), os.path.join(network_unit_file_path, unit + '.d'))
238
239def remove_unit_from_networkd_path(units):
240 for unit in units:
241 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
242 os.remove(os.path.join(network_unit_file_path, unit))
243 if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
244 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
245
246def warn_about_firewalld():
247 rc = call('systemctl -q is-active firewalld.service')
248 if rc == 0:
249 print('\nWARNING: firewalld.service is active. The test may fail.')
250
251def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'):
252 warn_about_firewalld()
253 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
254 check_output(dnsmasq_command)
255
256def stop_dnsmasq(pid_file):
257 if os.path.exists(pid_file):
258 with open(pid_file, 'r') as f:
259 pid = f.read().rstrip(' \t\r\n\0')
260 os.kill(int(pid), signal.SIGTERM)
261
262 os.remove(pid_file)
263
264def search_words_in_dnsmasq_log(words, show_all=False):
265 if os.path.exists(dnsmasq_log_file):
266 with open (dnsmasq_log_file) as in_file:
267 contents = in_file.read()
268 if show_all:
269 print(contents)
270 for line in contents.splitlines():
271 if words in line:
272 in_file.close()
273 print("%s, %s" % (words, line))
274 return True
275 return False
276
277def remove_lease_file():
278 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
279 os.remove(os.path.join(networkd_ci_path, 'lease'))
280
281def remove_log_file():
282 if os.path.exists(dnsmasq_log_file):
283 os.remove(dnsmasq_log_file)
284
aaae5713
YW
285def remove_networkd_state_files():
286 if os.path.exists(os.path.join(networkd_runtime_directory, 'state')):
ec38833c 287 os.remove(os.path.join(networkd_runtime_directory, 'state'))
aaae5713
YW
288
289def stop_networkd(show_logs=True, remove_state_files=True):
290 if show_logs:
291 invocation_id = check_output('systemctl show systemd-networkd -p InvocationID --value')
292 check_output('systemctl stop systemd-networkd')
293 if show_logs:
294 print(check_output('journalctl _SYSTEMD_INVOCATION_ID=' + invocation_id))
295 if remove_state_files:
296 remove_networkd_state_files()
297
298def start_networkd(sleep_sec=0):
299 check_output('systemctl start systemd-networkd')
ec38833c
ZJS
300 if sleep_sec > 0:
301 time.sleep(sleep_sec)
302
aaae5713
YW
303def restart_networkd(sleep_sec=0, show_logs=True, remove_state_files=True):
304 stop_networkd(show_logs, remove_state_files)
305 start_networkd(sleep_sec)
306
ec38833c
ZJS
307def wait_online(links_with_operstate, timeout='20s', bool_any=False):
308 args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate]
309 if bool_any:
310 args += ['--any']
311 try:
312 check_output(*args, env=env)
313 except subprocess.CalledProcessError:
314 for link in links_with_operstate:
315 output = check_output(*networkctl_cmd, 'status', link.split(':')[0], env=env)
316 print(output)
317 raise
4d7ed14f 318
ec38833c
ZJS
319def get_operstate(link, show_status=True, setup_state='configured'):
320 output = check_output(*networkctl_cmd, 'status', link, env=env)
321 if show_status:
322 print(output)
323 for line in output.splitlines():
324 if 'State:' in line and (not setup_state or setup_state in line):
325 return line.split()[1]
326 return None
1f0e3109 327
ec38833c 328class Utilities():
e39cc445 329 def check_link_exists(self, link):
ec38833c 330 self.assertTrue(link_exists(link))
2be0b6fc
YW
331
332 def check_operstate(self, link, expected, show_status=True, setup_state='configured'):
ec38833c 333 self.assertRegex(get_operstate(link, show_status, setup_state), expected)
2be0b6fc 334
53c32c2b 335 def wait_address(self, link, address_regex, scope='global', ipv='', timeout_sec=100):
2629df47
YW
336 for i in range(timeout_sec):
337 if i > 0:
338 time.sleep(1)
371810d1 339 output = check_output(f'ip {ipv} address show dev {link} scope {scope}')
2629df47
YW
340 if re.search(address_regex, output):
341 break
342 else:
343 self.assertRegex(output, address_regex)
344
1ca44d7d
YW
345class NetworkctlTests(unittest.TestCase, Utilities):
346
347 links = [
348 'test1',
349 'veth99',
350 ]
351
352 units = [
353 '11-dummy.netdev',
6d5b4efe 354 '11-dummy-mtu.netdev',
1ca44d7d
YW
355 '11-dummy.network',
356 '25-veth.netdev',
357 'netdev-link-local-addressing-yes.network',
358 ]
359
360 def setUp(self):
ec38833c 361 remove_links(self.links)
aaae5713 362 stop_networkd(show_logs=False)
1ca44d7d
YW
363
364 def tearDown(self):
ec38833c
ZJS
365 remove_links(self.links)
366 remove_unit_from_networkd_path(self.units)
aaae5713 367 stop_networkd(show_logs=True)
1ca44d7d
YW
368
369 def test_glob(self):
ec38833c 370 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
2cf6fdff 371 start_networkd()
1ca44d7d 372
ec38833c 373 wait_online(['test1:degraded'])
1ca44d7d 374
371810d1 375 output = check_output(*networkctl_cmd, 'list', env=env)
1ca44d7d
YW
376 self.assertRegex(output, '1 lo ')
377 self.assertRegex(output, 'test1')
378
371810d1 379 output = check_output(*networkctl_cmd, 'list', 'test1', env=env)
1ca44d7d
YW
380 self.assertNotRegex(output, '1 lo ')
381 self.assertRegex(output, 'test1')
382
371810d1 383 output = check_output(*networkctl_cmd, 'list', 'te*', env=env)
1ca44d7d
YW
384 self.assertNotRegex(output, '1 lo ')
385 self.assertRegex(output, 'test1')
386
371810d1 387 output = check_output(*networkctl_cmd, 'status', 'te*', env=env)
1ca44d7d
YW
388 self.assertNotRegex(output, '1: lo ')
389 self.assertRegex(output, 'test1')
390
371810d1 391 output = check_output(*networkctl_cmd, 'status', 'tes[a-z][0-9]', env=env)
1ca44d7d
YW
392 self.assertNotRegex(output, '1: lo ')
393 self.assertRegex(output, 'test1')
394
6d5b4efe 395 def test_mtu(self):
ec38833c 396 copy_unit_to_networkd_unit_path('11-dummy-mtu.netdev', '11-dummy.network')
2cf6fdff 397 start_networkd()
6d5b4efe 398
ec38833c 399 wait_online(['test1:degraded'])
6d5b4efe 400
371810d1 401 output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
6d5b4efe
YW
402 self.assertRegex(output, 'MTU: 1600')
403
e28fd95f
YW
404 def test_type(self):
405 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
406 start_networkd()
407 wait_online(['test1:degraded'])
408
409 output = check_output(*networkctl_cmd, 'status', 'test1')
410 print(output)
411 self.assertRegex(output, 'Type: ether')
412
413 output = check_output(*networkctl_cmd, 'status', 'lo')
414 print(output)
415 self.assertRegex(output, 'Type: loopback')
416
417 @expectedFailureIfLinkFileFieldIsNotSet()
418 def test_udev_link_file(self):
419 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network')
420 start_networkd()
421 wait_online(['test1:degraded'])
422
423 output = check_output(*networkctl_cmd, 'status', 'test1')
424 print(output)
425 self.assertRegex(output, r'Link File: (?:/usr)/lib/systemd/network/99-default.link')
426 self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
427
428 output = check_output(*networkctl_cmd, 'status', 'lo')
429 print(output)
430 self.assertRegex(output, r'Link File: (?:/usr)/lib/systemd/network/99-default.link')
431 self.assertRegex(output, r'Network File: n/a')
432
1ca44d7d
YW
433 @expectedFailureIfEthtoolDoesNotSupportDriver()
434 def test_udev_driver(self):
ec38833c
ZJS
435 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network',
436 '25-veth.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 437 start_networkd()
1ca44d7d 438
ec38833c 439 wait_online(['test1:degraded', 'veth99:degraded', 'veth-peer:degraded'])
1ca44d7d 440
371810d1 441 output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
1ca44d7d
YW
442 self.assertRegex(output, 'Driver: dummy')
443
371810d1 444 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1ca44d7d
YW
445 self.assertRegex(output, 'Driver: veth')
446
371810d1 447 output = check_output(*networkctl_cmd, 'status', 'veth-peer', env=env)
1ca44d7d 448 self.assertRegex(output, 'Driver: veth')
2be0b6fc 449
bee692fd 450 def test_delete_links(self):
ec38833c
ZJS
451 copy_unit_to_networkd_unit_path('11-dummy.netdev', '11-dummy.network',
452 '25-veth.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 453 start_networkd()
bee692fd 454
ec38833c 455 wait_online(['test1:degraded', 'veth99:degraded', 'veth-peer:degraded'])
bee692fd 456
371810d1 457 check_output(*networkctl_cmd, 'delete', 'test1', 'veth99')
ec38833c
ZJS
458 self.assertFalse(link_exists('test1'))
459 self.assertFalse(link_exists('veth99'))
460 self.assertFalse(link_exists('veth-peer'))
bee692fd 461
1f0e3109
SS
462class NetworkdNetDevTests(unittest.TestCase, Utilities):
463
09ea6724
YW
464 links =[
465 '6rdtun99',
466 'bond99',
467 'bridge99',
468 'dropin-test',
469 'dummy98',
6a97a864
YW
470 'erspan98',
471 'erspan99',
09ea6724 472 'geneve99',
4b6a6d1e 473 'gretap96',
6a97a864 474 'gretap98',
09ea6724 475 'gretap99',
4b6a6d1e 476 'gretun96',
6a97a864
YW
477 'gretun97',
478 'gretun98',
09ea6724 479 'gretun99',
6a97a864 480 'ip6gretap98',
09ea6724 481 'ip6gretap99',
6a97a864
YW
482 'ip6gretun97',
483 'ip6gretun98',
484 'ip6gretun99',
485 'ip6tnl97',
486 'ip6tnl98',
09ea6724 487 'ip6tnl99',
4b6a6d1e 488 'ipiptun96',
6a97a864
YW
489 'ipiptun97',
490 'ipiptun98',
09ea6724
YW
491 'ipiptun99',
492 'ipvlan99',
956c8fec 493 'ipvtap99',
09ea6724
YW
494 'isataptun99',
495 'macvlan99',
496 'macvtap99',
811f33d0 497 'nlmon99',
4b6a6d1e 498 'sittun96',
6a97a864
YW
499 'sittun97',
500 'sittun98',
09ea6724
YW
501 'sittun99',
502 'tap99',
503 'test1',
504 'tun99',
505 'vcan99',
506 'veth99',
507 'vlan99',
508 'vrf99',
6a97a864
YW
509 'vti6tun97',
510 'vti6tun98',
09ea6724 511 'vti6tun99',
6a97a864
YW
512 'vtitun97',
513 'vtitun98',
09ea6724 514 'vtitun99',
f63b14d3 515 'vxcan99',
09ea6724 516 'vxlan99',
da44fb8a 517 'wg98',
09ea6724
YW
518 'wg99']
519
520 units = [
521 '10-dropin-test.netdev',
522 '11-dummy.netdev',
03db80b2 523 '11-dummy.network',
09ea6724 524 '12-dummy.netdev',
6b9518a0
YW
525 '13-not-match-udev-property.network',
526 '14-match-udev-property.network',
753e0a24 527 '15-name-conflict-test.netdev',
09ea6724
YW
528 '21-macvlan.netdev',
529 '21-macvtap.netdev',
7f45d738 530 '21-vlan-test1.network',
09ea6724
YW
531 '21-vlan.netdev',
532 '21-vlan.network',
533 '25-6rd-tunnel.netdev',
534 '25-bond.netdev',
fde60a42 535 '25-bond-balanced-tlb.netdev',
09ea6724 536 '25-bridge.netdev',
1285edf3 537 '25-bridge-configure-without-carrier.network',
03db80b2 538 '25-bridge.network',
6a97a864 539 '25-erspan-tunnel-local-any.netdev',
09ea6724 540 '25-erspan-tunnel.netdev',
4b6a6d1e
YW
541 '25-fou-gretap.netdev',
542 '25-fou-gre.netdev',
543 '25-fou-ipip.netdev',
544 '25-fou-ipproto-gre.netdev',
545 '25-fou-ipproto-ipip.netdev',
546 '25-fou-sit.netdev',
09ea6724 547 '25-geneve.netdev',
6a97a864 548 '25-gretap-tunnel-local-any.netdev',
09ea6724 549 '25-gretap-tunnel.netdev',
6a97a864
YW
550 '25-gre-tunnel-local-any.netdev',
551 '25-gre-tunnel-remote-any.netdev',
09ea6724 552 '25-gre-tunnel.netdev',
6a97a864
YW
553 '25-ip6gretap-tunnel-local-any.netdev',
554 '25-ip6gretap-tunnel.netdev',
555 '25-ip6gre-tunnel-local-any.netdev',
556 '25-ip6gre-tunnel-remote-any.netdev',
09ea6724 557 '25-ip6gre-tunnel.netdev',
6a97a864
YW
558 '25-ip6tnl-tunnel-remote-any.netdev',
559 '25-ip6tnl-tunnel-local-any.netdev',
09ea6724
YW
560 '25-ip6tnl-tunnel.netdev',
561 '25-ipip-tunnel-independent.netdev',
6a97a864
YW
562 '25-ipip-tunnel-local-any.netdev',
563 '25-ipip-tunnel-remote-any.netdev',
09ea6724
YW
564 '25-ipip-tunnel.netdev',
565 '25-ipvlan.netdev',
956c8fec 566 '25-ipvtap.netdev',
09ea6724 567 '25-isatap-tunnel.netdev',
02849d8b
YW
568 '25-macsec.key',
569 '25-macsec.netdev',
570 '25-macsec.network',
811f33d0 571 '25-nlmon.netdev',
6a97a864
YW
572 '25-sit-tunnel-local-any.netdev',
573 '25-sit-tunnel-remote-any.netdev',
09ea6724
YW
574 '25-sit-tunnel.netdev',
575 '25-tap.netdev',
576 '25-tun.netdev',
11309591
YW
577 '25-tunnel-local-any.network',
578 '25-tunnel-remote-any.network',
579 '25-tunnel.network',
09ea6724
YW
580 '25-vcan.netdev',
581 '25-veth.netdev',
582 '25-vrf.netdev',
6a97a864
YW
583 '25-vti6-tunnel-local-any.netdev',
584 '25-vti6-tunnel-remote-any.netdev',
09ea6724 585 '25-vti6-tunnel.netdev',
6a97a864
YW
586 '25-vti-tunnel-local-any.netdev',
587 '25-vti-tunnel-remote-any.netdev',
09ea6724 588 '25-vti-tunnel.netdev',
f63b14d3 589 '25-vxcan.netdev',
09ea6724 590 '25-vxlan.netdev',
da44fb8a
YW
591 '25-wireguard-23-peers.netdev',
592 '25-wireguard-23-peers.network',
9e5d79e7 593 '25-wireguard-preshared-key.txt',
39bcff3b 594 '25-wireguard-private-key.txt',
09ea6724 595 '25-wireguard.netdev',
5a0bd90b 596 '25-wireguard.network',
09ea6724 597 '6rd.network',
6730a1f3 598 'erspan.network',
09ea6724
YW
599 'gre.network',
600 'gretap.network',
601 'gretun.network',
602 'ip6gretap.network',
6a97a864 603 'ip6gretun.network',
09ea6724
YW
604 'ip6tnl.network',
605 'ipip.network',
606 'ipvlan.network',
956c8fec 607 'ipvtap.network',
09ea6724 608 'isatap.network',
02849d8b 609 'macsec.network',
09ea6724
YW
610 'macvlan.network',
611 'macvtap.network',
077f9abc 612 'netdev-link-local-addressing-yes.network',
09ea6724
YW
613 'sit.network',
614 'vti6.network',
615 'vti.network',
1c862fe0 616 'vxlan-test1.network',
09ea6724 617 'vxlan.network']
1f0e3109 618
def9fc0d
YW
619 fou_ports = [
620 '55555',
621 '55556']
622
1f0e3109 623 def setUp(self):
ec38833c
ZJS
624 remove_fou_ports(self.fou_ports)
625 remove_links(self.links)
aaae5713 626 stop_networkd(show_logs=False)
1f0e3109
SS
627
628 def tearDown(self):
ec38833c
ZJS
629 remove_fou_ports(self.fou_ports)
630 remove_links(self.links)
631 remove_unit_from_networkd_path(self.units)
aaae5713 632 stop_networkd(show_logs=True)
1f0e3109 633
1ca44d7d 634 def test_dropin_and_name_conflict(self):
ec38833c 635 copy_unit_to_networkd_unit_path('10-dropin-test.netdev', '15-name-conflict-test.netdev')
2cf6fdff 636 start_networkd()
d80734f7 637
ec38833c 638 wait_online(['dropin-test:off'])
d80734f7 639
371810d1 640 output = check_output('ip link show dropin-test')
d80734f7
YW
641 print(output)
642 self.assertRegex(output, '00:50:56:c0:00:28')
643
6b9518a0
YW
644 def test_match_udev_property(self):
645 copy_unit_to_networkd_unit_path('12-dummy.netdev', '13-not-match-udev-property.network', '14-match-udev-property.network')
646 start_networkd()
647 wait_online(['dummy98:routable'])
648
649 output = check_output('networkctl status dummy98')
650 print(output)
651 self.assertRegex(output, 'Network File: /run/systemd/network/14-match-udev-property')
652
03db80b2 653 def test_wait_online_any(self):
ec38833c 654 copy_unit_to_networkd_unit_path('25-bridge.netdev', '25-bridge.network', '11-dummy.netdev', '11-dummy.network')
2cf6fdff 655 start_networkd()
03db80b2 656
ec38833c 657 wait_online(['bridge99', 'test1:degraded'], bool_any=True)
03db80b2 658
791c1140
YW
659 self.check_operstate('bridge99', '(?:off|no-carrier)', setup_state='configuring')
660 self.check_operstate('test1', 'degraded')
03db80b2 661
1f0e3109 662 def test_bridge(self):
1285edf3 663 copy_unit_to_networkd_unit_path('25-bridge.netdev', '25-bridge-configure-without-carrier.network')
2cf6fdff 664 start_networkd()
1f0e3109 665
1285edf3 666 wait_online(['bridge99:no-carrier'])
1f0e3109 667
3d165124 668 tick = os.sysconf('SC_CLK_TCK')
ec38833c
ZJS
669 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'hello_time')) / tick))
670 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'max_age')) / tick))
671 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge','forward_delay')) / tick))
672 self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge','ageing_time')) / tick))
673 self.assertEqual(9, int(read_link_attr('bridge99', 'bridge','priority')))
674 self.assertEqual(1, int(read_link_attr('bridge99', 'bridge','multicast_querier')))
675 self.assertEqual(1, int(read_link_attr('bridge99', 'bridge','multicast_snooping')))
676 self.assertEqual(1, int(read_link_attr('bridge99', 'bridge','stp_state')))
1f0e3109
SS
677
678 def test_bond(self):
ec38833c 679 copy_unit_to_networkd_unit_path('25-bond.netdev', '25-bond-balanced-tlb.netdev')
2cf6fdff 680 start_networkd()
ec38833c
ZJS
681
682 wait_online(['bond99:off', 'bond98:off'])
683
684 self.assertEqual('802.3ad 4', read_link_attr('bond99', 'bonding', 'mode'))
685 self.assertEqual('layer3+4 1', read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
686 self.assertEqual('1000', read_link_attr('bond99', 'bonding', 'miimon'))
687 self.assertEqual('fast 1', read_link_attr('bond99', 'bonding', 'lacp_rate'))
688 self.assertEqual('2000', read_link_attr('bond99', 'bonding', 'updelay'))
689 self.assertEqual('2000', read_link_attr('bond99', 'bonding', 'downdelay'))
690 self.assertEqual('4', read_link_attr('bond99', 'bonding', 'resend_igmp'))
691 self.assertEqual('1', read_link_attr('bond99', 'bonding', 'min_links'))
692 self.assertEqual('1218', read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
693 self.assertEqual('811', read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
694 self.assertEqual('00:11:22:33:44:55', read_link_attr('bond99', 'bonding', 'ad_actor_system'))
695
696 self.assertEqual('balance-tlb 5', read_link_attr('bond98', 'bonding', 'mode'))
697 self.assertEqual('1', read_link_attr('bond98', 'bonding', 'tlb_dynamic_lb'))
fde60a42 698
1f0e3109 699 def test_vlan(self):
ec38833c
ZJS
700 copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev',
701 '21-vlan.network', '21-vlan-test1.network')
2cf6fdff 702 start_networkd()
1f0e3109 703
ec38833c 704 wait_online(['test1:degraded', 'vlan99:routable'])
1f0e3109 705
371810d1 706 output = check_output('ip -d link show test1')
72b7f1b9 707 print(output)
7d7be1b9 708 self.assertRegex(output, ' mtu 2000 ')
72b7f1b9 709
371810d1 710 output = check_output('ip -d link show vlan99')
14ecd604 711 print(output)
06895a1d
YW
712 self.assertRegex(output, ' mtu 2000 ')
713 self.assertRegex(output, 'REORDER_HDR')
714 self.assertRegex(output, 'LOOSE_BINDING')
715 self.assertRegex(output, 'GVRP')
716 self.assertRegex(output, 'MVRP')
717 self.assertRegex(output, ' id 99 ')
1f0e3109 718
371810d1 719 output = check_output('ip -4 address show dev test1')
7f45d738
YW
720 print(output)
721 self.assertRegex(output, 'inet 192.168.24.5/24 brd 192.168.24.255 scope global test1')
722 self.assertRegex(output, 'inet 192.168.25.5/24 brd 192.168.25.255 scope global test1')
723
371810d1 724 output = check_output('ip -4 address show dev vlan99')
7f45d738
YW
725 print(output)
726 self.assertRegex(output, 'inet 192.168.23.5/24 brd 192.168.23.255 scope global vlan99')
727
1f0e3109 728 def test_macvtap(self):
460feb61
YW
729 for mode in ['private', 'vepa', 'bridge', 'passthru']:
730 with self.subTest(mode=mode):
731 if mode != 'private':
732 self.tearDown()
ec38833c
ZJS
733 copy_unit_to_networkd_unit_path('21-macvtap.netdev', 'netdev-link-local-addressing-yes.network',
734 '11-dummy.netdev', 'macvtap.network')
460feb61
YW
735 with open(os.path.join(network_unit_file_path, '21-macvtap.netdev'), mode='a') as f:
736 f.write('[MACVTAP]\nMode=' + mode)
2cf6fdff 737 start_networkd()
1f0e3109 738
ec38833c 739 wait_online(['macvtap99:degraded', 'test1:degraded'])
460feb61 740
371810d1 741 output = check_output('ip -d link show macvtap99')
460feb61
YW
742 print(output)
743 self.assertRegex(output, 'macvtap mode ' + mode + ' ')
1f0e3109
SS
744
745 def test_macvlan(self):
dff9792b
YW
746 for mode in ['private', 'vepa', 'bridge', 'passthru']:
747 with self.subTest(mode=mode):
748 if mode != 'private':
749 self.tearDown()
ec38833c
ZJS
750 copy_unit_to_networkd_unit_path('21-macvlan.netdev', 'netdev-link-local-addressing-yes.network',
751 '11-dummy.netdev', 'macvlan.network')
dff9792b
YW
752 with open(os.path.join(network_unit_file_path, '21-macvlan.netdev'), mode='a') as f:
753 f.write('[MACVLAN]\nMode=' + mode)
2cf6fdff 754 start_networkd()
dff9792b 755
ec38833c 756 wait_online(['macvlan99:degraded', 'test1:degraded'])
dff9792b 757
371810d1 758 output = check_output('ip -d link show test1')
dff9792b
YW
759 print(output)
760 self.assertRegex(output, ' mtu 2000 ')
72b7f1b9 761
371810d1 762 output = check_output('ip -d link show macvlan99')
dff9792b
YW
763 print(output)
764 self.assertRegex(output, ' mtu 2000 ')
765 self.assertRegex(output, 'macvlan mode ' + mode + ' ')
72b7f1b9 766
7a0a37b2 767 @expectedFailureIfModuleIsNotAvailable('ipvlan')
1f0e3109 768 def test_ipvlan(self):
bc6dff6e
YW
769 for mode, flag in [['L2', 'private'], ['L3', 'vepa'], ['L3S', 'bridge']]:
770 with self.subTest(mode=mode, flag=flag):
771 if mode != 'L2':
772 self.tearDown()
ec38833c
ZJS
773 copy_unit_to_networkd_unit_path('25-ipvlan.netdev', 'netdev-link-local-addressing-yes.network',
774 '11-dummy.netdev', 'ipvlan.network')
bc6dff6e
YW
775 with open(os.path.join(network_unit_file_path, '25-ipvlan.netdev'), mode='a') as f:
776 f.write('[IPVLAN]\nMode=' + mode + '\nFlags=' + flag)
1f0e3109 777
2cf6fdff 778 start_networkd()
ec38833c 779 wait_online(['ipvlan99:degraded', 'test1:degraded'])
bc6dff6e 780
371810d1 781 output = check_output('ip -d link show ipvlan99')
bc6dff6e
YW
782 print(output)
783 self.assertRegex(output, 'ipvlan *mode ' + mode.lower() + ' ' + flag)
1f0e3109 784
956c8fec
YW
785 @expectedFailureIfModuleIsNotAvailable('ipvtap')
786 def test_ipvtap(self):
40921f08
YW
787 for mode, flag in [['L2', 'private'], ['L3', 'vepa'], ['L3S', 'bridge']]:
788 with self.subTest(mode=mode, flag=flag):
789 if mode != 'L2':
790 self.tearDown()
ec38833c
ZJS
791 copy_unit_to_networkd_unit_path('25-ipvtap.netdev', 'netdev-link-local-addressing-yes.network',
792 '11-dummy.netdev', 'ipvtap.network')
40921f08
YW
793 with open(os.path.join(network_unit_file_path, '25-ipvtap.netdev'), mode='a') as f:
794 f.write('[IPVTAP]\nMode=' + mode + '\nFlags=' + flag)
795
2cf6fdff 796 start_networkd()
ec38833c 797 wait_online(['ipvtap99:degraded', 'test1:degraded'])
956c8fec 798
371810d1 799 output = check_output('ip -d link show ipvtap99')
40921f08
YW
800 print(output)
801 self.assertRegex(output, 'ipvtap *mode ' + mode.lower() + ' ' + flag)
956c8fec 802
1f0e3109 803 def test_veth(self):
ec38833c 804 copy_unit_to_networkd_unit_path('25-veth.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 805 start_networkd()
1f0e3109 806
ec38833c 807 wait_online(['veth99:degraded', 'veth-peer:degraded'])
671dacdf 808
371810d1 809 output = check_output('ip -d link show veth99')
671dacdf
YW
810 print(output)
811 self.assertRegex(output, 'link/ether 12:34:56:78:9a:bc')
371810d1 812 output = check_output('ip -d link show veth-peer')
671dacdf
YW
813 print(output)
814 self.assertRegex(output, 'link/ether 12:34:56:78:9a:bd')
1f0e3109 815
1f0e3109 816 def test_tun(self):
ec38833c 817 copy_unit_to_networkd_unit_path('25-tun.netdev')
2cf6fdff 818 start_networkd()
1f0e3109 819
ec38833c 820 wait_online(['tun99:off'])
1f0e3109 821
371810d1 822 output = check_output('ip -d link show tun99')
2746d307
YW
823 print(output)
824 # Old ip command does not support IFF_ flags
825 self.assertRegex(output, 'tun (?:type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
826
1f0e3109 827 def test_tap(self):
ec38833c 828 copy_unit_to_networkd_unit_path('25-tap.netdev')
2cf6fdff 829 start_networkd()
1f0e3109 830
ec38833c 831 wait_online(['tap99:off'])
1f0e3109 832
371810d1 833 output = check_output('ip -d link show tap99')
2746d307
YW
834 print(output)
835 # Old ip command does not support IFF_ flags
836 self.assertRegex(output, 'tun (?:type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
837
7a0a37b2 838 @expectedFailureIfModuleIsNotAvailable('vrf')
1f0e3109 839 def test_vrf(self):
ec38833c 840 copy_unit_to_networkd_unit_path('25-vrf.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 841 start_networkd()
1f0e3109 842
ec38833c 843 wait_online(['vrf99:carrier'])
1f0e3109 844
7a0a37b2 845 @expectedFailureIfModuleIsNotAvailable('vcan')
1f0e3109 846 def test_vcan(self):
ec38833c 847 copy_unit_to_networkd_unit_path('25-vcan.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 848 start_networkd()
1f0e3109 849
ec38833c 850 wait_online(['vcan99:carrier'])
1f0e3109 851
f63b14d3
YW
852 @expectedFailureIfModuleIsNotAvailable('vxcan')
853 def test_vxcan(self):
ec38833c 854 copy_unit_to_networkd_unit_path('25-vxcan.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 855 start_networkd()
f63b14d3 856
ec38833c 857 wait_online(['vxcan99:carrier', 'vxcan-peer:carrier'])
f63b14d3 858
7a3bc5a8
EV
859 @expectedFailureIfModuleIsNotAvailable('wireguard')
860 def test_wireguard(self):
ec38833c
ZJS
861 copy_unit_to_networkd_unit_path('25-wireguard.netdev', '25-wireguard.network',
862 '25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
863 '25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt')
2cf6fdff 864 start_networkd()
ec38833c 865 wait_online(['wg99:carrier', 'wg98:routable'])
5a0bd90b 866
7a3bc5a8 867 if shutil.which('wg'):
371810d1 868 call('wg')
5a0bd90b 869
371810d1 870 output = check_output('wg show wg99 listen-port')
06895a1d 871 self.assertRegex(output, '51820')
371810d1 872 output = check_output('wg show wg99 fwmark')
06895a1d 873 self.assertRegex(output, '0x4d2')
371810d1 874 output = check_output('wg show wg99 allowed-ips')
88aaf89e
ZJS
875 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
876 self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128')
371810d1 877 output = check_output('wg show wg99 persistent-keepalive')
88aaf89e 878 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t20')
371810d1 879 output = check_output('wg show wg99 endpoints')
88aaf89e 880 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.27.3:51820')
371810d1 881 output = check_output('wg show wg99 private-key')
88aaf89e 882 self.assertRegex(output, r'EEGlnEPYJV//kbvvIqxKkQwOiS\+UENyPncC4bF46ong=')
371810d1 883 output = check_output('wg show wg99 preshared-keys')
88aaf89e
ZJS
884 self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA= IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=')
885 self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc= cPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=')
7a3bc5a8 886
371810d1 887 output = check_output('wg show wg98 private-key')
88aaf89e 888 self.assertRegex(output, r'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr\+WHtZLZ90FU=')
da44fb8a 889
1f0e3109 890 def test_geneve(self):
ec38833c 891 copy_unit_to_networkd_unit_path('25-geneve.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 892 start_networkd()
1f0e3109 893
ec38833c 894 wait_online(['geneve99:degraded'])
1f0e3109 895
371810d1 896 output = check_output('ip -d link show geneve99')
14ecd604 897 print(output)
06895a1d
YW
898 self.assertRegex(output, '192.168.22.1')
899 self.assertRegex(output, '6082')
900 self.assertRegex(output, 'udpcsum')
901 self.assertRegex(output, 'udp6zerocsumrx')
1f0e3109
SS
902
903 def test_ipip_tunnel(self):
ec38833c
ZJS
904 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ipip.network',
905 '25-ipip-tunnel.netdev', '25-tunnel.network',
906 '25-ipip-tunnel-local-any.netdev', '25-tunnel-local-any.network',
907 '25-ipip-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 908 start_networkd()
ec38833c 909 wait_online(['ipiptun99:routable', 'ipiptun98:routable', 'ipiptun97:routable', 'dummy98:degraded'])
6a97a864 910
371810d1 911 output = check_output('ip -d link show ipiptun99')
6a97a864
YW
912 print(output)
913 self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local 192.168.223.238 dev dummy98')
371810d1 914 output = check_output('ip -d link show ipiptun98')
6a97a864
YW
915 print(output)
916 self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local any dev dummy98')
371810d1 917 output = check_output('ip -d link show ipiptun97')
6a97a864
YW
918 print(output)
919 self.assertRegex(output, 'ipip (?:ipip |)remote any local 192.168.223.238 dev dummy98')
1f0e3109
SS
920
921 def test_gre_tunnel(self):
ec38833c
ZJS
922 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretun.network',
923 '25-gre-tunnel.netdev', '25-tunnel.network',
924 '25-gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
925 '25-gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 926 start_networkd()
ec38833c 927 wait_online(['gretun99:routable', 'gretun98:routable', 'gretun97:routable', 'dummy98:degraded'])
6a97a864 928
371810d1 929 output = check_output('ip -d link show gretun99')
6a97a864
YW
930 print(output)
931 self.assertRegex(output, 'gre remote 10.65.223.239 local 10.65.223.238 dev dummy98')
38f4bb44
YW
932 self.assertRegex(output, 'ikey 1.2.3.103')
933 self.assertRegex(output, 'okey 1.2.4.103')
934 self.assertRegex(output, 'iseq')
935 self.assertRegex(output, 'oseq')
371810d1 936 output = check_output('ip -d link show gretun98')
6a97a864
YW
937 print(output)
938 self.assertRegex(output, 'gre remote 10.65.223.239 local any dev dummy98')
38f4bb44
YW
939 self.assertRegex(output, 'ikey 0.0.0.104')
940 self.assertRegex(output, 'okey 0.0.0.104')
941 self.assertNotRegex(output, 'iseq')
942 self.assertNotRegex(output, 'oseq')
371810d1 943 output = check_output('ip -d link show gretun97')
6a97a864
YW
944 print(output)
945 self.assertRegex(output, 'gre remote any local 10.65.223.238 dev dummy98')
38f4bb44
YW
946 self.assertRegex(output, 'ikey 0.0.0.105')
947 self.assertRegex(output, 'okey 0.0.0.105')
948 self.assertNotRegex(output, 'iseq')
949 self.assertNotRegex(output, 'oseq')
6a97a864
YW
950
951 def test_ip6gre_tunnel(self):
ec38833c
ZJS
952 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6gretun.network',
953 '25-ip6gre-tunnel.netdev', '25-tunnel.network',
954 '25-ip6gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
955 '25-ip6gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
01943d43 956 start_networkd(5)
6a97a864 957
17bcf0a0
YW
958 # Old kernels seem not to support IPv6LL address on ip6gre tunnel, So please do not use wait_online() here.
959
e39cc445
YW
960 self.check_link_exists('dummy98')
961 self.check_link_exists('ip6gretun99')
962 self.check_link_exists('ip6gretun98')
963 self.check_link_exists('ip6gretun97')
6a97a864 964
371810d1 965 output = check_output('ip -d link show ip6gretun99')
6a97a864
YW
966 print(output)
967 self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 968 output = check_output('ip -d link show ip6gretun98')
6a97a864
YW
969 print(output)
970 self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local any dev dummy98')
371810d1 971 output = check_output('ip -d link show ip6gretun97')
6a97a864
YW
972 print(output)
973 self.assertRegex(output, 'ip6gre remote any local 2a00:ffde:4567:edde::4987 dev dummy98')
1f0e3109 974
11309591 975 def test_gretap_tunnel(self):
ec38833c
ZJS
976 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'gretap.network',
977 '25-gretap-tunnel.netdev', '25-tunnel.network',
978 '25-gretap-tunnel-local-any.netdev', '25-tunnel-local-any.network')
2cf6fdff 979 start_networkd()
ec38833c 980 wait_online(['gretap99:routable', 'gretap98:routable', 'dummy98:degraded'])
6a97a864 981
371810d1 982 output = check_output('ip -d link show gretap99')
6a97a864
YW
983 print(output)
984 self.assertRegex(output, 'gretap remote 10.65.223.239 local 10.65.223.238 dev dummy98')
38f4bb44
YW
985 self.assertRegex(output, 'ikey 0.0.0.106')
986 self.assertRegex(output, 'okey 0.0.0.106')
987 self.assertRegex(output, 'iseq')
988 self.assertRegex(output, 'oseq')
371810d1 989 output = check_output('ip -d link show gretap98')
6a97a864
YW
990 print(output)
991 self.assertRegex(output, 'gretap remote 10.65.223.239 local any dev dummy98')
38f4bb44
YW
992 self.assertRegex(output, 'ikey 0.0.0.107')
993 self.assertRegex(output, 'okey 0.0.0.107')
994 self.assertRegex(output, 'iseq')
995 self.assertRegex(output, 'oseq')
1f0e3109
SS
996
997 def test_ip6gretap_tunnel(self):
ec38833c
ZJS
998 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6gretap.network',
999 '25-ip6gretap-tunnel.netdev', '25-tunnel.network',
1000 '25-ip6gretap-tunnel-local-any.netdev', '25-tunnel-local-any.network')
2cf6fdff 1001 start_networkd()
ec38833c 1002 wait_online(['ip6gretap99:routable', 'ip6gretap98:routable', 'dummy98:degraded'])
6a97a864 1003
371810d1 1004 output = check_output('ip -d link show ip6gretap99')
6a97a864
YW
1005 print(output)
1006 self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1007 output = check_output('ip -d link show ip6gretap98')
6a97a864
YW
1008 print(output)
1009 self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local any dev dummy98')
1f0e3109
SS
1010
1011 def test_vti_tunnel(self):
ec38833c
ZJS
1012 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'vti.network',
1013 '25-vti-tunnel.netdev', '25-tunnel.network',
1014 '25-vti-tunnel-local-any.netdev', '25-tunnel-local-any.network',
1015 '25-vti-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 1016 start_networkd()
ec38833c 1017 wait_online(['vtitun99:routable', 'vtitun98:routable', 'vtitun97:routable', 'dummy98:degraded'])
6a97a864 1018
371810d1 1019 output = check_output('ip -d link show vtitun99')
6a97a864
YW
1020 print(output)
1021 self.assertRegex(output, 'vti remote 10.65.223.239 local 10.65.223.238 dev dummy98')
371810d1 1022 output = check_output('ip -d link show vtitun98')
6a97a864
YW
1023 print(output)
1024 self.assertRegex(output, 'vti remote 10.65.223.239 local any dev dummy98')
371810d1 1025 output = check_output('ip -d link show vtitun97')
6a97a864
YW
1026 print(output)
1027 self.assertRegex(output, 'vti remote any local 10.65.223.238 dev dummy98')
1f0e3109
SS
1028
1029 def test_vti6_tunnel(self):
ec38833c
ZJS
1030 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'vti6.network',
1031 '25-vti6-tunnel.netdev', '25-tunnel.network',
1032 '25-vti6-tunnel-local-any.netdev', '25-tunnel-local-any.network',
1033 '25-vti6-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 1034 start_networkd()
ec38833c 1035 wait_online(['vti6tun99:routable', 'vti6tun98:routable', 'vti6tun97:routable', 'dummy98:degraded'])
6a97a864 1036
371810d1 1037 output = check_output('ip -d link show vti6tun99')
6a97a864
YW
1038 print(output)
1039 self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1040 output = check_output('ip -d link show vti6tun98')
6a97a864
YW
1041 print(output)
1042 self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
371810d1 1043 output = check_output('ip -d link show vti6tun97')
6a97a864
YW
1044 print(output)
1045 self.assertRegex(output, 'vti6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
1f0e3109
SS
1046
1047 def test_ip6tnl_tunnel(self):
ec38833c
ZJS
1048 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'ip6tnl.network',
1049 '25-ip6tnl-tunnel.netdev', '25-tunnel.network',
1050 '25-ip6tnl-tunnel-local-any.netdev', '25-tunnel-local-any.network',
1051 '25-ip6tnl-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 1052 start_networkd()
ec38833c 1053 wait_online(['ip6tnl99:routable', 'ip6tnl98:routable', 'ip6tnl97:routable', 'dummy98:degraded'])
6a97a864 1054
371810d1 1055 output = check_output('ip -d link show ip6tnl99')
6a97a864
YW
1056 print(output)
1057 self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
371810d1 1058 output = check_output('ip -d link show ip6tnl98')
6a97a864
YW
1059 print(output)
1060 self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
371810d1 1061 output = check_output('ip -d link show ip6tnl97')
6a97a864
YW
1062 print(output)
1063 self.assertRegex(output, 'ip6tnl ip6ip6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
1f0e3109
SS
1064
1065 def test_sit_tunnel(self):
ec38833c
ZJS
1066 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'sit.network',
1067 '25-sit-tunnel.netdev', '25-tunnel.network',
1068 '25-sit-tunnel-local-any.netdev', '25-tunnel-local-any.network',
1069 '25-sit-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
2cf6fdff 1070 start_networkd()
ec38833c 1071 wait_online(['sittun99:routable', 'sittun98:routable', 'sittun97:routable', 'dummy98:degraded'])
6a97a864 1072
371810d1 1073 output = check_output('ip -d link show sittun99')
6a97a864
YW
1074 print(output)
1075 self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local 10.65.223.238 dev dummy98")
371810d1 1076 output = check_output('ip -d link show sittun98')
6a97a864
YW
1077 print(output)
1078 self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local any dev dummy98")
371810d1 1079 output = check_output('ip -d link show sittun97')
6a97a864
YW
1080 print(output)
1081 self.assertRegex(output, "sit (?:ip6ip |)remote any local 10.65.223.238 dev dummy98")
1f0e3109 1082
d0e728b6 1083 def test_isatap_tunnel(self):
ec38833c
ZJS
1084 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'isatap.network',
1085 '25-isatap-tunnel.netdev', '25-tunnel.network')
2cf6fdff 1086 start_networkd()
ec38833c 1087 wait_online(['isataptun99:routable', 'dummy98:degraded'])
d0e728b6 1088
371810d1 1089 output = check_output('ip -d link show isataptun99')
14ecd604 1090 print(output)
d0e728b6
SS
1091 self.assertRegex(output, "isatap ")
1092
d29dc4f1 1093 def test_6rd_tunnel(self):
ec38833c
ZJS
1094 copy_unit_to_networkd_unit_path('12-dummy.netdev', '6rd.network',
1095 '25-6rd-tunnel.netdev', '25-tunnel.network')
2cf6fdff 1096 start_networkd()
ec38833c 1097 wait_online(['sittun99:routable', 'dummy98:degraded'])
d29dc4f1 1098
371810d1 1099 output = check_output('ip -d link show sittun99')
6a97a864
YW
1100 print(output)
1101 self.assertRegex(output, '6rd-prefix 2602::/24')
1102
7bea7f9b 1103 @expectedFailureIfERSPANModuleIsNotAvailable()
2266864b 1104 def test_erspan_tunnel(self):
ec38833c
ZJS
1105 copy_unit_to_networkd_unit_path('12-dummy.netdev', 'erspan.network',
1106 '25-erspan-tunnel.netdev', '25-tunnel.network',
1107 '25-erspan-tunnel-local-any.netdev', '25-tunnel-local-any.network')
2cf6fdff 1108 start_networkd()
ec38833c 1109 wait_online(['erspan99:routable', 'erspan98:routable', 'dummy98:degraded'])
2266864b 1110
371810d1 1111 output = check_output('ip -d link show erspan99')
6a97a864
YW
1112 print(output)
1113 self.assertRegex(output, 'erspan remote 172.16.1.100 local 172.16.1.200')
38f4bb44
YW
1114 self.assertRegex(output, 'ikey 0.0.0.101')
1115 self.assertRegex(output, 'okey 0.0.0.101')
1116 self.assertRegex(output, 'iseq')
1117 self.assertRegex(output, 'oseq')
371810d1 1118 output = check_output('ip -d link show erspan98')
2266864b 1119 print(output)
6a97a864
YW
1120 self.assertRegex(output, 'erspan remote 172.16.1.100 local any')
1121 self.assertRegex(output, '102')
38f4bb44
YW
1122 self.assertRegex(output, 'ikey 0.0.0.102')
1123 self.assertRegex(output, 'okey 0.0.0.102')
1124 self.assertRegex(output, 'iseq')
1125 self.assertRegex(output, 'oseq')
2266864b 1126
1f0e3109 1127 def test_tunnel_independent(self):
ec38833c 1128 copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1129 start_networkd()
e40a58b5 1130
ec38833c 1131 wait_online(['ipiptun99:carrier'])
1f0e3109 1132
4b6a6d1e
YW
1133 @expectedFailureIfModuleIsNotAvailable('fou')
1134 def test_fou(self):
1135 # The following redundant check is necessary for CentOS CI.
1136 # Maybe, error handling in lookup_id() in sd-netlink/generic-netlink.c needs to be updated.
1137 self.assertTrue(is_module_available('fou'))
1138
ec38833c
ZJS
1139 copy_unit_to_networkd_unit_path('25-fou-ipproto-ipip.netdev', '25-fou-ipproto-gre.netdev',
1140 '25-fou-ipip.netdev', '25-fou-sit.netdev',
1141 '25-fou-gre.netdev', '25-fou-gretap.netdev')
2cf6fdff 1142 start_networkd()
4b6a6d1e 1143
ec38833c 1144 wait_online(['ipiptun96:off', 'sittun96:off', 'gretun96:off', 'gretap96:off'])
4b6a6d1e 1145
371810d1 1146 output = check_output('ip fou show')
4b6a6d1e
YW
1147 print(output)
1148 self.assertRegex(output, 'port 55555 ipproto 4')
1149 self.assertRegex(output, 'port 55556 ipproto 47')
1150
371810d1 1151 output = check_output('ip -d link show ipiptun96')
4b6a6d1e
YW
1152 print(output)
1153 self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55555')
371810d1 1154 output = check_output('ip -d link show sittun96')
4b6a6d1e
YW
1155 print(output)
1156 self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55555')
371810d1 1157 output = check_output('ip -d link show gretun96')
4b6a6d1e
YW
1158 print(output)
1159 self.assertRegex(output, 'encap fou encap-sport 1001 encap-dport 55556')
371810d1 1160 output = check_output('ip -d link show gretap96')
4b6a6d1e
YW
1161 print(output)
1162 self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55556')
1163
1f0e3109 1164 def test_vxlan(self):
ec38833c
ZJS
1165 copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network',
1166 '11-dummy.netdev', 'vxlan-test1.network')
2cf6fdff 1167 start_networkd()
1f0e3109 1168
ec38833c 1169 wait_online(['test1:degraded', 'vxlan99:degraded'])
1f0e3109 1170
371810d1 1171 output = check_output('ip -d link show vxlan99')
14ecd604 1172 print(output)
1c862fe0 1173 self.assertRegex(output, '999')
1f0e3109
SS
1174 self.assertRegex(output, '5555')
1175 self.assertRegex(output, 'l2miss')
1176 self.assertRegex(output, 'l3miss')
1177 self.assertRegex(output, 'udpcsum')
1178 self.assertRegex(output, 'udp6zerocsumtx')
1179 self.assertRegex(output, 'udp6zerocsumrx')
1180 self.assertRegex(output, 'remcsumtx')
1181 self.assertRegex(output, 'remcsumrx')
1182 self.assertRegex(output, 'gbp')
1183
371810d1 1184 output = check_output('bridge fdb show dev vxlan99')
1c862fe0
YW
1185 print(output)
1186 self.assertRegex(output, '00:11:22:33:44:55 dst 10.0.0.5 self permanent')
1187 self.assertRegex(output, '00:11:22:33:44:66 dst 10.0.0.6 self permanent')
1188 self.assertRegex(output, '00:11:22:33:44:77 dst 10.0.0.7 self permanent')
1189
02849d8b 1190 def test_macsec(self):
ec38833c
ZJS
1191 copy_unit_to_networkd_unit_path('25-macsec.netdev', '25-macsec.network', '25-macsec.key',
1192 'macsec.network', '12-dummy.netdev')
2cf6fdff 1193 start_networkd()
02849d8b 1194
ec38833c 1195 wait_online(['dummy98:degraded', 'macsec99:routable'])
02849d8b 1196
371810d1 1197 output = check_output('ip -d link show macsec99')
02849d8b
YW
1198 print(output)
1199 self.assertRegex(output, 'macsec99@dummy98')
1200 self.assertRegex(output, 'macsec sci [0-9a-f]*000b')
1201 self.assertRegex(output, 'encrypt on')
1202
371810d1 1203 output = check_output('ip macsec show macsec99')
02849d8b
YW
1204 print(output)
1205 self.assertRegex(output, 'encrypt on')
1206 self.assertRegex(output, 'TXSC: [0-9a-f]*000b on SA 1')
1207 self.assertRegex(output, '0: PN [0-9]*, state on, key 01000000000000000000000000000000')
1208 self.assertRegex(output, '1: PN [0-9]*, state on, key 02030000000000000000000000000000')
1209 self.assertRegex(output, 'RXSC: c619528fe6a00100, state on')
1210 self.assertRegex(output, '0: PN [0-9]*, state on, key 02030405000000000000000000000000')
1211 self.assertRegex(output, '1: PN [0-9]*, state on, key 02030405060000000000000000000000')
1212 self.assertRegex(output, '2: PN [0-9]*, state off, key 02030405060700000000000000000000')
1213 self.assertRegex(output, '3: PN [0-9]*, state off, key 02030405060708000000000000000000')
1214 self.assertNotRegex(output, 'key 02030405067080900000000000000000')
1215 self.assertRegex(output, 'RXSC: 8c16456c83a90002, state on')
1216 self.assertRegex(output, '0: PN [0-9]*, state off, key 02030400000000000000000000000000')
1217
811f33d0 1218 def test_nlmon(self):
ec38833c 1219 copy_unit_to_networkd_unit_path('25-nlmon.netdev', 'netdev-link-local-addressing-yes.network')
2cf6fdff 1220 start_networkd()
811f33d0 1221
ec38833c 1222 wait_online(['nlmon99:carrier'])
02849d8b 1223
cff83db9
YW
1224class NetworkdL2TPTests(unittest.TestCase, Utilities):
1225
1226 links =[
1227 'l2tp-ses1',
1228 'l2tp-ses2',
1229 'l2tp-ses3',
1230 'l2tp-ses4',
1231 'test1']
1232
1233 units = [
1234 '11-dummy.netdev',
1235 '25-l2tp-dummy.network',
1236 '25-l2tp-ip.netdev',
1237 '25-l2tp-udp.netdev']
1238
1239 l2tp_tunnel_ids = [ '10' ]
1240
1241 def setUp(self):
ad78d7b0 1242 remove_l2tp_tunnels(self.l2tp_tunnel_ids)
ec38833c 1243 remove_links(self.links)
aaae5713 1244 stop_networkd(show_logs=False)
cff83db9
YW
1245
1246 def tearDown(self):
ad78d7b0 1247 remove_l2tp_tunnels(self.l2tp_tunnel_ids)
ec38833c
ZJS
1248 remove_links(self.links)
1249 remove_unit_from_networkd_path(self.units)
aaae5713 1250 stop_networkd(show_logs=True)
cff83db9
YW
1251
1252 @expectedFailureIfModuleIsNotAvailable('l2tp_eth')
1253 def test_l2tp_udp(self):
ec38833c 1254 copy_unit_to_networkd_unit_path('11-dummy.netdev', '25-l2tp-dummy.network', '25-l2tp-udp.netdev')
2cf6fdff 1255 start_networkd()
cff83db9 1256
ec38833c 1257 wait_online(['test1:routable', 'l2tp-ses1:off', 'l2tp-ses2:off'])
cff83db9 1258
371810d1 1259 output = check_output('ip l2tp show tunnel tunnel_id 10')
cff83db9
YW
1260 print(output)
1261 self.assertRegex(output, "Tunnel 10, encap UDP")
1262 self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
1263 self.assertRegex(output, "Peer tunnel 11")
1264 self.assertRegex(output, "UDP source / dest ports: 3000/4000")
1265 self.assertRegex(output, "UDP checksum: enabled")
1266
371810d1 1267 output = check_output('ip l2tp show session tid 10 session_id 15')
cff83db9
YW
1268 print(output)
1269 self.assertRegex(output, "Session 15 in tunnel 10")
1270 self.assertRegex(output, "Peer session 16, tunnel 11")
1271 self.assertRegex(output, "interface name: l2tp-ses1")
1272
371810d1 1273 output = check_output('ip l2tp show session tid 10 session_id 17')
cff83db9
YW
1274 print(output)
1275 self.assertRegex(output, "Session 17 in tunnel 10")
1276 self.assertRegex(output, "Peer session 18, tunnel 11")
1277 self.assertRegex(output, "interface name: l2tp-ses2")
1278
1279 @expectedFailureIfModuleIsNotAvailable('l2tp_ip')
1280 def test_l2tp_ip(self):
ec38833c 1281 copy_unit_to_networkd_unit_path('11-dummy.netdev', '25-l2tp-dummy.network', '25-l2tp-ip.netdev')
2cf6fdff 1282 start_networkd()
cff83db9 1283
ec38833c 1284 wait_online(['test1:routable', 'l2tp-ses3:off', 'l2tp-ses4:off'])
cff83db9 1285
371810d1 1286 output = check_output('ip l2tp show tunnel tunnel_id 10')
cff83db9
YW
1287 print(output)
1288 self.assertRegex(output, "Tunnel 10, encap IP")
1289 self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
1290 self.assertRegex(output, "Peer tunnel 12")
1291
371810d1 1292 output = check_output('ip l2tp show session tid 10 session_id 25')
cff83db9
YW
1293 print(output)
1294 self.assertRegex(output, "Session 25 in tunnel 10")
1295 self.assertRegex(output, "Peer session 26, tunnel 12")
1296 self.assertRegex(output, "interface name: l2tp-ses3")
1297
371810d1 1298 output = check_output('ip l2tp show session tid 10 session_id 27')
cff83db9
YW
1299 print(output)
1300 self.assertRegex(output, "Session 27 in tunnel 10")
1301 self.assertRegex(output, "Peer session 28, tunnel 12")
1302 self.assertRegex(output, "interface name: l2tp-ses4")
1303
be68c2c9 1304class NetworkdNetworkTests(unittest.TestCase, Utilities):
09ea6724
YW
1305 links = [
1306 'bond199',
1307 'dummy98',
cd65d067 1308 'dummy99',
09ea6724
YW
1309 'test1']
1310
1311 units = [
1312 '11-dummy.netdev',
1313 '12-dummy.netdev',
1314 '23-active-slave.network',
1e498853 1315 '24-keep-configuration-static.network',
fdcd1ec5 1316 '24-search-domain.network',
09ea6724 1317 '25-address-link-section.network',
b8102725
YW
1318 '25-address-preferred-lifetime-zero-ipv6.network',
1319 '25-address-static.network',
cd65d067 1320 '25-bind-carrier.network',
09ea6724
YW
1321 '25-bond-active-backup-slave.netdev',
1322 '25-fibrule-invert.network',
1323 '25-fibrule-port-range.network',
1324 '25-ipv6-address-label-section.network',
e4a71bf3 1325 '25-neighbor-section.network',
05514ae1
YW
1326 '25-link-local-addressing-no.network',
1327 '25-link-local-addressing-yes.network',
09ea6724 1328 '25-link-section-unmanaged.network',
20ca06a6 1329 '25-route-ipv6-src.network',
0ef830cf 1330 '25-route-static.network',
4da33154 1331 '25-sysctl-disable-ipv6.network',
09ea6724
YW
1332 '25-sysctl.network',
1333 'configure-without-carrier.network',
b677774d 1334 'routing-policy-rule-dummy98.network',
b8102725 1335 'routing-policy-rule-test1.network']
1f0e3109 1336
95c74b0a 1337 routing_policy_rule_tables = ['7', '8']
5f68a6a4 1338 routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
95c74b0a 1339
1f0e3109 1340 def setUp(self):
ec38833c
ZJS
1341 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
1342 remove_routes(self.routes)
1343 remove_links(self.links)
aaae5713 1344 stop_networkd(show_logs=False)
1f0e3109
SS
1345
1346 def tearDown(self):
ec38833c
ZJS
1347 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
1348 remove_routes(self.routes)
1349 remove_links(self.links)
1350 remove_unit_from_networkd_path(self.units)
aaae5713 1351 stop_networkd(show_logs=True)
1f0e3109 1352
b8102725 1353 def test_address_static(self):
ec38833c 1354 copy_unit_to_networkd_unit_path('25-address-static.network', '12-dummy.netdev')
2cf6fdff 1355 start_networkd()
b8102725 1356
ec38833c 1357 wait_online(['dummy98:routable'])
b8102725 1358
371810d1 1359 output = check_output('ip -4 address show dev dummy98')
b8102725
YW
1360 print(output)
1361 self.assertRegex(output, 'inet 10.1.2.3/16 brd 10.1.255.255 scope global dummy98')
1362 self.assertRegex(output, 'inet 10.1.2.4/16 brd 10.1.255.255 scope global secondary dummy98')
1363 self.assertRegex(output, 'inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98')
1364
1365 # invalid sections
1366 self.assertNotRegex(output, '10.10.0.1/16')
1367 self.assertNotRegex(output, '10.10.0.2/16')
1368
371810d1 1369 output = check_output('ip -4 address show dev dummy98 label 32')
b8102725
YW
1370 self.assertRegex(output, 'inet 10.3.2.3/16 brd 10.3.255.255 scope global 32')
1371
371810d1 1372 output = check_output('ip -4 address show dev dummy98 label 33')
b8102725
YW
1373 self.assertRegex(output, 'inet 10.4.2.3 peer 10.4.2.4/16 scope global 33')
1374
371810d1 1375 output = check_output('ip -4 address show dev dummy98 label 34')
b8102725
YW
1376 self.assertRegex(output, 'inet 192.168.[0-9]*.1/24 brd 192.168.[0-9]*.255 scope global 34')
1377
371810d1 1378 output = check_output('ip -4 address show dev dummy98 label 35')
b8102725
YW
1379 self.assertRegex(output, 'inet 172.[0-9]*.0.1/16 brd 172.[0-9]*.255.255 scope global 35')
1380
371810d1 1381 output = check_output('ip -6 address show dev dummy98')
b8102725
YW
1382 print(output)
1383 self.assertRegex(output, 'inet6 2001:db8:0:f101::15/64 scope global')
1384 self.assertRegex(output, 'inet6 2001:db8:0:f101::16/64 scope global')
1385 self.assertRegex(output, 'inet6 2001:db8:0:f102::15/64 scope global')
1386 self.assertRegex(output, 'inet6 2001:db8:0:f102::16/64 scope global')
1387 self.assertRegex(output, 'inet6 2001:db8:0:f103::20 peer 2001:db8:0:f103::10/128 scope global')
1388 self.assertRegex(output, 'inet6 fd[0-9a-f:]*1/64 scope global')
1389
1390 def test_address_preferred_lifetime_zero_ipv6(self):
ec38833c 1391 copy_unit_to_networkd_unit_path('25-address-preferred-lifetime-zero-ipv6.network', '12-dummy.netdev')
01943d43 1392 start_networkd(5)
1f0e3109 1393
e39cc445 1394 self.check_link_exists('dummy98')
791c1140 1395 self.check_operstate('dummy98', 'routable', setup_state='configuring')
b8102725 1396
371810d1 1397 output = check_output('ip address show dummy98')
b8102725
YW
1398 print(output)
1399 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
1400 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
1f0e3109
SS
1401
1402 def test_configure_without_carrier(self):
ec38833c 1403 copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
2cf6fdff 1404 start_networkd()
df7f9afa 1405 wait_online(['test1:routable'])
e40a58b5 1406
371810d1 1407 output = check_output(*networkctl_cmd, 'status', 'test1')
1f0e3109
SS
1408 print(output)
1409 self.assertRegex(output, '192.168.0.15')
1410 self.assertRegex(output, '192.168.0.1')
1411 self.assertRegex(output, 'routable')
1412
1f0e3109 1413 def test_routing_policy_rule(self):
ec38833c 1414 copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev')
2cf6fdff 1415 start_networkd()
df7f9afa 1416 wait_online(['test1:degraded'])
e40a58b5 1417
371810d1 1418 output = check_output('ip rule')
1f0e3109
SS
1419 print(output)
1420 self.assertRegex(output, '111')
1421 self.assertRegex(output, 'from 192.168.100.18')
f7bdd562 1422 self.assertRegex(output, r'tos (?:0x08|throughput)\s')
1f0e3109
SS
1423 self.assertRegex(output, 'iif test1')
1424 self.assertRegex(output, 'oif test1')
1425 self.assertRegex(output, 'lookup 7')
1426
b677774d 1427 def test_routing_policy_rule_issue_11280(self):
ec38833c
ZJS
1428 copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev',
1429 'routing-policy-rule-dummy98.network', '12-dummy.netdev')
b677774d 1430
b677774d
YW
1431 for trial in range(3):
1432 # Remove state files only first time
aaae5713 1433 start_networkd()
df7f9afa
YW
1434 wait_online(['test1:degraded', 'dummy98:degraded'])
1435 time.sleep(1)
b677774d 1436
371810d1 1437 output = check_output('ip rule list table 7')
b677774d
YW
1438 print(output)
1439 self.assertRegex(output, '111: from 192.168.100.18 tos (?:0x08|throughput) iif test1 oif test1 lookup 7')
1440
371810d1 1441 output = check_output('ip rule list table 8')
b677774d
YW
1442 print(output)
1443 self.assertRegex(output, '112: from 192.168.101.18 tos (?:0x08|throughput) iif dummy98 oif dummy98 lookup 8')
1444
aaae5713
YW
1445 stop_networkd(remove_state_files=False)
1446
d586a2c3 1447 @expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
926062f0 1448 def test_routing_policy_rule_port_range(self):
ec38833c 1449 copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
2cf6fdff 1450 start_networkd()
df7f9afa 1451 wait_online(['test1:degraded'])
e40a58b5 1452
371810d1 1453 output = check_output('ip rule')
926062f0
SS
1454 print(output)
1455 self.assertRegex(output, '111')
1456 self.assertRegex(output, 'from 192.168.100.18')
1457 self.assertRegex(output, '1123-1150')
1458 self.assertRegex(output, '3224-3290')
1459 self.assertRegex(output, 'tcp')
1460 self.assertRegex(output, 'lookup 7')
1f0e3109 1461
d586a2c3 1462 @expectedFailureIfRoutingPolicyIPProtoIsNotAvailable()
efecf9cd 1463 def test_routing_policy_rule_invert(self):
ec38833c 1464 copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
2cf6fdff 1465 start_networkd()
df7f9afa 1466 wait_online(['test1:degraded'])
e40a58b5 1467
371810d1 1468 output = check_output('ip rule')
efecf9cd 1469 print(output)
efecf9cd
SS
1470 self.assertRegex(output, '111')
1471 self.assertRegex(output, 'not.*?from.*?192.168.100.18')
1472 self.assertRegex(output, 'tcp')
1473 self.assertRegex(output, 'lookup 7')
1474
0ef830cf 1475 def test_route_static(self):
ec38833c 1476 copy_unit_to_networkd_unit_path('25-route-static.network', '12-dummy.netdev')
2cf6fdff 1477 start_networkd()
ec38833c 1478 wait_online(['dummy98:routable'])
0d34228f 1479
371810d1 1480 output = check_output('ip -6 route show dev dummy98')
0d34228f 1481 print(output)
0ef830cf
YW
1482 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff proto static')
1483 self.assertRegex(output, '2001:1234:5:8f63::1 proto kernel')
1f0e3109 1484
371810d1 1485 output = check_output('ip -6 route show dev dummy98 default')
0ef830cf 1486 self.assertRegex(output, 'default via 2001:1234:5:8fff:ff:ff:ff:ff proto static metric 1024 pref medium')
1f0e3109 1487
371810d1 1488 output = check_output('ip -4 route show dev dummy98')
1f0e3109 1489 print(output)
0ef830cf
YW
1490 self.assertRegex(output, '149.10.124.48/28 proto kernel scope link src 149.10.124.58')
1491 self.assertRegex(output, '149.10.124.64 proto static scope link')
2b00dff8 1492 self.assertRegex(output, '169.254.0.0/16 proto static scope link metric 2048')
0ef830cf
YW
1493 self.assertRegex(output, '192.168.1.1 proto static initcwnd 20')
1494 self.assertRegex(output, '192.168.1.2 proto static initrwnd 30')
1f0e3109 1495
371810d1 1496 output = check_output('ip -4 route show dev dummy98 default')
0ef830cf
YW
1497 self.assertRegex(output, 'default via 149.10.125.65 proto static onlink')
1498 self.assertRegex(output, 'default via 149.10.124.64 proto static')
6543b7fd 1499 self.assertRegex(output, 'default proto static')
1f0e3109 1500
371810d1 1501 output = check_output('ip route show type blackhole')
1f0e3109 1502 print(output)
0ef830cf 1503 self.assertRegex(output, 'blackhole 202.54.1.2 proto static')
f5050e48 1504
371810d1 1505 output = check_output('ip route show type unreachable')
f5050e48 1506 print(output)
0ef830cf 1507 self.assertRegex(output, 'unreachable 202.54.1.3 proto static')
f5050e48 1508
371810d1 1509 output = check_output('ip route show type prohibit')
f5050e48 1510 print(output)
0ef830cf 1511 self.assertRegex(output, 'prohibit 202.54.1.4 proto static')
f5050e48 1512
20ca06a6
DA
1513 def test_ip_route_ipv6_src_route(self):
1514 # a dummy device does not make the addresses go through tentative state, so we
1515 # reuse a bond from an earlier test, which does make the addresses go through
1516 # tentative state, and do our test on that
ec38833c 1517 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 1518 start_networkd()
df7f9afa 1519 wait_online(['dummy98:enslaved', 'bond199:routable'])
20ca06a6 1520
371810d1 1521 output = check_output('ip -6 route list dev bond199')
20ca06a6
DA
1522 print(output)
1523 self.assertRegex(output, 'abcd::/16')
1524 self.assertRegex(output, 'src')
1525 self.assertRegex(output, '2001:1234:56:8f63::2')
1526
1f0e3109 1527 def test_ip_link_mac_address(self):
ec38833c 1528 copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
2cf6fdff 1529 start_networkd()
df7f9afa 1530 wait_online(['dummy98:degraded'])
1f0e3109 1531
371810d1 1532 output = check_output('ip link show dummy98')
1f0e3109
SS
1533 print(output)
1534 self.assertRegex(output, '00:01:02:aa:bb:cc')
1535
1536 def test_ip_link_unmanaged(self):
ec38833c 1537 copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
df7f9afa 1538 start_networkd(5)
1f0e3109 1539
e39cc445 1540 self.check_link_exists('dummy98')
1f0e3109 1541
df7f9afa 1542 self.check_operstate('dummy98', 'off', setup_state='unmanaged')
1f0e3109
SS
1543
1544 def test_ipv6_address_label(self):
ec38833c 1545 copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
2cf6fdff 1546 start_networkd()
df7f9afa 1547 wait_online(['dummy98:degraded'])
1f0e3109 1548
371810d1 1549 output = check_output('ip addrlabel list')
1f0e3109
SS
1550 print(output)
1551 self.assertRegex(output, '2004:da8:1::/64')
1552
e4a71bf3 1553 def test_ipv6_neighbor(self):
ec38833c 1554 copy_unit_to_networkd_unit_path('25-neighbor-section.network', '12-dummy.netdev')
2cf6fdff 1555 start_networkd()
df7f9afa 1556 wait_online(['dummy98:degraded'], timeout='40s')
e4a71bf3 1557
df7f9afa 1558 output = check_output('ip neigh list dev dummy98')
e4a71bf3
WKI
1559 print(output)
1560 self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
094b5479 1561 self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
e4a71bf3 1562
05514ae1 1563 def test_link_local_addressing(self):
ec38833c
ZJS
1564 copy_unit_to_networkd_unit_path('25-link-local-addressing-yes.network', '11-dummy.netdev',
1565 '25-link-local-addressing-no.network', '12-dummy.netdev')
2cf6fdff 1566 start_networkd()
ec38833c 1567 wait_online(['test1:degraded', 'dummy98:carrier'])
05514ae1 1568
371810d1 1569 output = check_output('ip address show dev test1')
05514ae1
YW
1570 print(output)
1571 self.assertRegex(output, 'inet .* scope link')
1572 self.assertRegex(output, 'inet6 .* scope link')
1573
371810d1 1574 output = check_output('ip address show dev dummy98')
05514ae1
YW
1575 print(output)
1576 self.assertNotRegex(output, 'inet6* .* scope link')
1577
05514ae1
YW
1578 '''
1579 Documentation/networking/ip-sysctl.txt
1580
1581 addr_gen_mode - INTEGER
1582 Defines how link-local and autoconf addresses are generated.
1583
1584 0: generate address based on EUI64 (default)
1585 1: do no generate a link-local address, use EUI64 for addresses generated
1586 from autoconf
1587 2: generate stable privacy addresses, using the secret from
1588 stable_secret (RFC7217)
1589 3: generate stable privacy addresses, using a random secret if unset
1590 '''
1591
1592 test1_addr_gen_mode = ''
1593 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')):
1594 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')) as f:
1595 try:
1596 f.readline()
1597 except IOError:
1598 # if stable_secret is unset, then EIO is returned
1599 test1_addr_gen_mode = '0'
1600 else:
1601 test1_addr_gen_mode = '2'
1602 else:
1603 test1_addr_gen_mode = '0'
1604
1605 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'addr_gen_mode')):
ec38833c 1606 self.assertEqual(read_ipv6_sysctl_attr('test1', 'addr_gen_mode'), test1_addr_gen_mode)
05514ae1
YW
1607
1608 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'dummy98'), 'addr_gen_mode')):
ec38833c 1609 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'addr_gen_mode'), '1')
05514ae1 1610
1f0e3109 1611 def test_sysctl(self):
ec38833c 1612 copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
2cf6fdff 1613 start_networkd()
ec38833c
ZJS
1614 wait_online(['dummy98:degraded'])
1615
1616 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
1617 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
1618 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
1619 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
1620 self.assertEqual(read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
1621 self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
1622 self.assertEqual(read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
1f0e3109 1623
4da33154 1624 def test_sysctl_disable_ipv6(self):
ec38833c 1625 copy_unit_to_networkd_unit_path('25-sysctl-disable-ipv6.network', '12-dummy.netdev')
4da33154
YW
1626
1627 print('## Disable ipv6')
cefd6b3d
ZJS
1628 check_output('sysctl net.ipv6.conf.all.disable_ipv6=1')
1629 check_output('sysctl net.ipv6.conf.default.disable_ipv6=1')
4da33154 1630
2cf6fdff 1631 start_networkd()
ec38833c 1632 wait_online(['dummy98:routable'])
4da33154 1633
371810d1 1634 output = check_output('ip -4 address show dummy98')
4da33154
YW
1635 print(output)
1636 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
371810d1 1637 output = check_output('ip -6 address show dummy98')
4da33154
YW
1638 print(output)
1639 self.assertEqual(output, '')
4933b97d
YW
1640 output = check_output('ip -4 route show dev dummy98')
1641 print(output)
1642 self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
1643 output = check_output('ip -6 route show dev dummy98')
1644 print(output)
1645 self.assertEqual(output, '')
4da33154 1646
cefd6b3d 1647 check_output('ip link del dummy98')
4da33154
YW
1648
1649 print('## Enable ipv6')
cefd6b3d
ZJS
1650 check_output('sysctl net.ipv6.conf.all.disable_ipv6=0')
1651 check_output('sysctl net.ipv6.conf.default.disable_ipv6=0')
4da33154 1652
aaae5713 1653 restart_networkd()
ec38833c 1654 wait_online(['dummy98:routable'])
4da33154 1655
371810d1 1656 output = check_output('ip -4 address show dummy98')
4da33154
YW
1657 print(output)
1658 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
371810d1 1659 output = check_output('ip -6 address show dummy98')
4da33154 1660 print(output)
4933b97d 1661 self.assertRegex(output, 'inet6 2607:5300:203:3906::/64 scope global')
4da33154 1662 self.assertRegex(output, 'inet6 .* scope link')
4933b97d
YW
1663 output = check_output('ip -4 route show dev dummy98')
1664 print(output)
1665 self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
1666 output = check_output('ip -6 route show dev dummy98')
1667 print(output)
1668 self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
4da33154 1669
cd65d067 1670 def test_bind_carrier(self):
ec38833c 1671 copy_unit_to_networkd_unit_path('25-bind-carrier.network', '11-dummy.netdev')
2cf6fdff 1672 start_networkd()
df7f9afa 1673 wait_online(['test1:routable'])
cd65d067 1674
cefd6b3d
ZJS
1675 check_output('ip link add dummy98 type dummy')
1676 check_output('ip link set dummy98 up')
b117044c 1677 time.sleep(2)
371810d1 1678 output = check_output('ip address show test1')
cd65d067
YW
1679 print(output)
1680 self.assertRegex(output, 'UP,LOWER_UP')
1681 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
791c1140 1682 self.check_operstate('test1', 'routable')
cd65d067 1683
cefd6b3d
ZJS
1684 check_output('ip link add dummy99 type dummy')
1685 check_output('ip link set dummy99 up')
b117044c 1686 time.sleep(2)
371810d1 1687 output = check_output('ip address show test1')
cd65d067
YW
1688 print(output)
1689 self.assertRegex(output, 'UP,LOWER_UP')
1690 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
791c1140 1691 self.check_operstate('test1', 'routable')
cd65d067 1692
cefd6b3d 1693 check_output('ip link del dummy98')
b117044c 1694 time.sleep(2)
371810d1 1695 output = check_output('ip address show test1')
cd65d067
YW
1696 print(output)
1697 self.assertRegex(output, 'UP,LOWER_UP')
1698 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
791c1140 1699 self.check_operstate('test1', 'routable')
cd65d067 1700
cefd6b3d 1701 check_output('ip link del dummy99')
b117044c 1702 time.sleep(2)
371810d1 1703 output = check_output('ip address show test1')
cd65d067
YW
1704 print(output)
1705 self.assertNotRegex(output, 'UP,LOWER_UP')
1706 self.assertRegex(output, 'DOWN')
1707 self.assertNotRegex(output, '192.168.10')
791c1140 1708 self.check_operstate('test1', 'off')
cd65d067 1709
cefd6b3d
ZJS
1710 check_output('ip link add dummy98 type dummy')
1711 check_output('ip link set dummy98 up')
b117044c 1712 time.sleep(2)
371810d1 1713 output = check_output('ip address show test1')
cd65d067
YW
1714 print(output)
1715 self.assertRegex(output, 'UP,LOWER_UP')
1716 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
791c1140 1717 self.check_operstate('test1', 'routable')
cd65d067 1718
fdcd1ec5 1719 def test_domain(self):
ec38833c 1720 copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network')
2cf6fdff 1721 start_networkd()
ec38833c 1722 wait_online(['dummy98:routable'])
fdcd1ec5 1723
371810d1 1724 output = check_output(*networkctl_cmd, 'status', 'dummy98', env=env)
fdcd1ec5
YW
1725 print(output)
1726 self.assertRegex(output, 'Address: 192.168.42.100')
1727 self.assertRegex(output, 'DNS: 192.168.42.1')
1728 self.assertRegex(output, 'Search Domains: one')
1729
1e498853
YW
1730 def test_keep_configuration_static(self):
1731 check_output('systemctl stop systemd-networkd')
1732
1733 check_output('ip link add name dummy98 type dummy')
1734 check_output('ip address add 10.1.2.3/16 dev dummy98')
1735 check_output('ip address add 10.2.3.4/16 dev dummy98 valid_lft 600 preferred_lft 500')
1736 output = check_output('ip address show dummy98')
1737 print(output)
1738 self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
1739 self.assertRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
1740 output = check_output('ip route show dev dummy98')
1741 print(output)
1742
1743 copy_unit_to_networkd_unit_path('24-keep-configuration-static.network')
2cf6fdff 1744 start_networkd()
1e498853
YW
1745 wait_online(['dummy98:routable'])
1746
1747 output = check_output('ip address show dummy98')
1748 print(output)
1749 self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
1750 self.assertNotRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
1751
be68c2c9 1752class NetworkdBondTests(unittest.TestCase, Utilities):
c3a8853f 1753 links = [
c2990ec3 1754 'bond199',
c3a8853f 1755 'bond99',
cc3e488c
YW
1756 'dummy98',
1757 'test1']
c3a8853f
YW
1758
1759 units = [
cc3e488c
YW
1760 '11-dummy.netdev',
1761 '12-dummy.netdev',
c2990ec3
YW
1762 '23-active-slave.network',
1763 '23-bond199.network',
1764 '23-primary-slave.network',
c2990ec3 1765 '25-bond-active-backup-slave.netdev',
c3a8853f 1766 '25-bond.netdev',
c3a8853f 1767 'bond99.network',
cc3e488c 1768 'bond-slave.network']
c3a8853f
YW
1769
1770 def setUp(self):
ec38833c 1771 remove_links(self.links)
aaae5713 1772 stop_networkd(show_logs=False)
c3a8853f
YW
1773
1774 def tearDown(self):
ec38833c
ZJS
1775 remove_links(self.links)
1776 remove_unit_from_networkd_path(self.units)
aaae5713 1777 stop_networkd(show_logs=True)
c3a8853f 1778
c2990ec3 1779 def test_bond_active_slave(self):
ec38833c 1780 copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
2cf6fdff 1781 start_networkd()
35a78c51 1782 wait_online(['dummy98:enslaved', 'bond199:degraded'])
c2990ec3 1783
371810d1 1784 output = check_output('ip -d link show bond199')
c2990ec3
YW
1785 print(output)
1786 self.assertRegex(output, 'active_slave dummy98')
1787
1788 def test_bond_primary_slave(self):
35a78c51 1789 copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
2cf6fdff 1790 start_networkd()
35a78c51 1791 wait_online(['dummy98:enslaved', 'bond199:degraded'])
c2990ec3 1792
371810d1 1793 output = check_output('ip -d link show bond199')
c2990ec3 1794 print(output)
35a78c51 1795 self.assertRegex(output, 'primary dummy98')
c2990ec3 1796
cc3e488c 1797 def test_bond_operstate(self):
ec38833c
ZJS
1798 copy_unit_to_networkd_unit_path('25-bond.netdev', '11-dummy.netdev', '12-dummy.netdev',
1799 'bond99.network','bond-slave.network')
2cf6fdff 1800 start_networkd()
35a78c51 1801 wait_online(['dummy98:enslaved', 'test1:enslaved', 'bond99:routable'])
c3a8853f 1802
371810d1 1803 output = check_output('ip -d link show dummy98')
c3a8853f 1804 print(output)
cc3e488c 1805 self.assertRegex(output, 'SLAVE,UP,LOWER_UP')
c3a8853f 1806
371810d1 1807 output = check_output('ip -d link show test1')
c3a8853f
YW
1808 print(output)
1809 self.assertRegex(output, 'SLAVE,UP,LOWER_UP')
1810
371810d1 1811 output = check_output('ip -d link show bond99')
c3a8853f
YW
1812 print(output)
1813 self.assertRegex(output, 'MASTER,UP,LOWER_UP')
1814
791c1140
YW
1815 self.check_operstate('dummy98', 'enslaved')
1816 self.check_operstate('test1', 'enslaved')
1817 self.check_operstate('bond99', 'routable')
c3a8853f 1818
cefd6b3d 1819 check_output('ip link set dummy98 down')
c3a8853f
YW
1820 time.sleep(2)
1821
791c1140
YW
1822 self.check_operstate('dummy98', 'off')
1823 self.check_operstate('test1', 'enslaved')
1824 self.check_operstate('bond99', 'degraded-carrier')
c3a8853f 1825
cefd6b3d 1826 check_output('ip link set dummy98 up')
c3a8853f
YW
1827 time.sleep(2)
1828
791c1140
YW
1829 self.check_operstate('dummy98', 'enslaved')
1830 self.check_operstate('test1', 'enslaved')
1831 self.check_operstate('bond99', 'routable')
c3a8853f 1832
cefd6b3d
ZJS
1833 check_output('ip link set dummy98 down')
1834 check_output('ip link set test1 down')
2700d2c7 1835 time.sleep(2)
cc3e488c 1836
791c1140
YW
1837 self.check_operstate('dummy98', 'off')
1838 self.check_operstate('test1', 'off')
2700d2c7 1839
2700d2c7
YW
1840 for trial in range(30):
1841 if trial > 0:
1842 time.sleep(1)
371810d1 1843 output = check_output('ip address show bond99')
2700d2c7 1844 print(output)
ec38833c 1845 if get_operstate('bond99') == 'no-carrier':
2700d2c7
YW
1846 break
1847 else:
1848 # Huh? Kernel does not recognize that all slave interfaces are down?
1849 # Let's confirm that networkd's operstate is consistent with ip's result.
1850 self.assertNotRegex(output, 'NO-CARRIER')
cc3e488c 1851
be68c2c9 1852class NetworkdBridgeTests(unittest.TestCase, Utilities):
09ea6724
YW
1853 links = [
1854 'bridge99',
1855 'dummy98',
1856 'test1']
1857
1858 units = [
1859 '11-dummy.netdev',
1860 '12-dummy.netdev',
1861 '26-bridge.netdev',
1862 '26-bridge-slave-interface-1.network',
1863 '26-bridge-slave-interface-2.network',
804b6cd2 1864 'bridge99-ignore-carrier-loss.network',
09ea6724 1865 'bridge99.network']
1f0e3109 1866
8d17c386
YW
1867 routing_policy_rule_tables = ['100']
1868
1f0e3109 1869 def setUp(self):
8d17c386 1870 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
ec38833c 1871 remove_links(self.links)
aaae5713 1872 stop_networkd(show_logs=False)
1f0e3109
SS
1873
1874 def tearDown(self):
8d17c386 1875 remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
ec38833c
ZJS
1876 remove_links(self.links)
1877 remove_unit_from_networkd_path(self.units)
aaae5713 1878 stop_networkd(show_logs=True)
1f0e3109
SS
1879
1880 def test_bridge_property(self):
ec38833c
ZJS
1881 copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
1882 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
1883 'bridge99.network')
2cf6fdff 1884 start_networkd()
90e3bcbd 1885 wait_online(['dummy98:enslaved', 'test1:enslaved', 'bridge99:routable'])
1f0e3109 1886
371810d1 1887 output = check_output('ip -d link show test1')
1f0e3109
SS
1888 print(output)
1889 self.assertRegex(output, 'master')
1890 self.assertRegex(output, 'bridge')
1891
371810d1 1892 output = check_output('ip -d link show dummy98')
1f0e3109
SS
1893 print(output)
1894 self.assertRegex(output, 'master')
1895 self.assertRegex(output, 'bridge')
1896
371810d1 1897 output = check_output('ip addr show bridge99')
1f0e3109 1898 print(output)
2be6c5d2 1899 self.assertRegex(output, '192.168.0.15/24')
1f0e3109 1900
371810d1 1901 output = check_output('bridge -d link show dummy98')
1f0e3109 1902 print(output)
ec38833c
ZJS
1903 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
1904 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
1905 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
1906 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood'), '0')
1907 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
7f15b714 1908 if (os.path.exists('/sys/devices/virtual/net/bridge99/lower_dummy98/brport/neigh_suppress')):
ec38833c
ZJS
1909 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress'), '1')
1910 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'learning'), '0')
4d7ed14f
SS
1911
1912 # CONFIG_BRIDGE_IGMP_SNOOPING=y
1913 if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
ec38833c 1914 self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
1f0e3109 1915
371810d1 1916 check_output('ip address add 192.168.0.16/24 dev bridge99')
804b6cd2
YW
1917 time.sleep(1)
1918
371810d1 1919 output = check_output('ip addr show bridge99')
2be6c5d2
YW
1920 print(output)
1921 self.assertRegex(output, '192.168.0.16/24')
1922
371810d1 1923 self.assertEqual(call('ip link del test1'), 0)
2be6c5d2
YW
1924 time.sleep(3)
1925
791c1140 1926 self.check_operstate('bridge99', 'degraded-carrier')
2be6c5d2 1927
cefd6b3d 1928 check_output('ip link del dummy98')
804b6cd2
YW
1929 time.sleep(3)
1930
791c1140 1931 self.check_operstate('bridge99', 'no-carrier')
2be6c5d2 1932
371810d1 1933 output = check_output('ip address show bridge99')
804b6cd2
YW
1934 print(output)
1935 self.assertRegex(output, 'NO-CARRIER')
1936 self.assertNotRegex(output, '192.168.0.15/24')
1937 self.assertNotRegex(output, '192.168.0.16/24')
1938
1939 def test_bridge_ignore_carrier_loss(self):
ec38833c
ZJS
1940 copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
1941 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
1942 'bridge99-ignore-carrier-loss.network')
2cf6fdff 1943 start_networkd()
90e3bcbd 1944 wait_online(['dummy98:enslaved', 'test1:enslaved', 'bridge99:routable'])
804b6cd2 1945
371810d1 1946 check_output('ip address add 192.168.0.16/24 dev bridge99')
804b6cd2
YW
1947 time.sleep(1)
1948
371810d1
ZJS
1949 check_output('ip link del test1')
1950 check_output('ip link del dummy98')
804b6cd2
YW
1951 time.sleep(3)
1952
371810d1 1953 output = check_output('ip address show bridge99')
804b6cd2
YW
1954 print(output)
1955 self.assertRegex(output, 'NO-CARRIER')
1956 self.assertRegex(output, 'inet 192.168.0.15/24 brd 192.168.0.255 scope global bridge99')
1957 self.assertRegex(output, 'inet 192.168.0.16/24 scope global secondary bridge99')
1958
6609924c 1959 def test_bridge_ignore_carrier_loss_frequent_loss_and_gain(self):
ec38833c
ZJS
1960 copy_unit_to_networkd_unit_path('26-bridge.netdev', '26-bridge-slave-interface-1.network',
1961 'bridge99-ignore-carrier-loss.network')
2cf6fdff 1962 start_networkd()
90e3bcbd 1963 wait_online(['bridge99:no-carrier'])
6609924c 1964
90e3bcbd
YW
1965 for trial in range(4):
1966 check_output('ip link add dummy98 type dummy')
1967 check_output('ip link set dummy98 up')
1968 if trial < 3:
1969 check_output('ip link del dummy98')
6609924c 1970
90e3bcbd 1971 wait_online(['bridge99:routable', 'dummy98:enslaved'])
6609924c 1972
371810d1 1973 output = check_output('ip address show bridge99')
6609924c
YW
1974 print(output)
1975 self.assertRegex(output, 'inet 192.168.0.15/24 brd 192.168.0.255 scope global bridge99')
1976
371810d1 1977 output = check_output('ip rule list table 100')
6609924c
YW
1978 print(output)
1979 self.assertEqual(output, '0: from all to 8.8.8.8 lookup 100')
1980
be68c2c9 1981class NetworkdLLDPTests(unittest.TestCase, Utilities):
1f0e3109
SS
1982 links = ['veth99']
1983
09ea6724
YW
1984 units = [
1985 '23-emit-lldp.network',
1986 '24-lldp.network',
1987 '25-veth.netdev']
1f0e3109
SS
1988
1989 def setUp(self):
ec38833c 1990 remove_links(self.links)
aaae5713 1991 stop_networkd(show_logs=False)
1f0e3109
SS
1992
1993 def tearDown(self):
ec38833c
ZJS
1994 remove_links(self.links)
1995 remove_unit_from_networkd_path(self.units)
aaae5713 1996 stop_networkd(show_logs=True)
1f0e3109
SS
1997
1998 def test_lldp(self):
ec38833c 1999 copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
2cf6fdff 2000 start_networkd()
ec38833c 2001 wait_online(['veth99:degraded', 'veth-peer:degraded'])
1f0e3109 2002
371810d1 2003 output = check_output(*networkctl_cmd, 'lldp', env=env)
1f0e3109
SS
2004 print(output)
2005 self.assertRegex(output, 'veth-peer')
2006 self.assertRegex(output, 'veth99')
2007
be68c2c9 2008class NetworkdRATests(unittest.TestCase, Utilities):
1f0e3109
SS
2009 links = ['veth99']
2010
09ea6724
YW
2011 units = [
2012 '25-veth.netdev',
2013 'ipv6-prefix.network',
2014 'ipv6-prefix-veth.network']
1f0e3109
SS
2015
2016 def setUp(self):
ec38833c 2017 remove_links(self.links)
aaae5713 2018 stop_networkd(show_logs=False)
1f0e3109
SS
2019
2020 def tearDown(self):
ec38833c
ZJS
2021 remove_links(self.links)
2022 remove_unit_from_networkd_path(self.units)
aaae5713 2023 stop_networkd(show_logs=True)
1f0e3109
SS
2024
2025 def test_ipv6_prefix_delegation(self):
ec38833c
ZJS
2026 warn_about_firewalld()
2027 copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
2cf6fdff 2028 start_networkd()
ec38833c 2029 wait_online(['veth99:routable', 'veth-peer:degraded'])
1f0e3109 2030
371810d1 2031 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109
SS
2032 print(output)
2033 self.assertRegex(output, '2002:da8:1:0')
2034
be68c2c9 2035class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
fdcd1ec5 2036 links = ['veth99']
09ea6724
YW
2037
2038 units = [
09ea6724
YW
2039 '25-veth.netdev',
2040 'dhcp-client.network',
2041 'dhcp-client-timezone-router.network',
2042 'dhcp-server.network',
2043 'dhcp-server-timezone-router.network']
1f0e3109
SS
2044
2045 def setUp(self):
ec38833c 2046 remove_links(self.links)
aaae5713 2047 stop_networkd(show_logs=False)
1f0e3109
SS
2048
2049 def tearDown(self):
ec38833c
ZJS
2050 remove_links(self.links)
2051 remove_unit_from_networkd_path(self.units)
aaae5713 2052 stop_networkd(show_logs=True)
1f0e3109
SS
2053
2054 def test_dhcp_server(self):
ec38833c
ZJS
2055 warn_about_firewalld()
2056 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
2cf6fdff 2057 start_networkd()
ec38833c 2058 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2059
371810d1 2060 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109
SS
2061 print(output)
2062 self.assertRegex(output, '192.168.5.*')
2063 self.assertRegex(output, 'Gateway: 192.168.5.1')
2064 self.assertRegex(output, 'DNS: 192.168.5.1')
2065 self.assertRegex(output, 'NTP: 192.168.5.1')
2066
1f0e3109 2067 def test_emit_router_timezone(self):
ec38833c
ZJS
2068 warn_about_firewalld()
2069 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
2cf6fdff 2070 start_networkd()
ec38833c 2071 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2072
371810d1 2073 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109
SS
2074 print(output)
2075 self.assertRegex(output, 'Gateway: 192.168.5.*')
2076 self.assertRegex(output, '192.168.5.*')
2077 self.assertRegex(output, 'Europe/Berlin')
2078
be68c2c9 2079class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
09ea6724 2080 links = [
18c613dc
YW
2081 'veth99',
2082 'vrf99']
09ea6724
YW
2083
2084 units = [
2085 '25-veth.netdev',
18c613dc
YW
2086 '25-vrf.netdev',
2087 '25-vrf.network',
09ea6724 2088 'dhcp-client-anonymize.network',
af3b1498 2089 'dhcp-client-gateway-onlink-implicit.network',
09ea6724
YW
2090 'dhcp-client-ipv4-dhcp-settings.network',
2091 'dhcp-client-ipv4-only-ipv6-disabled.network',
2092 'dhcp-client-ipv4-only.network',
2093 'dhcp-client-ipv6-only.network',
2094 'dhcp-client-ipv6-rapid-commit.network',
1e498853
YW
2095 'dhcp-client-keep-configuration-dhcp-on-stop.network',
2096 'dhcp-client-keep-configuration-dhcp.network',
09ea6724
YW
2097 'dhcp-client-listen-port.network',
2098 'dhcp-client-route-metric.network',
2099 'dhcp-client-route-table.network',
18c613dc 2100 'dhcp-client-vrf.network',
117a55c7
YW
2101 'dhcp-client-with-ipv4ll-fallback-with-dhcp-server.network',
2102 'dhcp-client-with-ipv4ll-fallback-without-dhcp-server.network',
3e9d5552 2103 'dhcp-client.network',
09ea6724 2104 'dhcp-server-veth-peer.network',
30d3b54e
YW
2105 'dhcp-v4-server-veth-peer.network',
2106 'static.network']
1f0e3109
SS
2107
2108 def setUp(self):
ec38833c
ZJS
2109 stop_dnsmasq(dnsmasq_pid_file)
2110 remove_links(self.links)
aaae5713 2111 stop_networkd(show_logs=False)
1f0e3109
SS
2112
2113 def tearDown(self):
ec38833c
ZJS
2114 stop_dnsmasq(dnsmasq_pid_file)
2115 remove_lease_file()
2116 remove_log_file()
2117 remove_links(self.links)
2118 remove_unit_from_networkd_path(self.units)
aaae5713 2119 stop_networkd(show_logs=True)
1f0e3109
SS
2120
2121 def test_dhcp_client_ipv6_only(self):
ec38833c 2122 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
1f0e3109 2123
2cf6fdff 2124 start_networkd()
ec38833c
ZJS
2125 wait_online(['veth-peer:carrier'])
2126 start_dnsmasq()
2127 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2128
371810d1 2129 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109
SS
2130 print(output)
2131 self.assertRegex(output, '2600::')
2132 self.assertNotRegex(output, '192.168.5')
2133
3a956d38 2134 # Confirm that ipv6 token is not set in the kernel
371810d1 2135 output = check_output('ip token show dev veth99')
3a956d38
YW
2136 print(output)
2137 self.assertRegex(output, 'token :: dev veth99')
2138
1f0e3109 2139 def test_dhcp_client_ipv4_only(self):
ec38833c 2140 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-only-ipv6-disabled.network')
1f0e3109 2141
2cf6fdff 2142 start_networkd()
ec38833c
ZJS
2143 wait_online(['veth-peer:carrier'])
2144 start_dnsmasq()
2145 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2146
371810d1 2147 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109
SS
2148 print(output)
2149 self.assertNotRegex(output, '2600::')
2150 self.assertRegex(output, '192.168.5')
2151
2152 def test_dhcp_client_ipv4_ipv6(self):
ec38833c
ZJS
2153 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
2154 'dhcp-client-ipv4-only.network')
2cf6fdff 2155 start_networkd()
ec38833c
ZJS
2156 wait_online(['veth-peer:carrier'])
2157 start_dnsmasq()
2158 wait_online(['veth99:routable', 'veth-peer:routable'])
2629df47
YW
2159
2160 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79
YW
2161 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
2162 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
1f0e3109 2163
371810d1 2164 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109
SS
2165 print(output)
2166 self.assertRegex(output, '2600::')
2167 self.assertRegex(output, '192.168.5')
2168
2169 def test_dhcp_client_settings(self):
ec38833c 2170 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
1f0e3109 2171
2cf6fdff 2172 start_networkd()
ec38833c
ZJS
2173 wait_online(['veth-peer:carrier'])
2174 start_dnsmasq()
2175 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2176
0ae7a66d 2177 print('## ip address show dev veth99')
371810d1 2178 output = check_output('ip address show dev veth99')
1f0e3109
SS
2179 print(output)
2180 self.assertRegex(output, '12:34:56:78:9a:bc')
2181 self.assertRegex(output, '192.168.5')
2182 self.assertRegex(output, '1492')
2183
0ae7a66d
YW
2184 # issue #8726
2185 print('## ip route show table main dev veth99')
371810d1 2186 output = check_output('ip route show table main dev veth99')
1f0e3109 2187 print(output)
0ae7a66d 2188 self.assertNotRegex(output, 'proto dhcp')
1f0e3109 2189
0ae7a66d 2190 print('## ip route show table 211 dev veth99')
371810d1 2191 output = check_output('ip route show table 211 dev veth99')
0ae7a66d
YW
2192 print(output)
2193 self.assertRegex(output, 'default via 192.168.5.1 proto dhcp')
2194 self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 proto dhcp')
2195 self.assertRegex(output, '192.168.5.1 proto dhcp scope link')
2196
2197 print('## dnsmasq log')
ec38833c
ZJS
2198 self.assertTrue(search_words_in_dnsmasq_log('vendor class: SusantVendorTest', True))
2199 self.assertTrue(search_words_in_dnsmasq_log('DHCPDISCOVER(veth-peer) 12:34:56:78:9a:bc'))
2200 self.assertTrue(search_words_in_dnsmasq_log('client provides name: test-hostname'))
2201 self.assertTrue(search_words_in_dnsmasq_log('26:mtu'))
1f0e3109
SS
2202
2203 def test_dhcp6_client_settings_rapidcommit_true(self):
ec38833c 2204 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
2cf6fdff 2205 start_networkd()
ec38833c
ZJS
2206 wait_online(['veth-peer:carrier'])
2207 start_dnsmasq()
2208 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2209
371810d1 2210 output = check_output('ip address show dev veth99')
1f0e3109
SS
2211 print(output)
2212 self.assertRegex(output, '12:34:56:78:9a:bc')
ec38833c 2213 self.assertTrue(search_words_in_dnsmasq_log('14:rapid-commit', True))
1f0e3109
SS
2214
2215 def test_dhcp6_client_settings_rapidcommit_false(self):
ec38833c 2216 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
2cf6fdff 2217 start_networkd()
ec38833c
ZJS
2218 wait_online(['veth-peer:carrier'])
2219 start_dnsmasq()
2220 wait_online(['veth99:routable', 'veth-peer:routable'])
1f0e3109 2221
371810d1 2222 output = check_output('ip address show dev veth99')
1f0e3109
SS
2223 print(output)
2224 self.assertRegex(output, '12:34:56:78:9a:bc')
ec38833c 2225 self.assertFalse(search_words_in_dnsmasq_log('14:rapid-commit', True))
1f0e3109
SS
2226
2227 def test_dhcp_client_settings_anonymize(self):
ec38833c 2228 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
2cf6fdff 2229 start_networkd()
ec38833c
ZJS
2230 wait_online(['veth-peer:carrier'])
2231 start_dnsmasq()
2232 wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 2233
ec38833c
ZJS
2234 self.assertFalse(search_words_in_dnsmasq_log('VendorClassIdentifier=SusantVendorTest', True))
2235 self.assertFalse(search_words_in_dnsmasq_log('test-hostname'))
2236 self.assertFalse(search_words_in_dnsmasq_log('26:mtu'))
1f0e3109
SS
2237
2238 def test_dhcp_client_listen_port(self):
ec38833c 2239 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
2cf6fdff 2240 start_networkd()
ec38833c
ZJS
2241 wait_online(['veth-peer:carrier'])
2242 start_dnsmasq('--dhcp-alternate-port=67,5555')
2243 wait_online(['veth99:routable', 'veth-peer:routable'])
2629df47
YW
2244
2245 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79
YW
2246 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
2247 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
1f0e3109 2248
371810d1 2249 output = check_output('ip -4 address show dev veth99')
b412fce8
YW
2250 print(output)
2251 self.assertRegex(output, '192.168.5.* dynamic')
1f0e3109
SS
2252
2253 def test_dhcp_route_table_id(self):
ec38833c 2254 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
2cf6fdff 2255 start_networkd()
ec38833c
ZJS
2256 wait_online(['veth-peer:carrier'])
2257 start_dnsmasq()
2258 wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 2259
371810d1 2260 output = check_output('ip route show table 12')
1f0e3109 2261 print(output)
1f0e3109
SS
2262 self.assertRegex(output, 'veth99 proto dhcp')
2263 self.assertRegex(output, '192.168.5.1')
2264
2265 def test_dhcp_route_metric(self):
ec38833c 2266 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
2cf6fdff 2267 start_networkd()
ec38833c
ZJS
2268 wait_online(['veth-peer:carrier'])
2269 start_dnsmasq()
2270 wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 2271
371810d1 2272 output = check_output('ip route show dev veth99')
1f0e3109 2273 print(output)
1f0e3109
SS
2274 self.assertRegex(output, 'metric 24')
2275
1e498853
YW
2276 def test_dhcp_keep_configuration_dhcp(self):
2277 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp.network')
2cf6fdff 2278 start_networkd()
ec38833c 2279 wait_online(['veth-peer:carrier'])
1e498853 2280 start_dnsmasq(lease_time='2m')
ec38833c 2281 wait_online(['veth99:routable', 'veth-peer:routable'])
e40a58b5 2282
1e498853
YW
2283 output = check_output('ip address show dev veth99 scope global')
2284 print(output)
2285 self.assertRegex(output, r'192.168.5.*')
2286
371810d1 2287 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109 2288 print(output)
1e498853 2289 self.assertRegex(output, r'192.168.5.*')
e40a58b5 2290
5238e957 2291 # Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
ec38833c 2292 stop_dnsmasq(dnsmasq_pid_file)
1f0e3109
SS
2293
2294 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
1e498853 2295 print('Wait for the dynamic address to be expired')
1f0e3109
SS
2296 time.sleep(125)
2297
1e498853
YW
2298 print('The lease address should be kept after lease expired')
2299 output = check_output('ip address show dev veth99 scope global')
2300 print(output)
2301 self.assertRegex(output, r'192.168.5.*')
2302
371810d1 2303 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
1f0e3109 2304 print(output)
1e498853
YW
2305 self.assertRegex(output, r'192.168.5.*')
2306
2307 check_output('systemctl stop systemd-networkd')
2308
2309 print('The lease address should be kept after networkd stopped')
2310 output = check_output('ip address show dev veth99 scope global')
2311 print(output)
2312 self.assertRegex(output, r'192.168.5.*')
2313
2314 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
2315 print(output)
2316 self.assertRegex(output, r'192.168.5.*')
2317
2318 check_output('systemctl start systemd-networkd')
2319 wait_online(['veth-peer:routable'])
2320
2321 print('Still the lease address should be kept after networkd restarted')
2322 output = check_output('ip address show dev veth99 scope global')
2323 print(output)
2324 self.assertRegex(output, r'192.168.5.*')
2325
2326 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
2327 print(output)
2328 self.assertRegex(output, r'192.168.5.*')
2329
2330 def test_dhcp_keep_configuration_dhcp_on_stop(self):
2331 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp-on-stop.network')
2cf6fdff 2332 start_networkd()
1e498853
YW
2333 wait_online(['veth-peer:carrier'])
2334 start_dnsmasq(lease_time='2m')
2335 wait_online(['veth99:routable', 'veth-peer:routable'])
2336
2337 output = check_output('ip address show dev veth99 scope global')
2338 print(output)
2339 self.assertRegex(output, r'192.168.5.*')
2340
2341 stop_dnsmasq(dnsmasq_pid_file)
2342 check_output('systemctl stop systemd-networkd')
2343
2344 output = check_output('ip address show dev veth99 scope global')
2345 print(output)
2346 self.assertRegex(output, r'192.168.5.*')
2347
aaae5713 2348 restart_networkd()
1e498853
YW
2349 wait_online(['veth-peer:routable'])
2350
2351 output = check_output('ip address show dev veth99 scope global')
2352 print(output)
2353 self.assertNotRegex(output, r'192.168.5.*')
1f0e3109 2354
30d3b54e 2355 def test_dhcp_client_reuse_address_as_static(self):
ec38833c 2356 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
2cf6fdff 2357 start_networkd()
ec38833c
ZJS
2358 wait_online(['veth-peer:carrier'])
2359 start_dnsmasq()
2360 wait_online(['veth99:routable', 'veth-peer:routable'])
2629df47
YW
2361
2362 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79
YW
2363 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
2364 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
30d3b54e 2365
371810d1 2366 output = check_output('ip address show dev veth99 scope global')
30d3b54e
YW
2367 print(output)
2368 self.assertRegex(output, '192.168.5')
2369 self.assertRegex(output, '2600::')
2370
2629df47
YW
2371 ipv4_address = re.search(r'192.168.5.[0-9]*/24', output)
2372 ipv6_address = re.search(r'2600::[0-9a-f:]*/128', output)
30d3b54e
YW
2373 static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address.group(), 'Address=' + ipv6_address.group()])
2374 print(static_network)
2375
ec38833c 2376 remove_unit_from_networkd_path(['dhcp-client.network'])
30d3b54e
YW
2377
2378 with open(os.path.join(network_unit_file_path, 'static.network'), mode='w') as f:
2379 f.write(static_network)
2380
2629df47
YW
2381 # When networkd started, the links are already configured, so let's wait for 5 seconds
2382 # the links to be re-configured.
aaae5713 2383 restart_networkd(5)
ec38833c 2384 wait_online(['veth99:routable', 'veth-peer:routable'])
30d3b54e 2385
371810d1 2386 output = check_output('ip -4 address show dev veth99 scope global')
30d3b54e
YW
2387 print(output)
2388 self.assertRegex(output, '192.168.5')
2389 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
2390
371810d1 2391 output = check_output('ip -6 address show dev veth99 scope global')
30d3b54e
YW
2392 print(output)
2393 self.assertRegex(output, '2600::')
2394 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
2395
18c613dc
YW
2396 @expectedFailureIfModuleIsNotAvailable('vrf')
2397 def test_dhcp_client_vrf(self):
ec38833c
ZJS
2398 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-vrf.network',
2399 '25-vrf.netdev', '25-vrf.network')
2cf6fdff 2400 start_networkd()
ec38833c
ZJS
2401 wait_online(['veth-peer:carrier'])
2402 start_dnsmasq()
2403 wait_online(['veth99:routable', 'veth-peer:routable', 'vrf99:carrier'])
2629df47
YW
2404
2405 # link become 'routable' when at least one protocol provide an valid address.
e16ffe79
YW
2406 self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4')
2407 self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
18c613dc
YW
2408
2409 print('## ip -d link show dev vrf99')
371810d1 2410 output = check_output('ip -d link show dev vrf99')
18c613dc
YW
2411 print(output)
2412 self.assertRegex(output, 'vrf table 42')
2413
2414 print('## ip address show vrf vrf99')
371810d1 2415 output = check_output('ip address show vrf vrf99')
d90f4f7d
YW
2416 print(output)
2417 self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
2418 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
2419 self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)')
2420 self.assertRegex(output, 'inet6 .* scope link')
18c613dc
YW
2421
2422 print('## ip address show dev veth99')
371810d1 2423 output = check_output('ip address show dev veth99')
18c613dc 2424 print(output)
18c613dc
YW
2425 self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
2426 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
d90f4f7d 2427 self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (?:dynamic noprefixroute|noprefixroute dynamic)')
18c613dc
YW
2428 self.assertRegex(output, 'inet6 .* scope link')
2429
2430 print('## ip route show vrf vrf99')
371810d1 2431 output = check_output('ip route show vrf vrf99')
18c613dc
YW
2432 print(output)
2433 self.assertRegex(output, 'default via 192.168.5.1 dev veth99 proto dhcp src 192.168.5.')
2434 self.assertRegex(output, 'default dev veth99 proto static scope link')
2435 self.assertRegex(output, '169.254.0.0/16 dev veth99 proto kernel scope link src 169.254')
2436 self.assertRegex(output, '192.168.5.0/24 dev veth99 proto kernel scope link src 192.168.5')
2437 self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 dev veth99 proto dhcp')
2438 self.assertRegex(output, '192.168.5.1 dev veth99 proto dhcp scope link src 192.168.5')
2439
2440 print('## ip route show table main dev veth99')
371810d1 2441 output = check_output('ip route show table main dev veth99')
18c613dc
YW
2442 print(output)
2443 self.assertEqual(output, '')
2444
af3b1498 2445 def test_dhcp_client_gateway_onlink_implicit(self):
ec38833c
ZJS
2446 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
2447 'dhcp-client-gateway-onlink-implicit.network')
2cf6fdff 2448 start_networkd()
ec38833c
ZJS
2449 wait_online(['veth-peer:carrier'])
2450 start_dnsmasq()
2451 wait_online(['veth99:routable', 'veth-peer:routable'])
af3b1498 2452
371810d1 2453 output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
af3b1498
YW
2454 print(output)
2455 self.assertRegex(output, '192.168.5')
2456
371810d1 2457 output = check_output('ip route list dev veth99 10.0.0.0/8')
af3b1498
YW
2458 print(output)
2459 self.assertRegex(output, 'onlink')
371810d1 2460 output = check_output('ip route list dev veth99 192.168.100.0/24')
af3b1498
YW
2461 print(output)
2462 self.assertRegex(output, 'onlink')
2463
117a55c7 2464 def test_dhcp_client_with_ipv4ll_fallback_with_dhcp_server(self):
ec38833c
ZJS
2465 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
2466 'dhcp-client-with-ipv4ll-fallback-with-dhcp-server.network')
2cf6fdff 2467 start_networkd()
ec38833c
ZJS
2468 wait_online(['veth-peer:carrier'])
2469 start_dnsmasq(lease_time='2m')
2470 wait_online(['veth99:routable', 'veth-peer:routable'])
63c598ed 2471
371810d1 2472 output = check_output('ip address show dev veth99')
63c598ed
YW
2473 print(output)
2474
371810d1 2475 output = check_output('ip -6 address show dev veth99 scope global dynamic')
63c598ed 2476 self.assertNotRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic')
371810d1 2477 output = check_output('ip -6 address show dev veth99 scope link')
63c598ed 2478 self.assertRegex(output, 'inet6 .* scope link')
371810d1 2479 output = check_output('ip -4 address show dev veth99 scope global dynamic')
63c598ed 2480 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
371810d1 2481 output = check_output('ip -4 address show dev veth99 scope link')
63c598ed
YW
2482 self.assertNotRegex(output, 'inet .* scope link')
2483
2484 print('Wait for the dynamic address to be expired')
2485 time.sleep(130)
2486
371810d1 2487 output = check_output('ip address show dev veth99')
63c598ed
YW
2488 print(output)
2489
371810d1 2490 output = check_output('ip -6 address show dev veth99 scope global dynamic')
63c598ed 2491 self.assertNotRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic')
371810d1 2492 output = check_output('ip -6 address show dev veth99 scope link')
63c598ed 2493 self.assertRegex(output, 'inet6 .* scope link')
371810d1 2494 output = check_output('ip -4 address show dev veth99 scope global dynamic')
63c598ed 2495 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
371810d1 2496 output = check_output('ip -4 address show dev veth99 scope link')
63c598ed
YW
2497 self.assertNotRegex(output, 'inet .* scope link')
2498
ec38833c 2499 search_words_in_dnsmasq_log('DHCPOFFER', show_all=True)
63c598ed 2500
117a55c7 2501 def test_dhcp_client_with_ipv4ll_fallback_without_dhcp_server(self):
ec38833c
ZJS
2502 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
2503 'dhcp-client-with-ipv4ll-fallback-without-dhcp-server.network')
2cf6fdff 2504 start_networkd()
ec38833c 2505 wait_online(['veth99:degraded', 'veth-peer:routable'])
117a55c7 2506
371810d1 2507 output = check_output('ip address show dev veth99')
117a55c7
YW
2508 print(output)
2509
371810d1 2510 output = check_output('ip -6 address show dev veth99 scope global dynamic')
117a55c7 2511 self.assertNotRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic')
371810d1 2512 output = check_output('ip -6 address show dev veth99 scope link')
117a55c7 2513 self.assertRegex(output, 'inet6 .* scope link')
371810d1 2514 output = check_output('ip -4 address show dev veth99 scope global dynamic')
117a55c7 2515 self.assertNotRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
371810d1 2516 output = check_output('ip -4 address show dev veth99 scope link')
117a55c7
YW
2517 self.assertRegex(output, 'inet .* scope link')
2518
b6efd661 2519 def test_dhcp_client_route_remove_on_renew(self):
ec38833c
ZJS
2520 copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
2521 'dhcp-client-ipv4-only-ipv6-disabled.network')
2cf6fdff 2522 start_networkd()
ec38833c
ZJS
2523 wait_online(['veth-peer:carrier'])
2524 start_dnsmasq(ipv4_range='192.168.5.100,192.168.5.199', lease_time='2m')
2525 wait_online(['veth99:routable', 'veth-peer:routable'])
b6efd661
YW
2526
2527 # test for issue #12490
2528
371810d1 2529 output = check_output('ip -4 address show dev veth99 scope global dynamic')
b6efd661
YW
2530 print(output)
2531 self.assertRegex(output, 'inet 192.168.5.1[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
2532 address1=None
2533 for line in output.splitlines():
2534 if 'brd 192.168.5.255 scope global dynamic veth99' in line:
2535 address1 = line.split()[1].split('/')[0]
2536 break
2537
371810d1 2538 output = check_output('ip -4 route show dev veth99')
b6efd661
YW
2539 print(output)
2540 self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address1} metric 1024')
2541 self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address1} metric 1024')
2542
ec38833c
ZJS
2543 stop_dnsmasq(dnsmasq_pid_file)
2544 start_dnsmasq(ipv4_range='192.168.5.200,192.168.5.250', lease_time='2m')
b6efd661
YW
2545
2546 print('Wait for the dynamic address to be expired')
2547 time.sleep(130)
2548
371810d1 2549 output = check_output('ip -4 address show dev veth99 scope global dynamic')
b6efd661
YW
2550 print(output)
2551 self.assertRegex(output, 'inet 192.168.5.2[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
2552 address2=None
2553 for line in output.splitlines():
2554 if 'brd 192.168.5.255 scope global dynamic veth99' in line:
2555 address2 = line.split()[1].split('/')[0]
2556 break
2557
2558 self.assertNotEqual(address1, address2)
2559
371810d1 2560 output = check_output('ip -4 route show dev veth99')
b6efd661
YW
2561 print(output)
2562 self.assertNotRegex(output, f'default via 192.168.5.1 proto dhcp src {address1} metric 1024')
2563 self.assertNotRegex(output, f'192.168.5.1 proto dhcp scope link src {address1} metric 1024')
2564 self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address2} metric 1024')
2565 self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address2} metric 1024')
2566
1f0e3109 2567if __name__ == '__main__':
9c1ae484
YW
2568 parser = argparse.ArgumentParser()
2569 parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
2570 parser.add_argument('--networkd', help='Path to systemd-networkd', dest='networkd_bin')
2571 parser.add_argument('--wait-online', help='Path to systemd-networkd-wait-online', dest='wait_online_bin')
2572 parser.add_argument('--networkctl', help='Path to networkctl', dest='networkctl_bin')
2573 parser.add_argument('--valgrind', help='Enable valgrind', dest='use_valgrind', type=bool, nargs='?', const=True, default=use_valgrind)
2574 parser.add_argument('--debug', help='Generate debugging logs', dest='enable_debug', type=bool, nargs='?', const=True, default=enable_debug)
94c03122 2575 parser.add_argument('--asan-options', help='ASAN options', dest='asan_options')
fa4c6095 2576 parser.add_argument('--lsan-options', help='LSAN options', dest='lsan_options')
94c03122 2577 parser.add_argument('--ubsan-options', help='UBSAN options', dest='ubsan_options')
9c1ae484
YW
2578 ns, args = parser.parse_known_args(namespace=unittest)
2579
2580 if ns.build_dir:
2581 if ns.networkd_bin or ns.wait_online_bin or ns.networkctl_bin:
2582 print('WARNING: --networkd, --wait-online, or --networkctl options are ignored when --build-dir is specified.')
2583 networkd_bin = os.path.join(ns.build_dir, 'systemd-networkd')
2584 wait_online_bin = os.path.join(ns.build_dir, 'systemd-networkd-wait-online')
2585 networkctl_bin = os.path.join(ns.build_dir, 'networkctl')
2586 else:
2587 if ns.networkd_bin:
2588 networkd_bin = ns.networkd_bin
2589 if ns.wait_online_bin:
2590 wait_online_bin = ns.wait_online_bin
2591 if ns.networkctl_bin:
2592 networkctl_bin = ns.networkctl_bin
2593
2594 use_valgrind = ns.use_valgrind
2595 enable_debug = ns.enable_debug
94c03122 2596 asan_options = ns.asan_options
fa4c6095 2597 lsan_options = ns.lsan_options
94c03122 2598 ubsan_options = ns.ubsan_options
9c1ae484
YW
2599
2600 if use_valgrind:
2601 networkctl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', networkctl_bin]
2602 wait_online_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', wait_online_bin]
2603 else:
2604 networkctl_cmd = [networkctl_bin]
2605 wait_online_cmd = [wait_online_bin]
2606
2607 if enable_debug:
2608 env.update({ 'SYSTEMD_LOG_LEVEL' : 'debug' })
94c03122
YW
2609 if asan_options:
2610 env.update({ 'ASAN_OPTIONS' : asan_options })
fa4c6095
YW
2611 if lsan_options:
2612 env.update({ 'LSAN_OPTIONS' : lsan_options })
94c03122
YW
2613 if ubsan_options:
2614 env.update({ 'UBSAN_OPTIONS' : ubsan_options })
9c1ae484
YW
2615
2616 sys.argv[1:] = args
1f0e3109
SS
2617 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
2618 verbosity=3))