]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-network: add tests for DHCP IPv6 only mode 29472/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 6 Oct 2023 05:11:07 +0000 (14:11 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Oct 2023 12:42:13 +0000 (21:42 +0900)
For [DHCPv4] IPv6OnlyMode= and [DHCPServer] IPv6OnlyPreferredSec=.

test/test-network/conf/25-dhcp-client-ipv6-only-mode.network [new file with mode: 0644]
test/test-network/conf/25-dhcp-client-ipv6-only.network
test/test-network/conf/25-dhcp-server-ipv6-only-mode.network [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py

diff --git a/test/test-network/conf/25-dhcp-client-ipv6-only-mode.network b/test/test-network/conf/25-dhcp-client-ipv6-only-mode.network
new file mode 100644 (file)
index 0000000..21a6bc7
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=no
+
+[DHCPv4]
+IPv6OnlyMode=yes
index 017f76f4d589d4d8541eaf7d696e5d80ff8b76fa..4aba206cb4bfdfbec4cdda4d4ac04b53f35471c8 100644 (file)
@@ -3,7 +3,8 @@
 Name=veth99
 
 [Network]
-DHCP=ipv6
+# DHCPv4 is also enabled here, but will be stopped when an IPv6 address is acquired.
+DHCP=yes
 IPv6Token=::1a:2b:3c:4d
 
 [Route]
diff --git a/test/test-network/conf/25-dhcp-server-ipv6-only-mode.network b/test/test-network/conf/25-dhcp-server-ipv6-only-mode.network
new file mode 100644 (file)
index 0000000..cb19e74
--- /dev/null
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+Name=veth-peer
+
+[Network]
+IPv6AcceptRA=false
+DHCPServer=yes
+
+[DHCPServer]
+ServerAddress=192.168.5.1/24
+PoolOffset=10
+PoolSize=50
+Router=192.168.5.3
+DNS=_server_address 192.168.5.10
+NTP=_server_address 192.168.5.11
+IPv6OnlyPreferredSec=20s
index 1496a615fe48e35d5fffedc78efe5fc171f198b9..f0b248917ce5b90841420f4ff20e7bf93b0d2041 100755 (executable)
@@ -770,7 +770,11 @@ def setUpModule():
     save_timezone()
 
     create_service_dropin('systemd-networkd', networkd_bin,
-                          ['[Service]', 'Restart=no', '[Unit]', 'StartLimitIntervalSec=0'])
+                          ['[Service]',
+                           'Restart=no',
+                           'Environment=SYSTEMD_NETWORK_TEST_MODE=yes',
+                           '[Unit]',
+                           'StartLimitIntervalSec=0'])
     create_service_dropin('systemd-resolved', resolved_bin)
     create_service_dropin('systemd-timesyncd', timesyncd_bin)
 
@@ -5110,7 +5114,10 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         self.wait_online(['veth-peer:carrier'])
 
         # information request mode
-        start_dnsmasq('--dhcp-option=option6:dns-server,[2600::ee]',
+        # The name ipv6-only option may not be supported by older dnsmasq
+        # start_dnsmasq('--dhcp-option=option:ipv6-only,300')
+        start_dnsmasq('--dhcp-option=108,00:00:02:00',
+                      '--dhcp-option=option6:dns-server,[2600::ee]',
                       '--dhcp-option=option6:ntp-server,[2600::ff]',
                       ra_mode='ra-stateless')
         self.wait_online(['veth99:routable', 'veth-peer:routable'])
@@ -5140,7 +5147,8 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
 
         # solicit mode
         stop_dnsmasq()
-        start_dnsmasq('--dhcp-option=option6:dns-server,[2600::ee]',
+        start_dnsmasq('--dhcp-option=108,00:00:02:00',
+                      '--dhcp-option=option6:dns-server,[2600::ee]',
                       '--dhcp-option=option6:ntp-server,[2600::ff]')
         networkctl_reconfigure('veth99')
         self.wait_online(['veth99:routable', 'veth-peer:routable'])
@@ -5189,7 +5197,8 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
             f.write('\n[DHCPv6]\nRapidCommit=no\n')
 
         stop_dnsmasq()
-        start_dnsmasq('--dhcp-option=option6:dns-server,[2600::ee]',
+        start_dnsmasq('--dhcp-option=108,00:00:02:00',
+                      '--dhcp-option=option6:dns-server,[2600::ee]',
                       '--dhcp-option=option6:ntp-server,[2600::ff]')
 
         networkctl_reload()
@@ -5238,16 +5247,30 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         # Note that at this point the DHCPv6 client has not been started because no RA (with managed
         # bit set) has yet been received and the configuration does not include WithoutRA=true
         state = get_dhcp6_client_state('veth99')
-        print(f"State = {state}")
+        print(f"DHCPv6 client state = {state}")
         self.assertEqual(state, 'stopped')
 
-        start_dnsmasq()
+        state = get_dhcp4_client_state('veth99')
+        print(f"DHCPv4 client state = {state}")
+        self.assertEqual(state, 'selecting')
+
+        start_dnsmasq('--dhcp-option=108,00:00:02:00')
         self.wait_online(['veth99:routable', 'veth-peer:routable'])
 
         state = get_dhcp6_client_state('veth99')
-        print(f"State = {state}")
+        print(f"DHCPv6 client state = {state}")
         self.assertEqual(state, 'bound')
 
+        # DHCPv4 client will stop after an DHCPOFFER message received, so we need to wait for a while.
+        for _ in range(100):
+            state = get_dhcp4_client_state('veth99')
+            if state == 'stopped':
+                break
+            time.sleep(.2)
+
+        print(f"DHCPv4 client state = {state}")
+        self.assertEqual(state, 'stopped')
+
     def test_dhcp_client_ipv6_only_with_custom_client_identifier(self):
         copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client-ipv6-only-custom-client-identifier.network')
 
@@ -5493,6 +5516,18 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         print(f"State = {state}")
         self.assertEqual(state, 'bound')
 
+    def test_dhcp_client_ipv6_only_mode_without_ipv6_connectivity(self):
+        copy_network_unit('25-veth.netdev',
+                          '25-dhcp-server-ipv6-only-mode.network',
+                          '25-dhcp-client-ipv6-only-mode.network')
+        start_networkd()
+        self.wait_online(['veth99:routable', 'veth-peer:routable'], timeout='40s')
+        self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24', ipv='-4')
+
+        state = get_dhcp4_client_state('veth99')
+        print(f"State = {state}")
+        self.assertEqual(state, 'bound')
+
     def test_dhcp_client_ipv4_use_routes_gateway(self):
         first = True
         for (routes, gateway, dns_and_ntp_routes, classless) in itertools.product([True, False], repeat=4):