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