at 17.09-beta 16 kB view raw
1{ system ? builtins.currentSystem 2# bool: whether to use networkd in the tests 3, networkd }: 4 5with import ../lib/testing.nix { inherit system; }; 6with pkgs.lib; 7 8let 9 router = { config, pkgs, ... }: 10 with pkgs.lib; 11 let 12 vlanIfs = range 1 (length config.virtualisation.vlans); 13 in { 14 virtualisation.vlans = [ 1 2 3 ]; 15 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; 16 networking = { 17 useDHCP = false; 18 useNetworkd = networkd; 19 firewall.allowPing = true; 20 firewall.checkReversePath = true; 21 firewall.allowedUDPPorts = [ 547 ]; 22 interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: 23 nameValuePair "eth${toString n}" { 24 ipAddress = "192.168.${toString n}.1"; 25 prefixLength = 24; 26 ipv6Address = "fd00:1234:5678:${toString n}::1"; 27 ipv6PrefixLength = 64; 28 }))); 29 }; 30 services.dhcpd4 = { 31 enable = true; 32 interfaces = map (n: "eth${toString n}") vlanIfs; 33 extraConfig = '' 34 authoritative; 35 '' + flip concatMapStrings vlanIfs (n: '' 36 subnet 192.168.${toString n}.0 netmask 255.255.255.0 { 37 option routers 192.168.${toString n}.1; 38 # XXX: technically it's _not guaranteed_ that IP addresses will be 39 # issued from the first item in range onwards! We assume that in 40 # our tests however. 41 range 192.168.${toString n}.2 192.168.${toString n}.254; 42 } 43 ''); 44 }; 45 services.radvd = { 46 enable = true; 47 config = flip concatMapStrings vlanIfs (n: '' 48 interface eth${toString n} { 49 AdvSendAdvert on; 50 AdvManagedFlag on; 51 AdvOtherConfigFlag on; 52 53 prefix fd00:1234:5678:${toString n}::/64 { 54 AdvAutonomous off; 55 }; 56 }; 57 ''); 58 }; 59 services.dhcpd6 = { 60 enable = true; 61 interfaces = map (n: "eth${toString n}") vlanIfs; 62 extraConfig = '' 63 authoritative; 64 '' + flip concatMapStrings vlanIfs (n: '' 65 subnet6 fd00:1234:5678:${toString n}::/64 { 66 range6 fd00:1234:5678:${toString n}::2 fd00:1234:5678:${toString n}::2; 67 } 68 ''); 69 }; 70 }; 71 72 testCases = { 73 loopback = { 74 name = "Loopback"; 75 machine.networking.useNetworkd = networkd; 76 testScript = '' 77 startAll; 78 $machine->waitForUnit("network.target"); 79 $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); 80 $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); 81 ''; 82 }; 83 static = { 84 name = "Static"; 85 nodes.router = router; 86 nodes.client = { config, pkgs, ... }: with pkgs.lib; { 87 virtualisation.vlans = [ 1 2 ]; 88 networking = { 89 useNetworkd = networkd; 90 firewall.allowPing = true; 91 useDHCP = false; 92 defaultGateway = "192.168.1.1"; 93 interfaces.eth1.ip4 = mkOverride 0 [ 94 { address = "192.168.1.2"; prefixLength = 24; } 95 { address = "192.168.1.3"; prefixLength = 32; } 96 { address = "192.168.1.10"; prefixLength = 32; } 97 ]; 98 interfaces.eth2.ip4 = mkOverride 0 [ 99 { address = "192.168.2.2"; prefixLength = 24; } 100 ]; 101 }; 102 }; 103 testScript = { nodes, ... }: 104 '' 105 startAll; 106 107 $client->waitForUnit("network.target"); 108 $router->waitForUnit("network.target"); 109 110 # Make sure dhcpcd is not started 111 $client->fail("systemctl status dhcpcd.service"); 112 113 # Test vlan 1 114 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 115 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 116 $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 117 $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); 118 119 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 120 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 121 $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 122 $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); 123 124 # Test vlan 2 125 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 126 $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 127 128 $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 129 $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 130 131 # Test default gateway 132 $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); 133 $client->waitUntilSucceeds("ping -c 1 192.168.3.1"); 134 ''; 135 }; 136 dhcpSimple = { 137 name = "SimpleDHCP"; 138 nodes.router = router; 139 nodes.client = { config, pkgs, ... }: with pkgs.lib; { 140 virtualisation.vlans = [ 1 2 ]; 141 networking = { 142 useNetworkd = networkd; 143 firewall.allowPing = true; 144 useDHCP = true; 145 interfaces.eth1 = { 146 ip4 = mkOverride 0 [ ]; 147 ip6 = mkOverride 0 [ ]; 148 }; 149 interfaces.eth2 = { 150 ip4 = mkOverride 0 [ ]; 151 ip6 = mkOverride 0 [ ]; 152 }; 153 }; 154 }; 155 testScript = { nodes, ... }: 156 '' 157 startAll; 158 159 $client->waitForUnit("network.target"); 160 $router->waitForUnit("network.target"); 161 162 # Wait until we have an ip address on each interface 163 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 164 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'"); 165 $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); 166 $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q 'fd00:1234:5678:2:'"); 167 168 # Test vlan 1 169 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 170 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 171 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); 172 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); 173 174 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 175 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 176 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); 177 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); 178 179 # Test vlan 2 180 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 181 $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 182 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); 183 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); 184 185 $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 186 $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 187 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); 188 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); 189 ''; 190 }; 191 dhcpOneIf = { 192 name = "OneInterfaceDHCP"; 193 nodes.router = router; 194 nodes.client = { config, pkgs, ... }: with pkgs.lib; { 195 virtualisation.vlans = [ 1 2 ]; 196 networking = { 197 useNetworkd = networkd; 198 firewall.allowPing = true; 199 useDHCP = false; 200 interfaces.eth1 = { 201 ip4 = mkOverride 0 [ ]; 202 useDHCP = true; 203 }; 204 interfaces.eth2.ip4 = mkOverride 0 [ ]; 205 }; 206 }; 207 testScript = { nodes, ... }: 208 '' 209 startAll; 210 211 # Wait for networking to come up 212 $client->waitForUnit("network.target"); 213 $router->waitForUnit("network.target"); 214 215 # Wait until we have an ip address on each interface 216 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 217 218 # Test vlan 1 219 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 220 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 221 222 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 223 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 224 225 # Test vlan 2 226 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 227 $client->fail("ping -c 1 192.168.2.2"); 228 229 $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 230 $router->fail("ping -c 1 192.168.2.2"); 231 ''; 232 }; 233 bond = let 234 node = address: { config, pkgs, ... }: with pkgs.lib; { 235 virtualisation.vlans = [ 1 2 ]; 236 networking = { 237 useNetworkd = networkd; 238 firewall.allowPing = true; 239 useDHCP = false; 240 bonds.bond = { 241 interfaces = [ "eth1" "eth2" ]; 242 driverOptions.mode = "balance-rr"; 243 }; 244 interfaces.eth1.ip4 = mkOverride 0 [ ]; 245 interfaces.eth2.ip4 = mkOverride 0 [ ]; 246 interfaces.bond.ip4 = mkOverride 0 247 [ { inherit address; prefixLength = 30; } ]; 248 }; 249 }; 250 in { 251 name = "Bond"; 252 nodes.client1 = node "192.168.1.1"; 253 nodes.client2 = node "192.168.1.2"; 254 testScript = { nodes, ... }: 255 '' 256 startAll; 257 258 # Wait for networking to come up 259 $client1->waitForUnit("network.target"); 260 $client2->waitForUnit("network.target"); 261 262 # Test bonding 263 $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); 264 $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); 265 266 $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); 267 $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); 268 ''; 269 }; 270 bridge = let 271 node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; { 272 virtualisation.vlans = [ vlan ]; 273 networking = { 274 useNetworkd = networkd; 275 firewall.allowPing = true; 276 useDHCP = false; 277 interfaces.eth1.ip4 = mkOverride 0 278 [ { inherit address; prefixLength = 24; } ]; 279 }; 280 }; 281 in { 282 name = "Bridge"; 283 nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; 284 nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; 285 nodes.router = { config, pkgs, ... }: with pkgs.lib; { 286 virtualisation.vlans = [ 1 2 ]; 287 networking = { 288 useNetworkd = networkd; 289 firewall.allowPing = true; 290 useDHCP = false; 291 bridges.bridge.interfaces = [ "eth1" "eth2" ]; 292 interfaces.eth1.ip4 = mkOverride 0 [ ]; 293 interfaces.eth2.ip4 = mkOverride 0 [ ]; 294 interfaces.bridge.ip4 = mkOverride 0 295 [ { address = "192.168.1.1"; prefixLength = 24; } ]; 296 }; 297 }; 298 testScript = { nodes, ... }: 299 '' 300 startAll; 301 302 # Wait for networking to come up 303 $client1->waitForUnit("network.target"); 304 $client2->waitForUnit("network.target"); 305 $router->waitForUnit("network.target"); 306 307 # Test bridging 308 $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); 309 $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); 310 $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); 311 312 $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); 313 $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); 314 $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); 315 316 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 317 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 318 $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 319 ''; 320 }; 321 macvlan = { 322 name = "MACVLAN"; 323 nodes.router = router; 324 nodes.client = { config, pkgs, ... }: with pkgs.lib; { 325 virtualisation.vlans = [ 1 ]; 326 networking = { 327 useNetworkd = networkd; 328 firewall.allowPing = true; 329 useDHCP = true; 330 macvlans.macvlan.interface = "eth1"; 331 interfaces.eth1.ip4 = mkOverride 0 [ ]; 332 }; 333 }; 334 testScript = { nodes, ... }: 335 '' 336 startAll; 337 338 # Wait for networking to come up 339 $client->waitForUnit("network.target"); 340 $router->waitForUnit("network.target"); 341 342 # Wait until we have an ip address on each interface 343 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 344 $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); 345 346 # Print diagnosting information 347 $router->succeed("ip addr >&2"); 348 $client->succeed("ip addr >&2"); 349 350 # Test macvlan creates routable ips 351 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 352 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 353 $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 354 355 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 356 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 357 $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 358 ''; 359 }; 360 sit = let 361 node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; { 362 virtualisation.vlans = [ 1 ]; 363 networking = { 364 useNetworkd = networkd; 365 firewall.enable = false; 366 useDHCP = false; 367 sits.sit = { 368 inherit remote; 369 local = address4; 370 dev = "eth1"; 371 }; 372 interfaces.eth1.ip4 = mkOverride 0 373 [ { address = address4; prefixLength = 24; } ]; 374 interfaces.sit.ip6 = mkOverride 0 375 [ { address = address6; prefixLength = 64; } ]; 376 }; 377 }; 378 in { 379 name = "Sit"; 380 nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; 381 nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; 382 testScript = { nodes, ... }: 383 '' 384 startAll; 385 386 # Wait for networking to be configured 387 $client1->waitForUnit("network.target"); 388 $client2->waitForUnit("network.target"); 389 390 # Print diagnostic information 391 $client1->succeed("ip addr >&2"); 392 $client2->succeed("ip addr >&2"); 393 394 # Test ipv6 395 $client1->waitUntilSucceeds("ping -c 1 fc00::1"); 396 $client1->waitUntilSucceeds("ping -c 1 fc00::2"); 397 398 $client2->waitUntilSucceeds("ping -c 1 fc00::1"); 399 $client2->waitUntilSucceeds("ping -c 1 fc00::2"); 400 ''; 401 }; 402 vlan = let 403 node = address: { config, pkgs, ... }: with pkgs.lib; { 404 #virtualisation.vlans = [ 1 ]; 405 networking = { 406 useNetworkd = networkd; 407 firewall.allowPing = true; 408 useDHCP = false; 409 vlans.vlan = { 410 id = 1; 411 interface = "eth0"; 412 }; 413 interfaces.eth0.ip4 = mkOverride 0 [ ]; 414 interfaces.eth1.ip4 = mkOverride 0 [ ]; 415 interfaces.vlan.ip4 = mkOverride 0 416 [ { inherit address; prefixLength = 24; } ]; 417 }; 418 }; 419 in { 420 name = "vlan"; 421 nodes.client1 = node "192.168.1.1"; 422 nodes.client2 = node "192.168.1.2"; 423 testScript = { nodes, ... }: 424 '' 425 startAll; 426 427 # Wait for networking to be configured 428 $client1->waitForUnit("network.target"); 429 $client2->waitForUnit("network.target"); 430 431 # Test vlan is setup 432 $client1->succeed("ip addr show dev vlan >&2"); 433 $client2->succeed("ip addr show dev vlan >&2"); 434 ''; 435 }; 436 }; 437 438in mapAttrs (const (attrs: makeTest (attrs // { 439 name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; 440 meta = with pkgs.stdenv.lib.maintainers; { 441 maintainers = [ wkennington ]; 442 }; 443}))) testCases