]> git.ipfire.org Git - thirdparty/systemd.git/blob - test/test-network/systemd-networkd-tests.py
test-network: test stacked erspan tunnels
[thirdparty/systemd.git] / test / test-network / systemd-networkd-tests.py
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: LGPL-2.1+
3 # systemd-networkd tests
4
5 import os
6 import re
7 import shutil
8 import signal
9 import socket
10 import subprocess
11 import sys
12 import time
13 import unittest
14 from shutil import copytree
15
16 network_unit_file_path='/run/systemd/network'
17 networkd_runtime_directory='/run/systemd/netif'
18 networkd_ci_path='/run/networkd-ci'
19 network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
20 network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
21
22 dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
23 dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
24
25 def is_module_available(module_name):
26 lsmod_output = subprocess.check_output('lsmod', universal_newlines=True)
27 module_re = re.compile(r'^{0}\b'.format(re.escape(module_name)), re.MULTILINE)
28 return module_re.search(lsmod_output) or not subprocess.call(["modprobe", module_name])
29
30 def expectedFailureIfModuleIsNotAvailable(module_name):
31 def f(func):
32 if not is_module_available(module_name):
33 return unittest.expectedFailure(func)
34 return func
35
36 return f
37
38 def expectedFailureIfERSPANModuleIsNotAvailable():
39 def f(func):
40 rc = subprocess.call(['ip', 'link', 'add', 'dev', 'erspan99', 'type', 'erspan', 'seq', 'key', '30', 'local', '192.168.1.4', 'remote', '192.168.1.1', 'erspan_ver', '1', 'erspan', '123'])
41 if rc == 0:
42 subprocess.call(['ip', 'link', 'del', 'erspan99'])
43 return func
44 else:
45 return unittest.expectedFailure(func)
46
47 return f
48
49 def expectedFailureIfRoutingPolicyPortRangeIsNotAvailable():
50 def f(func):
51 rc = subprocess.call(['ip', 'rule', 'add', 'from', '192.168.100.19', 'sport', '1123-1150', 'dport', '3224-3290', 'table', '7'])
52 if rc == 0:
53 subprocess.call(['ip', 'rule', 'del', 'from', '192.168.100.19', 'sport', '1123-1150', 'dport', '3224-3290', 'table', '7'])
54 return func
55 else:
56 return unittest.expectedFailure(func)
57
58 return f
59
60 def expectedFailureIfRoutingPolicyIPProtoIsNotAvailable():
61 def f(func):
62 rc = subprocess.call(['ip', 'rule', 'add', 'not', 'from', '192.168.100.19', 'ipproto', 'tcp', 'table', '7'])
63 if rc == 0:
64 subprocess.call(['ip', 'rule', 'del', 'not', 'from', '192.168.100.19', 'ipproto', 'tcp', 'table', '7'])
65 return func
66 else:
67 return unittest.expectedFailure(func)
68
69 return f
70
71 def setUpModule():
72
73 os.makedirs(network_unit_file_path, exist_ok=True)
74 os.makedirs(networkd_ci_path, exist_ok=True)
75
76 shutil.rmtree(networkd_ci_path)
77 copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
78
79 subprocess.check_call('systemctl stop systemd-networkd.socket', shell=True)
80
81 def tearDownModule():
82 shutil.rmtree(networkd_ci_path)
83
84 subprocess.check_call('systemctl stop systemd-networkd.service', shell=True)
85 subprocess.check_call('systemctl start systemd-networkd.socket', shell=True)
86 subprocess.check_call('systemctl start systemd-networkd.service', shell=True)
87
88 class Utilities():
89 def read_link_attr(self, link, dev, attribute):
90 with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
91 return f.readline().strip()
92
93 def read_bridge_port_attr(self, bridge, link, attribute):
94
95 path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
96 path_port = 'lower_' + link + '/brport'
97 path = os.path.join(path_bridge, path_port)
98
99 with open(os.path.join(path, attribute)) as f:
100 return f.readline().strip()
101
102 def link_exits(self, link):
103 return os.path.exists(os.path.join('/sys/class/net', link))
104
105 def link_remove(self, links):
106 for link in links:
107 if os.path.exists(os.path.join('/sys/class/net', link)):
108 subprocess.call(['ip', 'link', 'del', 'dev', link])
109 time.sleep(1)
110
111 def l2tp_tunnel_remove(self, tunnel_ids):
112 output = subprocess.check_output(['ip', 'l2tp', 'show', 'tunnel']).rstrip().decode('utf-8')
113 for tid in tunnel_ids:
114 words='Tunnel ' + tid + ', encap'
115 if words in output:
116 subprocess.call(['ip', 'l2tp', 'del', 'tunnel', 'tid', tid])
117 time.sleep(1)
118
119 def read_ipv6_sysctl_attr(self, link, attribute):
120 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
121 return f.readline().strip()
122
123 def read_ipv4_sysctl_attr(self, link, attribute):
124 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
125 return f.readline().strip()
126
127 def copy_unit_to_networkd_unit_path(self, *units):
128 print()
129 for unit in units:
130 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
131 if (os.path.exists(os.path.join(networkd_ci_path, unit + '.d'))):
132 copytree(os.path.join(networkd_ci_path, unit + '.d'), os.path.join(network_unit_file_path, unit + '.d'))
133
134 def remove_unit_from_networkd_path(self, units):
135 for unit in units:
136 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
137 os.remove(os.path.join(network_unit_file_path, unit))
138 if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
139 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
140
141 def start_dnsmasq(self, additional_options=''):
142 dnsmasq_command = '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 ' + additional_options
143 subprocess.check_call(dnsmasq_command, shell=True)
144
145 time.sleep(10)
146
147 def stop_dnsmasq(self, pid_file):
148 if os.path.exists(pid_file):
149 with open(pid_file, 'r') as f:
150 pid = f.read().rstrip(' \t\r\n\0')
151 os.kill(int(pid), signal.SIGTERM)
152
153 os.remove(pid_file)
154
155 def search_words_in_dnsmasq_log(self, words, show_all=False):
156 if os.path.exists(dnsmasq_log_file):
157 with open (dnsmasq_log_file) as in_file:
158 contents = in_file.read()
159 if show_all:
160 print(contents)
161 for line in contents.split('\n'):
162 if words in line:
163 in_file.close()
164 print("%s, %s" % (words, line))
165 return True
166 return False
167
168 def remove_lease_file(self):
169 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
170 os.remove(os.path.join(networkd_ci_path, 'lease'))
171
172 def remove_log_file(self):
173 if os.path.exists(dnsmasq_log_file):
174 os.remove(dnsmasq_log_file)
175
176 def start_networkd(self, remove_state_files=True):
177 if (remove_state_files and
178 os.path.exists(os.path.join(networkd_runtime_directory, 'state'))):
179 subprocess.check_call('systemctl stop systemd-networkd', shell=True)
180 os.remove(os.path.join(networkd_runtime_directory, 'state'))
181 subprocess.check_call('systemctl start systemd-networkd', shell=True)
182 else:
183 subprocess.check_call('systemctl restart systemd-networkd', shell=True)
184 time.sleep(5)
185
186 class NetworkdNetDevTests(unittest.TestCase, Utilities):
187
188 links =[
189 '6rdtun99',
190 'bond99',
191 'bridge99',
192 'dropin-test',
193 'dummy98',
194 'erspan98',
195 'erspan99',
196 'geneve99',
197 'gretap98',
198 'gretap99',
199 'gretun97',
200 'gretun98',
201 'gretun99',
202 'ip6gretap98',
203 'ip6gretap99',
204 'ip6gretun97',
205 'ip6gretun98',
206 'ip6gretun99',
207 'ip6tnl97',
208 'ip6tnl98',
209 'ip6tnl99',
210 'ipiptun97',
211 'ipiptun98',
212 'ipiptun99',
213 'ipvlan99',
214 'isataptun99',
215 'macvlan99',
216 'macvtap99',
217 'sittun97',
218 'sittun98',
219 'sittun99',
220 'tap99',
221 'test1',
222 'tun99',
223 'vcan99',
224 'veth99',
225 'vlan99',
226 'vrf99',
227 'vti6tun97',
228 'vti6tun98',
229 'vti6tun99',
230 'vtitun97',
231 'vtitun98',
232 'vtitun99',
233 'vxlan99',
234 'wg98',
235 'wg99']
236
237 units = [
238 '10-dropin-test.netdev',
239 '11-dummy.netdev',
240 '12-dummy.netdev',
241 '21-macvlan.netdev',
242 '21-macvtap.netdev',
243 '21-vlan-test1.network',
244 '21-vlan.netdev',
245 '21-vlan.network',
246 '25-6rd-tunnel.netdev',
247 '25-bond.netdev',
248 '25-bond-balanced-tlb.netdev',
249 '25-bridge.netdev',
250 '25-erspan-tunnel-local-any.netdev',
251 '25-erspan-tunnel.netdev',
252 '25-geneve.netdev',
253 '25-gretap-tunnel-local-any.netdev',
254 '25-gretap-tunnel.netdev',
255 '25-gre-tunnel-local-any.netdev',
256 '25-gre-tunnel-remote-any.netdev',
257 '25-gre-tunnel.netdev',
258 '25-ip6gretap-tunnel-local-any.netdev',
259 '25-ip6gretap-tunnel.netdev',
260 '25-ip6gre-tunnel-local-any.netdev',
261 '25-ip6gre-tunnel-remote-any.netdev',
262 '25-ip6gre-tunnel.netdev',
263 '25-ip6tnl-tunnel-remote-any.netdev',
264 '25-ip6tnl-tunnel-local-any.netdev',
265 '25-ip6tnl-tunnel.netdev',
266 '25-ipip-tunnel-independent.netdev',
267 '25-ipip-tunnel-local-any.netdev',
268 '25-ipip-tunnel-remote-any.netdev',
269 '25-ipip-tunnel.netdev',
270 '25-ipvlan.netdev',
271 '25-isatap-tunnel.netdev',
272 '25-sit-tunnel-local-any.netdev',
273 '25-sit-tunnel-remote-any.netdev',
274 '25-sit-tunnel.netdev',
275 '25-tap.netdev',
276 '25-tun.netdev',
277 '25-vcan.netdev',
278 '25-veth.netdev',
279 '25-vrf.netdev',
280 '25-vti6-tunnel-local-any.netdev',
281 '25-vti6-tunnel-remote-any.netdev',
282 '25-vti6-tunnel.netdev',
283 '25-vti-tunnel-local-any.netdev',
284 '25-vti-tunnel-remote-any.netdev',
285 '25-vti-tunnel.netdev',
286 '25-vxlan.netdev',
287 '25-wireguard-23-peers.netdev',
288 '25-wireguard-23-peers.network',
289 '25-wireguard-private-key.txt',
290 '25-wireguard.netdev',
291 '6rd.network',
292 'erspan.network',
293 'gre.network',
294 'gretap.network',
295 'gretun.network',
296 'ip6gretap.network',
297 'ip6gretun.network',
298 'ip6tnl.network',
299 'ipip.network',
300 'ipvlan.network',
301 'isatap.network',
302 'macvlan.network',
303 'macvtap.network',
304 'sit.network',
305 'vti6.network',
306 'vti.network',
307 'vxlan.network']
308
309 def setUp(self):
310 self.link_remove(self.links)
311
312 def tearDown(self):
313 self.link_remove(self.links)
314 self.remove_unit_from_networkd_path(self.units)
315
316 def test_dropin(self):
317 self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev')
318 self.start_networkd()
319
320 self.assertTrue(self.link_exits('dropin-test'))
321
322 output = subprocess.check_output(['ip', 'link', 'show', 'dropin-test']).rstrip().decode('utf-8')
323 print(output)
324 self.assertRegex(output, '00:50:56:c0:00:28')
325
326 output = subprocess.check_output(['networkctl', 'list']).rstrip().decode('utf-8')
327 self.assertRegex(output, '1 lo ')
328 self.assertRegex(output, 'dropin-test')
329
330 output = subprocess.check_output(['networkctl', 'list', 'dropin-test']).rstrip().decode('utf-8')
331 self.assertNotRegex(output, '1 lo ')
332 self.assertRegex(output, 'dropin-test')
333
334 output = subprocess.check_output(['networkctl', 'list', 'dropin-*']).rstrip().decode('utf-8')
335 self.assertNotRegex(output, '1 lo ')
336 self.assertRegex(output, 'dropin-test')
337
338 output = subprocess.check_output(['networkctl', 'status', 'dropin-*']).rstrip().decode('utf-8')
339 self.assertNotRegex(output, '1: lo ')
340 self.assertRegex(output, 'dropin-test')
341
342 ret = subprocess.run(['ethtool', '--driver', 'dropin-test'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
343 print(ret.stdout.rstrip().decode('utf-8'))
344 if ret.returncode == 0 and re.search('driver: dummy', ret.stdout.rstrip().decode('utf-8')) != None:
345 self.assertRegex(output, 'Driver: dummy')
346 else:
347 print('ethtool does not support driver field at least for dummy interfaces, skipping test for Driver field of networkctl.')
348
349 def test_bridge(self):
350 self.copy_unit_to_networkd_unit_path('25-bridge.netdev')
351 self.start_networkd()
352
353 self.assertTrue(self.link_exits('bridge99'))
354
355 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'hello_time'))
356 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'max_age'))
357 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','forward_delay'))
358 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','ageing_time'))
359 self.assertEqual('9', self.read_link_attr('bridge99', 'bridge','priority'))
360 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_querier'))
361 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_snooping'))
362 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','stp_state'))
363
364 def test_bond(self):
365 self.copy_unit_to_networkd_unit_path('25-bond.netdev')
366 self.start_networkd()
367
368 self.assertTrue(self.link_exits('bond99'))
369
370 self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
371 self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
372 self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
373 self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
374 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
375 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
376 self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
377 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
378 self.assertEqual('1218', self.read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
379 self.assertEqual('811', self.read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
380 self.assertEqual('00:11:22:33:44:55', self.read_link_attr('bond99', 'bonding', 'ad_actor_system'))
381
382 def test_bond_balanced_tlb(self):
383 self.copy_unit_to_networkd_unit_path('25-bond-balanced-tlb.netdev')
384 self.start_networkd()
385
386 self.assertTrue(self.link_exits('bond99'))
387
388 self.assertEqual('balance-tlb 5', self.read_link_attr('bond99', 'bonding', 'mode'))
389 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'tlb_dynamic_lb'))
390
391 def test_vlan(self):
392 self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev',
393 '21-vlan.network', '21-vlan-test1.network')
394 self.start_networkd()
395
396 self.assertTrue(self.link_exits('test1'))
397 self.assertTrue(self.link_exits('vlan99'))
398
399 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
400 print(output)
401 self.assertTrue(output, ' mtu 2004 ')
402
403 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
404 print(output)
405 self.assertTrue(output, ' mtu 2000 ')
406 self.assertTrue(output, 'REORDER_HDR')
407 self.assertTrue(output, 'LOOSE_BINDING')
408 self.assertTrue(output, 'GVRP')
409 self.assertTrue(output, 'MVRP')
410 self.assertTrue(output, ' id 99 ')
411
412 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'test1']).rstrip().decode('utf-8')
413 print(output)
414 self.assertRegex(output, 'inet 192.168.24.5/24 brd 192.168.24.255 scope global test1')
415 self.assertRegex(output, 'inet 192.168.25.5/24 brd 192.168.25.255 scope global test1')
416
417 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'vlan99']).rstrip().decode('utf-8')
418 print(output)
419 self.assertRegex(output, 'inet 192.168.23.5/24 brd 192.168.23.255 scope global vlan99')
420
421 def test_macvtap(self):
422 self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
423 self.start_networkd()
424
425 self.assertTrue(self.link_exits('macvtap99'))
426
427 def test_macvlan(self):
428 self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
429 self.start_networkd()
430
431 self.assertTrue(self.link_exits('test1'))
432 self.assertTrue(self.link_exits('macvlan99'))
433
434 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
435 print(output)
436 self.assertTrue(output, ' mtu 2000 ')
437
438 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'macvlan99']).rstrip().decode('utf-8')
439 print(output)
440 self.assertTrue(output, ' mtu 2000 ')
441
442 @expectedFailureIfModuleIsNotAvailable('ipvlan')
443 def test_ipvlan(self):
444 self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
445 self.start_networkd()
446
447 self.assertTrue(self.link_exits('ipvlan99'))
448
449 def test_veth(self):
450 self.copy_unit_to_networkd_unit_path('25-veth.netdev')
451 self.start_networkd()
452
453 self.assertTrue(self.link_exits('veth99'))
454
455 def test_dummy(self):
456 self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
457 self.start_networkd()
458
459 self.assertTrue(self.link_exits('test1'))
460
461 def test_tun(self):
462 self.copy_unit_to_networkd_unit_path('25-tun.netdev')
463 self.start_networkd()
464
465 self.assertTrue(self.link_exits('tun99'))
466
467 def test_tap(self):
468 self.copy_unit_to_networkd_unit_path('25-tap.netdev')
469 self.start_networkd()
470
471 self.assertTrue(self.link_exits('tap99'))
472
473 @expectedFailureIfModuleIsNotAvailable('vrf')
474 def test_vrf(self):
475 self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
476 self.start_networkd()
477
478 self.assertTrue(self.link_exits('vrf99'))
479
480 @expectedFailureIfModuleIsNotAvailable('vcan')
481 def test_vcan(self):
482 self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
483 self.start_networkd()
484
485 self.assertTrue(self.link_exits('vcan99'))
486
487 @expectedFailureIfModuleIsNotAvailable('wireguard')
488 def test_wireguard(self):
489 self.copy_unit_to_networkd_unit_path('25-wireguard.netdev')
490 self.start_networkd()
491
492 if shutil.which('wg'):
493 subprocess.call('wg')
494 output = subprocess.check_output(['wg', 'show', 'wg99', 'listen-port']).rstrip().decode('utf-8')
495 self.assertTrue(output, '51820')
496 output = subprocess.check_output(['wg', 'show', 'wg99', 'fwmark']).rstrip().decode('utf-8')
497 self.assertTrue(output, '0x4d2')
498 output = subprocess.check_output(['wg', 'show', 'wg99', 'allowed-ips']).rstrip().decode('utf-8')
499 self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
500 output = subprocess.check_output(['wg', 'show', 'wg99', 'persistent-keepalive']).rstrip().decode('utf-8')
501 self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20')
502 output = subprocess.check_output(['wg', 'show', 'wg99', 'endpoints']).rstrip().decode('utf-8')
503 self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820')
504 output = subprocess.check_output(['wg', 'show', 'wg99', 'private-key']).rstrip().decode('utf-8')
505 self.assertTrue(output, 'EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=')
506
507 self.assertTrue(self.link_exits('wg99'))
508
509 @expectedFailureIfModuleIsNotAvailable('wireguard')
510 def test_wireguard_23_peers(self):
511 self.copy_unit_to_networkd_unit_path('25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
512 '25-wireguard-private-key.txt')
513 self.start_networkd()
514
515 if shutil.which('wg'):
516 subprocess.call('wg')
517 output = subprocess.check_output(['wg', 'show', 'wg98', 'private-key']).rstrip().decode('utf-8')
518 self.assertTrue(output, 'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr+WHtZLZ90FU=')
519
520 self.assertTrue(self.link_exits('wg98'))
521
522 def test_geneve(self):
523 self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
524 self.start_networkd()
525
526 self.assertTrue(self.link_exits('geneve99'))
527
528 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
529 print(output)
530 self.assertTrue(output, '192.168.22.1')
531 self.assertTrue(output, '6082')
532 self.assertTrue(output, 'udpcsum')
533 self.assertTrue(output, 'udp6zerocsumrx')
534
535 def test_ipip_tunnel(self):
536 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ipip-tunnel.netdev', 'ipip.network',
537 '25-ipip-tunnel-local-any.netdev', '25-ipip-tunnel-remote-any.netdev')
538 self.start_networkd()
539
540 self.assertTrue(self.link_exits('dummy98'))
541 self.assertTrue(self.link_exits('ipiptun99'))
542 self.assertTrue(self.link_exits('ipiptun98'))
543 self.assertTrue(self.link_exits('ipiptun97'))
544
545 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ipiptun99']).rstrip().decode('utf-8')
546 print(output)
547 self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local 192.168.223.238 dev dummy98')
548 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ipiptun98']).rstrip().decode('utf-8')
549 print(output)
550 self.assertRegex(output, 'ipip (?:ipip |)remote 192.169.224.239 local any dev dummy98')
551 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ipiptun97']).rstrip().decode('utf-8')
552 print(output)
553 self.assertRegex(output, 'ipip (?:ipip |)remote any local 192.168.223.238 dev dummy98')
554
555 def test_gre_tunnel(self):
556 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gre-tunnel.netdev', 'gretun.network',
557 '25-gre-tunnel-local-any.netdev', '25-gre-tunnel-remote-any.netdev')
558 self.start_networkd()
559
560 self.assertTrue(self.link_exits('dummy98'))
561 self.assertTrue(self.link_exits('gretun99'))
562 self.assertTrue(self.link_exits('gretun98'))
563 self.assertTrue(self.link_exits('gretun97'))
564
565 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun99']).rstrip().decode('utf-8')
566 print(output)
567 self.assertRegex(output, 'gre remote 10.65.223.239 local 10.65.223.238 dev dummy98')
568 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun98']).rstrip().decode('utf-8')
569 print(output)
570 self.assertRegex(output, 'gre remote 10.65.223.239 local any dev dummy98')
571 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun97']).rstrip().decode('utf-8')
572 print(output)
573 self.assertRegex(output, 'gre remote any local 10.65.223.238 dev dummy98')
574
575 def test_ip6gre_tunnel(self):
576 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretun.network',
577 '25-ip6gre-tunnel-local-any.netdev', '25-ip6gre-tunnel-remote-any.netdev')
578 self.start_networkd()
579
580 self.assertTrue(self.link_exits('dummy98'))
581 self.assertTrue(self.link_exits('ip6gretun99'))
582 self.assertTrue(self.link_exits('ip6gretun98'))
583 self.assertTrue(self.link_exits('ip6gretun97'))
584
585 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6gretun99']).rstrip().decode('utf-8')
586 print(output)
587 self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
588 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6gretun98']).rstrip().decode('utf-8')
589 print(output)
590 self.assertRegex(output, 'ip6gre remote 2001:473:fece:cafe::5179 local any dev dummy98')
591 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6gretun97']).rstrip().decode('utf-8')
592 print(output)
593 self.assertRegex(output, 'ip6gre remote any local 2a00:ffde:4567:edde::4987 dev dummy98')
594
595 def test_gretap_tunnel(self):
596 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gretap-tunnel.netdev', 'gretap.network',
597 '25-gretap-tunnel-local-any.netdev')
598 self.start_networkd()
599
600 self.assertTrue(self.link_exits('dummy98'))
601 self.assertTrue(self.link_exits('gretap99'))
602 self.assertTrue(self.link_exits('gretap98'))
603
604 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretap99']).rstrip().decode('utf-8')
605 print(output)
606 self.assertRegex(output, 'gretap remote 10.65.223.239 local 10.65.223.238 dev dummy98')
607 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretap98']).rstrip().decode('utf-8')
608 print(output)
609 self.assertRegex(output, 'gretap remote 10.65.223.239 local any dev dummy98')
610
611 def test_ip6gretap_tunnel(self):
612 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gretap-tunnel.netdev', 'ip6gretap.network',
613 '25-ip6gretap-tunnel-local-any.netdev')
614 self.start_networkd()
615
616 self.assertTrue(self.link_exits('dummy98'))
617 self.assertTrue(self.link_exits('ip6gretap99'))
618 self.assertTrue(self.link_exits('ip6gretap98'))
619
620 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6gretap99']).rstrip().decode('utf-8')
621 print(output)
622 self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
623 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6gretap98']).rstrip().decode('utf-8')
624 print(output)
625 self.assertRegex(output, 'ip6gretap remote 2001:473:fece:cafe::5179 local any dev dummy98')
626
627 def test_vti_tunnel(self):
628 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti-tunnel.netdev', 'vti.network',
629 '25-vti-tunnel-local-any.netdev', '25-vti-tunnel-remote-any.netdev')
630 self.start_networkd()
631
632 self.assertTrue(self.link_exits('dummy98'))
633 self.assertTrue(self.link_exits('vtitun99'))
634 self.assertTrue(self.link_exits('vtitun98'))
635 self.assertTrue(self.link_exits('vtitun97'))
636
637 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vtitun99']).rstrip().decode('utf-8')
638 print(output)
639 self.assertRegex(output, 'vti remote 10.65.223.239 local 10.65.223.238 dev dummy98')
640 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vtitun98']).rstrip().decode('utf-8')
641 print(output)
642 self.assertRegex(output, 'vti remote 10.65.223.239 local any dev dummy98')
643 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vtitun97']).rstrip().decode('utf-8')
644 print(output)
645 self.assertRegex(output, 'vti remote any local 10.65.223.238 dev dummy98')
646
647 def test_vti6_tunnel(self):
648 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti6-tunnel.netdev', 'vti6.network',
649 '25-vti6-tunnel-local-any.netdev', '25-vti6-tunnel-remote-any.netdev')
650 self.start_networkd()
651
652 self.assertTrue(self.link_exits('dummy98'))
653 self.assertTrue(self.link_exits('vti6tun99'))
654 self.assertTrue(self.link_exits('vti6tun98'))
655 self.assertTrue(self.link_exits('vti6tun97'))
656
657 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vti6tun99']).rstrip().decode('utf-8')
658 print(output)
659 self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
660 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vti6tun98']).rstrip().decode('utf-8')
661 print(output)
662 self.assertRegex(output, 'vti6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
663 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vti6tun97']).rstrip().decode('utf-8')
664 print(output)
665 self.assertRegex(output, 'vti6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
666
667 def test_ip6tnl_tunnel(self):
668 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6tnl-tunnel.netdev', 'ip6tnl.network',
669 '25-ip6tnl-tunnel-local-any.netdev', '25-ip6tnl-tunnel-remote-any.netdev')
670 self.start_networkd()
671
672 self.assertTrue(self.link_exits('dummy98'))
673 self.assertTrue(self.link_exits('ip6tnl99'))
674 self.assertTrue(self.link_exits('ip6tnl98'))
675 self.assertTrue(self.link_exits('ip6tnl97'))
676
677 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6tnl99']).rstrip().decode('utf-8')
678 print(output)
679 self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local 2a00:ffde:4567:edde::4987 dev dummy98')
680 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6tnl98']).rstrip().decode('utf-8')
681 print(output)
682 self.assertRegex(output, 'ip6tnl ip6ip6 remote 2001:473:fece:cafe::5179 local (?:any|::) dev dummy98')
683 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ip6tnl97']).rstrip().decode('utf-8')
684 print(output)
685 self.assertRegex(output, 'ip6tnl ip6ip6 remote (?:any|::) local 2a00:ffde:4567:edde::4987 dev dummy98')
686
687 def test_sit_tunnel(self):
688 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-sit-tunnel.netdev', 'sit.network',
689 '25-sit-tunnel-local-any.netdev',
690 '25-sit-tunnel-remote-any.netdev')
691 self.start_networkd()
692
693 self.assertTrue(self.link_exits('dummy98'))
694 self.assertTrue(self.link_exits('sittun99'))
695 self.assertTrue(self.link_exits('sittun98'))
696 self.assertTrue(self.link_exits('sittun97'))
697
698 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'sittun99']).rstrip().decode('utf-8')
699 print(output)
700 self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local 10.65.223.238 dev dummy98")
701 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'sittun98']).rstrip().decode('utf-8')
702 print(output)
703 self.assertRegex(output, "sit (?:ip6ip |)remote 10.65.223.239 local any dev dummy98")
704 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'sittun97']).rstrip().decode('utf-8')
705 print(output)
706 self.assertRegex(output, "sit (?:ip6ip |)remote any local 10.65.223.238 dev dummy98")
707
708 def test_isatap_tunnel(self):
709 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-isatap-tunnel.netdev', 'isatap.network')
710 self.start_networkd()
711
712 self.assertTrue(self.link_exits('dummy98'))
713 self.assertTrue(self.link_exits('isataptun99'))
714
715 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'isataptun99']).rstrip().decode('utf-8')
716 print(output)
717 self.assertRegex(output, "isatap ")
718
719 def test_6rd_tunnel(self):
720 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-6rd-tunnel.netdev', '6rd.network')
721 self.start_networkd()
722
723 self.assertTrue(self.link_exits('dummy98'))
724 self.assertTrue(self.link_exits('sittun99'))
725
726 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'sittun99']).rstrip().decode('utf-8')
727 print(output)
728 self.assertRegex(output, '6rd-prefix 2602::/24')
729
730 @expectedFailureIfERSPANModuleIsNotAvailable()
731 def test_erspan_tunnel(self):
732 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'erspan.network',
733 '25-erspan-tunnel.netdev', '25-erspan-tunnel-local-any.netdev')
734 self.start_networkd()
735
736 self.assertTrue(self.link_exits('dummy98'))
737 self.assertTrue(self.link_exits('erspan99'))
738 self.assertTrue(self.link_exits('erspan98'))
739
740 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan99']).rstrip().decode('utf-8')
741 print(output)
742 self.assertRegex(output, 'erspan remote 172.16.1.100 local 172.16.1.200')
743 self.assertRegex(output, '101')
744 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan98']).rstrip().decode('utf-8')
745 print(output)
746 self.assertRegex(output, 'erspan remote 172.16.1.100 local any')
747 self.assertRegex(output, '102')
748
749 def test_tunnel_independent(self):
750 self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
751 self.start_networkd()
752
753 self.assertTrue(self.link_exits('ipiptun99'))
754
755 def test_vxlan(self):
756 self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network', '11-dummy.netdev')
757 self.start_networkd()
758
759 self.assertTrue(self.link_exits('vxlan99'))
760
761 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
762 print(output)
763 self.assertRegex(output, "999")
764 self.assertRegex(output, '5555')
765 self.assertRegex(output, 'l2miss')
766 self.assertRegex(output, 'l3miss')
767 self.assertRegex(output, 'udpcsum')
768 self.assertRegex(output, 'udp6zerocsumtx')
769 self.assertRegex(output, 'udp6zerocsumrx')
770 self.assertRegex(output, 'remcsumtx')
771 self.assertRegex(output, 'remcsumrx')
772 self.assertRegex(output, 'gbp')
773
774 class NetworkdL2TPTests(unittest.TestCase, Utilities):
775
776 links =[
777 'l2tp-ses1',
778 'l2tp-ses2',
779 'l2tp-ses3',
780 'l2tp-ses4',
781 'test1']
782
783 units = [
784 '11-dummy.netdev',
785 '25-l2tp-dummy.network',
786 '25-l2tp-ip.netdev',
787 '25-l2tp-udp.netdev']
788
789 l2tp_tunnel_ids = [ '10' ]
790
791 def setUp(self):
792 self.l2tp_tunnel_remove(self.l2tp_tunnel_ids)
793 self.link_remove(self.links)
794
795 def tearDown(self):
796 self.l2tp_tunnel_remove(self.l2tp_tunnel_ids)
797 self.link_remove(self.links)
798 self.remove_unit_from_networkd_path(self.units)
799
800 @expectedFailureIfModuleIsNotAvailable('l2tp_eth')
801 def test_l2tp_udp(self):
802 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '25-l2tp-dummy.network', '25-l2tp-udp.netdev')
803 self.start_networkd()
804
805 self.assertTrue(self.link_exits('test1'))
806 self.assertTrue(self.link_exits('l2tp-ses1'))
807 self.assertTrue(self.link_exits('l2tp-ses2'))
808
809 output = subprocess.check_output(['ip', 'l2tp', 'show', 'tunnel', 'tunnel_id', '10']).rstrip().decode('utf-8')
810 print(output)
811 self.assertRegex(output, "Tunnel 10, encap UDP")
812 self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
813 self.assertRegex(output, "Peer tunnel 11")
814 self.assertRegex(output, "UDP source / dest ports: 3000/4000")
815 self.assertRegex(output, "UDP checksum: enabled")
816
817 output = subprocess.check_output(['ip', 'l2tp', 'show', 'session', 'tid', '10', 'session_id', '15']).rstrip().decode('utf-8')
818 print(output)
819 self.assertRegex(output, "Session 15 in tunnel 10")
820 self.assertRegex(output, "Peer session 16, tunnel 11")
821 self.assertRegex(output, "interface name: l2tp-ses1")
822
823 output = subprocess.check_output(['ip', 'l2tp', 'show', 'session', 'tid', '10', 'session_id', '17']).rstrip().decode('utf-8')
824 print(output)
825 self.assertRegex(output, "Session 17 in tunnel 10")
826 self.assertRegex(output, "Peer session 18, tunnel 11")
827 self.assertRegex(output, "interface name: l2tp-ses2")
828
829 @expectedFailureIfModuleIsNotAvailable('l2tp_ip')
830 def test_l2tp_ip(self):
831 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '25-l2tp-dummy.network', '25-l2tp-ip.netdev')
832 self.start_networkd()
833
834 self.assertTrue(self.link_exits('test1'))
835 self.assertTrue(self.link_exits('l2tp-ses3'))
836 self.assertTrue(self.link_exits('l2tp-ses4'))
837
838 output = subprocess.check_output(['ip', 'l2tp', 'show', 'tunnel', 'tunnel_id', '10']).rstrip().decode('utf-8')
839 print(output)
840 self.assertRegex(output, "Tunnel 10, encap IP")
841 self.assertRegex(output, "From 192.168.30.100 to 192.168.30.101")
842 self.assertRegex(output, "Peer tunnel 12")
843
844 output = subprocess.check_output(['ip', 'l2tp', 'show', 'session', 'tid', '10', 'session_id', '25']).rstrip().decode('utf-8')
845 print(output)
846 self.assertRegex(output, "Session 25 in tunnel 10")
847 self.assertRegex(output, "Peer session 26, tunnel 12")
848 self.assertRegex(output, "interface name: l2tp-ses3")
849
850 output = subprocess.check_output(['ip', 'l2tp', 'show', 'session', 'tid', '10', 'session_id', '27']).rstrip().decode('utf-8')
851 print(output)
852 self.assertRegex(output, "Session 27 in tunnel 10")
853 self.assertRegex(output, "Peer session 28, tunnel 12")
854 self.assertRegex(output, "interface name: l2tp-ses4")
855
856 class NetworkdNetWorkTests(unittest.TestCase, Utilities):
857 links = [
858 'bond199',
859 'dummy98',
860 'dummy99',
861 'test1']
862
863 units = [
864 '11-dummy.netdev',
865 '12-dummy.netdev',
866 '23-active-slave.network',
867 '23-bond199.network',
868 '23-primary-slave.network',
869 '23-test1-bond199.network',
870 '25-address-link-section.network',
871 '25-address-section-miscellaneous.network',
872 '25-address-section.network',
873 '25-bind-carrier.network',
874 '25-bond-active-backup-slave.netdev',
875 '25-fibrule-invert.network',
876 '25-fibrule-port-range.network',
877 '25-ipv6-address-label-section.network',
878 '25-neighbor-section.network',
879 '25-link-local-addressing-no.network',
880 '25-link-local-addressing-yes.network',
881 '25-link-section-unmanaged.network',
882 '25-route-gateway.network',
883 '25-route-gateway-on-link.network',
884 '25-route-ipv6-src.network',
885 '25-route-reverse-order.network',
886 '25-route-section.network',
887 '25-route-tcp-window-settings.network',
888 '25-route-type.network',
889 '25-sysctl-disable-ipv6.network',
890 '25-sysctl.network',
891 'configure-without-carrier.network',
892 'routing-policy-rule-dummy98.network',
893 'routing-policy-rule-test1.network',
894 'test-static.network']
895
896 def setUp(self):
897 self.link_remove(self.links)
898
899 def tearDown(self):
900 self.link_remove(self.links)
901 self.remove_unit_from_networkd_path(self.units)
902
903 def test_static_address(self):
904 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'test-static.network')
905 self.start_networkd()
906
907 self.assertTrue(self.link_exits('dummy98'))
908
909 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
910 print(output)
911 self.assertRegex(output, '192.168.0.15')
912 self.assertRegex(output, '192.168.0.1')
913 self.assertRegex(output, 'routable')
914
915 def test_configure_without_carrier(self):
916 self.copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
917 self.start_networkd()
918
919 self.assertTrue(self.link_exits('test1'))
920
921 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
922 print(output)
923 self.assertRegex(output, '192.168.0.15')
924 self.assertRegex(output, '192.168.0.1')
925 self.assertRegex(output, 'routable')
926
927 def test_bond_active_slave(self):
928 self.copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
929 self.start_networkd()
930
931 self.assertTrue(self.link_exits('dummy98'))
932 self.assertTrue(self.link_exits('bond199'))
933
934 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
935 print(output)
936 self.assertRegex(output, 'active_slave dummy98')
937
938 def test_bond_primary_slave(self):
939 self.copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-test1-bond199.network', '25-bond-active-backup-slave.netdev', '11-dummy.netdev')
940 self.start_networkd()
941
942 self.assertTrue(self.link_exits('test1'))
943 self.assertTrue(self.link_exits('bond199'))
944
945 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
946 print(output)
947 self.assertRegex(output, 'primary test1')
948
949 def test_routing_policy_rule(self):
950 self.copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev')
951
952 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
953
954 self.start_networkd()
955
956 self.assertTrue(self.link_exits('test1'))
957
958 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
959 print(output)
960 self.assertRegex(output, '111')
961 self.assertRegex(output, 'from 192.168.100.18')
962 self.assertRegex(output, r'tos (?:0x08|throughput)\s')
963 self.assertRegex(output, 'iif test1')
964 self.assertRegex(output, 'oif test1')
965 self.assertRegex(output, 'lookup 7')
966
967 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
968
969 def test_routing_policy_rule_issue_11280(self):
970 self.copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev',
971 'routing-policy-rule-dummy98.network', '12-dummy.netdev')
972
973 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
974 subprocess.call(['ip', 'rule', 'del', 'table', '8'])
975
976 for trial in range(3):
977 # Remove state files only first time
978 self.start_networkd(trial == 0)
979
980 self.assertTrue(self.link_exits('test1'))
981 self.assertTrue(self.link_exits('dummy98'))
982
983 output = subprocess.check_output(['ip', 'rule', 'list', 'table', '7']).rstrip().decode('utf-8')
984 print(output)
985 self.assertRegex(output, '111: from 192.168.100.18 tos (?:0x08|throughput) iif test1 oif test1 lookup 7')
986
987 output = subprocess.check_output(['ip', 'rule', 'list', 'table', '8']).rstrip().decode('utf-8')
988 print(output)
989 self.assertRegex(output, '112: from 192.168.101.18 tos (?:0x08|throughput) iif dummy98 oif dummy98 lookup 8')
990
991 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
992 subprocess.call(['ip', 'rule', 'del', 'table', '8'])
993
994 @expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
995 def test_routing_policy_rule_port_range(self):
996 self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
997
998 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
999
1000 self.start_networkd()
1001
1002 self.assertTrue(self.link_exits('test1'))
1003
1004 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
1005 print(output)
1006 self.assertRegex(output, '111')
1007 self.assertRegex(output, 'from 192.168.100.18')
1008 self.assertRegex(output, '1123-1150')
1009 self.assertRegex(output, '3224-3290')
1010 self.assertRegex(output, 'tcp')
1011 self.assertRegex(output, 'lookup 7')
1012
1013 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
1014
1015 @expectedFailureIfRoutingPolicyIPProtoIsNotAvailable()
1016 def test_routing_policy_rule_invert(self):
1017 self.copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
1018
1019 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
1020
1021 self.start_networkd()
1022
1023 self.assertTrue(self.link_exits('test1'))
1024
1025 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
1026 print(output)
1027 self.assertRegex(output, '111')
1028 self.assertRegex(output, 'not.*?from.*?192.168.100.18')
1029 self.assertRegex(output, 'tcp')
1030 self.assertRegex(output, 'lookup 7')
1031
1032 subprocess.call(['ip', 'rule', 'del', 'table', '7'])
1033
1034 def test_address_peer(self):
1035 self.copy_unit_to_networkd_unit_path('25-address-section.network', '12-dummy.netdev')
1036 self.start_networkd()
1037
1038 self.assertTrue(self.link_exits('dummy98'))
1039
1040 # This also tests address pool
1041
1042 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'dummy98', 'label', '32']).rstrip().decode('utf-8')
1043 print(output)
1044 self.assertRegex(output, 'inet 10.2.3.4 peer 10.2.3.5/16 scope global 32')
1045
1046 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'dummy98', 'label', '33']).rstrip().decode('utf-8')
1047 print(output)
1048 self.assertRegex(output, 'inet 10.6.7.8/16 brd 10.6.255.255 scope global 33')
1049
1050 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'dummy98', 'label', '34']).rstrip().decode('utf-8')
1051 print(output)
1052 self.assertRegex(output, 'inet 192.168.[0-9]*.1/24 brd 192.168.[0-9]*.255 scope global 34')
1053
1054 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'dummy98', 'label', '35']).rstrip().decode('utf-8')
1055 print(output)
1056 self.assertRegex(output, 'inet 172.[0-9]*.0.1/16 brd 172.[0-9]*.255.255 scope global 35')
1057
1058 output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
1059 print(output)
1060 self.assertRegex(output, 'inet6 2001:db8::20 peer 2001:db8::10/128 scope global')
1061 self.assertRegex(output, 'inet6 fd[0-9a-f:]*1/64 scope global')
1062
1063 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1064 print(output)
1065 self.assertRegex(output, 'State: routable \(configured\)')
1066
1067 def test_address_preferred_lifetime_zero_ipv6(self):
1068 self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
1069 self.start_networkd()
1070
1071 self.assertTrue(self.link_exits('dummy98'))
1072
1073 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
1074 print(output)
1075 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
1076 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
1077 # also tests invalid [Address] section
1078 self.assertNotRegex(output, '10.10.0.1/16')
1079 self.assertNotRegex(output, '10.10.0.2/16')
1080
1081 def test_ip_route(self):
1082 self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
1083 self.start_networkd()
1084
1085 self.assertTrue(self.link_exits('dummy98'))
1086
1087 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
1088 print(output)
1089 self.assertRegex(output, '192.168.0.1')
1090 self.assertRegex(output, 'static')
1091 self.assertRegex(output, '192.168.0.0/24')
1092
1093 def test_ip_route_reverse(self):
1094 self.copy_unit_to_networkd_unit_path('25-route-reverse-order.network', '12-dummy.netdev')
1095 self.start_networkd()
1096
1097 self.assertTrue(self.link_exits('dummy98'))
1098
1099 output = subprocess.check_output(['ip', '-6', 'route', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
1100 print(output)
1101 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff')
1102 self.assertRegex(output, '2001:1234:5:8f63::1')
1103
1104 def test_ip_route_blackhole_unreachable_prohibit(self):
1105 self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
1106 self.start_networkd()
1107
1108 self.assertTrue(self.link_exits('dummy98'))
1109
1110 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
1111 print(output)
1112 self.assertRegex(output, 'blackhole')
1113 self.assertRegex(output, 'unreachable')
1114 self.assertRegex(output, 'prohibit')
1115
1116 subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
1117 subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
1118 subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
1119
1120 def test_ip_route_tcp_window(self):
1121 self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
1122 self.start_networkd()
1123
1124 self.assertTrue(self.link_exits('test1'))
1125
1126 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
1127 print(output)
1128 self.assertRegex(output, 'initcwnd 20')
1129 self.assertRegex(output, 'initrwnd 30')
1130
1131 def test_ip_route_gateway(self):
1132 self.copy_unit_to_networkd_unit_path('25-route-gateway.network', '12-dummy.netdev')
1133 self.start_networkd()
1134
1135 self.assertTrue(self.link_exits('dummy98'))
1136
1137 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
1138 print(output)
1139 self.assertRegex(output, 'default')
1140 self.assertRegex(output, 'via')
1141 self.assertRegex(output, '149.10.124.64')
1142 self.assertRegex(output, 'proto')
1143 self.assertRegex(output, 'static')
1144
1145 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
1146 print(output)
1147 self.assertRegex(output, '149.10.124.48/28')
1148 self.assertRegex(output, 'proto')
1149 self.assertRegex(output, 'kernel')
1150 self.assertRegex(output, 'scope')
1151 self.assertRegex(output, 'link')
1152
1153 def test_ip_route_gateway_on_link(self):
1154 self.copy_unit_to_networkd_unit_path('25-route-gateway-on-link.network', '12-dummy.netdev')
1155 self.start_networkd()
1156
1157 self.assertTrue(self.link_exits('dummy98'))
1158
1159 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
1160 print(output)
1161 self.assertRegex(output, 'default')
1162 self.assertRegex(output, 'via')
1163 self.assertRegex(output, '149.10.125.65')
1164 self.assertRegex(output, 'proto')
1165 self.assertRegex(output, 'static')
1166 self.assertRegex(output, 'onlink')
1167
1168 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
1169 print(output)
1170 self.assertRegex(output, '149.10.124.48/28')
1171 self.assertRegex(output, 'proto')
1172 self.assertRegex(output, 'kernel')
1173 self.assertRegex(output, 'scope')
1174 self.assertRegex(output, 'link')
1175
1176 def test_ip_route_ipv6_src_route(self):
1177 # a dummy device does not make the addresses go through tentative state, so we
1178 # reuse a bond from an earlier test, which does make the addresses go through
1179 # tentative state, and do our test on that
1180 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')
1181 self.start_networkd()
1182
1183 self.assertTrue(self.link_exits('dummy98'))
1184 self.assertTrue(self.link_exits('bond199'))
1185
1186 output = subprocess.check_output(['ip', '-6', 'route', 'list', 'dev', 'bond199']).rstrip().decode('utf-8')
1187 print(output)
1188 self.assertRegex(output, 'abcd::/16')
1189 self.assertRegex(output, 'src')
1190 self.assertRegex(output, '2001:1234:56:8f63::2')
1191
1192 def test_ip_link_mac_address(self):
1193 self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
1194 self.start_networkd()
1195
1196 self.assertTrue(self.link_exits('dummy98'))
1197
1198 output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
1199 print(output)
1200 self.assertRegex(output, '00:01:02:aa:bb:cc')
1201
1202 def test_ip_link_unmanaged(self):
1203 self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
1204 self.start_networkd()
1205
1206 self.assertTrue(self.link_exits('dummy98'))
1207
1208 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1209 print(output)
1210 self.assertRegex(output, 'unmanaged')
1211
1212 def test_ipv6_address_label(self):
1213 self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
1214 self.start_networkd()
1215
1216 self.assertTrue(self.link_exits('dummy98'))
1217
1218 output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
1219 print(output)
1220 self.assertRegex(output, '2004:da8:1::/64')
1221
1222 def test_ipv6_neighbor(self):
1223 self.copy_unit_to_networkd_unit_path('25-neighbor-section.network', '12-dummy.netdev')
1224 self.start_networkd()
1225
1226 self.assertTrue(self.link_exits('dummy98'))
1227
1228 output = subprocess.check_output(['ip', 'neigh', 'list']).rstrip().decode('utf-8')
1229 print(output)
1230 self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
1231 self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
1232
1233 def test_link_local_addressing(self):
1234 self.copy_unit_to_networkd_unit_path('25-link-local-addressing-yes.network', '11-dummy.netdev',
1235 '25-link-local-addressing-no.network', '12-dummy.netdev')
1236 self.start_networkd()
1237
1238 self.assertTrue(self.link_exits('test1'))
1239 self.assertTrue(self.link_exits('dummy98'))
1240
1241 time.sleep(10)
1242
1243 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'test1']).rstrip().decode('utf-8')
1244 print(output)
1245 self.assertRegex(output, 'inet .* scope link')
1246 self.assertRegex(output, 'inet6 .* scope link')
1247
1248 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
1249 print(output)
1250 self.assertNotRegex(output, 'inet6* .* scope link')
1251
1252 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1253 print(output)
1254 self.assertRegex(output, 'State: degraded \(configured\)')
1255
1256 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1257 print(output)
1258 self.assertRegex(output, 'State: carrier \(configured\)')
1259
1260 '''
1261 Documentation/networking/ip-sysctl.txt
1262
1263 addr_gen_mode - INTEGER
1264 Defines how link-local and autoconf addresses are generated.
1265
1266 0: generate address based on EUI64 (default)
1267 1: do no generate a link-local address, use EUI64 for addresses generated
1268 from autoconf
1269 2: generate stable privacy addresses, using the secret from
1270 stable_secret (RFC7217)
1271 3: generate stable privacy addresses, using a random secret if unset
1272 '''
1273
1274 test1_addr_gen_mode = ''
1275 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')):
1276 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'stable_secret')) as f:
1277 try:
1278 f.readline()
1279 except IOError:
1280 # if stable_secret is unset, then EIO is returned
1281 test1_addr_gen_mode = '0'
1282 else:
1283 test1_addr_gen_mode = '2'
1284 else:
1285 test1_addr_gen_mode = '0'
1286
1287 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'test1'), 'addr_gen_mode')):
1288 self.assertEqual(self.read_ipv6_sysctl_attr('test1', 'addr_gen_mode'), '0')
1289
1290 if os.path.exists(os.path.join(os.path.join(network_sysctl_ipv6_path, 'dummy98'), 'addr_gen_mode')):
1291 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'addr_gen_mode'), '1')
1292
1293 def test_sysctl(self):
1294 self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
1295 self.start_networkd()
1296
1297 self.assertTrue(self.link_exits('dummy98'))
1298
1299 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
1300 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
1301 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
1302 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
1303 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
1304 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
1305 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
1306
1307 def test_sysctl_disable_ipv6(self):
1308 self.copy_unit_to_networkd_unit_path('25-sysctl-disable-ipv6.network', '12-dummy.netdev')
1309
1310 print('## Disable ipv6')
1311 self.assertEqual(subprocess.call(['sysctl', 'net.ipv6.conf.all.disable_ipv6=1']), 0)
1312 self.assertEqual(subprocess.call(['sysctl', 'net.ipv6.conf.default.disable_ipv6=1']), 0)
1313
1314 self.start_networkd()
1315
1316 self.assertTrue(self.link_exits('dummy98'))
1317
1318 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
1319 print(output)
1320 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
1321 output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
1322 print(output)
1323 self.assertEqual(output, '')
1324 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1325 self.assertRegex(output, 'State: routable \(configured\)')
1326
1327 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1328
1329 print('## Enable ipv6')
1330 self.assertEqual(subprocess.call(['sysctl', 'net.ipv6.conf.all.disable_ipv6=0']), 0)
1331 self.assertEqual(subprocess.call(['sysctl', 'net.ipv6.conf.default.disable_ipv6=0']), 0)
1332
1333 self.start_networkd()
1334
1335 self.assertTrue(self.link_exits('dummy98'))
1336
1337 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
1338 print(output)
1339 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
1340 output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
1341 print(output)
1342 self.assertRegex(output, 'inet6 .* scope link')
1343 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1344 self.assertRegex(output, 'State: routable \(configured\)')
1345
1346 def test_bind_carrier(self):
1347 self.copy_unit_to_networkd_unit_path('25-bind-carrier.network', '11-dummy.netdev')
1348 self.start_networkd()
1349
1350 self.assertTrue(self.link_exits('test1'))
1351
1352 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy98', 'type', 'dummy']), 0)
1353 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1354 time.sleep(2)
1355 output = subprocess.check_output(['ip', 'address', 'show', 'test1']).rstrip().decode('utf-8')
1356 print(output)
1357 self.assertRegex(output, 'UP,LOWER_UP')
1358 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
1359 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1360 self.assertRegex(output, 'State: routable \(configured\)')
1361
1362 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy99', 'type', 'dummy']), 0)
1363 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy99', 'up']), 0)
1364 time.sleep(2)
1365 output = subprocess.check_output(['ip', 'address', 'show', 'test1']).rstrip().decode('utf-8')
1366 print(output)
1367 self.assertRegex(output, 'UP,LOWER_UP')
1368 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
1369 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1370 self.assertRegex(output, 'State: routable \(configured\)')
1371
1372 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1373 time.sleep(2)
1374 output = subprocess.check_output(['ip', 'address', 'show', 'test1']).rstrip().decode('utf-8')
1375 print(output)
1376 self.assertRegex(output, 'UP,LOWER_UP')
1377 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
1378 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1379 self.assertRegex(output, 'State: routable \(configured\)')
1380
1381 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy99']), 0)
1382 time.sleep(2)
1383 output = subprocess.check_output(['ip', 'address', 'show', 'test1']).rstrip().decode('utf-8')
1384 print(output)
1385 self.assertNotRegex(output, 'UP,LOWER_UP')
1386 self.assertRegex(output, 'DOWN')
1387 self.assertNotRegex(output, '192.168.10')
1388 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1389 self.assertRegex(output, 'State: off \(configured\)')
1390
1391 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy98', 'type', 'dummy']), 0)
1392 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1393 time.sleep(2)
1394 output = subprocess.check_output(['ip', 'address', 'show', 'test1']).rstrip().decode('utf-8')
1395 print(output)
1396 self.assertRegex(output, 'UP,LOWER_UP')
1397 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
1398 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1399 self.assertRegex(output, 'State: routable \(configured\)')
1400
1401 class NetworkdNetWorkBondTests(unittest.TestCase, Utilities):
1402 links = [
1403 'bond99',
1404 'dummy98',
1405 'test1']
1406
1407 units = [
1408 '11-dummy.netdev',
1409 '12-dummy.netdev',
1410 '25-bond.netdev',
1411 'bond99.network',
1412 'bond-slave.network']
1413
1414 def setUp(self):
1415 self.link_remove(self.links)
1416
1417 def tearDown(self):
1418 self.link_remove(self.links)
1419 self.remove_unit_from_networkd_path(self.units)
1420
1421 def test_bond_operstate(self):
1422 self.copy_unit_to_networkd_unit_path('25-bond.netdev', '11-dummy.netdev', '12-dummy.netdev',
1423 'bond99.network','bond-slave.network')
1424 self.start_networkd()
1425
1426 self.assertTrue(self.link_exits('bond99'))
1427 self.assertTrue(self.link_exits('dummy98'))
1428 self.assertTrue(self.link_exits('test1'))
1429
1430 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
1431 print(output)
1432 self.assertRegex(output, 'SLAVE,UP,LOWER_UP')
1433
1434 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
1435 print(output)
1436 self.assertRegex(output, 'SLAVE,UP,LOWER_UP')
1437
1438 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond99']).rstrip().decode('utf-8')
1439 print(output)
1440 self.assertRegex(output, 'MASTER,UP,LOWER_UP')
1441
1442 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1443 print(output)
1444 self.assertRegex(output, 'State: enslaved \(configured\)')
1445
1446 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1447 print(output)
1448 self.assertRegex(output, 'State: enslaved \(configured\)')
1449
1450 output = subprocess.check_output(['networkctl', 'status', 'bond99']).rstrip().decode('utf-8')
1451 print(output)
1452 self.assertRegex(output, 'State: routable \(configured\)')
1453
1454 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'down']), 0)
1455 time.sleep(2)
1456
1457 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1458 print(output)
1459 self.assertRegex(output, 'State: off \(configured\)')
1460
1461 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1462 print(output)
1463 self.assertRegex(output, 'State: enslaved \(configured\)')
1464
1465 output = subprocess.check_output(['networkctl', 'status', 'bond99']).rstrip().decode('utf-8')
1466 print(output)
1467 self.assertRegex(output, 'State: degraded-carrier \(configured\)')
1468
1469 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1470 time.sleep(2)
1471
1472 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1473 print(output)
1474 self.assertRegex(output, 'State: enslaved \(configured\)')
1475
1476 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1477 print(output)
1478 self.assertRegex(output, 'State: enslaved \(configured\)')
1479
1480 output = subprocess.check_output(['networkctl', 'status', 'bond99']).rstrip().decode('utf-8')
1481 print(output)
1482 self.assertRegex(output, 'State: routable \(configured\)')
1483
1484 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'down']), 0)
1485 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'test1', 'down']), 0)
1486 time.sleep(5)
1487
1488 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1489 print(output)
1490 self.assertRegex(output, 'State: off \(configured\)')
1491
1492 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1493 print(output)
1494 self.assertRegex(output, 'State: off \(configured\)')
1495
1496 output = subprocess.check_output(['networkctl', 'status', 'bond99']).rstrip().decode('utf-8')
1497 print(output)
1498 self.assertRegex(output, 'State: no-carrier \(configured\)')
1499
1500 class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
1501 links = [
1502 'bridge99',
1503 'dummy98',
1504 'test1']
1505
1506 units = [
1507 '11-dummy.netdev',
1508 '12-dummy.netdev',
1509 '26-bridge.netdev',
1510 '26-bridge-slave-interface-1.network',
1511 '26-bridge-slave-interface-2.network',
1512 'bridge99-ignore-carrier-loss.network',
1513 'bridge99.network']
1514
1515 def setUp(self):
1516 self.link_remove(self.links)
1517
1518 def tearDown(self):
1519 self.link_remove(self.links)
1520 self.remove_unit_from_networkd_path(self.units)
1521
1522 def test_bridge_property(self):
1523 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
1524 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
1525 'bridge99.network')
1526 self.start_networkd()
1527
1528 self.assertTrue(self.link_exits('dummy98'))
1529 self.assertTrue(self.link_exits('test1'))
1530 self.assertTrue(self.link_exits('bridge99'))
1531
1532 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
1533 print(output)
1534 self.assertRegex(output, 'master')
1535 self.assertRegex(output, 'bridge')
1536
1537 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
1538 print(output)
1539 self.assertRegex(output, 'master')
1540 self.assertRegex(output, 'bridge')
1541
1542 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
1543 print(output)
1544 self.assertRegex(output, '192.168.0.15/24')
1545
1546 output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
1547 print(output)
1548 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
1549 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
1550 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
1551 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood'), '0')
1552 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
1553 if (os.path.exists('/sys/devices/virtual/net/bridge99/lower_dummy98/brport/neigh_suppress')):
1554 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress'), '1')
1555 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'learning'), '0')
1556
1557 # CONFIG_BRIDGE_IGMP_SNOOPING=y
1558 if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
1559 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
1560
1561 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
1562 self.assertRegex(output, 'State: enslaved \(configured\)')
1563
1564 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1565 self.assertRegex(output, 'State: enslaved \(configured\)')
1566
1567 output = subprocess.check_output(['networkctl', 'status', 'bridge99']).rstrip().decode('utf-8')
1568 self.assertRegex(output, 'State: routable \(configured\)')
1569
1570 self.assertEqual(subprocess.call(['ip', 'address', 'add', '192.168.0.16/24', 'dev', 'bridge99']), 0)
1571 time.sleep(1)
1572
1573 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
1574 print(output)
1575 self.assertRegex(output, '192.168.0.16/24')
1576
1577 output = subprocess.check_output(['networkctl', 'status', 'bridge99']).rstrip().decode('utf-8')
1578 self.assertRegex(output, 'State: routable \(configured\)')
1579
1580 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'test1']), 0)
1581 time.sleep(3)
1582
1583 output = subprocess.check_output(['networkctl', 'status', 'bridge99']).rstrip().decode('utf-8')
1584 self.assertRegex(output, 'State: degraded-carrier \(configured\)')
1585
1586 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1587 time.sleep(3)
1588
1589 output = subprocess.check_output(['networkctl', 'status', 'bridge99']).rstrip().decode('utf-8')
1590 self.assertRegex(output, 'State: no-carrier \(configured\)')
1591
1592 output = subprocess.check_output(['ip', 'address', 'show', 'bridge99']).rstrip().decode('utf-8')
1593 print(output)
1594 self.assertRegex(output, 'NO-CARRIER')
1595 self.assertNotRegex(output, '192.168.0.15/24')
1596 self.assertNotRegex(output, '192.168.0.16/24')
1597
1598 def test_bridge_ignore_carrier_loss(self):
1599 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
1600 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
1601 'bridge99-ignore-carrier-loss.network')
1602
1603 subprocess.call(['ip', 'rule', 'del', 'table', '100'])
1604
1605 self.start_networkd()
1606
1607 self.assertTrue(self.link_exits('dummy98'))
1608 self.assertTrue(self.link_exits('test1'))
1609 self.assertTrue(self.link_exits('bridge99'))
1610
1611 self.assertEqual(subprocess.call(['ip', 'address', 'add', '192.168.0.16/24', 'dev', 'bridge99']), 0)
1612 time.sleep(1)
1613
1614 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'test1']), 0)
1615 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1616 time.sleep(3)
1617
1618 output = subprocess.check_output(['ip', 'address', 'show', 'bridge99']).rstrip().decode('utf-8')
1619 print(output)
1620 self.assertRegex(output, 'NO-CARRIER')
1621 self.assertRegex(output, 'inet 192.168.0.15/24 brd 192.168.0.255 scope global bridge99')
1622 self.assertRegex(output, 'inet 192.168.0.16/24 scope global secondary bridge99')
1623
1624 subprocess.call(['ip', 'rule', 'del', 'table', '100'])
1625
1626 def test_bridge_ignore_carrier_loss_frequent_loss_and_gain(self):
1627 self.copy_unit_to_networkd_unit_path('26-bridge.netdev', '26-bridge-slave-interface-1.network',
1628 'bridge99-ignore-carrier-loss.network')
1629
1630 subprocess.call(['ip', 'rule', 'del', 'table', '100'])
1631
1632 self.start_networkd()
1633
1634 self.assertTrue(self.link_exits('bridge99'))
1635
1636 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy98', 'type', 'dummy']), 0)
1637 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1638 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1639
1640 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy98', 'type', 'dummy']), 0)
1641 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1642 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1643
1644 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy98', 'type', 'dummy']), 0)
1645 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1646 self.assertEqual(subprocess.call(['ip', 'link', 'del', 'dummy98']), 0)
1647
1648 self.assertEqual(subprocess.call(['ip', 'link', 'add', 'dummy98', 'type', 'dummy']), 0)
1649 self.assertEqual(subprocess.call(['ip', 'link', 'set', 'dummy98', 'up']), 0)
1650
1651 time.sleep(3)
1652
1653 output = subprocess.check_output(['ip', 'address', 'show', 'bridge99']).rstrip().decode('utf-8')
1654 print(output)
1655 self.assertRegex(output, 'inet 192.168.0.15/24 brd 192.168.0.255 scope global bridge99')
1656
1657 output = subprocess.check_output(['networkctl', 'status', 'bridge99']).rstrip().decode('utf-8')
1658 self.assertRegex(output, 'State: routable \(configured\)')
1659
1660 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1661 self.assertRegex(output, 'State: enslaved \(configured\)')
1662
1663 output = subprocess.check_output(['ip', 'rule', 'list', 'table', '100']).rstrip().decode('utf-8')
1664 print(output)
1665 self.assertEqual(output, '0: from all to 8.8.8.8 lookup 100')
1666
1667 subprocess.call(['ip', 'rule', 'del', 'table', '100'])
1668
1669 class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
1670 links = ['veth99']
1671
1672 units = [
1673 '23-emit-lldp.network',
1674 '24-lldp.network',
1675 '25-veth.netdev']
1676
1677 def setUp(self):
1678 self.link_remove(self.links)
1679
1680 def tearDown(self):
1681 self.link_remove(self.links)
1682 self.remove_unit_from_networkd_path(self.units)
1683
1684 def test_lldp(self):
1685 self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
1686 self.start_networkd()
1687
1688 self.assertTrue(self.link_exits('veth99'))
1689
1690 output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
1691 print(output)
1692 self.assertRegex(output, 'veth-peer')
1693 self.assertRegex(output, 'veth99')
1694
1695 class NetworkdNetworkRATests(unittest.TestCase, Utilities):
1696 links = ['veth99']
1697
1698 units = [
1699 '25-veth.netdev',
1700 'ipv6-prefix.network',
1701 'ipv6-prefix-veth.network']
1702
1703 def setUp(self):
1704 self.link_remove(self.links)
1705
1706 def tearDown(self):
1707 self.link_remove(self.links)
1708 self.remove_unit_from_networkd_path(self.units)
1709
1710 def test_ipv6_prefix_delegation(self):
1711 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
1712 self.start_networkd()
1713
1714 self.assertTrue(self.link_exits('veth99'))
1715
1716 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1717 print(output)
1718 self.assertRegex(output, '2002:da8:1:0')
1719
1720 class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
1721 links = [
1722 'dummy98',
1723 'veth99']
1724
1725 units = [
1726 '12-dummy.netdev',
1727 '24-search-domain.network',
1728 '25-veth.netdev',
1729 'dhcp-client.network',
1730 'dhcp-client-timezone-router.network',
1731 'dhcp-server.network',
1732 'dhcp-server-timezone-router.network']
1733
1734 def setUp(self):
1735 self.link_remove(self.links)
1736
1737 def tearDown(self):
1738 self.link_remove(self.links)
1739 self.remove_unit_from_networkd_path(self.units)
1740
1741 def test_dhcp_server(self):
1742 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
1743 self.start_networkd()
1744
1745 self.assertTrue(self.link_exits('veth99'))
1746
1747 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1748 print(output)
1749 self.assertRegex(output, '192.168.5.*')
1750 self.assertRegex(output, 'Gateway: 192.168.5.1')
1751 self.assertRegex(output, 'DNS: 192.168.5.1')
1752 self.assertRegex(output, 'NTP: 192.168.5.1')
1753
1754 def test_domain(self):
1755 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network')
1756 self.start_networkd()
1757
1758 self.assertTrue(self.link_exits('dummy98'))
1759
1760 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
1761 print(output)
1762 self.assertRegex(output, 'Address: 192.168.42.100')
1763 self.assertRegex(output, 'DNS: 192.168.42.1')
1764 self.assertRegex(output, 'Search Domains: one')
1765
1766 def test_emit_router_timezone(self):
1767 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
1768 self.start_networkd()
1769
1770 self.assertTrue(self.link_exits('veth99'))
1771
1772 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1773 print(output)
1774 self.assertRegex(output, 'Gateway: 192.168.5.*')
1775 self.assertRegex(output, '192.168.5.*')
1776 self.assertRegex(output, 'Europe/Berlin')
1777
1778 class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
1779 links = [
1780 'dummy98',
1781 'veth99',
1782 'vrf99']
1783
1784 units = [
1785 '25-veth.netdev',
1786 '25-vrf.netdev',
1787 '25-vrf.network',
1788 'dhcp-client-anonymize.network',
1789 'dhcp-client-critical-connection.network',
1790 'dhcp-client-gateway-onlink-implicit.network',
1791 'dhcp-client-ipv4-dhcp-settings.network',
1792 'dhcp-client-ipv4-only-ipv6-disabled.network',
1793 'dhcp-client-ipv4-only.network',
1794 'dhcp-client-ipv6-only.network',
1795 'dhcp-client-ipv6-rapid-commit.network',
1796 'dhcp-client-listen-port.network',
1797 'dhcp-client-route-metric.network',
1798 'dhcp-client-route-table.network',
1799 'dhcp-client-vrf.network',
1800 'dhcp-client.network',
1801 'dhcp-server-veth-peer.network',
1802 'dhcp-v4-server-veth-peer.network',
1803 'static.network']
1804
1805 def setUp(self):
1806 self.link_remove(self.links)
1807 self.stop_dnsmasq(dnsmasq_pid_file)
1808
1809 def tearDown(self):
1810 self.link_remove(self.links)
1811 self.remove_unit_from_networkd_path(self.units)
1812 self.stop_dnsmasq(dnsmasq_pid_file)
1813 self.remove_lease_file()
1814 self.remove_log_file()
1815
1816 def test_dhcp_client_ipv6_only(self):
1817 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
1818 self.start_networkd()
1819
1820 self.assertTrue(self.link_exits('veth99'))
1821
1822 self.start_dnsmasq()
1823
1824 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1825 print(output)
1826 self.assertRegex(output, '2600::')
1827 self.assertNotRegex(output, '192.168.5')
1828
1829 def test_dhcp_client_ipv4_only(self):
1830 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-only-ipv6-disabled.network')
1831 self.start_networkd()
1832
1833 self.assertTrue(self.link_exits('veth99'))
1834
1835 self.start_dnsmasq()
1836
1837 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1838 print(output)
1839 self.assertNotRegex(output, '2600::')
1840 self.assertRegex(output, '192.168.5')
1841
1842 def test_dhcp_client_ipv4_ipv6(self):
1843 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
1844 'dhcp-client-ipv4-only.network')
1845 self.start_networkd()
1846
1847 self.assertTrue(self.link_exits('veth99'))
1848
1849 self.start_dnsmasq()
1850
1851 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1852 print(output)
1853 self.assertRegex(output, '2600::')
1854 self.assertRegex(output, '192.168.5')
1855
1856 def test_dhcp_client_settings(self):
1857 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
1858 self.start_networkd()
1859
1860 self.assertTrue(self.link_exits('veth99'))
1861
1862 self.start_dnsmasq()
1863
1864 print('## ip address show dev veth99')
1865 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1866 print(output)
1867 self.assertRegex(output, '12:34:56:78:9a:bc')
1868 self.assertRegex(output, '192.168.5')
1869 self.assertRegex(output, '1492')
1870
1871 # issue #8726
1872 print('## ip route show table main dev veth99')
1873 output = subprocess.check_output(['ip', 'route', 'show', 'table', 'main', 'dev', 'veth99']).rstrip().decode('utf-8')
1874 print(output)
1875 self.assertNotRegex(output, 'proto dhcp')
1876
1877 print('## ip route show table 211 dev veth99')
1878 output = subprocess.check_output(['ip', 'route', 'show', 'table', '211', 'dev', 'veth99']).rstrip().decode('utf-8')
1879 print(output)
1880 self.assertRegex(output, 'default via 192.168.5.1 proto dhcp')
1881 self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 proto dhcp')
1882 self.assertRegex(output, '192.168.5.1 proto dhcp scope link')
1883
1884 print('## dnsmasq log')
1885 self.assertTrue(self.search_words_in_dnsmasq_log('vendor class: SusantVendorTest', True))
1886 self.assertTrue(self.search_words_in_dnsmasq_log('DHCPDISCOVER(veth-peer) 12:34:56:78:9a:bc'))
1887 self.assertTrue(self.search_words_in_dnsmasq_log('client provides name: test-hostname'))
1888 self.assertTrue(self.search_words_in_dnsmasq_log('26:mtu'))
1889
1890 def test_dhcp6_client_settings_rapidcommit_true(self):
1891 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
1892 self.start_networkd()
1893
1894 self.assertTrue(self.link_exits('veth99'))
1895
1896 self.start_dnsmasq()
1897
1898 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1899 print(output)
1900 self.assertRegex(output, '12:34:56:78:9a:bc')
1901 self.assertTrue(self.search_words_in_dnsmasq_log('14:rapid-commit', True))
1902
1903 def test_dhcp6_client_settings_rapidcommit_false(self):
1904 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
1905 self.start_networkd()
1906
1907 self.assertTrue(self.link_exits('veth99'))
1908
1909 self.start_dnsmasq()
1910
1911 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1912 print(output)
1913 self.assertRegex(output, '12:34:56:78:9a:bc')
1914 self.assertFalse(self.search_words_in_dnsmasq_log('14:rapid-commit', True))
1915
1916 def test_dhcp_client_settings_anonymize(self):
1917 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
1918 self.start_networkd()
1919
1920 self.assertTrue(self.link_exits('veth99'))
1921
1922 self.start_dnsmasq()
1923
1924 self.assertFalse(self.search_words_in_dnsmasq_log('VendorClassIdentifier=SusantVendorTest', True))
1925 self.assertFalse(self.search_words_in_dnsmasq_log('test-hostname'))
1926 self.assertFalse(self.search_words_in_dnsmasq_log('26:mtu'))
1927
1928 def test_dhcp_client_listen_port(self):
1929 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
1930 self.start_networkd()
1931
1932 self.assertTrue(self.link_exits('veth99'))
1933
1934 self.start_dnsmasq('--dhcp-alternate-port=67,5555')
1935
1936 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1937 print(output)
1938 self.assertRegex(output, '192.168.5.* dynamic')
1939
1940 def test_dhcp_route_table_id(self):
1941 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
1942 self.start_networkd()
1943
1944 self.assertTrue(self.link_exits('veth99'))
1945
1946 self.start_dnsmasq()
1947
1948 output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
1949 print(output)
1950 self.assertRegex(output, 'veth99 proto dhcp')
1951 self.assertRegex(output, '192.168.5.1')
1952
1953 def test_dhcp_route_metric(self):
1954 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
1955 self.start_networkd()
1956
1957 self.assertTrue(self.link_exits('veth99'))
1958
1959 self.start_dnsmasq()
1960
1961 output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1962 print(output)
1963 self.assertRegex(output, 'metric 24')
1964
1965 def test_dhcp_route_criticalconnection_true(self):
1966 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
1967 self.start_networkd()
1968
1969 self.assertTrue(self.link_exits('veth99'))
1970
1971 self.start_dnsmasq()
1972
1973 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1974 print(output)
1975 self.assertRegex(output, '192.168.5.*')
1976
1977 # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
1978 self.stop_dnsmasq(dnsmasq_pid_file)
1979
1980 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
1981 time.sleep(125)
1982
1983 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1984 print(output)
1985 self.assertRegex(output, '192.168.5.*')
1986
1987 def test_dhcp_client_reuse_address_as_static(self):
1988 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
1989 self.start_networkd()
1990
1991 self.assertTrue(self.link_exits('veth99'))
1992
1993 self.start_dnsmasq()
1994
1995 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
1996 print(output)
1997 self.assertRegex(output, '192.168.5')
1998 self.assertRegex(output, '2600::')
1999
2000 ipv4_address = re.search('192\.168\.5\.[0-9]*/24', output)
2001 ipv6_address = re.search('2600::[0-9a-f:]*/128', output)
2002 static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address.group(), 'Address=' + ipv6_address.group()])
2003 print(static_network)
2004
2005 self.remove_unit_from_networkd_path(['dhcp-client.network'])
2006
2007 with open(os.path.join(network_unit_file_path, 'static.network'), mode='w') as f:
2008 f.write(static_network)
2009
2010 self.start_networkd()
2011
2012 self.assertTrue(self.link_exits('veth99'))
2013
2014 output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
2015 print(output)
2016 self.assertRegex(output, '192.168.5')
2017 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
2018
2019 output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
2020 print(output)
2021 self.assertRegex(output, '2600::')
2022 self.assertRegex(output, 'valid_lft forever preferred_lft forever')
2023
2024 @expectedFailureIfModuleIsNotAvailable('vrf')
2025 def test_dhcp_client_vrf(self):
2026 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-vrf.network',
2027 '25-vrf.netdev', '25-vrf.network')
2028 self.start_networkd()
2029
2030 self.assertTrue(self.link_exits('veth99'))
2031 self.assertTrue(self.link_exits('vrf99'))
2032
2033 self.start_dnsmasq()
2034
2035 print('## ip -d link show dev vrf99')
2036 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dev', 'vrf99']).rstrip().decode('utf-8')
2037 print(output)
2038 self.assertRegex(output, 'vrf table 42')
2039
2040 print('## ip address show vrf vrf99')
2041 output_ip_vrf = subprocess.check_output(['ip', 'address', 'show', 'vrf', 'vrf99']).rstrip().decode('utf-8')
2042 print(output_ip_vrf)
2043
2044 print('## ip address show dev veth99')
2045 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
2046 print(output)
2047 self.assertEqual(output, output_ip_vrf)
2048 self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
2049 self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
2050 self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic noprefixroute')
2051 self.assertRegex(output, 'inet6 .* scope link')
2052
2053 print('## ip route show vrf vrf99')
2054 output = subprocess.check_output(['ip', 'route', 'show', 'vrf', 'vrf99']).rstrip().decode('utf-8')
2055 print(output)
2056 self.assertRegex(output, 'default via 192.168.5.1 dev veth99 proto dhcp src 192.168.5.')
2057 self.assertRegex(output, 'default dev veth99 proto static scope link')
2058 self.assertRegex(output, '169.254.0.0/16 dev veth99 proto kernel scope link src 169.254')
2059 self.assertRegex(output, '192.168.5.0/24 dev veth99 proto kernel scope link src 192.168.5')
2060 self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 dev veth99 proto dhcp')
2061 self.assertRegex(output, '192.168.5.1 dev veth99 proto dhcp scope link src 192.168.5')
2062
2063 print('## ip route show table main dev veth99')
2064 output = subprocess.check_output(['ip', 'route', 'show', 'table', 'main', 'dev', 'veth99']).rstrip().decode('utf-8')
2065 print(output)
2066 self.assertEqual(output, '')
2067
2068 output = subprocess.check_output(['networkctl', 'status', 'vrf99']).rstrip().decode('utf-8')
2069 print(output)
2070 self.assertRegex(output, 'State: carrier \(configured\)')
2071
2072 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
2073 print(output)
2074 self.assertRegex(output, 'State: routable \(configured\)')
2075
2076 def test_dhcp_client_gateway_onlink_implicit(self):
2077 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
2078 'dhcp-client-gateway-onlink-implicit.network')
2079 self.start_networkd()
2080
2081 self.assertTrue(self.link_exits('veth99'))
2082
2083 self.start_dnsmasq()
2084
2085 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
2086 print(output)
2087 self.assertRegex(output, '192.168.5')
2088
2089 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'veth99', '10.0.0.0/8']).rstrip().decode('utf-8')
2090 print(output)
2091 self.assertRegex(output, 'onlink')
2092 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'veth99', '192.168.100.0/24']).rstrip().decode('utf-8')
2093 print(output)
2094 self.assertRegex(output, 'onlink')
2095
2096 if __name__ == '__main__':
2097 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
2098 verbosity=3))