| 
									
										
										
										
											2017-03-06 13:23:45 +01:00
										 |  |  | { system ? builtins.currentSystem | 
					
						
							|  |  |  | # bool: whether to use networkd in the tests | 
					
						
							|  |  |  | , networkd }: | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | with import ../lib/testing.nix { inherit system; }; | 
					
						
							|  |  |  | with pkgs.lib; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  |   router = { config, pkgs, ... }: | 
					
						
							|  |  |  |     with pkgs.lib; | 
					
						
							|  |  |  |     let | 
					
						
							|  |  |  |       vlanIfs = range 1 (length config.virtualisation.vlans); | 
					
						
							|  |  |  |     in { | 
					
						
							|  |  |  |       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; | 
					
						
							|  |  |  |         firewall.allowPing = true; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |         firewall.checkReversePath = true; | 
					
						
							|  |  |  |         firewall.allowedUDPPorts = [ 547 ]; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: | 
					
						
							|  |  |  |           nameValuePair "eth${toString n}" { | 
					
						
							|  |  |  |             ipAddress = "192.168.${toString n}.1"; | 
					
						
							|  |  |  |             prefixLength = 24; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |             ipv6Address = "fd00:1234:5678:${toString n}::1"; | 
					
						
							|  |  |  |             ipv6PrefixLength = 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"; | 
					
						
							|  |  |  |       machine.networking.useNetworkd = networkd; | 
					
						
							|  |  |  |       testScript = ''
 | 
					
						
							|  |  |  |         startAll; | 
					
						
							|  |  |  |         $machine->waitForUnit("network.target"); | 
					
						
							|  |  |  |         $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); | 
					
						
							|  |  |  |         $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     static = { | 
					
						
							|  |  |  |       name = "Static"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							|  |  |  |       nodes.client = { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           defaultGateway = "192.168.1.1"; | 
					
						
							|  |  |  |           interfaces.eth1.ip4 = mkOverride 0 [ | 
					
						
							|  |  |  |             { address = "192.168.1.2"; prefixLength = 24; } | 
					
						
							|  |  |  |             { address = "192.168.1.3"; prefixLength = 32; } | 
					
						
							|  |  |  |             { address = "192.168.1.10"; prefixLength = 32; } | 
					
						
							|  |  |  |           ]; | 
					
						
							|  |  |  |           interfaces.eth2.ip4 = mkOverride 0 [ | 
					
						
							|  |  |  |             { address = "192.168.2.2"; prefixLength = 24; } | 
					
						
							|  |  |  |           ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2015-12-18 07:09:42 +01:00
										 |  |  |           startAll; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |           $client->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $router->waitForUnit("network.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Make sure dhcpcd is not started | 
					
						
							|  |  |  |           $client->fail("systemctl status dhcpcd.service"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test vlan 1 | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test vlan 2 | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test default gateway | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("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; | 
					
						
							|  |  |  |       nodes.client = { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           useDHCP = true; | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           interfaces.eth1 = { | 
					
						
							|  |  |  |             ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             ip6 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |           interfaces.eth2 = { | 
					
						
							|  |  |  |             ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             ip6 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           }; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           $client->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $router->waitForUnit("network.target"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Wait until we have an ip address on each interface | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'"); | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); | 
					
						
							| 
									
										
										
										
											2017-01-14 19:01:46 +03:00
										 |  |  |           $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q 'fd00:1234:5678:2:'"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Test vlan 1 | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							| 
									
										
										
										
											2017-02-15 11:05:50 +01:00
										 |  |  |           $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							| 
									
										
										
										
											2017-02-15 11:05:50 +01:00
										 |  |  |           $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Test vlan 2 | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); | 
					
						
							| 
									
										
										
										
											2017-02-15 11:05:50 +01:00
										 |  |  |           $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); | 
					
						
							| 
									
										
										
										
											2017-02-15 11:05:50 +01:00
										 |  |  |           $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     dhcpOneIf = { | 
					
						
							|  |  |  |       name = "OneInterfaceDHCP"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							|  |  |  |       nodes.client = { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           interfaces.eth1 = { | 
					
						
							|  |  |  |             ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |             useDHCP = true; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           interfaces.eth2.ip4 = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       }; | 
					
						
							|  |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Wait for networking to come up | 
					
						
							|  |  |  |           $client->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $router->waitForUnit("network.target"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Wait until we have an ip address on each interface | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Test vlan 1 | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           # Test vlan 2 | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); | 
					
						
							|  |  |  |           $client->fail("ping -c 1 192.168.2.2"); | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); | 
					
						
							|  |  |  |           $router->fail("ping -c 1 192.168.2.2"); | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     bond = let | 
					
						
							|  |  |  |       node = address: { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           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
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           interfaces.eth1.ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.eth2.ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.bond.ip4 = mkOverride 0 | 
					
						
							|  |  |  |             [ { 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"; | 
					
						
							|  |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Wait for networking to come up | 
					
						
							|  |  |  |           $client1->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $client2->waitForUnit("network.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test bonding | 
					
						
							|  |  |  |           $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); | 
					
						
							|  |  |  |           $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); | 
					
						
							|  |  |  |           $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     bridge = let | 
					
						
							|  |  |  |       node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ vlan ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           interfaces.eth1.ip4 = mkOverride 0 | 
					
						
							|  |  |  |             [ { 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; }; | 
					
						
							|  |  |  |       nodes.router = { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 2 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           bridges.bridge.interfaces = [ "eth1" "eth2" ]; | 
					
						
							|  |  |  |           interfaces.eth1.ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.eth2.ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.bridge.ip4 = mkOverride 0 | 
					
						
							|  |  |  |             [ { address = "192.168.1.1"; prefixLength = 24; } ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Wait for networking to come up | 
					
						
							|  |  |  |           $client1->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $client2->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $router->waitForUnit("network.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test bridging | 
					
						
							|  |  |  |           $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     macvlan = { | 
					
						
							|  |  |  |       name = "MACVLAN"; | 
					
						
							|  |  |  |       nodes.router = router; | 
					
						
							|  |  |  |       nodes.client = { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           useDHCP = true; | 
					
						
							|  |  |  |           macvlans.macvlan.interface = "eth1"; | 
					
						
							|  |  |  |           interfaces.eth1.ip4 = mkOverride 0 [ ]; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Wait for networking to come up | 
					
						
							|  |  |  |           $client->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $router->waitForUnit("network.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Wait until we have an ip address on each interface | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Print diagnosting information | 
					
						
							|  |  |  |           $router->succeed("ip addr >&2"); | 
					
						
							|  |  |  |           $client->succeed("ip addr >&2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test macvlan creates routable ips | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); | 
					
						
							|  |  |  |           $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     sit = let | 
					
						
							|  |  |  |       node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         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
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           interfaces.eth1.ip4 = mkOverride 0 | 
					
						
							|  |  |  |             [ { address = address4; prefixLength = 24; } ]; | 
					
						
							|  |  |  |           interfaces.sit.ip6 = mkOverride 0 | 
					
						
							|  |  |  |             [ { 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"; }; | 
					
						
							|  |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Wait for networking to be configured | 
					
						
							|  |  |  |           $client1->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $client2->waitForUnit("network.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Print diagnostic information | 
					
						
							|  |  |  |           $client1->succeed("ip addr >&2"); | 
					
						
							|  |  |  |           $client2->succeed("ip addr >&2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test ipv6 | 
					
						
							| 
									
										
										
										
											2017-02-15 11:05:50 +01:00
										 |  |  |           $client1->waitUntilSucceeds("ping -c 1 fc00::1"); | 
					
						
							|  |  |  |           $client1->waitUntilSucceeds("ping -c 1 fc00::2"); | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-15 11:05:50 +01:00
										 |  |  |           $client2->waitUntilSucceeds("ping -c 1 fc00::1"); | 
					
						
							|  |  |  |           $client2->waitUntilSucceeds("ping -c 1 fc00::2"); | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     vlan = let | 
					
						
							|  |  |  |       node = address: { config, pkgs, ... }: with pkgs.lib; { | 
					
						
							|  |  |  |         #virtualisation.vlans = [ 1 ]; | 
					
						
							|  |  |  |         networking = { | 
					
						
							|  |  |  |           useNetworkd = networkd; | 
					
						
							|  |  |  |           firewall.allowPing = true; | 
					
						
							|  |  |  |           useDHCP = false; | 
					
						
							|  |  |  |           vlans.vlan = { | 
					
						
							|  |  |  |             id = 1; | 
					
						
							|  |  |  |             interface = "eth0"; | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |           }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |           interfaces.eth0.ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.eth1.ip4 = mkOverride 0 [ ]; | 
					
						
							|  |  |  |           interfaces.vlan.ip4 = mkOverride 0 | 
					
						
							|  |  |  |             [ { 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"; | 
					
						
							|  |  |  |       testScript = { nodes, ... }: | 
					
						
							|  |  |  |         ''
 | 
					
						
							|  |  |  |           startAll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Wait for networking to be configured | 
					
						
							|  |  |  |           $client1->waitForUnit("network.target"); | 
					
						
							|  |  |  |           $client2->waitForUnit("network.target"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           # Test vlan is setup | 
					
						
							|  |  |  |           $client1->succeed("ip addr show dev vlan >&2"); | 
					
						
							|  |  |  |           $client2->succeed("ip addr show dev vlan >&2"); | 
					
						
							|  |  |  |         '';
 | 
					
						
							| 
									
										
										
										
											2014-11-25 15:40:49 -08:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:55 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in mapAttrs (const (attrs: makeTest (attrs // { | 
					
						
							|  |  |  |   name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; | 
					
						
							|  |  |  |   meta = with pkgs.stdenv.lib.maintainers; { | 
					
						
							|  |  |  |     maintainers = [ wkennington ]; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }))) testCases |