]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
test: add test for sd_device
[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
10import shutil
11import signal
12import socket
13import threading
14from shutil import copytree
15
16network_unit_file_path='/var/run/systemd/network'
17networkd_ci_path='/var/run/networkd-ci'
18network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
19network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
20
21dnsmasq_config_file='/var/run/networkd-ci/test-dnsmasq.conf'
22dnsmasq_pid_file='/var/run/networkd-ci/test-test-dnsmasq.pid'
23dnsmasq_log_file='/var/run/networkd-ci/test-dnsmasq-log-file'
24
25def setUpModule():
26
27 os.makedirs(network_unit_file_path, exist_ok=True)
28 os.makedirs(networkd_ci_path, exist_ok=True)
29
30 shutil.rmtree(networkd_ci_path)
31 copytree('conf', networkd_ci_path)
32
33def tearDownModule():
34 shutil.rmtree(networkd_ci_path)
35
36class Utilities():
37 dhcp_server_data = []
38
39 def read_link_attr(self, link, dev, attribute):
40 with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
41 return f.readline().strip()
42
43 def link_exits(self, link):
44 return os.path.exists(os.path.join('/sys/class/net', link))
45
46 def link_remove(self, links):
47 for link in links:
48 if os.path.exists(os.path.join('/sys/class/net', link)):
49 subprocess.call(['ip', 'link', 'del', 'dev', link])
50
51 def read_ipv6_sysctl_attr(self, link, attribute):
52 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
53 return f.readline().strip()
54
55 def read_ipv4_sysctl_attr(self, link, attribute):
56 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
57 return f.readline().strip()
58
59 def copy_unit_to_networkd_unit_path(self, *units):
60 for unit in units:
61 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
62
63 def remove_unit_from_networkd_path(self, units):
64 for unit in units:
65 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
66 os.remove(os.path.join(network_unit_file_path, unit))
67
68 def start_dnsmasq(self):
69 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)
70
71 time.sleep(10)
72
73 def stop_dnsmasq(self, pid_file):
74 if os.path.exists(pid_file):
75 with open(pid_file, 'r') as f:
76 pid = f.read().rstrip(' \t\r\n\0')
77 os.kill(int(pid), signal.SIGTERM)
78
79 os.remove(pid_file)
80
81 def search_words_in_file(self, word):
82 if os.path.exists(dnsmasq_log_file):
83 with open (dnsmasq_log_file) as in_file:
84 contents = in_file.read()
85 print(contents)
86 for part in contents.split():
87 if word in part:
88 in_file.close()
89 print("%s, %s" % (word, part))
90 return True
91 return False
92
93 def remove_lease_file(self):
94 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
95 os.remove(os.path.join(networkd_ci_path, 'lease'))
96
97 def remove_log_file(self):
98 if os.path.exists(dnsmasq_log_file):
99 os.remove(dnsmasq_log_file)
100
101 def start_networkd(self):
102 subprocess.check_call('systemctl stop systemd-networkd', shell=True)
103 time.sleep(1)
104 subprocess.check_call('systemctl start systemd-networkd', shell=True)
105 time.sleep(5)
106
107global ip
108global port
109
110class DHCPServer(threading.Thread):
111 def __init__(self, name):
112 threading.Thread.__init__(self)
113 self.name = name
114
115 def run(self):
116 self.start_dhcp_server()
117
118 def start_dhcp_server(self):
119 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
120
121 server_address = ('0.0.0.0', 67)
122 sock.bind(server_address)
123
124 print('Starting DHCP Server ...\n')
125 data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
126
127 global ip
128 ip = addr[0]
129
130 global port
131 port = addr[1]
132 sock.close()
133
134class NetworkdNetDevTests(unittest.TestCase, Utilities):
135
136 links =['bridge99', 'bond99', 'bond99', 'vlan99', 'test1', 'macvtap99',
137 'macvlan99', 'ipvlan99', 'vxlan99', 'veth99', 'vrf99', 'tun99',
138 'tap99', 'vcan99', 'geneve99', 'dummy98', 'ipiptun99', 'sittun99',
139 'gretap99', 'vtitun99', 'vti6tun99','ip6tnl99', 'gretun99', 'ip6gretap99']
140
141 units = ['25-bridge.netdev', '25-bond.netdev', '21-vlan.netdev', '11-dummy.netdev', '21-vlan.network',
142 '21-macvtap.netdev', 'macvtap.network', '21-macvlan.netdev', 'macvlan.network', 'vxlan.network',
143 '25-vxlan.netdev', '25-ipvlan.netdev', 'ipvlan.network', '25-veth.netdev', '25-vrf.netdev',
144 '25-tun.netdev', '25-tun.netdev', '25-vcan.netdev', '25-geneve.netdev', '25-ipip-tunnel.netdev',
145 '25-ip6tnl-tunnel.netdev', '25-ip6gre-tunnel.netdev','25-sit-tunnel.netdev', '25-gre-tunnel.netdev',
146 '25-gretap-tunnel.netdev', '25-vti-tunnel.netdev', '25-vti6-tunnel.netdev', '12-dummy.netdev',
147 'gre.network', 'ipip.network', 'ip6gretap.network', 'gretun.network', 'ip6tnl.network', '25-tap.netdev',
148 'vti6.network', 'vti.network', 'gretap.network', 'sit.network', '25-ipip-tunnel-independent.netdev']
149
150 def setUp(self):
151 self.link_remove(self.links)
152
153 def tearDown(self):
154 self.link_remove(self.links)
155 self.remove_unit_from_networkd_path(self.units)
156
157 def test_bridge(self):
158 self.copy_unit_to_networkd_unit_path('25-bridge.netdev')
159 self.start_networkd()
160
161 self.assertTrue(self.link_exits('bridge99'))
162
163 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'hello_time'))
164 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'max_age'))
165 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','forward_delay'))
166 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','ageing_time'))
167 self.assertEqual('9', self.read_link_attr('bridge99', 'bridge','priority'))
168 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_querier'))
169 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_snooping'))
170 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','stp_state'))
171
172 def test_bond(self):
173 self.copy_unit_to_networkd_unit_path('25-bond.netdev')
174 self.start_networkd()
175
176 self.assertTrue(self.link_exits('bond99'))
177
178 self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
179 self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
180 self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
181 self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
182 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
183 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
184 self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
185 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
186
187 def test_vlan(self):
188 self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
189
190 self.start_networkd()
191
192 self.assertTrue(self.link_exits('vlan99'))
193
194 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
195 self.assertTrue(output, 'REORDER_HDR')
196 self.assertTrue(output, 'LOOSE_BINDING')
197 self.assertTrue(output, 'GVRP')
198 self.assertTrue(output, 'MVRP')
199 self.assertTrue(output, '99')
200
201 def test_macvtap(self):
202 self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
203
204 self.start_networkd()
205
206 self.assertTrue(self.link_exits('macvtap99'))
207
208 def test_macvlan(self):
209 self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
210
211 self.start_networkd()
212
213 self.assertTrue(self.link_exits('macvlan99'))
214
215 def test_ipvlan(self):
216 self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
217
218 self.start_networkd()
219
220 self.assertTrue(self.link_exits('ipvlan99'))
221
222 def test_veth(self):
223 self.copy_unit_to_networkd_unit_path('25-veth.netdev')
224
225 self.start_networkd()
226
227 self.assertTrue(self.link_exits('veth99'))
228
229 def test_dummy(self):
230 self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
231
232 self.start_networkd()
233
234 self.assertTrue(self.link_exits('test1'))
235
236 def test_tun(self):
237 self.copy_unit_to_networkd_unit_path('25-tun.netdev')
238
239 self.start_networkd()
240
241 self.assertTrue(self.link_exits('tun99'))
242
243 def test_tap(self):
244 self.copy_unit_to_networkd_unit_path('25-tap.netdev')
245
246 self.start_networkd()
247
248 self.assertTrue(self.link_exits('tap99'))
249
250 def test_vrf(self):
251 self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
252
253 self.start_networkd()
254
255 self.assertTrue(self.link_exits('vrf99'))
256
257 def test_vcan(self):
258 self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
259
260 self.start_networkd()
261
262 self.assertTrue(self.link_exits('vcan99'))
263
264 def test_geneve(self):
265 self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
266
267 self.start_networkd()
268
269 self.assertTrue(self.link_exits('geneve99'))
270
271 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
272 self.assertTrue(output, '192.168.22.1')
273 self.assertTrue(output, '6082')
274 self.assertTrue(output, 'udpcsum')
275 self.assertTrue(output, 'udp6zerocsumrx')
276
277 def test_ipip_tunnel(self):
278 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ipip-tunnel.netdev', 'ipip.network')
279 self.start_networkd()
280
281 self.assertTrue(self.link_exits('dummy98'))
282 self.assertTrue(self.link_exits('ipiptun99'))
283
284 def test_gre_tunnel(self):
285 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gre-tunnel.netdev', 'gretun.network')
286 self.start_networkd()
287
288 self.assertTrue(self.link_exits('dummy98'))
289 self.assertTrue(self.link_exits('gretun99'))
290
291 def test_gretap_tunnel(self):
292 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gretap-tunnel.netdev', 'gretap.network')
293 self.start_networkd()
294
295 self.assertTrue(self.link_exits('dummy98'))
296 self.assertTrue(self.link_exits('gretap99'))
297
298 def test_ip6gretap_tunnel(self):
299 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretap.network')
300 self.start_networkd()
301
302 self.assertTrue(self.link_exits('dummy98'))
303 self.assertTrue(self.link_exits('ip6gretap99'))
304
305 def test_vti_tunnel(self):
306 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti-tunnel.netdev', 'vti.network')
307 self.start_networkd()
308
309 self.assertTrue(self.link_exits('dummy98'))
310 self.assertTrue(self.link_exits('vtitun99'))
311
312 def test_vti6_tunnel(self):
313 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti6-tunnel.netdev', 'vti6.network')
314 self.start_networkd()
315
316 self.assertTrue(self.link_exits('dummy98'))
317 self.assertTrue(self.link_exits('vti6tun99'))
318
319 def test_ip6tnl_tunnel(self):
320 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6tnl-tunnel.netdev', 'ip6tnl.network')
321 self.start_networkd()
322
323 self.assertTrue(self.link_exits('dummy98'))
324 self.assertTrue(self.link_exits('ip6tnl99'))
325
326 def test_sit_tunnel(self):
327 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-sit-tunnel.netdev', 'sit.network')
328 self.start_networkd()
329
330 self.assertTrue(self.link_exits('dummy98'))
331 self.assertTrue(self.link_exits('sittun99'))
332
333 def test_tunnel_independent(self):
334 self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
335
336 self.start_networkd()
337 self.assertTrue(self.link_exits('ipiptun99'))
338
339 def test_vxlan(self):
340 self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network','11-dummy.netdev')
341
342 self.start_networkd()
343
344 self.assertTrue(self.link_exits('vxlan99'))
345
346 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
347 self.assertRegex(output, "999")
348 self.assertRegex(output, '5555')
349 self.assertRegex(output, 'l2miss')
350 self.assertRegex(output, 'l3miss')
351 self.assertRegex(output, 'udpcsum')
352 self.assertRegex(output, 'udp6zerocsumtx')
353 self.assertRegex(output, 'udp6zerocsumrx')
354 self.assertRegex(output, 'remcsumtx')
355 self.assertRegex(output, 'remcsumrx')
356 self.assertRegex(output, 'gbp')
357
358class NetworkdNetWorkTests(unittest.TestCase, Utilities):
359 links = ['dummy98', 'test1', 'bond199']
360
361 units = ['12-dummy.netdev', 'test-static.network', 'configure-without-carrier.network', '11-dummy.netdev',
362 '23-primary-slave.network', '23-test1-bond199.network', '11-dummy.netdev', '23-bond199.network',
363 '25-bond-active-backup-slave.netdev', '12-dummy.netdev', '23-active-slave.network',
364 'routing-policy-rule.network', '25-address-section.network', '25-address-section-miscellaneous.network',
365 '25-route-section.network', '25-route-type.network', '25-route-tcp-window-settings.network',
366 '25-address-link-section.network', '25-ipv6-address-label-section.network', '25-link-section-unmanaged.network',
367 '25-sysctl.network']
368
369 def setUp(self):
370 self.link_remove(self.links)
371
372 def tearDown(self):
373 self.link_remove(self.links)
374 self.remove_unit_from_networkd_path(self.units)
375
376 def test_static_address(self):
377 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'test-static.network')
378 self.start_networkd()
379
380 self.assertTrue(self.link_exits('dummy98'))
381 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
382 print(output)
383 self.assertRegex(output, '192.168.0.15')
384 self.assertRegex(output, '192.168.0.1')
385 self.assertRegex(output, 'routable')
386
387 def test_configure_without_carrier(self):
388 self.copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
389 self.start_networkd()
390
391 self.assertTrue(self.link_exits('test1'))
392 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
393 print(output)
394 self.assertRegex(output, '192.168.0.15')
395 self.assertRegex(output, '192.168.0.1')
396 self.assertRegex(output, 'routable')
397
398 def test_bond_active_slave(self):
399 self.copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
400 self.start_networkd()
401
402 self.assertTrue(self.link_exits('dummy98'))
403 self.assertTrue(self.link_exits('bond199'))
404 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
405 print(output)
406 self.assertRegex(output, 'active_slave dummy98')
407
408 def test_bond_primary_slave(self):
409 self.copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-test1-bond199.network', '25-bond-active-backup-slave.netdev', '11-dummy.netdev')
410 self.start_networkd()
411
412 self.assertTrue(self.link_exits('test1'))
413 self.assertTrue(self.link_exits('bond199'))
414 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
415 print(output)
416 self.assertRegex(output, 'primary test1')
417
418 def test_routing_policy_rule(self):
419 self.copy_unit_to_networkd_unit_path('routing-policy-rule.network', '11-dummy.netdev')
420 self.start_networkd()
421
422 self.assertTrue(self.link_exits('test1'))
423 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
424 print(output)
425 self.assertRegex(output, '111')
426 self.assertRegex(output, 'from 192.168.100.18')
427 self.assertRegex(output, 'tos 0x08')
428 self.assertRegex(output, 'iif test1')
429 self.assertRegex(output, 'oif test1')
430 self.assertRegex(output, 'lookup 7')
431
432 def test_address_preferred_lifetime_zero_ipv6(self):
433 self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
434 self.start_networkd()
435
436 self.assertTrue(self.link_exits('dummy98'))
437
438 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
439 print(output)
440 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
441 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
442
443 def test_ip_route(self):
444 self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
445 self.start_networkd()
446
447 self.assertTrue(self.link_exits('dummy98'))
448
449 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
450 print(output)
451 self.assertRegex(output, '192.168.0.1')
452 self.assertRegex(output, 'static')
453 self.assertRegex(output, '192.168.0.0/24')
454
455 def test_ip_route_blackhole_unreachable_prohibit(self):
456 self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
457 self.start_networkd()
458
459 self.assertTrue(self.link_exits('dummy98'))
460
461 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
462 print(output)
463 self.assertRegex(output, 'blackhole')
464 self.assertRegex(output, 'unreachable')
465 self.assertRegex(output, 'prohibit')
466
467 subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
468 subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
469 subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
470
471 def test_ip_route_tcp_window(self):
472 self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
473 self.start_networkd()
474
475 self.assertTrue(self.link_exits('test1'))
476
477 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
478 print(output)
479 self.assertRegex(output, 'initcwnd 20')
480 self.assertRegex(output, 'initrwnd 30')
481
482 def test_ip_link_mac_address(self):
483 self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
484 self.start_networkd()
485
486 self.assertTrue(self.link_exits('dummy98'))
487
488 output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
489 print(output)
490 self.assertRegex(output, '00:01:02:aa:bb:cc')
491
492 def test_ip_link_unmanaged(self):
493 self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
494 self.start_networkd()
495
496 self.assertTrue(self.link_exits('dummy98'))
497
498 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
499 print(output)
500 self.assertRegex(output, 'unmanaged')
501
502 def test_ipv6_address_label(self):
503 self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
504 self.start_networkd()
505
506 self.assertTrue(self.link_exits('dummy98'))
507
508 output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
509 print(output)
510 self.assertRegex(output, '2004:da8:1::/64')
511
512 def test_sysctl(self):
513 self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
514 self.start_networkd()
515
516 self.assertTrue(self.link_exits('dummy98'))
517
518 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
519 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
520 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
521 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
522 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
523 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
524 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
525
526class NetworkdNetWorkBrideTests(unittest.TestCase, Utilities):
527 links = ['dummy98', 'test1', 'bridge99']
528
529 units = ['11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev', '26-bridge-slave-interface-1.network',
530 '26-bridge-slave-interface-2.network', 'bridge99.network']
531
532 def setUp(self):
533 self.link_remove(self.links)
534
535 def tearDown(self):
536 self.link_remove(self.links)
537 self.remove_unit_from_networkd_path(self.units)
538
539 def test_bridge_property(self):
540 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
541 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
542 'bridge99.network')
543 self.start_networkd()
544
545 self.assertTrue(self.link_exits('dummy98'))
546 self.assertTrue(self.link_exits('test1'))
547 self.assertTrue(self.link_exits('bridge99'))
548
549 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
550 print(output)
551 self.assertRegex(output, 'master')
552 self.assertRegex(output, 'bridge')
553
554 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
555 print(output)
556 self.assertRegex(output, 'master')
557 self.assertRegex(output, 'bridge')
558
559 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
560 print(output)
561 self.assertRegex(output, '192.168.0.15')
562 self.assertRegex(output, '192.168.0.1')
563
564 output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
565 print(output)
566 self.assertRegex(output, 'cost 400')
567 self.assertRegex(output, 'hairpin on')
568 self.assertRegex(output, 'flood on')
569 self.assertRegex(output, 'fastleave on')
570
571class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
572 links = ['veth99']
573
574 units = ['23-emit-lldp.network', '24-lldp.network', '25-veth.netdev']
575
576 def setUp(self):
577 self.link_remove(self.links)
578
579 def tearDown(self):
580 self.link_remove(self.links)
581 self.remove_unit_from_networkd_path(self.units)
582
583 def test_lldp(self):
584 self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
585 self.start_networkd()
586
587 self.assertTrue(self.link_exits('veth99'))
588
589 output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
590 print(output)
591 self.assertRegex(output, 'veth-peer')
592 self.assertRegex(output, 'veth99')
593
594class NetworkdNetworkRATests(unittest.TestCase, Utilities):
595 links = ['veth99']
596
597 units = ['25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network']
598
599 def setUp(self):
600 self.link_remove(self.links)
601
602 def tearDown(self):
603 self.link_remove(self.links)
604 self.remove_unit_from_networkd_path(self.units)
605
606 def test_ipv6_prefix_delegation(self):
607 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
608 self.start_networkd()
609
610 self.assertTrue(self.link_exits('veth99'))
611
612 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
613 print(output)
614 self.assertRegex(output, '2002:da8:1:0')
615
616class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
617 links = ['veth99', 'dummy98']
618
619 units = ['25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network', '12-dummy.netdev', '24-search-domain.network',
620 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network']
621
622 def setUp(self):
623 self.link_remove(self.links)
624
625 def tearDown(self):
626 self.link_remove(self.links)
627 self.remove_unit_from_networkd_path(self.units)
628
629 def test_dhcp_server(self):
630 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
631 self.start_networkd()
632
633 self.assertTrue(self.link_exits('veth99'))
634
635 time.sleep(5)
636
637 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
638 print(output)
639 self.assertRegex(output, '192.168.5.*')
640 self.assertRegex(output, 'Gateway: 192.168.5.1')
641 self.assertRegex(output, 'DNS: 192.168.5.1')
642 self.assertRegex(output, 'NTP: 192.168.5.1')
643
644 def test_domain(self):
645 self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
646 self.start_networkd()
647
648 self.assertTrue(self.link_exits('dummy98'))
649
650 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
651 print(output)
652 self.assertRegex(output, 'Address: 192.168.42.100')
653 self.assertRegex(output, 'DNS: 192.168.42.1')
654 self.assertRegex(output, 'Search Domains: one')
655
656 def test_emit_router_timezone(self):
657 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
658 self.start_networkd()
659
660 self.assertTrue(self.link_exits('veth99'))
661
662 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
663 print(output)
664 self.assertRegex(output, 'Gateway: 192.168.5.*')
665 self.assertRegex(output, '192.168.5.*')
666 self.assertRegex(output, 'Europe/Berlin')
667
668class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
669 links = ['veth99', 'dummy98']
670
671 units = ['25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network',
672 'dhcp-client-ipv4-only-ipv6-disabled.network', 'dhcp-client-ipv4-only.network',
673 'dhcp-client-ipv4-dhcp-settings.network', 'dhcp-client-anonymize.network',
674 'dhcp-client-ipv6-rapid-commit.network', 'dhcp-client-route-table.network',
675 'dhcp-v4-server-veth-peer.network', 'dhcp-client-listen-port.network',
676 'dhcp-client-route-metric.network', 'dhcp-client-critical-connection.network']
677
678 def setUp(self):
679 self.link_remove(self.links)
680 self.stop_dnsmasq(dnsmasq_pid_file)
681
682 def tearDown(self):
683 self.link_remove(self.links)
684 self.remove_unit_from_networkd_path(self.units)
685 self.stop_dnsmasq(dnsmasq_pid_file)
686 self.remove_lease_file()
687 self.remove_log_file()
688
689 def test_dhcp_client_ipv6_only(self):
690 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
691 self.start_networkd()
692
693 self.assertTrue(self.link_exits('veth99'))
694
695 self.start_dnsmasq()
696
697 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
698 print(output)
699 self.assertRegex(output, '2600::')
700 self.assertNotRegex(output, '192.168.5')
701
702 def test_dhcp_client_ipv4_only(self):
703 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
704 self.start_networkd()
705
706 self.assertTrue(self.link_exits('veth99'))
707
708 self.start_dnsmasq()
709
710 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
711 print(output)
712 self.assertNotRegex(output, '2600::')
713 self.assertRegex(output, '192.168.5')
714
715 def test_dhcp_client_ipv4_ipv6(self):
716 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
717 'dhcp-client-ipv4-only.network')
718 self.start_networkd()
719
720 self.assertTrue(self.link_exits('veth99'))
721
722 self.start_dnsmasq()
723
724 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
725 print(output)
726 self.assertRegex(output, '2600::')
727 self.assertRegex(output, '192.168.5')
728
729 def test_dhcp_client_settings(self):
730 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
731 self.start_networkd()
732
733 self.assertTrue(self.link_exits('veth99'))
734
735 self.start_dnsmasq()
736
737 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
738 print(output)
739 self.assertRegex(output, '12:34:56:78:9a:bc')
740 self.assertRegex(output, '192.168.5')
741 self.assertRegex(output, '1492')
742
743 output = subprocess.check_output(['ip', 'route']).rstrip().decode('utf-8')
744 print(output)
745 self.assertRegex(output, 'default.*dev veth99 proto dhcp')
746
747 self.search_words_in_file('vendor class: SusantVendorTest')
748 self.search_words_in_file('client MAC address: 12:34:56:78:9a:bc')
749 self.search_words_in_file('client provides name: test-hostname')
750 self.search_words_in_file('26:mtu')
751
752 def test_dhcp6_client_settings_rapidcommit_true(self):
753 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
754 self.start_networkd()
755
756 self.assertTrue(self.link_exits('veth99'))
757
758 self.start_dnsmasq()
759
760 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
761 print(output)
762 self.assertRegex(output, '12:34:56:78:9a:bc')
763
764 self.assertTrue(self.search_words_in_file('14:rapid-commit'))
765
766 def test_dhcp6_client_settings_rapidcommit_false(self):
767 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
768 self.start_networkd()
769
770 self.assertTrue(self.link_exits('veth99'))
771
772 self.start_dnsmasq()
773
774 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
775 print(output)
776 self.assertRegex(output, '12:34:56:78:9a:bc')
777
778 self.assertFalse(self.search_words_in_file('14:rapid-commit'))
779
780 def test_dhcp_client_settings_anonymize(self):
781 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
782 self.start_networkd()
783
784 self.assertTrue(self.link_exits('veth99'))
785
786 self.start_dnsmasq()
787 self.assertFalse(self.search_words_in_file('VendorClassIdentifier=SusantVendorTest'))
788 self.assertFalse(self.search_words_in_file('test-hostname'))
789 self.assertFalse(self.search_words_in_file('26:mtu'))
790
791 def test_dhcp_client_listen_port(self):
792 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
793 dh_server = DHCPServer("dhcp_server")
794 dh_server.start()
795
796 self.start_networkd()
797
798 self.assertTrue(self.link_exits('veth99'))
799
800 global port
801 global ip
802
803 self.assertRegex(str(port), '5555')
804 self.assertRegex(str(ip), '0.0.0.0')
805
806 dh_server.join()
807
808 def test_dhcp_route_table_id(self):
809 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
810 self.start_networkd()
811 self.start_dnsmasq()
812
813 self.assertTrue(self.link_exits('veth99'))
814
815 output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
816 print(output)
817
818 self.assertRegex(output, 'veth99 proto dhcp')
819 self.assertRegex(output, '192.168.5.1')
820
821 def test_dhcp_route_metric(self):
822 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
823 self.start_networkd()
824 self.start_dnsmasq()
825
826 self.assertTrue(self.link_exits('veth99'))
827
828 output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
829 print(output)
830
831 self.assertRegex(output, 'metric 24')
832
833 def test_dhcp_route_criticalconnection_true(self):
834 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
835 self.start_networkd()
836 self.start_dnsmasq()
837
838 self.assertTrue(self.link_exits('veth99'))
839
840 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
841 print(output)
842
843 self.assertRegex(output, '192.168.5.*')
844 # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
845 self.stop_dnsmasq(dnsmasq_pid_file)
846
847 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
848 time.sleep(125)
849
850 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
851 print(output)
852 self.assertRegex(output, '192.168.5.*')
853
854if __name__ == '__main__':
855 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
856 verbosity=3))