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