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