diff --git a/test/test-network/conf/25-vrf.network b/test/test-network/conf/25-vrf.network new file mode 100644 index 0000000000..42ce5b1925 --- /dev/null +++ b/test/test-network/conf/25-vrf.network @@ -0,0 +1,2 @@ +[Match] +Name=vrf99 diff --git a/test/test-network/conf/dhcp-client-vrf.network b/test/test-network/conf/dhcp-client-vrf.network new file mode 100644 index 0000000000..bb1d2e09c5 --- /dev/null +++ b/test/test-network/conf/dhcp-client-vrf.network @@ -0,0 +1,8 @@ +[Match] +Name=veth99 + +[Network] +DHCP=yes +IPv6AcceptRA=yes +LinkLocalAddressing=yes +VRF=vrf99 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 64a3d25bd4..d1d4f4c3da 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1104,10 +1104,13 @@ class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities): class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities): links = [ 'dummy98', - 'veth99'] + 'veth99', + 'vrf99'] units = [ '25-veth.netdev', + '25-vrf.netdev', + '25-vrf.network', 'dhcp-client-anonymize.network', 'dhcp-client-critical-connection.network', 'dhcp-client-ipv4-dhcp-settings.network', @@ -1118,6 +1121,7 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities): 'dhcp-client-listen-port.network', 'dhcp-client-route-metric.network', 'dhcp-client-route-table.network', + 'dhcp-client-vrf.network', 'dhcp-client.network', 'dhcp-server-veth-peer.network', 'dhcp-v4-server-veth-peer.network', @@ -1342,6 +1346,58 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities): self.assertRegex(output, '2600::') self.assertRegex(output, 'valid_lft forever preferred_lft forever') + @expectedFailureIfModuleIsNotAvailable('vrf') + def test_dhcp_client_vrf(self): + self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-vrf.network', + '25-vrf.netdev', '25-vrf.network') + self.start_networkd() + + self.assertTrue(self.link_exits('veth99')) + self.assertTrue(self.link_exits('vrf99')) + + self.start_dnsmasq() + + print('## ip -d link show dev vrf99') + output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dev', 'vrf99']).rstrip().decode('utf-8') + print(output) + self.assertRegex(output, 'vrf table 42') + + print('## ip address show vrf vrf99') + output_ip_vrf = subprocess.check_output(['ip', 'address', 'show', 'vrf', 'vrf99']).rstrip().decode('utf-8') + print(output_ip_vrf) + + print('## ip address show dev veth99') + output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8') + print(output) + self.assertEqual(output, output_ip_vrf) + self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99') + self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') + self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global dynamic noprefixroute') + self.assertRegex(output, 'inet6 .* scope link') + + print('## ip route show vrf vrf99') + output = subprocess.check_output(['ip', 'route', 'show', 'vrf', 'vrf99']).rstrip().decode('utf-8') + print(output) + self.assertRegex(output, 'default via 192.168.5.1 dev veth99 proto dhcp src 192.168.5.') + self.assertRegex(output, 'default dev veth99 proto static scope link') + self.assertRegex(output, '169.254.0.0/16 dev veth99 proto kernel scope link src 169.254') + self.assertRegex(output, '192.168.5.0/24 dev veth99 proto kernel scope link src 192.168.5') + self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 dev veth99 proto dhcp') + self.assertRegex(output, '192.168.5.1 dev veth99 proto dhcp scope link src 192.168.5') + + print('## ip route show table main dev veth99') + output = subprocess.check_output(['ip', 'route', 'show', 'table', 'main', 'dev', 'veth99']).rstrip().decode('utf-8') + print(output) + self.assertEqual(output, '') + + output = subprocess.check_output(['networkctl', 'status', 'vrf99']).rstrip().decode('utf-8') + print(output) + self.assertRegex(output, 'State: carrier \(configured\)') + + output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8') + print(output) + self.assertRegex(output, 'State: routable \(configured\)') + if __name__ == '__main__': unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=3))