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