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