| 
									
										
										
										
											2017-03-06 13:23:45 +01:00
										 |  |  | { system ? builtins.currentSystem | 
					
						
							| 
									
										
										
										
											2018-11-11 17:41:11 +09:00
										 |  |  | , config ? {} | 
					
						
							| 
									
										
										
										
											2018-11-12 16:18:58 +01:00
										 |  |  | , pkgs ? import ../.. { inherit system config; } | 
					
						
							| 
									
										
										
										
											2017-03-06 13:23:45 +01:00
										 |  |  | # bool: whether to use networkd in the tests | 
					
						
							|  |  |  | , networkd }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  | with import ../lib/testing-python.nix { inherit system pkgs; }; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  | with pkgs.lib; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |   router = { config, pkgs, ... }: | 
					
						
							|  |  |  |     with pkgs.lib; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |     let | 
					
						
							|  |  |  |       vlanIfs = range 1 (length config.virtualisation.vlans); | 
					
						
							|  |  |  |     in { | 
					
						
							| 
									
										
										
										
											2018-09-02 12:13:06 +02:00
										 |  |  |       environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       virtualisation.vlans = [ 1 2 3 ]; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |       boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       networking = { | 
					
						
							|  |  |  |         useDHCP = false; | 
					
						
							|  |  |  |         useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |         firewall.checkReversePath = true; | 
					
						
							|  |  |  |         firewall.allowedUDPPorts = [ 547 ]; | 
					
						
							| 
									
										
										
										
											2019-08-05 14:03:38 +03:00
										 |  |  |         interfaces = mkOverride 0 (listToAttrs (forEach vlanIfs (n: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           nameValuePair "eth${toString n}" { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:14:54 +01:00
										 |  |  |             ipv4.addresses = [ { address = "192.168.${toString n}.1"; prefixLength = 24; } ]; | 
					
						
							|  |  |  |             ipv6.addresses = [ { address = "fd00:1234:5678:${toString n}::1"; prefixLength = 64; } ]; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           }))); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |       services.dhcpd4 = { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         enable = true; | 
					
						
							|  |  |  |         interfaces = map (n: "eth${toString n}") vlanIfs; | 
					
						
							|  |  |  |         extraConfig = ''
 | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           authoritative; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '' + flip concatMapStrings vlanIfs (n: '' | 
					
						
							|  |  |  |           subnet 192.168.${toString n}.0 netmask 255.255.255.0 { | 
					
						
							|  |  |  |             option routers 192.168.${toString n}.1; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |             # XXX: technically it's _not guaranteed_ that IP addresses will be | 
					
						
							|  |  |  |             # issued from the first item in range onwards! We assume that in | 
					
						
							|  |  |  |             # our tests however. | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             range 192.168.${toString n}.2 192.168.${toString n}.254; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         '');
 | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |       services.radvd = { | 
					
						
							|  |  |  |         enable = true; | 
					
						
							|  |  |  |         config = flip concatMapStrings vlanIfs (n: ''
 | 
					
						
							|  |  |  |           interface eth${toString n} { | 
					
						
							|  |  |  |             AdvSendAdvert on; | 
					
						
							|  |  |  |             AdvManagedFlag on; | 
					
						
							|  |  |  |             AdvOtherConfigFlag on; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             prefix fd00:1234:5678:${toString n}::/64 { | 
					
						
							|  |  |  |               AdvAutonomous off; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         '');
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       services.dhcpd6 = { | 
					
						
							|  |  |  |         enable = true; | 
					
						
							|  |  |  |         interfaces = map (n: "eth${toString n}") vlanIfs; | 
					
						
							|  |  |  |         extraConfig = ''
 | 
					
						
							|  |  |  |           authoritative; | 
					
						
							|  |  |  |         '' + flip concatMapStrings vlanIfs (n: '' | 
					
						
							|  |  |  |           subnet6 fd00:1234:5678:${toString n}::/64 { | 
					
						
							|  |  |  |             range6 fd00:1234:5678:${toString n}::2 fd00:1234:5678:${toString n}::2; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         '');
 | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   testCases = { | 
					
						
							|  |  |  |     loopback = { | 
					
						
							|  |  |  |       name = "Loopback"; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |       machine.networking.useDHCP = false; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       machine.networking.useNetworkd = networkd; | 
					
						
							|  |  |  |       testScript = ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |         start_all() | 
					
						
							|  |  |  |         machine.wait_for_unit("network.target") | 
					
						
							|  |  |  |         loopback_addresses = machine.succeed("ip addr show lo") | 
					
						
							|  |  |  |         assert "inet 127.0.0.1/8" in loopback_addresses | 
					
						
							|  |  |  |         assert "inet6 ::1/128" in loopback_addresses | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     static = { | 
					
						
							|  |  |  |       name = "Static"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.client = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           defaultGateway = "192.168.1.1"; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth1.ipv4.addresses = mkOverride 0 [ | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             { address = "192.168.1.2"; prefixLength = 24; } | 
					
						
							|  |  |  |             { address = "192.168.1.3"; prefixLength = 32; } | 
					
						
							|  |  |  |             { address = "192.168.1.10"; prefixLength = 32; } | 
					
						
							|  |  |  |           ]; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth2.ipv4.addresses = mkOverride 0 [ | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             { address = "192.168.2.2"; prefixLength = 24; } | 
					
						
							|  |  |  |           ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           client.wait_for_unit("network.target") | 
					
						
							|  |  |  |           router.wait_for_unit("network-online.target") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Make sure dhcpcd is not started"): | 
					
						
							|  |  |  |               client.fail("systemctl status dhcpcd.service") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test vlan 1"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.10") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.10") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test vlan 2"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.2.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.2.2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               router.wait_until_succeeds("ping -c 1 192.168.2.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.2.2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test default gateway"): | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.3.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.3.1") | 
					
						
							| 
									
										
										
										
											2015-12-18 07:09:42 +01:00
										 |  |  |         '';
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  |     dhcpSimple = { | 
					
						
							|  |  |  |       name = "SimpleDHCP"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.client = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |           useDHCP = false; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           interfaces.eth1 = { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |             ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             ipv6.addresses = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |             useDHCP = true; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           }; | 
					
						
							|  |  |  |           interfaces.eth2 = { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |             ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             ipv6.addresses = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |             useDHCP = true; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           client.wait_for_unit("network.target") | 
					
						
							|  |  |  |           router.wait_for_unit("network-online.target") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Wait until we have an ip address on each interface"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth2 | grep -q '192.168.2'") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth2 | grep -q 'fd00:1234:5678:2:'") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Test vlan 1"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Test vlan 2"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.2.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.2.2") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.2.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.2.2") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     dhcpOneIf = { | 
					
						
							|  |  |  |       name = "OneInterfaceDHCP"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.client = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           interfaces.eth1 = { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |             ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2020-04-13 19:17:56 +02:00
										 |  |  |             mtu = 1343; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             useDHCP = true; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Wait for networking to come up"): | 
					
						
							|  |  |  |               client.wait_for_unit("network.target") | 
					
						
							|  |  |  |               router.wait_for_unit("network.target") | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Wait until we have an ip address on each interface"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 19:17:56 +02:00
										 |  |  |           with subtest("ensure MTU is set"): | 
					
						
							|  |  |  |               assert "mtu 1343" in client.succeed("ip link show dev eth1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test vlan 1"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test vlan 2"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.2.1") | 
					
						
							|  |  |  |               client.fail("ping -c 1 192.168.2.2") | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               router.wait_until_succeeds("ping -c 1 192.168.2.1") | 
					
						
							|  |  |  |               router.fail("ping -c 1 192.168.2.2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     bond = let | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       node = address: { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           bonds.bond = { | 
					
						
							|  |  |  |             interfaces = [ "eth1" "eth2" ]; | 
					
						
							| 
									
										
										
										
											2017-02-02 22:21:03 +01:00
										 |  |  |             driverOptions.mode = "balance-rr"; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.bond.ipv4.addresses = mkOverride 0 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             [ { inherit address; prefixLength = 30; } ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |     in { | 
					
						
							|  |  |  |       name = "Bond"; | 
					
						
							|  |  |  |       nodes.client1 = node "192.168.1.1"; | 
					
						
							|  |  |  |       nodes.client2 = node "192.168.1.2"; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Wait for networking to come up"): | 
					
						
							|  |  |  |               client1.wait_for_unit("network.target") | 
					
						
							|  |  |  |               client2.wait_for_unit("network.target") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test bonding"): | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 2 192.168.1.1") | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 2 192.168.1.2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               client2.wait_until_succeeds("ping -c 2 192.168.1.1") | 
					
						
							|  |  |  |               client2.wait_until_succeeds("ping -c 2 192.168.1.2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     bridge = let | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       node = { address, vlan }: { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ vlan ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth1.ipv4.addresses = mkOverride 0 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             [ { inherit address; prefixLength = 24; } ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       }; | 
					
						
							|  |  |  |     in { | 
					
						
							|  |  |  |       name = "Bridge"; | 
					
						
							|  |  |  |       nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; | 
					
						
							|  |  |  |       nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.router = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           bridges.bridge.interfaces = [ "eth1" "eth2" ]; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.bridge.ipv4.addresses = mkOverride 0 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             [ { address = "192.168.1.1"; prefixLength = 24; } ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Wait for networking to come up"): | 
					
						
							|  |  |  |               for machine in client1, client2, router: | 
					
						
							|  |  |  |                   machine.wait_for_unit("network.target") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test bridging"): | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               client2.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               client2.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               client2.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     macvlan = { | 
					
						
							|  |  |  |       name = "MACVLAN"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.client = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2018-09-02 12:13:06 +02:00
										 |  |  |         environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |           useDHCP = false; | 
					
						
							| 
									
										
										
										
											2018-09-02 12:13:06 +02:00
										 |  |  |           firewall.logReversePathDrops = true; # to debug firewall rules | 
					
						
							|  |  |  |           # reverse path filtering rules for the macvlan interface seem | 
					
						
							|  |  |  |           # to be incorrect, causing the test to fail. Disable temporarily. | 
					
						
							|  |  |  |           firewall.checkReversePath = false; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           macvlans.macvlan.interface = "eth1"; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |           interfaces.eth1 = { | 
					
						
							|  |  |  |             ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             useDHCP = true; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |           interfaces.macvlan = { | 
					
						
							|  |  |  |             useDHCP = true; | 
					
						
							|  |  |  |           }; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Wait for networking to come up"): | 
					
						
							|  |  |  |               client.wait_for_unit("network.target") | 
					
						
							|  |  |  |               router.wait_for_unit("network.target") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Wait until we have an ip address on each interface"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev macvlan | grep -q '192.168.1'") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Print lots of diagnostic information"): | 
					
						
							|  |  |  |               router.log("**********************************************") | 
					
						
							|  |  |  |               router.succeed("ip addr >&2") | 
					
						
							|  |  |  |               router.succeed("ip route >&2") | 
					
						
							|  |  |  |               router.execute("iptables-save >&2") | 
					
						
							|  |  |  |               client.log("==============================================") | 
					
						
							|  |  |  |               client.succeed("ip addr >&2") | 
					
						
							|  |  |  |               client.succeed("ip route >&2") | 
					
						
							|  |  |  |               client.execute("iptables-save >&2") | 
					
						
							|  |  |  |               client.log("##############################################") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Test macvlan creates routable ips"): | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.1") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.2") | 
					
						
							|  |  |  |               router.wait_until_succeeds("ping -c 1 192.168.1.3") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     sit = let | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       node = { address4, remote, address6 }: { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.enable = false; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           sits.sit = { | 
					
						
							|  |  |  |             inherit remote; | 
					
						
							|  |  |  |             local = address4; | 
					
						
							|  |  |  |             dev = "eth1"; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth1.ipv4.addresses = mkOverride 0 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             [ { address = address4; prefixLength = 24; } ]; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.sit.ipv6.addresses = mkOverride 0 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             [ { address = address6; prefixLength = 64; } ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |     in { | 
					
						
							|  |  |  |       name = "Sit"; | 
					
						
							|  |  |  |       nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; | 
					
						
							|  |  |  |       nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Wait for networking to be configured"): | 
					
						
							|  |  |  |               client1.wait_for_unit("network.target") | 
					
						
							|  |  |  |               client2.wait_for_unit("network.target") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               # Print diagnostic information | 
					
						
							|  |  |  |               client1.succeed("ip addr >&2") | 
					
						
							|  |  |  |               client2.succeed("ip addr >&2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test ipv6"): | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 1 fc00::1") | 
					
						
							|  |  |  |               client1.wait_until_succeeds("ping -c 1 fc00::2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               client2.wait_until_succeeds("ping -c 1 fc00::1") | 
					
						
							|  |  |  |               client2.wait_until_succeeds("ping -c 1 fc00::2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     vlan = let | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       node = address: { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         #virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           vlans.vlan = { | 
					
						
							|  |  |  |             id = 1; | 
					
						
							|  |  |  |             interface = "eth0"; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           interfaces.eth0.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.vlan.ipv4.addresses = mkOverride 0 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |             [ { inherit address; prefixLength = 24; } ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |     in { | 
					
						
							|  |  |  |       name = "vlan"; | 
					
						
							|  |  |  |       nodes.client1 = node "192.168.1.1"; | 
					
						
							|  |  |  |       nodes.client2 = node "192.168.1.2"; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Wait for networking to be configured"): | 
					
						
							|  |  |  |               client1.wait_for_unit("network.target") | 
					
						
							|  |  |  |               client2.wait_for_unit("network.target") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           with subtest("Test vlan is setup"): | 
					
						
							|  |  |  |               client1.succeed("ip addr show dev vlan >&2") | 
					
						
							|  |  |  |               client2.succeed("ip addr show dev vlan >&2") | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-01-31 05:52:22 +01:00
										 |  |  |     virtual = { | 
					
						
							|  |  |  |       name = "Virtual"; | 
					
						
							|  |  |  |       machine = { | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |         networking.useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2019-10-08 17:09:05 +02:00
										 |  |  |         networking.useDHCP = false; | 
					
						
							| 
									
										
										
										
											2019-08-13 21:52:01 +00:00
										 |  |  |         networking.interfaces.tap0 = { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:14:54 +01:00
										 |  |  |           ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ]; | 
					
						
							|  |  |  |           ipv6.addresses = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ]; | 
					
						
							| 
									
										
										
										
											2018-01-31 05:52:22 +01:00
										 |  |  |           virtual = true; | 
					
						
							| 
									
										
										
										
											2020-04-13 19:17:56 +02:00
										 |  |  |           mtu = 1342; | 
					
						
							|  |  |  |           macAddress = "02:de:ad:be:ef:01"; | 
					
						
							| 
									
										
										
										
											2018-01-31 05:52:22 +01:00
										 |  |  |         }; | 
					
						
							| 
									
										
										
										
											2019-08-13 21:52:01 +00:00
										 |  |  |         networking.interfaces.tun0 = { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:14:54 +01:00
										 |  |  |           ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; | 
					
						
							|  |  |  |           ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ]; | 
					
						
							| 
									
										
										
										
											2018-01-31 05:52:22 +01:00
										 |  |  |           virtual = true; | 
					
						
							| 
									
										
										
										
											2020-04-13 19:17:56 +02:00
										 |  |  |           mtu = 1343; | 
					
						
							| 
									
										
										
										
											2018-01-31 05:52:22 +01:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       testScript = ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |         targetList = """
 | 
					
						
							| 
									
										
										
										
											2018-08-26 14:24:07 +02:00
										 |  |  |         tap0: tap persist user 0 | 
					
						
							|  |  |  |         tun0: tun persist user 0 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |         """.strip()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with subtest("Wait for networking to come up"): | 
					
						
							|  |  |  |             machine.start() | 
					
						
							| 
									
										
										
										
											2020-04-13 19:15:08 +02:00
										 |  |  |             machine.wait_for_unit("network.target") | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         with subtest("Test interfaces set up"): | 
					
						
							|  |  |  |             list = machine.succeed("ip tuntap list | sort").strip() | 
					
						
							|  |  |  |             assert ( | 
					
						
							|  |  |  |                 list == targetList | 
					
						
							|  |  |  |             ), """
 | 
					
						
							|  |  |  |             The list of virtual interfaces does not match the expected one: | 
					
						
							|  |  |  |             Result: | 
					
						
							|  |  |  |               {} | 
					
						
							|  |  |  |             Expected: | 
					
						
							|  |  |  |               {} | 
					
						
							|  |  |  |             """.format(
 | 
					
						
							|  |  |  |                 list, targetList | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2020-04-13 19:17:56 +02:00
										 |  |  |         with subtest("Test MTU and MAC Address are configured"): | 
					
						
							|  |  |  |             assert "mtu 1342" in machine.succeed("ip link show dev tap0") | 
					
						
							|  |  |  |             assert "mtu 1343" in machine.succeed("ip link show dev tun0") | 
					
						
							|  |  |  |             assert "02:de:ad:be:ef:01" in machine.succeed("ip link show dev tap0") | 
					
						
							| 
									
										
										
										
											2020-04-13 19:15:08 +02:00
										 |  |  |       '' # network-addresses-* only exist in scripted networking
 | 
					
						
							|  |  |  |       + optionalString (!networkd) ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |         with subtest("Test interfaces clean up"): | 
					
						
							|  |  |  |             machine.succeed("systemctl stop network-addresses-tap0") | 
					
						
							|  |  |  |             machine.sleep(10) | 
					
						
							|  |  |  |             machine.succeed("systemctl stop network-addresses-tun0") | 
					
						
							|  |  |  |             machine.sleep(10) | 
					
						
							|  |  |  |             residue = machine.succeed("ip tuntap list") | 
					
						
							|  |  |  |             assert ( | 
					
						
							|  |  |  |                 residue is "" | 
					
						
							|  |  |  |             ), "Some virtual interface has not been properly cleaned:\n{}".format(residue) | 
					
						
							| 
									
										
										
										
											2018-01-31 05:52:22 +01:00
										 |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |     privacy = { | 
					
						
							|  |  |  |       name = "Privacy"; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       nodes.router = { ... }: { | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |           useDHCP = false; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:14:54 +01:00
										 |  |  |           interfaces.eth1.ipv6.addresses = singleton { | 
					
						
							|  |  |  |             address = "fd00:1234:5678:1::1"; | 
					
						
							|  |  |  |             prefixLength = 64; | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         services.radvd = { | 
					
						
							|  |  |  |           enable = true; | 
					
						
							|  |  |  |           config = ''
 | 
					
						
							|  |  |  |             interface eth1 { | 
					
						
							|  |  |  |               AdvSendAdvert on; | 
					
						
							|  |  |  |               AdvManagedFlag on; | 
					
						
							|  |  |  |               AdvOtherConfigFlag on; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               prefix fd00:1234:5678:1::/64 { | 
					
						
							|  |  |  |                 AdvAutonomous on; | 
					
						
							|  |  |  |                 AdvOnLink on; | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.client_with_privacy = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |           useDHCP = false; | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |           interfaces.eth1 = { | 
					
						
							| 
									
										
										
										
											2020-01-30 11:57:09 +01:00
										 |  |  |             tempAddress = "default"; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:14:54 +01:00
										 |  |  |             ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             ipv6.addresses = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |             useDHCP = true; | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  |       nodes.client = { pkgs, ... }: with pkgs.lib; { | 
					
						
							| 
									
										
										
										
											2019-07-09 08:06:52 +02:00
										 |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |           useDHCP = false; | 
					
						
							| 
									
										
										
										
											2019-07-09 08:06:52 +02:00
										 |  |  |           interfaces.eth1 = { | 
					
						
							| 
									
										
										
										
											2020-01-30 11:57:09 +01:00
										 |  |  |             tempAddress = "enabled"; | 
					
						
							| 
									
										
										
										
											2019-07-09 08:06:52 +02:00
										 |  |  |             ipv4.addresses = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             ipv6.addresses = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:37:58 +02:00
										 |  |  |             useDHCP = true; | 
					
						
							| 
									
										
										
										
											2019-07-09 08:06:52 +02:00
										 |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |       testScript = { ... }: | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |           start_all() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           client.wait_for_unit("network.target") | 
					
						
							|  |  |  |           client_with_privacy.wait_for_unit("network.target") | 
					
						
							|  |  |  |           router.wait_for_unit("network-online.target") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Wait until we have an ip address"): | 
					
						
							|  |  |  |               client_with_privacy.wait_until_succeeds( | 
					
						
							|  |  |  |                   "ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'" | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |               client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Test vlan 1"): | 
					
						
							|  |  |  |               client_with_privacy.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") | 
					
						
							|  |  |  |               client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Test address used is temporary"): | 
					
						
							|  |  |  |               client_with_privacy.wait_until_succeeds( | 
					
						
							|  |  |  |                   "! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'" | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           with subtest("Test address used is EUI-64"): | 
					
						
							|  |  |  |               client.wait_until_succeeds( | 
					
						
							|  |  |  |                   "ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'" | 
					
						
							|  |  |  |               ) | 
					
						
							| 
									
										
										
										
											2018-02-01 15:50:35 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-07-28 16:45:58 +02:00
										 |  |  |     routes = { | 
					
						
							|  |  |  |       name = "routes"; | 
					
						
							|  |  |  |       machine = { | 
					
						
							|  |  |  |         networking.useDHCP = false; | 
					
						
							| 
									
										
										
										
											2019-08-13 21:52:01 +00:00
										 |  |  |         networking.interfaces.eth0 = { | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; | 
					
						
							|  |  |  |           ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ]; | 
					
						
							|  |  |  |           ipv6.routes = [ | 
					
						
							| 
									
										
										
										
											2017-07-28 16:45:58 +02:00
										 |  |  |             { address = "fdfd:b3f0::"; prefixLength = 48; } | 
					
						
							|  |  |  |             { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; } | 
					
						
							|  |  |  |           ]; | 
					
						
							| 
									
										
										
										
											2017-12-03 05:13:14 +01:00
										 |  |  |           ipv4.routes = [ | 
					
						
							| 
									
										
										
										
											2017-07-28 16:45:58 +02:00
										 |  |  |             { address = "10.0.0.0"; prefixLength = 16; options = { mtu = "1500"; }; } | 
					
						
							|  |  |  |             { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; } | 
					
						
							|  |  |  |           ]; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         virtualisation.vlans = [ ]; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       testScript = ''
 | 
					
						
							| 
									
										
										
										
											2020-04-13 19:16:12 +02:00
										 |  |  |         targetIPv4Table = [ | 
					
						
							|  |  |  |             "10.0.0.0/16 proto static scope link mtu 1500", | 
					
						
							|  |  |  |             "192.168.1.0/24 proto kernel scope link src 192.168.1.2", | 
					
						
							|  |  |  |             "192.168.2.0/24 via 192.168.1.1 proto static", | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         targetIPv6Table = [ | 
					
						
							|  |  |  |             "2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium", | 
					
						
							|  |  |  |             "2001:1470:fffd:2098::/64 via fdfd:b3f0::1 proto static metric 1024 pref medium", | 
					
						
							|  |  |  |             "fdfd:b3f0::/48 proto static metric 1024 pref medium", | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         machine.start() | 
					
						
							|  |  |  |         machine.wait_for_unit("network.target") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with subtest("test routing tables"): | 
					
						
							|  |  |  |             ipv4Table = machine.succeed("ip -4 route list dev eth0 | head -n3").strip() | 
					
						
							|  |  |  |             ipv6Table = machine.succeed("ip -6 route list dev eth0 | head -n3").strip() | 
					
						
							| 
									
										
										
										
											2020-04-13 19:16:12 +02:00
										 |  |  |             assert [ | 
					
						
							|  |  |  |                 l.strip() for l in ipv4Table.splitlines() | 
					
						
							|  |  |  |             ] == targetIPv4Table, """
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               The IPv4 routing table does not match the expected one: | 
					
						
							|  |  |  |                 Result: | 
					
						
							|  |  |  |                   {} | 
					
						
							|  |  |  |                 Expected: | 
					
						
							|  |  |  |                   {} | 
					
						
							|  |  |  |               """.format(
 | 
					
						
							|  |  |  |                 ipv4Table, targetIPv4Table | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2020-04-13 19:16:12 +02:00
										 |  |  |             assert [ | 
					
						
							|  |  |  |                 l.strip() for l in ipv6Table.splitlines() | 
					
						
							|  |  |  |             ] == targetIPv6Table, """
 | 
					
						
							| 
									
										
										
										
											2019-12-15 22:21:17 +01:00
										 |  |  |               The IPv6 routing table does not match the expected one: | 
					
						
							|  |  |  |                 Result: | 
					
						
							|  |  |  |                   {} | 
					
						
							|  |  |  |                 Expected: | 
					
						
							|  |  |  |                   {} | 
					
						
							|  |  |  |               """.format(
 | 
					
						
							|  |  |  |                 ipv6Table, targetIPv6Table | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with subtest("test clean-up of the tables"): | 
					
						
							|  |  |  |             machine.succeed("systemctl stop network-addresses-eth0") | 
					
						
							|  |  |  |             ipv4Residue = machine.succeed("ip -4 route list dev eth0 | head -n-3").strip() | 
					
						
							|  |  |  |             ipv6Residue = machine.succeed("ip -6 route list dev eth0 | head -n-3").strip() | 
					
						
							|  |  |  |             assert ( | 
					
						
							|  |  |  |                 ipv4Residue is "" | 
					
						
							|  |  |  |             ), "The IPv4 routing table has not been properly cleaned:\n{}".format(ipv4Residue) | 
					
						
							|  |  |  |             assert ( | 
					
						
							|  |  |  |                 ipv6Residue is "" | 
					
						
							|  |  |  |             ), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue) | 
					
						
							| 
									
										
										
										
											2017-07-28 16:45:58 +02:00
										 |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-03-11 00:24:50 +01:00
										 |  |  |     # even with disabled networkd, systemd.network.links should work | 
					
						
							|  |  |  |     # (as it's handled by udev, not networkd) | 
					
						
							|  |  |  |     link = { | 
					
						
							|  |  |  |       name = "Link"; | 
					
						
							|  |  |  |       nodes.client = { pkgs, ... }: { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         systemd.network.links."50-foo" = { | 
					
						
							|  |  |  |           matchConfig = { | 
					
						
							|  |  |  |             Name = "foo"; | 
					
						
							|  |  |  |             Driver = "dummy"; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |           linkConfig.MTUBytes = "1442"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       testScript = ''
 | 
					
						
							|  |  |  |         print(client.succeed("ip l add name foo type dummy")) | 
					
						
							|  |  |  |         print(client.succeed("stat /etc/systemd/network/50-foo.link")) | 
					
						
							|  |  |  |         client.succeed("udevadm settle") | 
					
						
							|  |  |  |         assert "mtu 1442" in client.succeed("ip l show dummy0") | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-13 21:47:07 +01:00
										 |  |  | in mapAttrs (const (attrs: makeTest (attrs // { | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |   name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; | 
					
						
							|  |  |  | }))) testCases |