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