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