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