]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-network: add test for 6rd
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 6 Dec 2021 00:03:54 +0000 (09:03 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 7 Dec 2021 11:33:20 +0000 (20:33 +0900)
test/test-network/conf/dhcp4-6rd-server.network [new file with mode: 0644]
test/test-network/conf/dhcp4-6rd-upstream.network [new file with mode: 0644]
test/test-network/conf/isc-dhcpd-6rd.conf [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py

diff --git a/test/test-network/conf/dhcp4-6rd-server.network b/test/test-network/conf/dhcp4-6rd-server.network
new file mode 100644 (file)
index 0000000..91dc71a
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+Name=veth-peer
+
+[Network]
+IPv6AcceptRA=no
+Address=10.0.0.1/8
diff --git a/test/test-network/conf/dhcp4-6rd-upstream.network b/test/test-network/conf/dhcp4-6rd-upstream.network
new file mode 100644 (file)
index 0000000..e146337
--- /dev/null
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+Name=veth99
+
+[Network]
+IPv6PrivacyExtensions=yes
+IPv6AcceptRA=no
+DHCP=ipv4
+DHCPPrefixDelegation=yes
+
+[DHCPv4]
+Use6RD=yes
+
+[DHCPPrefixDelegation]
+UplinkInterface=:self
+SubnetId=10
+Announce=no
+Token=eui64
+Token=::1a:2b:3c:4d
diff --git a/test/test-network/conf/isc-dhcpd-6rd.conf b/test/test-network/conf/isc-dhcpd-6rd.conf
new file mode 100644 (file)
index 0000000..0b32f4b
--- /dev/null
@@ -0,0 +1,22 @@
+default-lease-time 2592000;
+preferred-lifetime 604800;
+
+default-lease-time 600;
+max-lease-time 7200;
+
+option domain-name-servers 10.0.0.2;
+option domain-search "test.example.com","example.com";
+
+# ipv4masklen = 8
+# 6rd prefix = 2001:db8::/32
+# BR address = 10.0.0.1
+option option-6rd code 212 = {
+    integer 8, integer 8, ip6-address, array of ip-address
+};
+
+option option-6rd 8 32 2001:db8:: 10.0.0.1;
+
+subnet 10.0.0.0 netmask 255.0.0.0 {
+       # Addresses available to clients
+       range 10.100.100.100 10.100.100.199;
+}
index f6c91ea96959c99cd25262bb5de022efa0b9b33d..57acd27f8496d8374afd34bced209b96df20231e 100755 (executable)
@@ -5020,6 +5020,8 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
         'dhcp-pd-downstream-veth97-peer.network',
         'dhcp-pd-downstream-veth98.network',
         'dhcp-pd-downstream-veth98-peer.network',
+        'dhcp4-6rd-server.network',
+        'dhcp4-6rd-upstream.network',
         'dhcp6pd-server.network',
         'dhcp6pd-upstream.network',
     ]
@@ -5229,6 +5231,241 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities):
         print(output)
         self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]03::/64 proto dhcp metric [0-9]* expires')
 
+    def test_dhcp4_6rd(self):
+        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp4-6rd-server.network', 'dhcp4-6rd-upstream.network',
+                                        '25-veth-downstream-veth97.netdev', 'dhcp-pd-downstream-veth97.network', 'dhcp-pd-downstream-veth97-peer.network',
+                                        '25-veth-downstream-veth98.netdev', 'dhcp-pd-downstream-veth98.network', 'dhcp-pd-downstream-veth98-peer.network',
+                                        '11-dummy.netdev', 'dhcp-pd-downstream-test1.network',
+                                        'dhcp-pd-downstream-dummy97.network',
+                                        '12-dummy.netdev', 'dhcp-pd-downstream-dummy98.network',
+                                        '13-dummy.netdev', 'dhcp-pd-downstream-dummy99.network')
+
+        start_networkd()
+        self.wait_online(['veth-peer:routable'])
+        start_isc_dhcpd('veth-peer', 'isc-dhcpd-6rd.conf', ip='-4')
+        self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded',
+                          'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable'])
+
+        print('### ip -4 address show dev veth-peer scope global')
+        output = check_output('ip -4 address show dev veth-peer scope global')
+        print(output)
+        self.assertIn('inet 10.0.0.1/8 brd 10.255.255.255 scope global veth-peer', output)
+
+        '''
+        Link     Subnet IDs
+        test1:   0x00
+        dummy97: 0x01 (The link will appear later)
+        dummy98: 0x02
+        dummy99: auto -> 0x03 (No address assignment)
+        veth97:  0x08
+        veth98:  0x09
+        veth99:  0x10
+        '''
+
+        print('### ip -4 address show dev veth99 scope global')
+        output = check_output('ip -4 address show dev veth99 scope global')
+        print(output)
+        self.assertRegex(output, 'inet 10.100.100.[0-9]*/8 (metric 1024 |)brd 10.255.255.255 scope global dynamic veth99')
+
+        print('### ip -6 address show dev veth99 scope global')
+        output = check_output('ip -6 address show dev veth99 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (Token=eui64)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+10:1034:56ff:fe78:9abc/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        # Note that the temporary addresses may appear after the link enters configured state
+        self.wait_address('veth99', 'inet6 2001:db8:6464:[0-9a-f]+10:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev test1 scope global')
+        output = check_output('ip -6 address show dev test1 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        self.wait_address('test1', 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev dummy98 scope global')
+        output = check_output('ip -6 address show dev dummy98 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+02:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        self.wait_address('dummy98', 'inet6 2001:db8:6464:[0-9a-f]+02:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev dummy99 scope global')
+        output = check_output('ip -6 address show dev dummy99 scope global')
+        print(output)
+        # Assign=no
+        self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+03')
+
+        print('### ip -6 address show dev veth97 scope global')
+        output = check_output('ip -6 address show dev veth97 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (Token=eui64)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9ace/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        self.wait_address('veth97', 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev veth97-peer scope global')
+        output = check_output('ip -6 address show dev veth97-peer scope global')
+        print(output)
+        # NDisc address (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # NDisc address (Token=eui64)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+08:1034:56ff:fe78:9acf/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # NDisc address (temporary)
+        self.wait_address('veth97-peer', 'inet6 2001:db8:6464:[0-9a-f]+08:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev veth98 scope global')
+        output = check_output('ip -6 address show dev veth98 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (Token=eui64)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abe/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        self.wait_address('veth98', 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev veth98-peer scope global')
+        output = check_output('ip -6 address show dev veth98-peer scope global')
+        print(output)
+        # NDisc address (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1a:2b:3c:4e/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # NDisc address (Token=eui64)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+09:1034:56ff:fe78:9abf/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # NDisc address (temporary)
+        self.wait_address('veth98-peer', 'inet6 2001:db8:6464:[0-9a-f]+09:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 route show type unreachable')
+        output = check_output('ip -6 route show type unreachable')
+        print(output)
+        self.assertRegex(output, 'unreachable 2001:db8:6464:[0-9a-f]+00::/56 dev lo proto dhcp')
+
+        print('### ip -6 route show dev veth99')
+        output = check_output('ip -6 route show dev veth99')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+10::/64 proto kernel metric [0-9]* expires')
+
+        print('### ip -6 route show dev test1')
+        output = check_output('ip -6 route show dev test1')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+00::/64 proto kernel metric [0-9]* expires')
+
+        print('### ip -6 route show dev dummy98')
+        output = check_output('ip -6 route show dev dummy98')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+02::/64 proto kernel metric [0-9]* expires')
+
+        print('### ip -6 route show dev dummy99')
+        output = check_output('ip -6 route show dev dummy99')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+03::/64 proto dhcp metric [0-9]* expires')
+
+        print('### ip -6 route show dev veth97')
+        output = check_output('ip -6 route show dev veth97')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+08::/64 proto kernel metric [0-9]* expires')
+
+        print('### ip -6 route show dev veth97-peer')
+        output = check_output('ip -6 route show dev veth97-peer')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+08::/64 proto ra metric [0-9]* expires')
+
+        print('### ip -6 route show dev veth98')
+        output = check_output('ip -6 route show dev veth98')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+09::/64 proto kernel metric [0-9]* expires')
+
+        print('### ip -6 route show dev veth98-peer')
+        output = check_output('ip -6 route show dev veth98-peer')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+09::/64 proto ra metric [0-9]* expires')
+
+        # Test case for a downstream which appears later
+        check_output('ip link add dummy97 type dummy')
+        self.wait_online(['dummy97:routable'])
+
+        print('### ip -6 address show dev dummy97 scope global')
+        output = check_output('ip -6 address show dev dummy97 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+01:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        self.wait_address('dummy97', 'inet6 2001:db8:6464:[0-9a-f]+01:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 route show dev dummy97')
+        output = check_output('ip -6 route show dev dummy97')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+01::/64 proto kernel metric [0-9]* expires')
+
+        # Test case for reconfigure
+        check_output(*networkctl_cmd, 'reconfigure', 'dummy98', 'dummy99', env=env)
+        self.wait_online(['dummy98:routable'])
+
+        print('### ip -6 address show dev dummy98 scope global')
+        output = check_output('ip -6 address show dev dummy98 scope global')
+        print(output)
+        # address in IA_PD (Token=static)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+02:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr')
+        # address in IA_PD (temporary)
+        self.wait_address('dummy98', 'inet6 2001:db8:6464:[0-9a-f]+02:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6')
+
+        print('### ip -6 address show dev dummy99 scope global')
+        output = check_output('ip -6 address show dev dummy99 scope global')
+        print(output)
+        # Assign=no
+        self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+03')
+
+        print('### ip -6 route show dev dummy98')
+        output = check_output('ip -6 route show dev dummy98')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+02::/64 proto kernel metric [0-9]* expires')
+
+        print('### ip -6 route show dev dummy99')
+        output = check_output('ip -6 route show dev dummy99')
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+03::/64 proto dhcp metric [0-9]* expires')
+
+        tunnel_name = None
+        for name in os.listdir('/sys/class/net/'):
+            if name.startswith('6rd-'):
+                tunnel_name = name
+                break
+
+        self.wait_online(['{}:routable'.format(tunnel_name)])
+
+        print('### ip -d link show dev {}'.format(tunnel_name))
+        output = check_output('ip -d link show dev {}'.format(tunnel_name))
+        print(output)
+        self.assertIn('link/sit 10.100.100.', output)
+        self.assertIn('local 10.100.100.', output)
+        self.assertIn('dev veth99', output)
+        self.assertIn('ttl 64', output)
+        self.assertIn('6rd-prefix 2001:db8::/32', output)
+        self.assertIn('6rd-relay_prefix 10.0.0.0/8', output)
+
+        print('### ip -6 address show dev {}'.format(tunnel_name))
+        output = check_output('ip -6 address show dev {}'.format(tunnel_name))
+        print(output)
+        self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+00:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/56 (metric 256 |)scope global dynamic')
+        self.assertRegex(output, 'inet6 ::10.100.100.[0-9]+/96 scope global')
+
+        print('### ip -6 route show dev {}'.format(tunnel_name))
+        output = check_output('ip -6 route show dev {}'.format(tunnel_name))
+        print(output)
+        self.assertRegex(output, '2001:db8:6464:[0-9a-f]+00::/56 proto kernel metric [0-9]* expires')
+        self.assertRegex(output, '::/96 proto kernel metric [0-9]*')
+
+        print('### ip -6 route show default')
+        output = check_output('ip -6 route show default')
+        print(output)
+        self.assertIn('default', output)
+        self.assertIn('via ::10.0.0.1 dev {}'.format(tunnel_name), output)
+
 class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
     links = [
         'dummy98',