]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
Merge pull request #11592 from evverx/ignore-memory-leaks-in-dbus
[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
201bf07f 6import re
1f0e3109
SS
7import shutil
8import signal
9import socket
a9bc5e37
YW
10import subprocess
11import sys
1f0e3109 12import threading
a9bc5e37
YW
13import time
14import unittest
1f0e3109
SS
15from shutil import copytree
16
d486a2d0 17network_unit_file_path='/run/systemd/network'
bad4969b 18networkd_runtime_directory='/run/systemd/netif'
d486a2d0 19networkd_ci_path='/run/networkd-ci'
1f0e3109
SS
20network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
21network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
22
d486a2d0
YW
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 46
c0bf6733
YW
47 subprocess.check_call('systemctl stop systemd-networkd.socket', shell=True)
48
1f0e3109
SS
49def tearDownModule():
50 shutil.rmtree(networkd_ci_path)
51
c0bf6733
YW
52 subprocess.check_call('systemctl stop systemd-networkd.service', shell=True)
53 subprocess.check_call('systemctl start systemd-networkd.socket', shell=True)
54 subprocess.check_call('systemctl start systemd-networkd.service', shell=True)
55
1f0e3109
SS
56class Utilities():
57 dhcp_server_data = []
58
59 def read_link_attr(self, link, dev, attribute):
60 with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
61 return f.readline().strip()
62
4d7ed14f
SS
63 def read_bridge_port_attr(self, bridge, link, attribute):
64
65 path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
66 path_port = 'lower_' + link + '/brport'
67 path = os.path.join(path_bridge, path_port)
68
69 with open(os.path.join(path, attribute)) as f:
70 return f.readline().strip()
71
1f0e3109
SS
72 def link_exits(self, link):
73 return os.path.exists(os.path.join('/sys/class/net', link))
74
75 def link_remove(self, links):
76 for link in links:
77 if os.path.exists(os.path.join('/sys/class/net', link)):
78 subprocess.call(['ip', 'link', 'del', 'dev', link])
9a4720a9 79 time.sleep(1)
1f0e3109
SS
80
81 def read_ipv6_sysctl_attr(self, link, attribute):
82 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
83 return f.readline().strip()
84
85 def read_ipv4_sysctl_attr(self, link, attribute):
86 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
87 return f.readline().strip()
88
89 def copy_unit_to_networkd_unit_path(self, *units):
90 for unit in units:
91 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
013c8dc9
YW
92 if (os.path.exists(os.path.join(networkd_ci_path, unit + '.d'))):
93 copytree(os.path.join(networkd_ci_path, unit + '.d'), os.path.join(network_unit_file_path, unit + '.d'))
1f0e3109
SS
94
95 def remove_unit_from_networkd_path(self, units):
96 for unit in units:
97 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
98 os.remove(os.path.join(network_unit_file_path, unit))
013c8dc9
YW
99 if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
100 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
1f0e3109
SS
101
102 def start_dnsmasq(self):
6f783ce5 103 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 --port=0', shell=True)
1f0e3109
SS
104
105 time.sleep(10)
106
107 def stop_dnsmasq(self, pid_file):
108 if os.path.exists(pid_file):
109 with open(pid_file, 'r') as f:
110 pid = f.read().rstrip(' \t\r\n\0')
111 os.kill(int(pid), signal.SIGTERM)
112
113 os.remove(pid_file)
114
131717cb 115 def search_words_in_dnsmasq_log(self, words, show_all=False):
1f0e3109
SS
116 if os.path.exists(dnsmasq_log_file):
117 with open (dnsmasq_log_file) as in_file:
118 contents = in_file.read()
131717cb
YW
119 if show_all:
120 print(contents)
121 for line in contents.split('\n'):
122 if words in line:
1f0e3109 123 in_file.close()
131717cb 124 print("%s, %s" % (words, line))
1f0e3109
SS
125 return True
126 return False
127
128 def remove_lease_file(self):
129 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
130 os.remove(os.path.join(networkd_ci_path, 'lease'))
131
132 def remove_log_file(self):
133 if os.path.exists(dnsmasq_log_file):
134 os.remove(dnsmasq_log_file)
135
136 def start_networkd(self):
bad4969b
YW
137 if (os.path.exists(os.path.join(networkd_runtime_directory, 'state'))):
138 subprocess.check_call('systemctl stop systemd-networkd', shell=True)
139 os.remove(os.path.join(networkd_runtime_directory, 'state'))
140 subprocess.check_call('systemctl start systemd-networkd', shell=True)
141 else:
142 subprocess.check_call('systemctl restart systemd-networkd', shell=True)
1f0e3109 143 time.sleep(5)
fa7cd602 144 print()
1f0e3109
SS
145
146global ip
147global port
148
149class DHCPServer(threading.Thread):
150 def __init__(self, name):
151 threading.Thread.__init__(self)
152 self.name = name
153
154 def run(self):
155 self.start_dhcp_server()
156
157 def start_dhcp_server(self):
158 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
159
160 server_address = ('0.0.0.0', 67)
161 sock.bind(server_address)
162
163 print('Starting DHCP Server ...\n')
164 data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
165
166 global ip
167 ip = addr[0]
168
169 global port
170 port = addr[1]
171 sock.close()
172
173class NetworkdNetDevTests(unittest.TestCase, Utilities):
174
09ea6724
YW
175 links =[
176 '6rdtun99',
177 'bond99',
178 'bridge99',
179 'dropin-test',
180 'dummy98',
181 'erspan-test',
182 'geneve99',
183 'gretap99',
184 'gretun99',
185 'ip6gretap99',
186 'ip6tnl99',
187 'ipiptun99',
188 'ipvlan99',
189 'isataptun99',
190 'macvlan99',
191 'macvtap99',
192 'sittun99',
193 'tap99',
194 'test1',
195 'tun99',
196 'vcan99',
197 'veth99',
198 'vlan99',
199 'vrf99',
200 'vti6tun99',
201 'vtitun99',
202 'vxlan99',
da44fb8a 203 'wg98',
09ea6724
YW
204 'wg99']
205
206 units = [
207 '10-dropin-test.netdev',
208 '11-dummy.netdev',
209 '12-dummy.netdev',
210 '21-macvlan.netdev',
211 '21-macvtap.netdev',
212 '21-vlan.netdev',
213 '21-vlan.network',
214 '25-6rd-tunnel.netdev',
215 '25-bond.netdev',
fde60a42 216 '25-bond-balanced-tlb.netdev',
09ea6724
YW
217 '25-bridge.netdev',
218 '25-erspan-tunnel.netdev',
219 '25-geneve.netdev',
220 '25-gretap-tunnel.netdev',
221 '25-gre-tunnel.netdev',
222 '25-ip6gre-tunnel.netdev',
223 '25-ip6tnl-tunnel.netdev',
224 '25-ipip-tunnel-independent.netdev',
225 '25-ipip-tunnel.netdev',
226 '25-ipvlan.netdev',
227 '25-isatap-tunnel.netdev',
228 '25-sit-tunnel.netdev',
229 '25-tap.netdev',
230 '25-tun.netdev',
231 '25-vcan.netdev',
232 '25-veth.netdev',
233 '25-vrf.netdev',
234 '25-vti6-tunnel.netdev',
235 '25-vti-tunnel.netdev',
236 '25-vxlan.netdev',
da44fb8a
YW
237 '25-wireguard-23-peers.netdev',
238 '25-wireguard-23-peers.network',
09ea6724
YW
239 '25-wireguard.netdev',
240 '6rd.network',
241 'gre.network',
242 'gretap.network',
243 'gretun.network',
244 'ip6gretap.network',
245 'ip6tnl.network',
246 'ipip.network',
247 'ipvlan.network',
248 'isatap.network',
249 'macvlan.network',
250 'macvtap.network',
251 'sit.network',
252 'vti6.network',
253 'vti.network',
254 'vxlan.network']
1f0e3109
SS
255
256 def setUp(self):
257 self.link_remove(self.links)
258
259 def tearDown(self):
260 self.link_remove(self.links)
261 self.remove_unit_from_networkd_path(self.units)
262
d80734f7
YW
263 def test_dropin(self):
264 self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev')
d80734f7
YW
265 self.start_networkd()
266
267 self.assertTrue(self.link_exits('dropin-test'))
268
269 output = subprocess.check_output(['ip', 'link', 'show', 'dropin-test']).rstrip().decode('utf-8')
270 print(output)
271 self.assertRegex(output, '00:50:56:c0:00:28')
272
1f0e3109
SS
273 def test_bridge(self):
274 self.copy_unit_to_networkd_unit_path('25-bridge.netdev')
275 self.start_networkd()
276
277 self.assertTrue(self.link_exits('bridge99'))
278
279 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'hello_time'))
280 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'max_age'))
281 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','forward_delay'))
282 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','ageing_time'))
283 self.assertEqual('9', self.read_link_attr('bridge99', 'bridge','priority'))
284 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_querier'))
285 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_snooping'))
286 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','stp_state'))
287
288 def test_bond(self):
289 self.copy_unit_to_networkd_unit_path('25-bond.netdev')
290 self.start_networkd()
291
292 self.assertTrue(self.link_exits('bond99'))
293
99f68ef0
TJ
294 self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
295 self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
296 self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
297 self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
298 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
299 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
300 self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
301 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
302 self.assertEqual('1218', self.read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
303 self.assertEqual('811', self.read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
304 self.assertEqual('00:11:22:33:44:55', self.read_link_attr('bond99', 'bonding', 'ad_actor_system'))
1f0e3109 305
fde60a42
SS
306 def test_bond_balanced_tlb(self):
307 self.copy_unit_to_networkd_unit_path('25-bond-balanced-tlb.netdev')
308 self.start_networkd()
309
310 self.assertTrue(self.link_exits('bond99'))
311
312 self.assertEqual('balance-tlb 5', self.read_link_attr('bond99', 'bonding', 'mode'))
313 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'tlb_dynamic_lb'))
314
1f0e3109
SS
315 def test_vlan(self):
316 self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
1f0e3109
SS
317 self.start_networkd()
318
319 self.assertTrue(self.link_exits('vlan99'))
320
321 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
14ecd604 322 print(output)
1f0e3109
SS
323 self.assertTrue(output, 'REORDER_HDR')
324 self.assertTrue(output, 'LOOSE_BINDING')
325 self.assertTrue(output, 'GVRP')
326 self.assertTrue(output, 'MVRP')
327 self.assertTrue(output, '99')
328
329 def test_macvtap(self):
330 self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
1f0e3109
SS
331 self.start_networkd()
332
333 self.assertTrue(self.link_exits('macvtap99'))
334
335 def test_macvlan(self):
336 self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
1f0e3109
SS
337 self.start_networkd()
338
339 self.assertTrue(self.link_exits('macvlan99'))
340
7a0a37b2 341 @expectedFailureIfModuleIsNotAvailable('ipvlan')
1f0e3109
SS
342 def test_ipvlan(self):
343 self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
1f0e3109
SS
344 self.start_networkd()
345
346 self.assertTrue(self.link_exits('ipvlan99'))
347
348 def test_veth(self):
349 self.copy_unit_to_networkd_unit_path('25-veth.netdev')
1f0e3109
SS
350 self.start_networkd()
351
352 self.assertTrue(self.link_exits('veth99'))
353
354 def test_dummy(self):
355 self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
1f0e3109
SS
356 self.start_networkd()
357
358 self.assertTrue(self.link_exits('test1'))
359
360 def test_tun(self):
361 self.copy_unit_to_networkd_unit_path('25-tun.netdev')
1f0e3109
SS
362 self.start_networkd()
363
364 self.assertTrue(self.link_exits('tun99'))
365
366 def test_tap(self):
367 self.copy_unit_to_networkd_unit_path('25-tap.netdev')
1f0e3109
SS
368 self.start_networkd()
369
370 self.assertTrue(self.link_exits('tap99'))
371
7a0a37b2 372 @expectedFailureIfModuleIsNotAvailable('vrf')
1f0e3109
SS
373 def test_vrf(self):
374 self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
1f0e3109
SS
375 self.start_networkd()
376
377 self.assertTrue(self.link_exits('vrf99'))
378
7a0a37b2 379 @expectedFailureIfModuleIsNotAvailable('vcan')
1f0e3109
SS
380 def test_vcan(self):
381 self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
1f0e3109
SS
382 self.start_networkd()
383
384 self.assertTrue(self.link_exits('vcan99'))
385
7a3bc5a8
EV
386 @expectedFailureIfModuleIsNotAvailable('wireguard')
387 def test_wireguard(self):
388 self.copy_unit_to_networkd_unit_path('25-wireguard.netdev')
7a3bc5a8
EV
389 self.start_networkd()
390
391 if shutil.which('wg'):
392 subprocess.call('wg')
16ab043b
YW
393 output = subprocess.check_output(['wg', 'show', 'wg99', 'listen-port']).rstrip().decode('utf-8')
394 self.assertTrue(output, '51820')
395 output = subprocess.check_output(['wg', 'show', 'wg99', 'fwmark']).rstrip().decode('utf-8')
396 self.assertTrue(output, '0x4d2')
397 output = subprocess.check_output(['wg', 'show', 'wg99', 'allowed-ips']).rstrip().decode('utf-8')
398 self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
399 output = subprocess.check_output(['wg', 'show', 'wg99', 'persistent-keepalive']).rstrip().decode('utf-8')
400 self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20')
401 output = subprocess.check_output(['wg', 'show', 'wg99', 'endpoints']).rstrip().decode('utf-8')
402 self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820')
7a3bc5a8
EV
403
404 self.assertTrue(self.link_exits('wg99'))
405
da44fb8a
YW
406 @expectedFailureIfModuleIsNotAvailable('wireguard')
407 def test_wireguard_23_peers(self):
408 self.copy_unit_to_networkd_unit_path('25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network')
409 self.start_networkd()
410
411 if shutil.which('wg'):
412 subprocess.call('wg')
413
414 self.assertTrue(self.link_exits('wg98'))
415
1f0e3109
SS
416 def test_geneve(self):
417 self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
1f0e3109
SS
418 self.start_networkd()
419
420 self.assertTrue(self.link_exits('geneve99'))
421
422 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
14ecd604 423 print(output)
1f0e3109
SS
424 self.assertTrue(output, '192.168.22.1')
425 self.assertTrue(output, '6082')
426 self.assertTrue(output, 'udpcsum')
427 self.assertTrue(output, 'udp6zerocsumrx')
428
429 def test_ipip_tunnel(self):
430 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ipip-tunnel.netdev', 'ipip.network')
431 self.start_networkd()
432
433 self.assertTrue(self.link_exits('dummy98'))
434 self.assertTrue(self.link_exits('ipiptun99'))
435
436 def test_gre_tunnel(self):
437 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gre-tunnel.netdev', 'gretun.network')
438 self.start_networkd()
439
440 self.assertTrue(self.link_exits('dummy98'))
441 self.assertTrue(self.link_exits('gretun99'))
442
443 def test_gretap_tunnel(self):
444 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gretap-tunnel.netdev', 'gretap.network')
445 self.start_networkd()
446
447 self.assertTrue(self.link_exits('dummy98'))
448 self.assertTrue(self.link_exits('gretap99'))
449
450 def test_ip6gretap_tunnel(self):
451 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretap.network')
452 self.start_networkd()
453
454 self.assertTrue(self.link_exits('dummy98'))
455 self.assertTrue(self.link_exits('ip6gretap99'))
456
457 def test_vti_tunnel(self):
458 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti-tunnel.netdev', 'vti.network')
459 self.start_networkd()
460
461 self.assertTrue(self.link_exits('dummy98'))
462 self.assertTrue(self.link_exits('vtitun99'))
463
464 def test_vti6_tunnel(self):
465 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti6-tunnel.netdev', 'vti6.network')
466 self.start_networkd()
467
468 self.assertTrue(self.link_exits('dummy98'))
469 self.assertTrue(self.link_exits('vti6tun99'))
470
471 def test_ip6tnl_tunnel(self):
472 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6tnl-tunnel.netdev', 'ip6tnl.network')
473 self.start_networkd()
474
475 self.assertTrue(self.link_exits('dummy98'))
476 self.assertTrue(self.link_exits('ip6tnl99'))
477
478 def test_sit_tunnel(self):
479 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-sit-tunnel.netdev', 'sit.network')
480 self.start_networkd()
481
482 self.assertTrue(self.link_exits('dummy98'))
483 self.assertTrue(self.link_exits('sittun99'))
484
d0e728b6
SS
485 def test_isatap_tunnel(self):
486 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-isatap-tunnel.netdev', 'isatap.network')
487 self.start_networkd()
488
489 self.assertTrue(self.link_exits('dummy98'))
490 self.assertTrue(self.link_exits('isataptun99'))
e40a58b5 491
d0e728b6 492 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'isataptun99']).rstrip().decode('utf-8')
14ecd604 493 print(output)
d0e728b6
SS
494 self.assertRegex(output, "isatap ")
495
d29dc4f1
DA
496 def test_6rd_tunnel(self):
497 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-6rd-tunnel.netdev', '6rd.network')
498 self.start_networkd()
499
500 self.assertTrue(self.link_exits('dummy98'))
501 self.assertTrue(self.link_exits('sittun99'))
502
2266864b
SS
503 def test_erspan_tunnel(self):
504 self.copy_unit_to_networkd_unit_path('25-erspan-tunnel.netdev')
505 self.start_networkd()
506
507 self.assertTrue(self.link_exits('erspan-test'))
508
509 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan-test']).rstrip().decode('utf-8')
510 print(output)
511 self.assertTrue(output, '172.16.1.200')
512 self.assertTrue(output, '172.16.1.100')
513 self.assertTrue(output, '101')
514
1f0e3109
SS
515 def test_tunnel_independent(self):
516 self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
1f0e3109 517 self.start_networkd()
e40a58b5 518
1f0e3109
SS
519 self.assertTrue(self.link_exits('ipiptun99'))
520
521 def test_vxlan(self):
522 self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network','11-dummy.netdev')
1f0e3109
SS
523 self.start_networkd()
524
525 self.assertTrue(self.link_exits('vxlan99'))
526
527 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
14ecd604 528 print(output)
1f0e3109
SS
529 self.assertRegex(output, "999")
530 self.assertRegex(output, '5555')
531 self.assertRegex(output, 'l2miss')
532 self.assertRegex(output, 'l3miss')
533 self.assertRegex(output, 'udpcsum')
534 self.assertRegex(output, 'udp6zerocsumtx')
535 self.assertRegex(output, 'udp6zerocsumrx')
536 self.assertRegex(output, 'remcsumtx')
537 self.assertRegex(output, 'remcsumrx')
538 self.assertRegex(output, 'gbp')
539
540class NetworkdNetWorkTests(unittest.TestCase, Utilities):
09ea6724
YW
541 links = [
542 'bond199',
543 'dummy98',
544 'test1']
545
546 units = [
547 '11-dummy.netdev',
548 '12-dummy.netdev',
549 '23-active-slave.network',
550 '23-bond199.network',
551 '23-primary-slave.network',
552 '23-test1-bond199.network',
553 '25-address-link-section.network',
554 '25-address-section-miscellaneous.network',
555 '25-address-section.network',
556 '25-bond-active-backup-slave.netdev',
557 '25-fibrule-invert.network',
558 '25-fibrule-port-range.network',
559 '25-ipv6-address-label-section.network',
e4a71bf3 560 '25-neighbor-section.network',
09ea6724
YW
561 '25-link-section-unmanaged.network',
562 '25-route-gateway.network',
563 '25-route-gateway-on-link.network',
20ca06a6 564 '25-route-ipv6-src.network',
09ea6724
YW
565 '25-route-reverse-order.network',
566 '25-route-section.network',
567 '25-route-tcp-window-settings.network',
568 '25-route-type.network',
569 '25-sysctl.network',
570 'configure-without-carrier.network',
571 'routing-policy-rule.network',
572 'test-static.network']
1f0e3109
SS
573
574 def setUp(self):
575 self.link_remove(self.links)
576
577 def tearDown(self):
578 self.link_remove(self.links)
579 self.remove_unit_from_networkd_path(self.units)
580
581 def test_static_address(self):
582 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'test-static.network')
583 self.start_networkd()
584
585 self.assertTrue(self.link_exits('dummy98'))
e40a58b5 586
1f0e3109
SS
587 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
588 print(output)
589 self.assertRegex(output, '192.168.0.15')
590 self.assertRegex(output, '192.168.0.1')
591 self.assertRegex(output, 'routable')
592
593 def test_configure_without_carrier(self):
594 self.copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
595 self.start_networkd()
596
597 self.assertTrue(self.link_exits('test1'))
e40a58b5 598
1f0e3109
SS
599 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
600 print(output)
601 self.assertRegex(output, '192.168.0.15')
602 self.assertRegex(output, '192.168.0.1')
603 self.assertRegex(output, 'routable')
604
605 def test_bond_active_slave(self):
606 self.copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
607 self.start_networkd()
608
609 self.assertTrue(self.link_exits('dummy98'))
610 self.assertTrue(self.link_exits('bond199'))
e40a58b5 611
1f0e3109
SS
612 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
613 print(output)
614 self.assertRegex(output, 'active_slave dummy98')
615
616 def test_bond_primary_slave(self):
617 self.copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-test1-bond199.network', '25-bond-active-backup-slave.netdev', '11-dummy.netdev')
618 self.start_networkd()
619
620 self.assertTrue(self.link_exits('test1'))
621 self.assertTrue(self.link_exits('bond199'))
e40a58b5 622
1f0e3109
SS
623 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
624 print(output)
625 self.assertRegex(output, 'primary test1')
626
627 def test_routing_policy_rule(self):
628 self.copy_unit_to_networkd_unit_path('routing-policy-rule.network', '11-dummy.netdev')
629 self.start_networkd()
630
631 self.assertTrue(self.link_exits('test1'))
e40a58b5 632
1f0e3109
SS
633 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
634 print(output)
635 self.assertRegex(output, '111')
636 self.assertRegex(output, 'from 192.168.100.18')
f7bdd562 637 self.assertRegex(output, r'tos (?:0x08|throughput)\s')
1f0e3109
SS
638 self.assertRegex(output, 'iif test1')
639 self.assertRegex(output, 'oif test1')
640 self.assertRegex(output, 'lookup 7')
641
e4eacdb0
YW
642 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
643
926062f0
SS
644 def test_routing_policy_rule_port_range(self):
645 self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
646 self.start_networkd()
647
648 self.assertTrue(self.link_exits('test1'))
e40a58b5 649
926062f0
SS
650 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
651 print(output)
652 self.assertRegex(output, '111')
653 self.assertRegex(output, 'from 192.168.100.18')
654 self.assertRegex(output, '1123-1150')
655 self.assertRegex(output, '3224-3290')
656 self.assertRegex(output, 'tcp')
657 self.assertRegex(output, 'lookup 7')
1f0e3109 658
e4eacdb0
YW
659 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
660
efecf9cd
SS
661 def test_routing_policy_rule_invert(self):
662 self.copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
663 self.start_networkd()
664
665 self.assertTrue(self.link_exits('test1'))
e40a58b5 666
efecf9cd
SS
667 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
668 print(output)
efecf9cd
SS
669 self.assertRegex(output, '111')
670 self.assertRegex(output, 'not.*?from.*?192.168.100.18')
671 self.assertRegex(output, 'tcp')
672 self.assertRegex(output, 'lookup 7')
673
e4eacdb0
YW
674 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
675
ac60877f
YW
676 def test_address_peer(self):
677 self.copy_unit_to_networkd_unit_path('25-address-section.network', '12-dummy.netdev')
678 self.start_networkd()
679
680 self.assertTrue(self.link_exits('dummy98'))
681
682 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
683 print(output)
684 self.assertRegex(output, 'inet 10.2.3.4 peer 10.2.3.5/16 scope global 32')
685 self.assertRegex(output, 'inet 10.6.7.8/16 brd 10.6.255.255 scope global 33')
7e663619 686 self.assertRegex(output, 'inet6 2001:db8::20 peer 2001:db8::10/128 scope global')
ac60877f
YW
687
688 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
689 print(output)
690 self.assertRegex(output, 'State: routable \(configured\)')
691
1f0e3109
SS
692 def test_address_preferred_lifetime_zero_ipv6(self):
693 self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
694 self.start_networkd()
695
696 self.assertTrue(self.link_exits('dummy98'))
697
698 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
699 print(output)
700 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
701 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
702
703 def test_ip_route(self):
704 self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
705 self.start_networkd()
706
707 self.assertTrue(self.link_exits('dummy98'))
708
709 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
710 print(output)
711 self.assertRegex(output, '192.168.0.1')
712 self.assertRegex(output, 'static')
713 self.assertRegex(output, '192.168.0.0/24')
714
0d34228f
SS
715 def test_ip_route_reverse(self):
716 self.copy_unit_to_networkd_unit_path('25-route-reverse-order.network', '12-dummy.netdev')
717 self.start_networkd()
718
719 self.assertTrue(self.link_exits('dummy98'))
720
721 output = subprocess.check_output(['ip', '-6', 'route', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
722 print(output)
723 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff')
724 self.assertRegex(output, '2001:1234:5:8f63::1')
725
1f0e3109
SS
726 def test_ip_route_blackhole_unreachable_prohibit(self):
727 self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
728 self.start_networkd()
729
730 self.assertTrue(self.link_exits('dummy98'))
731
732 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
733 print(output)
734 self.assertRegex(output, 'blackhole')
735 self.assertRegex(output, 'unreachable')
736 self.assertRegex(output, 'prohibit')
737
738 subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
739 subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
740 subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
741
742 def test_ip_route_tcp_window(self):
743 self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
744 self.start_networkd()
745
746 self.assertTrue(self.link_exits('test1'))
747
748 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
749 print(output)
750 self.assertRegex(output, 'initcwnd 20')
751 self.assertRegex(output, 'initrwnd 30')
752
f5050e48
YW
753 def test_ip_route_gateway(self):
754 self.copy_unit_to_networkd_unit_path('25-route-gateway.network', '12-dummy.netdev')
755 self.start_networkd()
756
757 self.assertTrue(self.link_exits('dummy98'))
758
759 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
760 print(output)
761 self.assertRegex(output, 'default')
762 self.assertRegex(output, 'via')
763 self.assertRegex(output, '149.10.124.64')
764 self.assertRegex(output, 'proto')
765 self.assertRegex(output, 'static')
766
767 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
768 print(output)
769 self.assertRegex(output, '149.10.124.48/28')
770 self.assertRegex(output, 'proto')
771 self.assertRegex(output, 'kernel')
772 self.assertRegex(output, 'scope')
773 self.assertRegex(output, 'link')
774
775 def test_ip_route_gateway_on_link(self):
776 self.copy_unit_to_networkd_unit_path('25-route-gateway-on-link.network', '12-dummy.netdev')
777 self.start_networkd()
778
779 self.assertTrue(self.link_exits('dummy98'))
780
781 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
782 print(output)
783 self.assertRegex(output, 'default')
784 self.assertRegex(output, 'via')
785 self.assertRegex(output, '149.10.125.65')
786 self.assertRegex(output, 'proto')
787 self.assertRegex(output, 'static')
788 self.assertRegex(output, 'onlink')
789
790 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
791 print(output)
792 self.assertRegex(output, '149.10.124.48/28')
793 self.assertRegex(output, 'proto')
794 self.assertRegex(output, 'kernel')
795 self.assertRegex(output, 'scope')
796 self.assertRegex(output, 'link')
797
20ca06a6
DA
798 def test_ip_route_ipv6_src_route(self):
799 # a dummy device does not make the addresses go through tentative state, so we
800 # reuse a bond from an earlier test, which does make the addresses go through
801 # tentative state, and do our test on that
802 self.copy_unit_to_networkd_unit_path('23-active-slave.network', '25-route-ipv6-src.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
803 self.start_networkd()
804
805 self.assertTrue(self.link_exits('dummy98'))
806 self.assertTrue(self.link_exits('bond199'))
807
808 output = subprocess.check_output(['ip', '-6', 'route', 'list', 'dev', 'bond199']).rstrip().decode('utf-8')
809 print(output)
810 self.assertRegex(output, 'abcd::/16')
811 self.assertRegex(output, 'src')
812 self.assertRegex(output, '2001:1234:56:8f63::2')
813
1f0e3109
SS
814 def test_ip_link_mac_address(self):
815 self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
816 self.start_networkd()
817
818 self.assertTrue(self.link_exits('dummy98'))
819
820 output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
821 print(output)
822 self.assertRegex(output, '00:01:02:aa:bb:cc')
823
824 def test_ip_link_unmanaged(self):
825 self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
826 self.start_networkd()
827
828 self.assertTrue(self.link_exits('dummy98'))
829
830 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
831 print(output)
832 self.assertRegex(output, 'unmanaged')
833
834 def test_ipv6_address_label(self):
835 self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
836 self.start_networkd()
837
838 self.assertTrue(self.link_exits('dummy98'))
839
840 output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
841 print(output)
842 self.assertRegex(output, '2004:da8:1::/64')
843
e4a71bf3
WKI
844 def test_ipv6_neighbor(self):
845 self.copy_unit_to_networkd_unit_path('25-neighbor-section.network', '12-dummy.netdev')
846 self.start_networkd()
847
848 self.assertTrue(self.link_exits('dummy98'))
849
850 output = subprocess.check_output(['ip', 'neigh', 'list']).rstrip().decode('utf-8')
851 print(output)
852 self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
094b5479 853 self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
e4a71bf3 854
1f0e3109
SS
855 def test_sysctl(self):
856 self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
857 self.start_networkd()
858
859 self.assertTrue(self.link_exits('dummy98'))
860
861 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
862 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
863 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
864 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
865 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
866 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
867 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
868
14dc0335 869class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
09ea6724
YW
870 links = [
871 'bridge99',
872 'dummy98',
873 'test1']
874
875 units = [
876 '11-dummy.netdev',
877 '12-dummy.netdev',
878 '26-bridge.netdev',
879 '26-bridge-slave-interface-1.network',
880 '26-bridge-slave-interface-2.network',
881 'bridge99.network']
1f0e3109
SS
882
883 def setUp(self):
884 self.link_remove(self.links)
885
886 def tearDown(self):
887 self.link_remove(self.links)
888 self.remove_unit_from_networkd_path(self.units)
889
890 def test_bridge_property(self):
891 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
892 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
893 'bridge99.network')
894 self.start_networkd()
895
896 self.assertTrue(self.link_exits('dummy98'))
897 self.assertTrue(self.link_exits('test1'))
898 self.assertTrue(self.link_exits('bridge99'))
899
900 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
901 print(output)
902 self.assertRegex(output, 'master')
903 self.assertRegex(output, 'bridge')
904
905 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
906 print(output)
907 self.assertRegex(output, 'master')
908 self.assertRegex(output, 'bridge')
909
910 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
911 print(output)
912 self.assertRegex(output, '192.168.0.15')
913 self.assertRegex(output, '192.168.0.1')
914
915 output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
916 print(output)
4d7ed14f
SS
917 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
918 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
919 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
920 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
921
922 # CONFIG_BRIDGE_IGMP_SNOOPING=y
923 if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
924 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
1f0e3109
SS
925
926class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
927 links = ['veth99']
928
09ea6724
YW
929 units = [
930 '23-emit-lldp.network',
931 '24-lldp.network',
932 '25-veth.netdev']
1f0e3109
SS
933
934 def setUp(self):
935 self.link_remove(self.links)
936
937 def tearDown(self):
938 self.link_remove(self.links)
939 self.remove_unit_from_networkd_path(self.units)
940
941 def test_lldp(self):
942 self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
943 self.start_networkd()
944
945 self.assertTrue(self.link_exits('veth99'))
946
947 output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
948 print(output)
949 self.assertRegex(output, 'veth-peer')
950 self.assertRegex(output, 'veth99')
951
952class NetworkdNetworkRATests(unittest.TestCase, Utilities):
953 links = ['veth99']
954
09ea6724
YW
955 units = [
956 '25-veth.netdev',
957 'ipv6-prefix.network',
958 'ipv6-prefix-veth.network']
1f0e3109
SS
959
960 def setUp(self):
961 self.link_remove(self.links)
962
963 def tearDown(self):
964 self.link_remove(self.links)
965 self.remove_unit_from_networkd_path(self.units)
966
967 def test_ipv6_prefix_delegation(self):
968 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
969 self.start_networkd()
970
971 self.assertTrue(self.link_exits('veth99'))
972
973 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
974 print(output)
975 self.assertRegex(output, '2002:da8:1:0')
976
977class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
09ea6724
YW
978 links = [
979 'dummy98',
980 'veth99']
981
982 units = [
983 '12-dummy.netdev',
984 '24-search-domain.network',
985 '25-veth.netdev',
986 'dhcp-client.network',
987 'dhcp-client-timezone-router.network',
988 'dhcp-server.network',
989 'dhcp-server-timezone-router.network']
1f0e3109
SS
990
991 def setUp(self):
992 self.link_remove(self.links)
993
994 def tearDown(self):
995 self.link_remove(self.links)
996 self.remove_unit_from_networkd_path(self.units)
997
998 def test_dhcp_server(self):
999 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
1000 self.start_networkd()
1001
1002 self.assertTrue(self.link_exits('veth99'))
1003
1f0e3109
SS
1004 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1005 print(output)
1006 self.assertRegex(output, '192.168.5.*')
1007 self.assertRegex(output, 'Gateway: 192.168.5.1')
1008 self.assertRegex(output, 'DNS: 192.168.5.1')
1009 self.assertRegex(output, 'NTP: 192.168.5.1')
1010
1011 def test_domain(self):
1012 self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
1013 self.start_networkd()
1014
1015 self.assertTrue(self.link_exits('dummy98'))
1016
1017 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1018 print(output)
1019 self.assertRegex(output, 'Address: 192.168.42.100')
1020 self.assertRegex(output, 'DNS: 192.168.42.1')
1021 self.assertRegex(output, 'Search Domains: one')
1022
1023 def test_emit_router_timezone(self):
1024 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
1025 self.start_networkd()
1026
1027 self.assertTrue(self.link_exits('veth99'))
1028
1029 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1030 print(output)
1031 self.assertRegex(output, 'Gateway: 192.168.5.*')
1032 self.assertRegex(output, '192.168.5.*')
1033 self.assertRegex(output, 'Europe/Berlin')
1034
1035class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
09ea6724
YW
1036 links = [
1037 'dummy98',
1038 'veth99']
1039
1040 units = [
1041 '25-veth.netdev',
1042 'dhcp-client-anonymize.network',
1043 'dhcp-client-critical-connection.network',
1044 'dhcp-client-ipv4-dhcp-settings.network',
1045 'dhcp-client-ipv4-only-ipv6-disabled.network',
1046 'dhcp-client-ipv4-only.network',
1047 'dhcp-client-ipv6-only.network',
1048 'dhcp-client-ipv6-rapid-commit.network',
1049 'dhcp-client-listen-port.network',
1050 'dhcp-client-route-metric.network',
1051 'dhcp-client-route-table.network',
30d3b54e 1052 'dhcp-client.network'
09ea6724 1053 'dhcp-server-veth-peer.network',
30d3b54e
YW
1054 'dhcp-v4-server-veth-peer.network',
1055 'static.network']
1f0e3109
SS
1056
1057 def setUp(self):
1058 self.link_remove(self.links)
1059 self.stop_dnsmasq(dnsmasq_pid_file)
1060
1061 def tearDown(self):
1062 self.link_remove(self.links)
1063 self.remove_unit_from_networkd_path(self.units)
1064 self.stop_dnsmasq(dnsmasq_pid_file)
1065 self.remove_lease_file()
1066 self.remove_log_file()
1067
1068 def test_dhcp_client_ipv6_only(self):
1069 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
1070 self.start_networkd()
1071
1072 self.assertTrue(self.link_exits('veth99'))
1073
1074 self.start_dnsmasq()
1075
1076 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1077 print(output)
1078 self.assertRegex(output, '2600::')
1079 self.assertNotRegex(output, '192.168.5')
1080
1081 def test_dhcp_client_ipv4_only(self):
1082 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
1083 self.start_networkd()
1084
1085 self.assertTrue(self.link_exits('veth99'))
1086
1087 self.start_dnsmasq()
1088
1089 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1090 print(output)
1091 self.assertNotRegex(output, '2600::')
1092 self.assertRegex(output, '192.168.5')
1093
1094 def test_dhcp_client_ipv4_ipv6(self):
1095 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
1096 'dhcp-client-ipv4-only.network')
1097 self.start_networkd()
1098
1099 self.assertTrue(self.link_exits('veth99'))
1100
1101 self.start_dnsmasq()
1102
1103 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1104 print(output)
1105 self.assertRegex(output, '2600::')
1106 self.assertRegex(output, '192.168.5')
1107
1108 def test_dhcp_client_settings(self):
1109 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
1110 self.start_networkd()
1111
1112 self.assertTrue(self.link_exits('veth99'))
1113
1114 self.start_dnsmasq()
1115
1116 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1117 print(output)
1118 self.assertRegex(output, '12:34:56:78:9a:bc')
1119 self.assertRegex(output, '192.168.5')
1120 self.assertRegex(output, '1492')
1121
1122 output = subprocess.check_output(['ip', 'route']).rstrip().decode('utf-8')
1123 print(output)
1124 self.assertRegex(output, 'default.*dev veth99 proto dhcp')
1125
131717cb
YW
1126 self.assertTrue(self.search_words_in_dnsmasq_log('vendor class: SusantVendorTest', True))
1127 self.assertTrue(self.search_words_in_dnsmasq_log('DHCPDISCOVER(veth-peer) 12:34:56:78:9a:bc'))
1128 self.assertTrue(self.search_words_in_dnsmasq_log('client provides name: test-hostname'))
1129 self.assertTrue(self.search_words_in_dnsmasq_log('26:mtu'))
1f0e3109
SS
1130
1131 def test_dhcp6_client_settings_rapidcommit_true(self):
1132 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
1133 self.start_networkd()
1134
1135 self.assertTrue(self.link_exits('veth99'))
1136
1137 self.start_dnsmasq()
1138
1139 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1140 print(output)
1141 self.assertRegex(output, '12:34:56:78:9a:bc')
131717cb 1142 self.assertTrue(self.search_words_in_dnsmasq_log('14:rapid-commit', True))
1f0e3109
SS
1143
1144 def test_dhcp6_client_settings_rapidcommit_false(self):
1145 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
1146 self.start_networkd()
1147
1148 self.assertTrue(self.link_exits('veth99'))
1149
1150 self.start_dnsmasq()
1151
1152 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1153 print(output)
1154 self.assertRegex(output, '12:34:56:78:9a:bc')
131717cb 1155 self.assertFalse(self.search_words_in_dnsmasq_log('14:rapid-commit', True))
1f0e3109
SS
1156
1157 def test_dhcp_client_settings_anonymize(self):
1158 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
1159 self.start_networkd()
1160
1161 self.assertTrue(self.link_exits('veth99'))
1162
1163 self.start_dnsmasq()
e40a58b5 1164
131717cb
YW
1165 self.assertFalse(self.search_words_in_dnsmasq_log('VendorClassIdentifier=SusantVendorTest', True))
1166 self.assertFalse(self.search_words_in_dnsmasq_log('test-hostname'))
1167 self.assertFalse(self.search_words_in_dnsmasq_log('26:mtu'))
1f0e3109
SS
1168
1169 def test_dhcp_client_listen_port(self):
1170 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
e40a58b5 1171
1f0e3109
SS
1172 dh_server = DHCPServer("dhcp_server")
1173 dh_server.start()
1174
1175 self.start_networkd()
1176
1177 self.assertTrue(self.link_exits('veth99'))
1178
1179 global port
1180 global ip
1181
1182 self.assertRegex(str(port), '5555')
1183 self.assertRegex(str(ip), '0.0.0.0')
1184
1185 dh_server.join()
1186
1187 def test_dhcp_route_table_id(self):
1188 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
1189 self.start_networkd()
1f0e3109
SS
1190
1191 self.assertTrue(self.link_exits('veth99'))
1192
e40a58b5
YW
1193 self.start_dnsmasq()
1194
1f0e3109
SS
1195 output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
1196 print(output)
1f0e3109
SS
1197 self.assertRegex(output, 'veth99 proto dhcp')
1198 self.assertRegex(output, '192.168.5.1')
1199
1200 def test_dhcp_route_metric(self):
1201 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
1202 self.start_networkd()
1f0e3109
SS
1203
1204 self.assertTrue(self.link_exits('veth99'))
1205
e40a58b5
YW
1206 self.start_dnsmasq()
1207
1f0e3109
SS
1208 output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1209 print(output)
1f0e3109
SS
1210 self.assertRegex(output, 'metric 24')
1211
1212 def test_dhcp_route_criticalconnection_true(self):
1213 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
1214 self.start_networkd()
1f0e3109
SS
1215
1216 self.assertTrue(self.link_exits('veth99'))
1217
e40a58b5
YW
1218 self.start_dnsmasq()
1219
1f0e3109
SS
1220 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1221 print(output)
1f0e3109 1222 self.assertRegex(output, '192.168.5.*')
e40a58b5 1223
1f0e3109
SS
1224 # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
1225 self.stop_dnsmasq(dnsmasq_pid_file)
1226
1227 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
1228 time.sleep(125)
1229
1230 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1231 print(output)
1232 self.assertRegex(output, '192.168.5.*')
1233
30d3b54e
YW
1234 def test_dhcp_client_reuse_address_as_static(self):
1235 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
1236 self.start_networkd()
1237
1238 self.assertTrue(self.link_exits('veth99'))
1239
1240 self.start_dnsmasq()
1241
1242 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
1243 print(output)
1244 self.assertRegex(output, '192.168.5')
1245 self.assertRegex(output, '2600::')
1246
1247 ipv4_address = re.search('192\.168\.5\.[0-9]*/24', output)
1248 ipv6_address = re.search('2600::[0-9a-f:]*/128', output)
1249 static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address.group(), 'Address=' + ipv6_address.group()])
1250 print(static_network)
1251
1252 self.remove_unit_from_networkd_path(['dhcp-client.network'])
1253
1254 with open(os.path.join(network_unit_file_path, 'static.network'), mode='w') as f:
1255 f.write(static_network)
1256
1257 self.start_networkd()
1258
1259 self.assertTrue(self.link_exits('veth99'))
1260
1261 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
1262 print(output)
1263 self.assertRegex(output, '192.168.5')
1264 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
1265
1266 output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
1267 print(output)
1268 self.assertRegex(output, '2600::')
1269 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
1270
1f0e3109
SS
1271if __name__ == '__main__':
1272 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
1273 verbosity=3))