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