]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
test-network: sort links and units
[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
5import os
6import sys
7import unittest
8import subprocess
9import time
201bf07f 10import re
1f0e3109
SS
11import shutil
12import signal
13import socket
14import threading
15from shutil import copytree
16
d486a2d0 17network_unit_file_path='/run/systemd/network'
bad4969b 18networkd_runtime_directory='/run/systemd/netif'
d486a2d0 19networkd_ci_path='/run/networkd-ci'
1f0e3109
SS
20network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
21network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
22
d486a2d0
YW
23dnsmasq_config_file='/run/networkd-ci/test-dnsmasq.conf'
24dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
25dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
1f0e3109 26
7a0a37b2 27def is_module_available(module_name):
201bf07f
EV
28 lsmod_output = subprocess.check_output('lsmod', universal_newlines=True)
29 module_re = re.compile(r'^{0}\b'.format(re.escape(module_name)), re.MULTILINE)
30 return module_re.search(lsmod_output) or not subprocess.call(["modprobe", module_name])
7a0a37b2
EV
31
32def expectedFailureIfModuleIsNotAvailable(module_name):
33 def f(func):
34 if not is_module_available(module_name):
35 return unittest.expectedFailure(func)
36 return func
37
38 return f
39
1f0e3109
SS
40def setUpModule():
41
42 os.makedirs(network_unit_file_path, exist_ok=True)
43 os.makedirs(networkd_ci_path, exist_ok=True)
44
45 shutil.rmtree(networkd_ci_path)
6aea9276 46 copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
1f0e3109 47
c0bf6733
YW
48 subprocess.check_call('systemctl stop systemd-networkd.socket', shell=True)
49
1f0e3109
SS
50def tearDownModule():
51 shutil.rmtree(networkd_ci_path)
52
c0bf6733
YW
53 subprocess.check_call('systemctl stop systemd-networkd.service', shell=True)
54 subprocess.check_call('systemctl start systemd-networkd.socket', shell=True)
55 subprocess.check_call('systemctl start systemd-networkd.service', shell=True)
56
1f0e3109
SS
57class Utilities():
58 dhcp_server_data = []
59
60 def read_link_attr(self, link, dev, attribute):
61 with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
62 return f.readline().strip()
63
4d7ed14f
SS
64 def read_bridge_port_attr(self, bridge, link, attribute):
65
66 path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
67 path_port = 'lower_' + link + '/brport'
68 path = os.path.join(path_bridge, path_port)
69
70 with open(os.path.join(path, attribute)) as f:
71 return f.readline().strip()
72
1f0e3109
SS
73 def link_exits(self, link):
74 return os.path.exists(os.path.join('/sys/class/net', link))
75
76 def link_remove(self, links):
77 for link in links:
78 if os.path.exists(os.path.join('/sys/class/net', link)):
79 subprocess.call(['ip', 'link', 'del', 'dev', link])
9a4720a9 80 time.sleep(1)
1f0e3109
SS
81
82 def read_ipv6_sysctl_attr(self, link, attribute):
83 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
84 return f.readline().strip()
85
86 def read_ipv4_sysctl_attr(self, link, attribute):
87 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
88 return f.readline().strip()
89
90 def copy_unit_to_networkd_unit_path(self, *units):
91 for unit in units:
92 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
013c8dc9
YW
93 if (os.path.exists(os.path.join(networkd_ci_path, unit + '.d'))):
94 copytree(os.path.join(networkd_ci_path, unit + '.d'), os.path.join(network_unit_file_path, unit + '.d'))
1f0e3109
SS
95
96 def remove_unit_from_networkd_path(self, units):
97 for unit in units:
98 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
99 os.remove(os.path.join(network_unit_file_path, unit))
013c8dc9
YW
100 if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
101 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
1f0e3109
SS
102
103 def start_dnsmasq(self):
104 subprocess.check_call('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=2600::10,2600::20 --dhcp-range=192.168.5.10,192.168.5.200 -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', shell=True)
105
106 time.sleep(10)
107
108 def stop_dnsmasq(self, pid_file):
109 if os.path.exists(pid_file):
110 with open(pid_file, 'r') as f:
111 pid = f.read().rstrip(' \t\r\n\0')
112 os.kill(int(pid), signal.SIGTERM)
113
114 os.remove(pid_file)
115
116 def search_words_in_file(self, word):
117 if os.path.exists(dnsmasq_log_file):
118 with open (dnsmasq_log_file) as in_file:
119 contents = in_file.read()
120 print(contents)
121 for part in contents.split():
122 if word in part:
123 in_file.close()
124 print("%s, %s" % (word, part))
125 return True
126 return False
127
128 def remove_lease_file(self):
129 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
130 os.remove(os.path.join(networkd_ci_path, 'lease'))
131
132 def remove_log_file(self):
133 if os.path.exists(dnsmasq_log_file):
134 os.remove(dnsmasq_log_file)
135
136 def start_networkd(self):
bad4969b
YW
137 if (os.path.exists(os.path.join(networkd_runtime_directory, 'state'))):
138 subprocess.check_call('systemctl stop systemd-networkd', shell=True)
139 os.remove(os.path.join(networkd_runtime_directory, 'state'))
140 subprocess.check_call('systemctl start systemd-networkd', shell=True)
141 else:
142 subprocess.check_call('systemctl restart systemd-networkd', shell=True)
1f0e3109
SS
143 time.sleep(5)
144
145global ip
146global port
147
148class DHCPServer(threading.Thread):
149 def __init__(self, name):
150 threading.Thread.__init__(self)
151 self.name = name
152
153 def run(self):
154 self.start_dhcp_server()
155
156 def start_dhcp_server(self):
157 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
158
159 server_address = ('0.0.0.0', 67)
160 sock.bind(server_address)
161
162 print('Starting DHCP Server ...\n')
163 data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
164
165 global ip
166 ip = addr[0]
167
168 global port
169 port = addr[1]
170 sock.close()
171
172class NetworkdNetDevTests(unittest.TestCase, Utilities):
173
09ea6724
YW
174 links =[
175 '6rdtun99',
176 'bond99',
177 'bridge99',
178 'dropin-test',
179 'dummy98',
180 'erspan-test',
181 'geneve99',
182 'gretap99',
183 'gretun99',
184 'ip6gretap99',
185 'ip6tnl99',
186 'ipiptun99',
187 'ipvlan99',
188 'isataptun99',
189 'macvlan99',
190 'macvtap99',
191 'sittun99',
192 'tap99',
193 'test1',
194 'tun99',
195 'vcan99',
196 'veth99',
197 'vlan99',
198 'vrf99',
199 'vti6tun99',
200 'vtitun99',
201 'vxlan99',
202 'wg99']
203
204 units = [
205 '10-dropin-test.netdev',
206 '11-dummy.netdev',
207 '12-dummy.netdev',
208 '21-macvlan.netdev',
209 '21-macvtap.netdev',
210 '21-vlan.netdev',
211 '21-vlan.network',
212 '25-6rd-tunnel.netdev',
213 '25-bond.netdev',
214 '25-bridge.netdev',
215 '25-erspan-tunnel.netdev',
216 '25-geneve.netdev',
217 '25-gretap-tunnel.netdev',
218 '25-gre-tunnel.netdev',
219 '25-ip6gre-tunnel.netdev',
220 '25-ip6tnl-tunnel.netdev',
221 '25-ipip-tunnel-independent.netdev',
222 '25-ipip-tunnel.netdev',
223 '25-ipvlan.netdev',
224 '25-isatap-tunnel.netdev',
225 '25-sit-tunnel.netdev',
226 '25-tap.netdev',
227 '25-tun.netdev',
228 '25-vcan.netdev',
229 '25-veth.netdev',
230 '25-vrf.netdev',
231 '25-vti6-tunnel.netdev',
232 '25-vti-tunnel.netdev',
233 '25-vxlan.netdev',
234 '25-wireguard.netdev',
235 '6rd.network',
236 'gre.network',
237 'gretap.network',
238 'gretun.network',
239 'ip6gretap.network',
240 'ip6tnl.network',
241 'ipip.network',
242 'ipvlan.network',
243 'isatap.network',
244 'macvlan.network',
245 'macvtap.network',
246 'sit.network',
247 'vti6.network',
248 'vti.network',
249 'vxlan.network']
1f0e3109
SS
250
251 def setUp(self):
252 self.link_remove(self.links)
253
254 def tearDown(self):
255 self.link_remove(self.links)
256 self.remove_unit_from_networkd_path(self.units)
257
d80734f7
YW
258 def test_dropin(self):
259 self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev')
260
261 self.start_networkd()
262
263 self.assertTrue(self.link_exits('dropin-test'))
264
265 output = subprocess.check_output(['ip', 'link', 'show', 'dropin-test']).rstrip().decode('utf-8')
266 print(output)
267 self.assertRegex(output, '00:50:56:c0:00:28')
268
1f0e3109
SS
269 def test_bridge(self):
270 self.copy_unit_to_networkd_unit_path('25-bridge.netdev')
271 self.start_networkd()
272
273 self.assertTrue(self.link_exits('bridge99'))
274
275 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'hello_time'))
276 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'max_age'))
277 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','forward_delay'))
278 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','ageing_time'))
279 self.assertEqual('9', self.read_link_attr('bridge99', 'bridge','priority'))
280 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_querier'))
281 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_snooping'))
282 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','stp_state'))
283
284 def test_bond(self):
285 self.copy_unit_to_networkd_unit_path('25-bond.netdev')
286 self.start_networkd()
287
288 self.assertTrue(self.link_exits('bond99'))
289
99f68ef0
TJ
290 self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
291 self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
292 self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
293 self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
294 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
295 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
296 self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
297 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
298 self.assertEqual('1218', self.read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
299 self.assertEqual('811', self.read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
300 self.assertEqual('00:11:22:33:44:55', self.read_link_attr('bond99', 'bonding', 'ad_actor_system'))
1f0e3109
SS
301
302 def test_vlan(self):
303 self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
304
305 self.start_networkd()
306
307 self.assertTrue(self.link_exits('vlan99'))
308
309 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
310 self.assertTrue(output, 'REORDER_HDR')
311 self.assertTrue(output, 'LOOSE_BINDING')
312 self.assertTrue(output, 'GVRP')
313 self.assertTrue(output, 'MVRP')
314 self.assertTrue(output, '99')
315
316 def test_macvtap(self):
317 self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
318
319 self.start_networkd()
320
321 self.assertTrue(self.link_exits('macvtap99'))
322
323 def test_macvlan(self):
324 self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
325
326 self.start_networkd()
327
328 self.assertTrue(self.link_exits('macvlan99'))
329
7a0a37b2 330 @expectedFailureIfModuleIsNotAvailable('ipvlan')
1f0e3109
SS
331 def test_ipvlan(self):
332 self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
333
334 self.start_networkd()
335
336 self.assertTrue(self.link_exits('ipvlan99'))
337
338 def test_veth(self):
339 self.copy_unit_to_networkd_unit_path('25-veth.netdev')
340
341 self.start_networkd()
342
343 self.assertTrue(self.link_exits('veth99'))
344
345 def test_dummy(self):
346 self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
347
348 self.start_networkd()
349
350 self.assertTrue(self.link_exits('test1'))
351
352 def test_tun(self):
353 self.copy_unit_to_networkd_unit_path('25-tun.netdev')
354
355 self.start_networkd()
356
357 self.assertTrue(self.link_exits('tun99'))
358
359 def test_tap(self):
360 self.copy_unit_to_networkd_unit_path('25-tap.netdev')
361
362 self.start_networkd()
363
364 self.assertTrue(self.link_exits('tap99'))
365
7a0a37b2 366 @expectedFailureIfModuleIsNotAvailable('vrf')
1f0e3109
SS
367 def test_vrf(self):
368 self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
369
370 self.start_networkd()
371
372 self.assertTrue(self.link_exits('vrf99'))
373
7a0a37b2 374 @expectedFailureIfModuleIsNotAvailable('vcan')
1f0e3109
SS
375 def test_vcan(self):
376 self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
377
378 self.start_networkd()
379
380 self.assertTrue(self.link_exits('vcan99'))
381
7a3bc5a8
EV
382 @expectedFailureIfModuleIsNotAvailable('wireguard')
383 def test_wireguard(self):
384 self.copy_unit_to_networkd_unit_path('25-wireguard.netdev')
385
386 self.start_networkd()
387
388 if shutil.which('wg'):
389 subprocess.call('wg')
390
391 self.assertTrue(self.link_exits('wg99'))
392
1f0e3109
SS
393 def test_geneve(self):
394 self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
395
396 self.start_networkd()
397
398 self.assertTrue(self.link_exits('geneve99'))
399
400 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
401 self.assertTrue(output, '192.168.22.1')
402 self.assertTrue(output, '6082')
403 self.assertTrue(output, 'udpcsum')
404 self.assertTrue(output, 'udp6zerocsumrx')
405
406 def test_ipip_tunnel(self):
407 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ipip-tunnel.netdev', 'ipip.network')
408 self.start_networkd()
409
410 self.assertTrue(self.link_exits('dummy98'))
411 self.assertTrue(self.link_exits('ipiptun99'))
412
413 def test_gre_tunnel(self):
414 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gre-tunnel.netdev', 'gretun.network')
415 self.start_networkd()
416
417 self.assertTrue(self.link_exits('dummy98'))
418 self.assertTrue(self.link_exits('gretun99'))
419
420 def test_gretap_tunnel(self):
421 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gretap-tunnel.netdev', 'gretap.network')
422 self.start_networkd()
423
424 self.assertTrue(self.link_exits('dummy98'))
425 self.assertTrue(self.link_exits('gretap99'))
426
427 def test_ip6gretap_tunnel(self):
428 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretap.network')
429 self.start_networkd()
430
431 self.assertTrue(self.link_exits('dummy98'))
432 self.assertTrue(self.link_exits('ip6gretap99'))
433
434 def test_vti_tunnel(self):
435 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti-tunnel.netdev', 'vti.network')
436 self.start_networkd()
437
438 self.assertTrue(self.link_exits('dummy98'))
439 self.assertTrue(self.link_exits('vtitun99'))
440
441 def test_vti6_tunnel(self):
442 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti6-tunnel.netdev', 'vti6.network')
443 self.start_networkd()
444
445 self.assertTrue(self.link_exits('dummy98'))
446 self.assertTrue(self.link_exits('vti6tun99'))
447
448 def test_ip6tnl_tunnel(self):
449 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6tnl-tunnel.netdev', 'ip6tnl.network')
450 self.start_networkd()
451
452 self.assertTrue(self.link_exits('dummy98'))
453 self.assertTrue(self.link_exits('ip6tnl99'))
454
455 def test_sit_tunnel(self):
456 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-sit-tunnel.netdev', 'sit.network')
457 self.start_networkd()
458
459 self.assertTrue(self.link_exits('dummy98'))
460 self.assertTrue(self.link_exits('sittun99'))
461
d0e728b6
SS
462 def test_isatap_tunnel(self):
463 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-isatap-tunnel.netdev', 'isatap.network')
464 self.start_networkd()
465
466 self.assertTrue(self.link_exits('dummy98'))
467 self.assertTrue(self.link_exits('isataptun99'))
468 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'isataptun99']).rstrip().decode('utf-8')
469 self.assertRegex(output, "isatap ")
470
d29dc4f1
DA
471 def test_6rd_tunnel(self):
472 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-6rd-tunnel.netdev', '6rd.network')
473 self.start_networkd()
474
475 self.assertTrue(self.link_exits('dummy98'))
476 self.assertTrue(self.link_exits('sittun99'))
477
2266864b
SS
478 def test_erspan_tunnel(self):
479 self.copy_unit_to_networkd_unit_path('25-erspan-tunnel.netdev')
480 self.start_networkd()
481
482 self.assertTrue(self.link_exits('erspan-test'))
483
484 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan-test']).rstrip().decode('utf-8')
485 print(output)
486 self.assertTrue(output, '172.16.1.200')
487 self.assertTrue(output, '172.16.1.100')
488 self.assertTrue(output, '101')
489
1f0e3109
SS
490 def test_tunnel_independent(self):
491 self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
492
493 self.start_networkd()
494 self.assertTrue(self.link_exits('ipiptun99'))
495
496 def test_vxlan(self):
497 self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network','11-dummy.netdev')
498
499 self.start_networkd()
500
501 self.assertTrue(self.link_exits('vxlan99'))
502
503 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
504 self.assertRegex(output, "999")
505 self.assertRegex(output, '5555')
506 self.assertRegex(output, 'l2miss')
507 self.assertRegex(output, 'l3miss')
508 self.assertRegex(output, 'udpcsum')
509 self.assertRegex(output, 'udp6zerocsumtx')
510 self.assertRegex(output, 'udp6zerocsumrx')
511 self.assertRegex(output, 'remcsumtx')
512 self.assertRegex(output, 'remcsumrx')
513 self.assertRegex(output, 'gbp')
514
515class NetworkdNetWorkTests(unittest.TestCase, Utilities):
09ea6724
YW
516 links = [
517 'bond199',
518 'dummy98',
519 'test1']
520
521 units = [
522 '11-dummy.netdev',
523 '12-dummy.netdev',
524 '23-active-slave.network',
525 '23-bond199.network',
526 '23-primary-slave.network',
527 '23-test1-bond199.network',
528 '25-address-link-section.network',
529 '25-address-section-miscellaneous.network',
530 '25-address-section.network',
531 '25-bond-active-backup-slave.netdev',
532 '25-fibrule-invert.network',
533 '25-fibrule-port-range.network',
534 '25-ipv6-address-label-section.network',
535 '25-link-section-unmanaged.network',
536 '25-route-gateway.network',
537 '25-route-gateway-on-link.network',
538 '25-route-reverse-order.network',
539 '25-route-section.network',
540 '25-route-tcp-window-settings.network',
541 '25-route-type.network',
542 '25-sysctl.network',
543 'configure-without-carrier.network',
544 'routing-policy-rule.network',
545 'test-static.network']
1f0e3109
SS
546
547 def setUp(self):
548 self.link_remove(self.links)
549
550 def tearDown(self):
551 self.link_remove(self.links)
552 self.remove_unit_from_networkd_path(self.units)
553
554 def test_static_address(self):
555 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'test-static.network')
556 self.start_networkd()
557
558 self.assertTrue(self.link_exits('dummy98'))
559 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
560 print(output)
561 self.assertRegex(output, '192.168.0.15')
562 self.assertRegex(output, '192.168.0.1')
563 self.assertRegex(output, 'routable')
564
565 def test_configure_without_carrier(self):
566 self.copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
567 self.start_networkd()
568
569 self.assertTrue(self.link_exits('test1'))
570 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
571 print(output)
572 self.assertRegex(output, '192.168.0.15')
573 self.assertRegex(output, '192.168.0.1')
574 self.assertRegex(output, 'routable')
575
576 def test_bond_active_slave(self):
577 self.copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
578 self.start_networkd()
579
580 self.assertTrue(self.link_exits('dummy98'))
581 self.assertTrue(self.link_exits('bond199'))
582 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
583 print(output)
584 self.assertRegex(output, 'active_slave dummy98')
585
586 def test_bond_primary_slave(self):
587 self.copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-test1-bond199.network', '25-bond-active-backup-slave.netdev', '11-dummy.netdev')
588 self.start_networkd()
589
590 self.assertTrue(self.link_exits('test1'))
591 self.assertTrue(self.link_exits('bond199'))
592 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
593 print(output)
594 self.assertRegex(output, 'primary test1')
595
596 def test_routing_policy_rule(self):
597 self.copy_unit_to_networkd_unit_path('routing-policy-rule.network', '11-dummy.netdev')
598 self.start_networkd()
599
600 self.assertTrue(self.link_exits('test1'))
601 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
602 print(output)
603 self.assertRegex(output, '111')
604 self.assertRegex(output, 'from 192.168.100.18')
f7bdd562 605 self.assertRegex(output, r'tos (?:0x08|throughput)\s')
1f0e3109
SS
606 self.assertRegex(output, 'iif test1')
607 self.assertRegex(output, 'oif test1')
608 self.assertRegex(output, 'lookup 7')
609
926062f0
SS
610 def test_routing_policy_rule_port_range(self):
611 self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
612 self.start_networkd()
613
614 self.assertTrue(self.link_exits('test1'))
615 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
616 print(output)
617 self.assertRegex(output, '111')
618 self.assertRegex(output, 'from 192.168.100.18')
619 self.assertRegex(output, '1123-1150')
620 self.assertRegex(output, '3224-3290')
621 self.assertRegex(output, 'tcp')
622 self.assertRegex(output, 'lookup 7')
1f0e3109 623
efecf9cd
SS
624 def test_routing_policy_rule_invert(self):
625 self.copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
626 self.start_networkd()
627
628 self.assertTrue(self.link_exits('test1'))
629 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
630 print(output)
631
632 self.assertRegex(output, '111')
633 self.assertRegex(output, 'not.*?from.*?192.168.100.18')
634 self.assertRegex(output, 'tcp')
635 self.assertRegex(output, 'lookup 7')
636
1f0e3109
SS
637 def test_address_preferred_lifetime_zero_ipv6(self):
638 self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
639 self.start_networkd()
640
641 self.assertTrue(self.link_exits('dummy98'))
642
643 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
644 print(output)
645 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
646 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
647
648 def test_ip_route(self):
649 self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
650 self.start_networkd()
651
652 self.assertTrue(self.link_exits('dummy98'))
653
654 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
655 print(output)
656 self.assertRegex(output, '192.168.0.1')
657 self.assertRegex(output, 'static')
658 self.assertRegex(output, '192.168.0.0/24')
659
0d34228f
SS
660 def test_ip_route_reverse(self):
661 self.copy_unit_to_networkd_unit_path('25-route-reverse-order.network', '12-dummy.netdev')
662 self.start_networkd()
663
664 self.assertTrue(self.link_exits('dummy98'))
665
666 output = subprocess.check_output(['ip', '-6', 'route', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
667 print(output)
668 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff')
669 self.assertRegex(output, '2001:1234:5:8f63::1')
670
1f0e3109
SS
671 def test_ip_route_blackhole_unreachable_prohibit(self):
672 self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
673 self.start_networkd()
674
675 self.assertTrue(self.link_exits('dummy98'))
676
677 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
678 print(output)
679 self.assertRegex(output, 'blackhole')
680 self.assertRegex(output, 'unreachable')
681 self.assertRegex(output, 'prohibit')
682
683 subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
684 subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
685 subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
686
687 def test_ip_route_tcp_window(self):
688 self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
689 self.start_networkd()
690
691 self.assertTrue(self.link_exits('test1'))
692
693 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
694 print(output)
695 self.assertRegex(output, 'initcwnd 20')
696 self.assertRegex(output, 'initrwnd 30')
697
f5050e48
YW
698 def test_ip_route_gateway(self):
699 self.copy_unit_to_networkd_unit_path('25-route-gateway.network', '12-dummy.netdev')
700 self.start_networkd()
701
702 self.assertTrue(self.link_exits('dummy98'))
703
704 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
705 print(output)
706 self.assertRegex(output, 'default')
707 self.assertRegex(output, 'via')
708 self.assertRegex(output, '149.10.124.64')
709 self.assertRegex(output, 'proto')
710 self.assertRegex(output, 'static')
711
712 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
713 print(output)
714 self.assertRegex(output, '149.10.124.48/28')
715 self.assertRegex(output, 'proto')
716 self.assertRegex(output, 'kernel')
717 self.assertRegex(output, 'scope')
718 self.assertRegex(output, 'link')
719
720 def test_ip_route_gateway_on_link(self):
721 self.copy_unit_to_networkd_unit_path('25-route-gateway-on-link.network', '12-dummy.netdev')
722 self.start_networkd()
723
724 self.assertTrue(self.link_exits('dummy98'))
725
726 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
727 print(output)
728 self.assertRegex(output, 'default')
729 self.assertRegex(output, 'via')
730 self.assertRegex(output, '149.10.125.65')
731 self.assertRegex(output, 'proto')
732 self.assertRegex(output, 'static')
733 self.assertRegex(output, 'onlink')
734
735 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
736 print(output)
737 self.assertRegex(output, '149.10.124.48/28')
738 self.assertRegex(output, 'proto')
739 self.assertRegex(output, 'kernel')
740 self.assertRegex(output, 'scope')
741 self.assertRegex(output, 'link')
742
1f0e3109
SS
743 def test_ip_link_mac_address(self):
744 self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
745 self.start_networkd()
746
747 self.assertTrue(self.link_exits('dummy98'))
748
749 output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
750 print(output)
751 self.assertRegex(output, '00:01:02:aa:bb:cc')
752
753 def test_ip_link_unmanaged(self):
754 self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
755 self.start_networkd()
756
757 self.assertTrue(self.link_exits('dummy98'))
758
759 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
760 print(output)
761 self.assertRegex(output, 'unmanaged')
762
763 def test_ipv6_address_label(self):
764 self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
765 self.start_networkd()
766
767 self.assertTrue(self.link_exits('dummy98'))
768
769 output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
770 print(output)
771 self.assertRegex(output, '2004:da8:1::/64')
772
773 def test_sysctl(self):
774 self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
775 self.start_networkd()
776
777 self.assertTrue(self.link_exits('dummy98'))
778
779 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
780 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
781 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
782 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
783 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
784 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
785 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
786
14dc0335 787class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
09ea6724
YW
788 links = [
789 'bridge99',
790 'dummy98',
791 'test1']
792
793 units = [
794 '11-dummy.netdev',
795 '12-dummy.netdev',
796 '26-bridge.netdev',
797 '26-bridge-slave-interface-1.network',
798 '26-bridge-slave-interface-2.network',
799 'bridge99.network']
1f0e3109
SS
800
801 def setUp(self):
802 self.link_remove(self.links)
803
804 def tearDown(self):
805 self.link_remove(self.links)
806 self.remove_unit_from_networkd_path(self.units)
807
808 def test_bridge_property(self):
809 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
810 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
811 'bridge99.network')
812 self.start_networkd()
813
814 self.assertTrue(self.link_exits('dummy98'))
815 self.assertTrue(self.link_exits('test1'))
816 self.assertTrue(self.link_exits('bridge99'))
817
818 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
819 print(output)
820 self.assertRegex(output, 'master')
821 self.assertRegex(output, 'bridge')
822
823 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
824 print(output)
825 self.assertRegex(output, 'master')
826 self.assertRegex(output, 'bridge')
827
828 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
829 print(output)
830 self.assertRegex(output, '192.168.0.15')
831 self.assertRegex(output, '192.168.0.1')
832
833 output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
834 print(output)
4d7ed14f
SS
835
836 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
837 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
838 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
839 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
840
841 # CONFIG_BRIDGE_IGMP_SNOOPING=y
842 if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
843 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
1f0e3109
SS
844
845class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
846 links = ['veth99']
847
09ea6724
YW
848 units = [
849 '23-emit-lldp.network',
850 '24-lldp.network',
851 '25-veth.netdev']
1f0e3109
SS
852
853 def setUp(self):
854 self.link_remove(self.links)
855
856 def tearDown(self):
857 self.link_remove(self.links)
858 self.remove_unit_from_networkd_path(self.units)
859
860 def test_lldp(self):
861 self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
862 self.start_networkd()
863
864 self.assertTrue(self.link_exits('veth99'))
865
866 output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
867 print(output)
868 self.assertRegex(output, 'veth-peer')
869 self.assertRegex(output, 'veth99')
870
871class NetworkdNetworkRATests(unittest.TestCase, Utilities):
872 links = ['veth99']
873
09ea6724
YW
874 units = [
875 '25-veth.netdev',
876 'ipv6-prefix.network',
877 'ipv6-prefix-veth.network']
1f0e3109
SS
878
879 def setUp(self):
880 self.link_remove(self.links)
881
882 def tearDown(self):
883 self.link_remove(self.links)
884 self.remove_unit_from_networkd_path(self.units)
885
886 def test_ipv6_prefix_delegation(self):
887 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
888 self.start_networkd()
889
890 self.assertTrue(self.link_exits('veth99'))
891
892 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
893 print(output)
894 self.assertRegex(output, '2002:da8:1:0')
895
896class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
09ea6724
YW
897 links = [
898 'dummy98',
899 'veth99']
900
901 units = [
902 '12-dummy.netdev',
903 '24-search-domain.network',
904 '25-veth.netdev',
905 'dhcp-client.network',
906 'dhcp-client-timezone-router.network',
907 'dhcp-server.network',
908 'dhcp-server-timezone-router.network']
1f0e3109
SS
909
910 def setUp(self):
911 self.link_remove(self.links)
912
913 def tearDown(self):
914 self.link_remove(self.links)
915 self.remove_unit_from_networkd_path(self.units)
916
917 def test_dhcp_server(self):
918 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
919 self.start_networkd()
920
921 self.assertTrue(self.link_exits('veth99'))
922
923 time.sleep(5)
924
925 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
926 print(output)
927 self.assertRegex(output, '192.168.5.*')
928 self.assertRegex(output, 'Gateway: 192.168.5.1')
929 self.assertRegex(output, 'DNS: 192.168.5.1')
930 self.assertRegex(output, 'NTP: 192.168.5.1')
931
932 def test_domain(self):
933 self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
934 self.start_networkd()
935
936 self.assertTrue(self.link_exits('dummy98'))
937
938 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
939 print(output)
940 self.assertRegex(output, 'Address: 192.168.42.100')
941 self.assertRegex(output, 'DNS: 192.168.42.1')
942 self.assertRegex(output, 'Search Domains: one')
943
944 def test_emit_router_timezone(self):
945 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
946 self.start_networkd()
947
948 self.assertTrue(self.link_exits('veth99'))
949
950 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
951 print(output)
952 self.assertRegex(output, 'Gateway: 192.168.5.*')
953 self.assertRegex(output, '192.168.5.*')
954 self.assertRegex(output, 'Europe/Berlin')
955
956class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
09ea6724
YW
957 links = [
958 'dummy98',
959 'veth99']
960
961 units = [
962 '25-veth.netdev',
963 'dhcp-client-anonymize.network',
964 'dhcp-client-critical-connection.network',
965 'dhcp-client-ipv4-dhcp-settings.network',
966 'dhcp-client-ipv4-only-ipv6-disabled.network',
967 'dhcp-client-ipv4-only.network',
968 'dhcp-client-ipv6-only.network',
969 'dhcp-client-ipv6-rapid-commit.network',
970 'dhcp-client-listen-port.network',
971 'dhcp-client-route-metric.network',
972 'dhcp-client-route-table.network',
973 'dhcp-server-veth-peer.network',
974 'dhcp-v4-server-veth-peer.network']
1f0e3109
SS
975
976 def setUp(self):
977 self.link_remove(self.links)
978 self.stop_dnsmasq(dnsmasq_pid_file)
979
980 def tearDown(self):
981 self.link_remove(self.links)
982 self.remove_unit_from_networkd_path(self.units)
983 self.stop_dnsmasq(dnsmasq_pid_file)
984 self.remove_lease_file()
985 self.remove_log_file()
986
987 def test_dhcp_client_ipv6_only(self):
988 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
989 self.start_networkd()
990
991 self.assertTrue(self.link_exits('veth99'))
992
993 self.start_dnsmasq()
994
995 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
996 print(output)
997 self.assertRegex(output, '2600::')
998 self.assertNotRegex(output, '192.168.5')
999
1000 def test_dhcp_client_ipv4_only(self):
1001 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
1002 self.start_networkd()
1003
1004 self.assertTrue(self.link_exits('veth99'))
1005
1006 self.start_dnsmasq()
1007
1008 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1009 print(output)
1010 self.assertNotRegex(output, '2600::')
1011 self.assertRegex(output, '192.168.5')
1012
1013 def test_dhcp_client_ipv4_ipv6(self):
1014 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
1015 'dhcp-client-ipv4-only.network')
1016 self.start_networkd()
1017
1018 self.assertTrue(self.link_exits('veth99'))
1019
1020 self.start_dnsmasq()
1021
1022 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1023 print(output)
1024 self.assertRegex(output, '2600::')
1025 self.assertRegex(output, '192.168.5')
1026
1027 def test_dhcp_client_settings(self):
1028 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
1029 self.start_networkd()
1030
1031 self.assertTrue(self.link_exits('veth99'))
1032
1033 self.start_dnsmasq()
1034
1035 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1036 print(output)
1037 self.assertRegex(output, '12:34:56:78:9a:bc')
1038 self.assertRegex(output, '192.168.5')
1039 self.assertRegex(output, '1492')
1040
1041 output = subprocess.check_output(['ip', 'route']).rstrip().decode('utf-8')
1042 print(output)
1043 self.assertRegex(output, 'default.*dev veth99 proto dhcp')
1044
1045 self.search_words_in_file('vendor class: SusantVendorTest')
1046 self.search_words_in_file('client MAC address: 12:34:56:78:9a:bc')
1047 self.search_words_in_file('client provides name: test-hostname')
1048 self.search_words_in_file('26:mtu')
1049
1050 def test_dhcp6_client_settings_rapidcommit_true(self):
1051 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
1052 self.start_networkd()
1053
1054 self.assertTrue(self.link_exits('veth99'))
1055
1056 self.start_dnsmasq()
1057
1058 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1059 print(output)
1060 self.assertRegex(output, '12:34:56:78:9a:bc')
1061
1062 self.assertTrue(self.search_words_in_file('14:rapid-commit'))
1063
1064 def test_dhcp6_client_settings_rapidcommit_false(self):
1065 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
1066 self.start_networkd()
1067
1068 self.assertTrue(self.link_exits('veth99'))
1069
1070 self.start_dnsmasq()
1071
1072 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1073 print(output)
1074 self.assertRegex(output, '12:34:56:78:9a:bc')
1075
1076 self.assertFalse(self.search_words_in_file('14:rapid-commit'))
1077
1078 def test_dhcp_client_settings_anonymize(self):
1079 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
1080 self.start_networkd()
1081
1082 self.assertTrue(self.link_exits('veth99'))
1083
1084 self.start_dnsmasq()
1085 self.assertFalse(self.search_words_in_file('VendorClassIdentifier=SusantVendorTest'))
1086 self.assertFalse(self.search_words_in_file('test-hostname'))
1087 self.assertFalse(self.search_words_in_file('26:mtu'))
1088
1089 def test_dhcp_client_listen_port(self):
1090 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
1091 dh_server = DHCPServer("dhcp_server")
1092 dh_server.start()
1093
1094 self.start_networkd()
1095
1096 self.assertTrue(self.link_exits('veth99'))
1097
1098 global port
1099 global ip
1100
1101 self.assertRegex(str(port), '5555')
1102 self.assertRegex(str(ip), '0.0.0.0')
1103
1104 dh_server.join()
1105
1106 def test_dhcp_route_table_id(self):
1107 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
1108 self.start_networkd()
1109 self.start_dnsmasq()
1110
1111 self.assertTrue(self.link_exits('veth99'))
1112
1113 output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
1114 print(output)
1115
1116 self.assertRegex(output, 'veth99 proto dhcp')
1117 self.assertRegex(output, '192.168.5.1')
1118
1119 def test_dhcp_route_metric(self):
1120 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
1121 self.start_networkd()
1122 self.start_dnsmasq()
1123
1124 self.assertTrue(self.link_exits('veth99'))
1125
1126 output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1127 print(output)
1128
1129 self.assertRegex(output, 'metric 24')
1130
1131 def test_dhcp_route_criticalconnection_true(self):
1132 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
1133 self.start_networkd()
1134 self.start_dnsmasq()
1135
1136 self.assertTrue(self.link_exits('veth99'))
1137
1138 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1139 print(output)
1140
1141 self.assertRegex(output, '192.168.5.*')
1142 # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
1143 self.stop_dnsmasq(dnsmasq_pid_file)
1144
1145 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
1146 time.sleep(125)
1147
1148 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1149 print(output)
1150 self.assertRegex(output, '192.168.5.*')
1151
1152if __name__ == '__main__':
1153 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
1154 verbosity=3))