]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
test-network: use /run instead of legacy /var/run
[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
d486a2d0
YW
17network_unit_file_path='/run/systemd/network'
18networkd_ci_path='/run/networkd-ci'
1f0e3109
SS
19network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
20network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
21
d486a2d0
YW
22dnsmasq_config_file='/run/networkd-ci/test-dnsmasq.conf'
23dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
24dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
1f0e3109 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',
926062f0
SS
430 'routing-policy-rule.network', '25-fibrule-port-range.network', '25-address-section.network',
431 '25-address-section-miscellaneous.network', '25-route-section.network', '25-route-type.network',
432 '25-route-tcp-window-settings.network', '25-route-gateway.network', '25-route-gateway-on-link.network',
1f0e3109 433 '25-address-link-section.network', '25-ipv6-address-label-section.network', '25-link-section-unmanaged.network',
0d34228f 434 '25-sysctl.network', '25-route-reverse-order.network']
1f0e3109
SS
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
926062f0
SS
499 def test_routing_policy_rule_port_range(self):
500 self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
501 self.start_networkd()
502
503 self.assertTrue(self.link_exits('test1'))
504 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
505 print(output)
506 self.assertRegex(output, '111')
507 self.assertRegex(output, 'from 192.168.100.18')
508 self.assertRegex(output, '1123-1150')
509 self.assertRegex(output, '3224-3290')
510 self.assertRegex(output, 'tcp')
511 self.assertRegex(output, 'lookup 7')
1f0e3109
SS
512
513 def test_address_preferred_lifetime_zero_ipv6(self):
514 self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
515 self.start_networkd()
516
517 self.assertTrue(self.link_exits('dummy98'))
518
519 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
520 print(output)
521 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
522 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
523
524 def test_ip_route(self):
525 self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
526 self.start_networkd()
527
528 self.assertTrue(self.link_exits('dummy98'))
529
530 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
531 print(output)
532 self.assertRegex(output, '192.168.0.1')
533 self.assertRegex(output, 'static')
534 self.assertRegex(output, '192.168.0.0/24')
535
0d34228f
SS
536 def test_ip_route_reverse(self):
537 self.copy_unit_to_networkd_unit_path('25-route-reverse-order.network', '12-dummy.netdev')
538 self.start_networkd()
539
540 self.assertTrue(self.link_exits('dummy98'))
541
542 output = subprocess.check_output(['ip', '-6', 'route', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
543 print(output)
544 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff')
545 self.assertRegex(output, '2001:1234:5:8f63::1')
546
1f0e3109
SS
547 def test_ip_route_blackhole_unreachable_prohibit(self):
548 self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
549 self.start_networkd()
550
551 self.assertTrue(self.link_exits('dummy98'))
552
553 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
554 print(output)
555 self.assertRegex(output, 'blackhole')
556 self.assertRegex(output, 'unreachable')
557 self.assertRegex(output, 'prohibit')
558
559 subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
560 subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
561 subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
562
563 def test_ip_route_tcp_window(self):
564 self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
565 self.start_networkd()
566
567 self.assertTrue(self.link_exits('test1'))
568
569 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
570 print(output)
571 self.assertRegex(output, 'initcwnd 20')
572 self.assertRegex(output, 'initrwnd 30')
573
f5050e48
YW
574 def test_ip_route_gateway(self):
575 self.copy_unit_to_networkd_unit_path('25-route-gateway.network', '12-dummy.netdev')
576 self.start_networkd()
577
578 self.assertTrue(self.link_exits('dummy98'))
579
580 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
581 print(output)
582 self.assertRegex(output, 'default')
583 self.assertRegex(output, 'via')
584 self.assertRegex(output, '149.10.124.64')
585 self.assertRegex(output, 'proto')
586 self.assertRegex(output, 'static')
587
588 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
589 print(output)
590 self.assertRegex(output, '149.10.124.48/28')
591 self.assertRegex(output, 'proto')
592 self.assertRegex(output, 'kernel')
593 self.assertRegex(output, 'scope')
594 self.assertRegex(output, 'link')
595
596 def test_ip_route_gateway_on_link(self):
597 self.copy_unit_to_networkd_unit_path('25-route-gateway-on-link.network', '12-dummy.netdev')
598 self.start_networkd()
599
600 self.assertTrue(self.link_exits('dummy98'))
601
602 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
603 print(output)
604 self.assertRegex(output, 'default')
605 self.assertRegex(output, 'via')
606 self.assertRegex(output, '149.10.125.65')
607 self.assertRegex(output, 'proto')
608 self.assertRegex(output, 'static')
609 self.assertRegex(output, 'onlink')
610
611 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
612 print(output)
613 self.assertRegex(output, '149.10.124.48/28')
614 self.assertRegex(output, 'proto')
615 self.assertRegex(output, 'kernel')
616 self.assertRegex(output, 'scope')
617 self.assertRegex(output, 'link')
618
1f0e3109
SS
619 def test_ip_link_mac_address(self):
620 self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
621 self.start_networkd()
622
623 self.assertTrue(self.link_exits('dummy98'))
624
625 output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
626 print(output)
627 self.assertRegex(output, '00:01:02:aa:bb:cc')
628
629 def test_ip_link_unmanaged(self):
630 self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
631 self.start_networkd()
632
633 self.assertTrue(self.link_exits('dummy98'))
634
635 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
636 print(output)
637 self.assertRegex(output, 'unmanaged')
638
639 def test_ipv6_address_label(self):
640 self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
641 self.start_networkd()
642
643 self.assertTrue(self.link_exits('dummy98'))
644
645 output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
646 print(output)
647 self.assertRegex(output, '2004:da8:1::/64')
648
649 def test_sysctl(self):
650 self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
651 self.start_networkd()
652
653 self.assertTrue(self.link_exits('dummy98'))
654
655 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
656 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
657 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
658 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
659 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
660 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
661 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
662
663class NetworkdNetWorkBrideTests(unittest.TestCase, Utilities):
664 links = ['dummy98', 'test1', 'bridge99']
665
666 units = ['11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev', '26-bridge-slave-interface-1.network',
667 '26-bridge-slave-interface-2.network', 'bridge99.network']
668
669 def setUp(self):
670 self.link_remove(self.links)
671
672 def tearDown(self):
673 self.link_remove(self.links)
674 self.remove_unit_from_networkd_path(self.units)
675
676 def test_bridge_property(self):
677 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
678 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
679 'bridge99.network')
680 self.start_networkd()
681
682 self.assertTrue(self.link_exits('dummy98'))
683 self.assertTrue(self.link_exits('test1'))
684 self.assertTrue(self.link_exits('bridge99'))
685
686 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
687 print(output)
688 self.assertRegex(output, 'master')
689 self.assertRegex(output, 'bridge')
690
691 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
692 print(output)
693 self.assertRegex(output, 'master')
694 self.assertRegex(output, 'bridge')
695
696 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
697 print(output)
698 self.assertRegex(output, '192.168.0.15')
699 self.assertRegex(output, '192.168.0.1')
700
701 output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
702 print(output)
703 self.assertRegex(output, 'cost 400')
704 self.assertRegex(output, 'hairpin on')
705 self.assertRegex(output, 'flood on')
706 self.assertRegex(output, 'fastleave on')
707
708class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
709 links = ['veth99']
710
711 units = ['23-emit-lldp.network', '24-lldp.network', '25-veth.netdev']
712
713 def setUp(self):
714 self.link_remove(self.links)
715
716 def tearDown(self):
717 self.link_remove(self.links)
718 self.remove_unit_from_networkd_path(self.units)
719
720 def test_lldp(self):
721 self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
722 self.start_networkd()
723
724 self.assertTrue(self.link_exits('veth99'))
725
726 output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
727 print(output)
728 self.assertRegex(output, 'veth-peer')
729 self.assertRegex(output, 'veth99')
730
731class NetworkdNetworkRATests(unittest.TestCase, Utilities):
732 links = ['veth99']
733
734 units = ['25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network']
735
736 def setUp(self):
737 self.link_remove(self.links)
738
739 def tearDown(self):
740 self.link_remove(self.links)
741 self.remove_unit_from_networkd_path(self.units)
742
743 def test_ipv6_prefix_delegation(self):
744 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
745 self.start_networkd()
746
747 self.assertTrue(self.link_exits('veth99'))
748
749 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
750 print(output)
751 self.assertRegex(output, '2002:da8:1:0')
752
753class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
754 links = ['veth99', 'dummy98']
755
756 units = ['25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network', '12-dummy.netdev', '24-search-domain.network',
757 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network']
758
759 def setUp(self):
760 self.link_remove(self.links)
761
762 def tearDown(self):
763 self.link_remove(self.links)
764 self.remove_unit_from_networkd_path(self.units)
765
766 def test_dhcp_server(self):
767 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
768 self.start_networkd()
769
770 self.assertTrue(self.link_exits('veth99'))
771
772 time.sleep(5)
773
774 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
775 print(output)
776 self.assertRegex(output, '192.168.5.*')
777 self.assertRegex(output, 'Gateway: 192.168.5.1')
778 self.assertRegex(output, 'DNS: 192.168.5.1')
779 self.assertRegex(output, 'NTP: 192.168.5.1')
780
781 def test_domain(self):
782 self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
783 self.start_networkd()
784
785 self.assertTrue(self.link_exits('dummy98'))
786
787 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
788 print(output)
789 self.assertRegex(output, 'Address: 192.168.42.100')
790 self.assertRegex(output, 'DNS: 192.168.42.1')
791 self.assertRegex(output, 'Search Domains: one')
792
793 def test_emit_router_timezone(self):
794 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
795 self.start_networkd()
796
797 self.assertTrue(self.link_exits('veth99'))
798
799 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
800 print(output)
801 self.assertRegex(output, 'Gateway: 192.168.5.*')
802 self.assertRegex(output, '192.168.5.*')
803 self.assertRegex(output, 'Europe/Berlin')
804
805class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
806 links = ['veth99', 'dummy98']
807
808 units = ['25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network',
809 'dhcp-client-ipv4-only-ipv6-disabled.network', 'dhcp-client-ipv4-only.network',
810 'dhcp-client-ipv4-dhcp-settings.network', 'dhcp-client-anonymize.network',
811 'dhcp-client-ipv6-rapid-commit.network', 'dhcp-client-route-table.network',
812 'dhcp-v4-server-veth-peer.network', 'dhcp-client-listen-port.network',
813 'dhcp-client-route-metric.network', 'dhcp-client-critical-connection.network']
814
815 def setUp(self):
816 self.link_remove(self.links)
817 self.stop_dnsmasq(dnsmasq_pid_file)
818
819 def tearDown(self):
820 self.link_remove(self.links)
821 self.remove_unit_from_networkd_path(self.units)
822 self.stop_dnsmasq(dnsmasq_pid_file)
823 self.remove_lease_file()
824 self.remove_log_file()
825
826 def test_dhcp_client_ipv6_only(self):
827 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
828 self.start_networkd()
829
830 self.assertTrue(self.link_exits('veth99'))
831
832 self.start_dnsmasq()
833
834 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
835 print(output)
836 self.assertRegex(output, '2600::')
837 self.assertNotRegex(output, '192.168.5')
838
839 def test_dhcp_client_ipv4_only(self):
840 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
841 self.start_networkd()
842
843 self.assertTrue(self.link_exits('veth99'))
844
845 self.start_dnsmasq()
846
847 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
848 print(output)
849 self.assertNotRegex(output, '2600::')
850 self.assertRegex(output, '192.168.5')
851
852 def test_dhcp_client_ipv4_ipv6(self):
853 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
854 'dhcp-client-ipv4-only.network')
855 self.start_networkd()
856
857 self.assertTrue(self.link_exits('veth99'))
858
859 self.start_dnsmasq()
860
861 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
862 print(output)
863 self.assertRegex(output, '2600::')
864 self.assertRegex(output, '192.168.5')
865
866 def test_dhcp_client_settings(self):
867 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
868 self.start_networkd()
869
870 self.assertTrue(self.link_exits('veth99'))
871
872 self.start_dnsmasq()
873
874 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
875 print(output)
876 self.assertRegex(output, '12:34:56:78:9a:bc')
877 self.assertRegex(output, '192.168.5')
878 self.assertRegex(output, '1492')
879
880 output = subprocess.check_output(['ip', 'route']).rstrip().decode('utf-8')
881 print(output)
882 self.assertRegex(output, 'default.*dev veth99 proto dhcp')
883
884 self.search_words_in_file('vendor class: SusantVendorTest')
885 self.search_words_in_file('client MAC address: 12:34:56:78:9a:bc')
886 self.search_words_in_file('client provides name: test-hostname')
887 self.search_words_in_file('26:mtu')
888
889 def test_dhcp6_client_settings_rapidcommit_true(self):
890 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
891 self.start_networkd()
892
893 self.assertTrue(self.link_exits('veth99'))
894
895 self.start_dnsmasq()
896
897 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
898 print(output)
899 self.assertRegex(output, '12:34:56:78:9a:bc')
900
901 self.assertTrue(self.search_words_in_file('14:rapid-commit'))
902
903 def test_dhcp6_client_settings_rapidcommit_false(self):
904 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
905 self.start_networkd()
906
907 self.assertTrue(self.link_exits('veth99'))
908
909 self.start_dnsmasq()
910
911 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
912 print(output)
913 self.assertRegex(output, '12:34:56:78:9a:bc')
914
915 self.assertFalse(self.search_words_in_file('14:rapid-commit'))
916
917 def test_dhcp_client_settings_anonymize(self):
918 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
919 self.start_networkd()
920
921 self.assertTrue(self.link_exits('veth99'))
922
923 self.start_dnsmasq()
924 self.assertFalse(self.search_words_in_file('VendorClassIdentifier=SusantVendorTest'))
925 self.assertFalse(self.search_words_in_file('test-hostname'))
926 self.assertFalse(self.search_words_in_file('26:mtu'))
927
928 def test_dhcp_client_listen_port(self):
929 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
930 dh_server = DHCPServer("dhcp_server")
931 dh_server.start()
932
933 self.start_networkd()
934
935 self.assertTrue(self.link_exits('veth99'))
936
937 global port
938 global ip
939
940 self.assertRegex(str(port), '5555')
941 self.assertRegex(str(ip), '0.0.0.0')
942
943 dh_server.join()
944
945 def test_dhcp_route_table_id(self):
946 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
947 self.start_networkd()
948 self.start_dnsmasq()
949
950 self.assertTrue(self.link_exits('veth99'))
951
952 output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
953 print(output)
954
955 self.assertRegex(output, 'veth99 proto dhcp')
956 self.assertRegex(output, '192.168.5.1')
957
958 def test_dhcp_route_metric(self):
959 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
960 self.start_networkd()
961 self.start_dnsmasq()
962
963 self.assertTrue(self.link_exits('veth99'))
964
965 output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
966 print(output)
967
968 self.assertRegex(output, 'metric 24')
969
970 def test_dhcp_route_criticalconnection_true(self):
971 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
972 self.start_networkd()
973 self.start_dnsmasq()
974
975 self.assertTrue(self.link_exits('veth99'))
976
977 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
978 print(output)
979
980 self.assertRegex(output, '192.168.5.*')
981 # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
982 self.stop_dnsmasq(dnsmasq_pid_file)
983
984 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
985 time.sleep(125)
986
987 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
988 print(output)
989 self.assertRegex(output, '192.168.5.*')
990
991if __name__ == '__main__':
992 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
993 verbosity=3))