1 { system ? builtins.currentSystem
3 , pkgs ? import ../.. { inherit system config; }
4 # bool: whether to use networkd in the tests
7 with import ../../lib/testing-python.nix { inherit system pkgs; };
11 router = import ./router.nix { inherit networkd; };
12 clientConfig = extraConfig: lib.recursiveUpdate {
13 networking.useDHCP = false;
14 networking.useNetworkd = networkd;
19 nodes.client = clientConfig {};
22 client.wait_for_unit("network.target")
23 loopback_addresses = client.succeed("ip addr show lo")
24 assert "inet 127.0.0.1/8" in loopback_addresses
25 assert "inet6 ::1/128" in loopback_addresses
30 nodes.router = router;
31 nodes.client = clientConfig {
32 virtualisation.interfaces.enp1s0.vlan = 1;
33 virtualisation.interfaces.enp2s0.vlan = 2;
35 defaultGateway = { address = "192.168.1.1"; interface = "enp1s0"; };
36 defaultGateway6 = { address = "fd00:1234:5678:1::1"; interface = "enp1s0"; };
37 interfaces.enp1s0.ipv4.addresses = [
38 { address = "192.168.1.2"; prefixLength = 24; }
39 { address = "192.168.1.3"; prefixLength = 32; }
40 { address = "192.168.1.10"; prefixLength = 32; }
42 interfaces.enp2s0.ipv4.addresses = [
43 { address = "192.168.2.2"; prefixLength = 24; }
50 client.wait_for_unit("network.target")
51 router.systemctl("start network-online.target")
52 router.wait_for_unit("network-online.target")
54 with subtest("Make sure DHCP server is not started"):
55 client.fail("systemctl status kea-dhcp4-server.service")
56 client.fail("systemctl status kea-dhcp6-server.service")
58 with subtest("Test vlan 1"):
59 client.wait_until_succeeds("ping -c 1 192.168.1.1")
60 router.wait_until_succeeds("ping -c 1 192.168.1.2")
61 router.wait_until_succeeds("ping -c 1 192.168.1.3")
62 router.wait_until_succeeds("ping -c 1 192.168.1.10")
64 with subtest("Test vlan 2"):
65 client.wait_until_succeeds("ping -c 1 192.168.2.1")
66 router.wait_until_succeeds("ping -c 1 192.168.2.2")
68 with subtest("Test default gateway"):
69 client.wait_until_succeeds("ping -c 1 192.168.3.1")
70 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:3::1")
75 nodes.client = clientConfig {
77 interfaces.eth1.ipv4.routes = [{
78 address = "192.168.1.127";
86 client.wait_for_unit("network.target")
87 client.succeed("ip -4 route list table local | grep 'local 192.168.1.127'")
91 name = "useDHCP-by-default";
92 nodes.router = router;
94 # Disable test driver default config
95 networking.interfaces = lib.mkForce {
96 # Make sure DHCP defaults correctly even when some unrelated config
97 # is set on the interface (nothing, in this case).
100 networking.useNetworkd = networkd;
101 virtualisation.interfaces.enp1s0.vlan = 1;
105 client.wait_for_unit("multi-user.target")
106 client.wait_until_succeeds("ip addr show dev enp1s0 | grep '192.168.1'")
107 router.succeed("ping -c 1 192.168.1.1")
108 client.succeed("ping -c 1 192.168.1.2")
113 nodes.router = router;
114 nodes.client = clientConfig {
115 virtualisation.interfaces.enp1s0.vlan = 1;
116 virtualisation.interfaces.enp2s0.vlan = 2;
118 interfaces.enp1s0.useDHCP = true;
119 interfaces.enp2s0.useDHCP = true;
125 client.wait_for_unit("network.target")
126 router.systemctl("start network-online.target")
127 router.wait_for_unit("network-online.target")
129 with subtest("Wait until we have an ip address on each interface"):
130 client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q '192.168.1'")
131 client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q 'fd00:1234:5678:1:'")
132 client.wait_until_succeeds("ip addr show dev enp2s0 | grep -q '192.168.2'")
133 client.wait_until_succeeds("ip addr show dev enp2s0 | grep -q 'fd00:1234:5678:2:'")
135 with subtest("Test vlan 1"):
136 client.wait_until_succeeds("ping -c 1 192.168.1.1")
137 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1")
138 router.wait_until_succeeds("ping -c 1 192.168.1.2")
139 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2")
141 with subtest("Test vlan 2"):
142 client.wait_until_succeeds("ping -c 1 192.168.2.1")
143 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::1")
144 router.wait_until_succeeds("ping -c 1 192.168.2.2")
145 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2")
149 name = "OneInterfaceDHCP";
150 nodes.router = router;
151 nodes.client = clientConfig {
152 virtualisation.interfaces.enp1s0.vlan = 1;
153 virtualisation.interfaces.enp2s0.vlan = 2;
155 interfaces.enp1s0 = {
164 with subtest("Wait for networking to come up"):
165 client.wait_for_unit("network.target")
166 router.wait_for_unit("network.target")
168 with subtest("Wait until we have an ip address on each interface"):
169 client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q '192.168.1'")
171 with subtest("ensure MTU is set"):
172 assert "mtu 1343" in client.succeed("ip link show dev enp1s0")
174 with subtest("Test vlan 1"):
175 client.wait_until_succeeds("ping -c 1 192.168.1.1")
176 router.wait_until_succeeds("ping -c 1 192.168.1.2")
178 with subtest("Test vlan 2"):
179 client.wait_until_succeeds("ping -c 1 192.168.2.1")
180 client.fail("ping -c 1 192.168.2.2")
182 router.wait_until_succeeds("ping -c 1 192.168.2.1")
183 router.fail("ping -c 1 192.168.2.2")
187 node = address: clientConfig {
188 virtualisation.interfaces.enp1s0.vlan = 1;
189 virtualisation.interfaces.enp2s0.vlan = 2;
192 interfaces = [ "enp1s0" "enp2s0" ];
193 driverOptions.mode = "802.3ad";
195 interfaces.bond0.ipv4.addresses = lib.mkOverride 0
196 [ { inherit address; prefixLength = 30; } ];
201 nodes.client1 = node "192.168.1.1";
202 nodes.client2 = node "192.168.1.2";
206 with subtest("Wait for networking to come up"):
207 client1.wait_for_unit("network.target")
208 client2.wait_for_unit("network.target")
210 with subtest("Test bonding"):
211 client1.wait_until_succeeds("ping -c 2 192.168.1.1")
212 client1.wait_until_succeeds("ping -c 2 192.168.1.2")
214 client2.wait_until_succeeds("ping -c 2 192.168.1.1")
215 client2.wait_until_succeeds("ping -c 2 192.168.1.2")
217 with subtest("Verify bonding mode"):
218 for client in client1, client2:
219 client.succeed('grep -q "Bonding Mode: IEEE 802.3ad Dynamic link aggregation" /proc/net/bonding/bond0')
223 node = { address, vlan }: { pkgs, ... }: {
224 virtualisation.interfaces.enp1s0.vlan = vlan;
226 useNetworkd = networkd;
228 interfaces.enp1s0.ipv4.addresses = [ { inherit address; prefixLength = 24; } ];
233 nodes.client1 = node { address = "192.168.1.2"; vlan = 1; };
234 nodes.client2 = node { address = "192.168.1.3"; vlan = 2; };
236 virtualisation.interfaces.enp1s0.vlan = 1;
237 virtualisation.interfaces.enp2s0.vlan = 2;
239 useNetworkd = networkd;
241 bridges.bridge.interfaces = [ "enp1s0" "enp2s0" ];
242 interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [ ];
243 interfaces.eth2.ipv4.addresses = lib.mkOverride 0 [ ];
244 interfaces.bridge.ipv4.addresses = lib.mkOverride 0
245 [ { address = "192.168.1.1"; prefixLength = 24; } ];
251 with subtest("Wait for networking to come up"):
252 for machine in client1, client2, router:
253 machine.wait_for_unit("network.target")
255 with subtest("Test bridging"):
256 client1.wait_until_succeeds("ping -c 1 192.168.1.1")
257 client1.wait_until_succeeds("ping -c 1 192.168.1.2")
258 client1.wait_until_succeeds("ping -c 1 192.168.1.3")
260 client2.wait_until_succeeds("ping -c 1 192.168.1.1")
261 client2.wait_until_succeeds("ping -c 1 192.168.1.2")
262 client2.wait_until_succeeds("ping -c 1 192.168.1.3")
264 router.wait_until_succeeds("ping -c 1 192.168.1.1")
265 router.wait_until_succeeds("ping -c 1 192.168.1.2")
266 router.wait_until_succeeds("ping -c 1 192.168.1.3")
271 nodes.router = router;
272 nodes.client = { pkgs, ... }: {
273 environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules
274 virtualisation.interfaces.enp1s0.vlan = 1;
276 useNetworkd = networkd;
278 firewall.logReversePathDrops = true; # to debug firewall rules
279 # reverse path filtering rules for the macvlan interface seem
280 # to be incorrect, causing the test to fail. Disable temporarily.
281 firewall.checkReversePath = false;
282 macvlans.macvlan.interface = "enp1s0";
283 interfaces.enp1s0.useDHCP = true;
284 interfaces.macvlan.useDHCP = true;
290 with subtest("Wait for networking to come up"):
291 client.wait_for_unit("network.target")
292 router.wait_for_unit("network.target")
294 with subtest("Wait until we have an ip address on each interface"):
295 client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q '192.168.1'")
296 client.wait_until_succeeds("ip addr show dev macvlan | grep -q '192.168.1'")
298 with subtest("Print lots of diagnostic information"):
299 router.log("**********************************************")
300 router.succeed("ip addr >&2")
301 router.succeed("ip route >&2")
302 router.execute("iptables-save >&2")
303 client.log("==============================================")
304 client.succeed("ip addr >&2")
305 client.succeed("ip route >&2")
306 client.execute("iptables-save >&2")
307 client.log("##############################################")
309 with subtest("Test macvlan creates routable ips"):
310 client.wait_until_succeeds("ping -c 1 192.168.1.1")
311 client.wait_until_succeeds("ping -c 1 192.168.1.2")
312 client.wait_until_succeeds("ping -c 1 192.168.1.3")
314 router.wait_until_succeeds("ping -c 1 192.168.1.1")
315 router.wait_until_succeeds("ping -c 1 192.168.1.2")
316 router.wait_until_succeeds("ping -c 1 192.168.1.3")
320 name = "foo-over-udp";
321 nodes.machine = clientConfig {
322 virtualisation.interfaces.enp1s0.vlan = 1;
324 interfaces.enp1s0.ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
326 fou1 = { port = 9001; };
327 fou2 = { port = 9002; protocol = 41; };
328 fou3 = lib.mkIf (!networkd)
329 { port = 9003; local.address = "192.168.1.1"; };
330 fou4 = lib.mkIf (!networkd)
331 { port = 9004; local = { address = "192.168.1.1"; dev = "enp1s0"; }; };
335 fou3-fou-encap.after = lib.optional (!networkd) "network-addresses-enp1s0.service";
341 machine.wait_for_unit("network.target")
342 fous = json.loads(machine.succeed("ip -json fou show"))
343 assert {"port": 9001, "gue": None, "family": "inet"} in fous, "fou1 exists"
344 assert {"port": 9002, "ipproto": 41, "family": "inet"} in fous, "fou2 exists"
345 '' + lib.optionalString (!networkd) ''
350 "local": "192.168.1.1",
351 } in fous, "fou3 exists"
356 "local": "192.168.1.1",
358 } in fous, "fou4 exists"
362 node = { address4, remote, address6 }: { pkgs, ... }: {
363 virtualisation.interfaces.enp1s0.vlan = 1;
365 useNetworkd = networkd;
372 interfaces.enp1s0.ipv4.addresses = lib.mkOverride 0
373 [ { address = address4; prefixLength = 24; } ];
374 interfaces.sit.ipv6.addresses = lib.mkOverride 0
375 [ { address = address6; prefixLength = 64; } ];
380 # note on firewalling: the two nodes are explicitly asymmetric.
381 # client1 sends SIT packets in UDP, but accepts only proto-41 incoming.
382 # client2 does the reverse, sending in proto-41 and accepting only UDP incoming.
383 # that way we'll notice when either SIT itself or FOU breaks.
384 nodes.client1 = args@{ pkgs, ... }:
386 (node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; } args)
389 firewall.extraCommands = "iptables -A INPUT -p 41 -j ACCEPT";
390 sits.sit.encapsulation = { type = "fou"; port = 9001; };
394 nodes.client2 = args@{ pkgs, ... }:
396 (node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; } args)
399 firewall.allowedUDPPorts = [ 9001 ];
400 fooOverUDP.fou1 = { port = 9001; protocol = 41; };
407 with subtest("Wait for networking to be configured"):
408 client1.wait_for_unit("network.target")
409 client2.wait_for_unit("network.target")
411 # Print diagnostic information
412 client1.succeed("ip addr >&2")
413 client2.succeed("ip addr >&2")
415 with subtest("Test ipv6"):
416 client1.wait_until_succeeds("ping -c 1 fc00::1")
417 client1.wait_until_succeeds("ping -c 1 fc00::2")
419 client2.wait_until_succeeds("ping -c 1 fc00::1")
420 client2.wait_until_succeeds("ping -c 1 fc00::2")
426 useNetworkd = networkd;
428 firewall.extraCommands = "ip6tables -A nixos-fw -p gre -j nixos-fw-accept";
433 nodes.client1 = args@{ pkgs, ... }:
437 virtualisation.vlans = [ 1 2 4 ];
441 local = "192.168.2.1";
442 remote = "192.168.2.2";
448 local = "fd00:1234:5678:4::1";
449 remote = "fd00:1234:5678:4::2";
455 bridges.bridge.interfaces = [ "greTunnel" "eth1" ];
456 interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [];
457 interfaces.bridge.ipv4.addresses = lib.mkOverride 0 [
458 { address = "192.168.1.1"; prefixLength = 24; }
460 interfaces.eth3.ipv6.addresses = [
461 { address = "fd00:1234:5678:4::1"; prefixLength = 64; }
463 interfaces.gre6Tunnel.ipv6.addresses = lib.mkOverride 0 [
464 { address = "fc00::1"; prefixLength = 64; }
469 nodes.client2 = args@{ pkgs, ... }:
473 virtualisation.vlans = [ 2 3 4 ];
477 local = "192.168.2.2";
478 remote = "192.168.2.1";
484 local = "fd00:1234:5678:4::2";
485 remote = "fd00:1234:5678:4::1";
491 bridges.bridge.interfaces = [ "greTunnel" "eth2" ];
492 interfaces.eth2.ipv4.addresses = lib.mkOverride 0 [];
493 interfaces.bridge.ipv4.addresses = lib.mkOverride 0 [
494 { address = "192.168.1.2"; prefixLength = 24; }
496 interfaces.eth3.ipv6.addresses = [
497 { address = "fd00:1234:5678:4::2"; prefixLength = 64; }
499 interfaces.gre6Tunnel.ipv6.addresses = lib.mkOverride 0 [
500 { address = "fc00::2"; prefixLength = 64; }
509 with subtest("Wait for networking to be configured"):
510 client1.wait_for_unit("network.target")
511 client2.wait_for_unit("network.target")
513 # Print diagnostic information
514 client1.succeed("ip addr >&2")
515 client2.succeed("ip addr >&2")
517 with subtest("Test GRE tunnel bridge over VLAN"):
518 client1.wait_until_succeeds("ping -c 1 192.168.1.2")
520 client2.wait_until_succeeds("ping -c 1 192.168.1.1")
522 client1.wait_until_succeeds("ping -c 1 fc00::2")
524 client2.wait_until_succeeds("ping -c 1 fc00::1")
526 with subtest("Test GRE tunnel TTL"):
527 links = json.loads(client1.succeed("ip -details -json link show greTunnel"))
528 assert links[0]['linkinfo']['info_data']['ttl'] == 225, "ttl not set for greTunnel"
530 links = json.loads(client2.succeed("ip -details -json link show gre6Tunnel"))
531 assert links[0]['linkinfo']['info_data']['ttl'] == 255, "ttl not set for gre6Tunnel"
537 useNetworkd = networkd;
543 interfaces.eth0.ipv4.addresses = lib.mkOverride 0 [ ];
544 interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [ ];
545 interfaces.vlan.ipv4.addresses = lib.mkOverride 0
546 [ { inherit address; prefixLength = 24; } ];
551 nodes.client1 = node "192.168.1.1";
552 nodes.client2 = node "192.168.1.2";
556 with subtest("Wait for networking to be configured"):
557 client1.wait_for_unit("network.target")
558 client2.wait_for_unit("network.target")
560 with subtest("Test vlan is setup"):
561 client1.succeed("ip addr show dev vlan >&2")
562 client2.succeed("ip addr show dev vlan >&2")
566 baseIP = number: "10.10.10.${number}";
567 vlanIP = number: "10.1.1.${number}";
568 baseInterface = "enp1s0";
569 vlanInterface = "vlan42";
571 virtualisation.interfaces.enp1s0.vlan = 1;
573 #useNetworkd = networkd;
575 vlans.${vlanInterface} = { id = 42; interface = baseInterface; };
576 interfaces.${baseInterface}.ipv4.addresses = lib.mkOverride 0 [{ address = baseIP number; prefixLength = 24; }];
577 interfaces.${vlanInterface}.ipv4.addresses = lib.mkOverride 0 [{ address = vlanIP number; prefixLength = 24; }];
586 nodes.server = node serverNodeNum;
587 nodes.client = node clientNodeNum;
591 with subtest("Wait for networking to be configured"):
592 server.wait_for_unit("network.target")
593 client.wait_for_unit("network.target")
595 with subtest("Test ping on base interface in setup"):
596 client.succeed("ping -I ${baseInterface} -c 1 ${baseIP serverNodeNum}")
597 server.succeed("ping -I ${baseInterface} -c 1 ${baseIP clientNodeNum}")
599 with subtest("Test ping on vlan subinterface in setup"):
600 client.succeed("ping -I ${vlanInterface} -c 1 ${vlanIP serverNodeNum}")
601 server.succeed("ping -I ${vlanInterface} -c 1 ${vlanIP clientNodeNum}")
607 networking.useNetworkd = networkd;
608 networking.useDHCP = false;
609 networking.interfaces.tap0 = {
610 ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
611 ipv6.addresses = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ];
614 macAddress = "02:de:ad:be:ef:01";
616 networking.interfaces.tun0 = {
617 ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
618 ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ];
626 tap0: tap persist user 0
627 tun0: tun persist user 0
630 with subtest("Wait for networking to come up"):
632 machine.wait_for_unit("network.target")
634 with subtest("Test interfaces set up"):
635 list = machine.succeed("ip tuntap list | sort").strip()
639 The list of virtual interfaces does not match the expected one:
647 with subtest("Test MTU and MAC Address are configured"):
648 machine.wait_until_succeeds("ip link show dev tap0 | grep 'mtu 1342'")
649 machine.wait_until_succeeds("ip link show dev tun0 | grep 'mtu 1343'")
650 assert "02:de:ad:be:ef:01" in machine.succeed("ip link show dev tap0")
651 '' # network-addresses-* only exist in scripted networking
652 + lib.optionalString (!networkd) ''
653 with subtest("Test interfaces clean up"):
654 machine.succeed("systemctl stop network-addresses-tap0")
656 machine.succeed("systemctl stop network-addresses-tun0")
658 residue = machine.succeed("ip tuntap list")
661 ), "Some virtual interface has not been properly cleaned:\n{}".format(residue)
667 virtualisation.interfaces.enp1s0.vlan = 1;
668 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true;
670 useNetworkd = networkd;
672 interfaces.enp1s0.ipv6.addresses = lib.singleton {
673 address = "fd00:1234:5678:1::1";
683 AdvOtherConfigFlag on;
685 prefix fd00:1234:5678:1::/64 {
693 nodes.client_with_privacy = {
694 virtualisation.interfaces.enp1s0.vlan = 1;
696 useNetworkd = networkd;
698 interfaces.enp1s0 = {
699 tempAddress = "default";
700 ipv4.addresses = lib.mkOverride 0 [ ];
701 ipv6.addresses = lib.mkOverride 0 [ ];
707 virtualisation.interfaces.enp1s0.vlan = 1;
709 useNetworkd = networkd;
711 interfaces.enp1s0 = {
712 tempAddress = "enabled";
713 ipv4.addresses = lib.mkOverride 0 [ ];
714 ipv6.addresses = lib.mkOverride 0 [ ];
722 client.wait_for_unit("network.target")
723 client_with_privacy.wait_for_unit("network.target")
724 router.systemctl("start network-online.target")
725 router.wait_for_unit("network-online.target")
727 with subtest("Wait until we have an ip address"):
728 client_with_privacy.wait_until_succeeds(
729 "ip addr show dev enp1s0 | grep -q 'fd00:1234:5678:1:'"
731 client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q 'fd00:1234:5678:1:'")
733 with subtest("Test vlan 1"):
734 client_with_privacy.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1")
735 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1")
737 with subtest("Test address used is temporary"):
738 client_with_privacy.wait_until_succeeds(
739 "! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'"
742 with subtest("Test address used is EUI-64"):
743 client.wait_until_succeeds(
744 "ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'"
751 networking.useNetworkd = networkd;
752 networking.useDHCP = false;
753 networking.interfaces.eth0 = {
754 ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
755 ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ];
757 { address = "fdfd:b3f0::"; prefixLength = 48; }
758 { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; }
761 { address = "10.0.0.0"; prefixLength = 16; options = {
763 # Explicitly set scope because iproute and systemd-networkd
764 # disagree on what the scope should be
765 # if the type is the default "unicast"
768 { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; }
771 virtualisation.vlans = [ ];
776 "10.0.0.0/16 proto static scope link mtu 1500",
777 "192.168.1.0/24 proto kernel scope link src 192.168.1.2",
778 "192.168.2.0/24 via 192.168.1.1 proto static",
782 "2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium",
783 "2001:1470:fffd:2098::/64 via fdfd:b3f0::1 proto static metric 1024 pref medium",
784 "fdfd:b3f0::/48 proto static metric 1024 pref medium",
788 machine.wait_for_unit("network.target")
790 with subtest("test routing tables"):
791 ipv4Table = machine.succeed("ip -4 route list dev eth0 | head -n3").strip()
792 ipv6Table = machine.succeed("ip -6 route list dev eth0 | head -n3").strip()
794 l.strip() for l in ipv4Table.splitlines()
795 ] == targetIPv4Table, """
796 The IPv4 routing table does not match the expected one:
802 ipv4Table, targetIPv4Table
805 l.strip() for l in ipv6Table.splitlines()
806 ] == targetIPv6Table, """
807 The IPv6 routing table does not match the expected one:
813 ipv6Table, targetIPv6Table
816 '' + lib.optionalString (!networkd) ''
817 with subtest("test clean-up of the tables"):
818 machine.succeed("systemctl stop network-addresses-eth0")
819 ipv4Residue = machine.succeed("ip -4 route list dev eth0 | head -n-3").strip()
820 ipv6Residue = machine.succeed("ip -6 route list dev eth0 | head -n-3").strip()
823 ), "The IPv4 routing table has not been properly cleaned:\n{}".format(ipv4Residue)
826 ), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue)
829 rename = if networkd then {
830 name = "RenameInterface";
832 virtualisation.vlans = [ 1 ];
834 useNetworkd = networkd;
837 systemd.network.links."10-custom_name" = {
838 matchConfig.MACAddress = "52:54:00:12:01:01";
839 linkConfig.Name = "custom_name";
843 machine.succeed("udevadm settle")
844 print(machine.succeed("ip link show dev custom_name"))
847 name = "RenameInterface";
851 # even with disabled networkd, systemd.network.links should work
852 # (as it's handled by udev, not networkd)
856 virtualisation.vlans = [ 1 ];
858 useNetworkd = networkd;
861 systemd.network.links."50-foo" = {
866 linkConfig.MTUBytes = "1442";
870 print(client.succeed("ip l add name foo type dummy"))
871 print(client.succeed("stat /etc/systemd/network/50-foo.link"))
872 client.succeed("udevadm settle")
873 assert "mtu 1442" in client.succeed("ip l show dev foo")
877 testMac = "06:00:00:00:02:00";
879 name = "WlanInterface";
881 boot.kernelModules = [ "mac80211_hwsim" ];
882 networking.wlanInterfaces = {
883 wlan0 = { device = "wlan0"; };
884 wap0 = { device = "wlan0"; mac = testMac; };
889 machine.wait_for_unit("network.target")
890 machine.wait_until_succeeds("ip address show wap0 | grep -q ${testMac}")
891 machine.fail("ip address show wlan0 | grep -q ${testMac}")
894 naughtyInterfaceNames = let
896 # flags of ip-address
897 "home" "temporary" "optimistic"
898 "bridge_slave" "flush"
900 "up" "type" "nomaster" "address"
902 "very_loong_name" "lowerUpper" "-"
905 name = "naughtyInterfaceNames";
907 networking.useNetworkd = networkd;
908 networking.bridges = lib.listToAttrs
909 (lib.flip builtins.map ifnames
910 (name: { inherit name; value.interfaces = []; }));
914 machine.wait_for_unit("network.target")
915 for ifname in ${builtins.toJSON ifnames}:
916 machine.wait_until_succeeds(f"ip link show dev '{ifname}' | grep -q '{ifname}'")
919 caseSensitiveRenaming = {
920 name = "CaseSensitiveRenaming";
922 virtualisation.interfaces.enCustom.vlan = 11;
924 useNetworkd = networkd;
929 machine.succeed("udevadm settle")
930 print(machine.succeed("ip link show dev enCustom"))
931 machine.wait_until_succeeds("ip link show dev enCustom | grep -q 52:54:00:12:0b:01")
936 in lib.mapAttrs (lib.const (attrs: makeTest (attrs // {
937 name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}";