at 18.09-beta 22 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 environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules 15 virtualisation.vlans = [ 1 2 3 ]; 16 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; 17 networking = { 18 useDHCP = false; 19 useNetworkd = networkd; 20 firewall.allowPing = true; 21 firewall.checkReversePath = true; 22 firewall.allowedUDPPorts = [ 547 ]; 23 interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: 24 nameValuePair "eth${toString n}" { 25 ipv4.addresses = [ { address = "192.168.${toString n}.1"; prefixLength = 24; } ]; 26 ipv6.addresses = [ { address = "fd00:1234:5678:${toString n}::1"; prefixLength = 64; } ]; 27 }))); 28 }; 29 services.dhcpd4 = { 30 enable = true; 31 interfaces = map (n: "eth${toString n}") vlanIfs; 32 extraConfig = '' 33 authoritative; 34 '' + flip concatMapStrings vlanIfs (n: '' 35 subnet 192.168.${toString n}.0 netmask 255.255.255.0 { 36 option routers 192.168.${toString n}.1; 37 # XXX: technically it's _not guaranteed_ that IP addresses will be 38 # issued from the first item in range onwards! We assume that in 39 # our tests however. 40 range 192.168.${toString n}.2 192.168.${toString n}.254; 41 } 42 ''); 43 }; 44 services.radvd = { 45 enable = true; 46 config = flip concatMapStrings vlanIfs (n: '' 47 interface eth${toString n} { 48 AdvSendAdvert on; 49 AdvManagedFlag on; 50 AdvOtherConfigFlag on; 51 52 prefix fd00:1234:5678:${toString n}::/64 { 53 AdvAutonomous off; 54 }; 55 }; 56 ''); 57 }; 58 services.dhcpd6 = { 59 enable = true; 60 interfaces = map (n: "eth${toString n}") vlanIfs; 61 extraConfig = '' 62 authoritative; 63 '' + flip concatMapStrings vlanIfs (n: '' 64 subnet6 fd00:1234:5678:${toString n}::/64 { 65 range6 fd00:1234:5678:${toString n}::2 fd00:1234:5678:${toString n}::2; 66 } 67 ''); 68 }; 69 }; 70 71 testCases = { 72 loopback = { 73 name = "Loopback"; 74 machine.networking.useNetworkd = networkd; 75 testScript = '' 76 startAll; 77 $machine->waitForUnit("network.target"); 78 $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); 79 $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); 80 ''; 81 }; 82 static = { 83 name = "Static"; 84 nodes.router = router; 85 nodes.client = { pkgs, ... }: with pkgs.lib; { 86 virtualisation.vlans = [ 1 2 ]; 87 networking = { 88 useNetworkd = networkd; 89 firewall.allowPing = true; 90 useDHCP = false; 91 defaultGateway = "192.168.1.1"; 92 interfaces.eth1.ipv4.addresses = mkOverride 0 [ 93 { address = "192.168.1.2"; prefixLength = 24; } 94 { address = "192.168.1.3"; prefixLength = 32; } 95 { address = "192.168.1.10"; prefixLength = 32; } 96 ]; 97 interfaces.eth2.ipv4.addresses = mkOverride 0 [ 98 { address = "192.168.2.2"; prefixLength = 24; } 99 ]; 100 }; 101 }; 102 testScript = { ... }: 103 '' 104 startAll; 105 106 $client->waitForUnit("network.target"); 107 $router->waitForUnit("network-online.target"); 108 109 # Make sure dhcpcd is not started 110 $client->fail("systemctl status dhcpcd.service"); 111 112 # Test vlan 1 113 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 114 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 115 $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 116 $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); 117 118 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 119 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 120 $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 121 $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); 122 123 # Test vlan 2 124 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 125 $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 126 127 $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 128 $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 129 130 # Test default gateway 131 $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); 132 $client->waitUntilSucceeds("ping -c 1 192.168.3.1"); 133 ''; 134 }; 135 dhcpSimple = { 136 name = "SimpleDHCP"; 137 nodes.router = router; 138 nodes.client = { pkgs, ... }: with pkgs.lib; { 139 virtualisation.vlans = [ 1 2 ]; 140 networking = { 141 useNetworkd = networkd; 142 firewall.allowPing = true; 143 useDHCP = true; 144 interfaces.eth1 = { 145 ipv4.addresses = mkOverride 0 [ ]; 146 ipv6.addresses = mkOverride 0 [ ]; 147 }; 148 interfaces.eth2 = { 149 ipv4.addresses = mkOverride 0 [ ]; 150 ipv6.addresses = mkOverride 0 [ ]; 151 }; 152 }; 153 }; 154 testScript = { ... }: 155 '' 156 startAll; 157 158 $client->waitForUnit("network.target"); 159 $router->waitForUnit("network-online.target"); 160 161 # Wait until we have an ip address on each interface 162 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 163 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'"); 164 $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); 165 $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q 'fd00:1234:5678:2:'"); 166 167 # Test vlan 1 168 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 169 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 170 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); 171 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); 172 173 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 174 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 175 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); 176 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::2"); 177 178 # Test vlan 2 179 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 180 $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 181 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); 182 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); 183 184 $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 185 $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 186 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::1"); 187 $router->waitUntilSucceeds("ping -c 1 fd00:1234:5678:2::2"); 188 ''; 189 }; 190 dhcpOneIf = { 191 name = "OneInterfaceDHCP"; 192 nodes.router = router; 193 nodes.client = { pkgs, ... }: with pkgs.lib; { 194 virtualisation.vlans = [ 1 2 ]; 195 networking = { 196 useNetworkd = networkd; 197 firewall.allowPing = true; 198 useDHCP = false; 199 interfaces.eth1 = { 200 ipv4.addresses = mkOverride 0 [ ]; 201 useDHCP = true; 202 }; 203 interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; 204 }; 205 }; 206 testScript = { ... }: 207 '' 208 startAll; 209 210 # Wait for networking to come up 211 $client->waitForUnit("network.target"); 212 $router->waitForUnit("network.target"); 213 214 # Wait until we have an ip address on each interface 215 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 216 217 # Test vlan 1 218 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 219 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 220 221 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 222 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 223 224 # Test vlan 2 225 $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 226 $client->fail("ping -c 1 192.168.2.2"); 227 228 $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 229 $router->fail("ping -c 1 192.168.2.2"); 230 ''; 231 }; 232 bond = let 233 node = address: { pkgs, ... }: with pkgs.lib; { 234 virtualisation.vlans = [ 1 2 ]; 235 networking = { 236 useNetworkd = networkd; 237 firewall.allowPing = true; 238 useDHCP = false; 239 bonds.bond = { 240 interfaces = [ "eth1" "eth2" ]; 241 driverOptions.mode = "balance-rr"; 242 }; 243 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 244 interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; 245 interfaces.bond.ipv4.addresses = mkOverride 0 246 [ { inherit address; prefixLength = 30; } ]; 247 }; 248 }; 249 in { 250 name = "Bond"; 251 nodes.client1 = node "192.168.1.1"; 252 nodes.client2 = node "192.168.1.2"; 253 testScript = { ... }: 254 '' 255 startAll; 256 257 # Wait for networking to come up 258 $client1->waitForUnit("network.target"); 259 $client2->waitForUnit("network.target"); 260 261 # Test bonding 262 $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); 263 $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); 264 265 $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); 266 $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); 267 ''; 268 }; 269 bridge = let 270 node = { address, vlan }: { pkgs, ... }: with pkgs.lib; { 271 virtualisation.vlans = [ vlan ]; 272 networking = { 273 useNetworkd = networkd; 274 firewall.allowPing = true; 275 useDHCP = false; 276 interfaces.eth1.ipv4.addresses = mkOverride 0 277 [ { inherit address; prefixLength = 24; } ]; 278 }; 279 }; 280 in { 281 name = "Bridge"; 282 nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; 283 nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; 284 nodes.router = { pkgs, ... }: with pkgs.lib; { 285 virtualisation.vlans = [ 1 2 ]; 286 networking = { 287 useNetworkd = networkd; 288 firewall.allowPing = true; 289 useDHCP = false; 290 bridges.bridge.interfaces = [ "eth1" "eth2" ]; 291 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 292 interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; 293 interfaces.bridge.ipv4.addresses = mkOverride 0 294 [ { address = "192.168.1.1"; prefixLength = 24; } ]; 295 }; 296 }; 297 testScript = { ... }: 298 '' 299 startAll; 300 301 # Wait for networking to come up 302 $client1->waitForUnit("network.target"); 303 $client2->waitForUnit("network.target"); 304 $router->waitForUnit("network.target"); 305 306 # Test bridging 307 $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); 308 $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); 309 $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); 310 311 $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); 312 $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); 313 $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); 314 315 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 316 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 317 $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 318 ''; 319 }; 320 macvlan = { 321 name = "MACVLAN"; 322 nodes.router = router; 323 nodes.client = { pkgs, ... }: with pkgs.lib; { 324 environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules 325 virtualisation.vlans = [ 1 ]; 326 networking = { 327 useNetworkd = networkd; 328 firewall.logReversePathDrops = true; # to debug firewall rules 329 # reverse path filtering rules for the macvlan interface seem 330 # to be incorrect, causing the test to fail. Disable temporarily. 331 firewall.checkReversePath = false; 332 firewall.allowPing = true; 333 useDHCP = true; 334 macvlans.macvlan.interface = "eth1"; 335 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 336 }; 337 }; 338 testScript = { ... }: 339 '' 340 startAll; 341 342 # Wait for networking to come up 343 $client->waitForUnit("network.target"); 344 $router->waitForUnit("network.target"); 345 346 # Wait until we have an ip address on each interface 347 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 348 $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); 349 350 # Print lots of diagnostic information 351 $router->log('**********************************************'); 352 $router->succeed("ip addr >&2"); 353 $router->succeed("ip route >&2"); 354 $router->execute("iptables-save >&2"); 355 $client->log('=============================================='); 356 $client->succeed("ip addr >&2"); 357 $client->succeed("ip route >&2"); 358 $client->execute("iptables-save >&2"); 359 $client->log('##############################################'); 360 361 # Test macvlan creates routable ips 362 $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 363 $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 364 $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 365 366 $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 367 $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 368 $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 369 ''; 370 }; 371 sit = let 372 node = { address4, remote, address6 }: { pkgs, ... }: with pkgs.lib; { 373 virtualisation.vlans = [ 1 ]; 374 networking = { 375 useNetworkd = networkd; 376 firewall.enable = false; 377 useDHCP = false; 378 sits.sit = { 379 inherit remote; 380 local = address4; 381 dev = "eth1"; 382 }; 383 interfaces.eth1.ipv4.addresses = mkOverride 0 384 [ { address = address4; prefixLength = 24; } ]; 385 interfaces.sit.ipv6.addresses = mkOverride 0 386 [ { address = address6; prefixLength = 64; } ]; 387 }; 388 }; 389 in { 390 name = "Sit"; 391 nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; 392 nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; 393 testScript = { ... }: 394 '' 395 startAll; 396 397 # Wait for networking to be configured 398 $client1->waitForUnit("network.target"); 399 $client2->waitForUnit("network.target"); 400 401 # Print diagnostic information 402 $client1->succeed("ip addr >&2"); 403 $client2->succeed("ip addr >&2"); 404 405 # Test ipv6 406 $client1->waitUntilSucceeds("ping -c 1 fc00::1"); 407 $client1->waitUntilSucceeds("ping -c 1 fc00::2"); 408 409 $client2->waitUntilSucceeds("ping -c 1 fc00::1"); 410 $client2->waitUntilSucceeds("ping -c 1 fc00::2"); 411 ''; 412 }; 413 vlan = let 414 node = address: { pkgs, ... }: with pkgs.lib; { 415 #virtualisation.vlans = [ 1 ]; 416 networking = { 417 useNetworkd = networkd; 418 firewall.allowPing = true; 419 useDHCP = false; 420 vlans.vlan = { 421 id = 1; 422 interface = "eth0"; 423 }; 424 interfaces.eth0.ipv4.addresses = mkOverride 0 [ ]; 425 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 426 interfaces.vlan.ipv4.addresses = mkOverride 0 427 [ { inherit address; prefixLength = 24; } ]; 428 }; 429 }; 430 in { 431 name = "vlan"; 432 nodes.client1 = node "192.168.1.1"; 433 nodes.client2 = node "192.168.1.2"; 434 testScript = { ... }: 435 '' 436 startAll; 437 438 # Wait for networking to be configured 439 $client1->waitForUnit("network.target"); 440 $client2->waitForUnit("network.target"); 441 442 # Test vlan is setup 443 $client1->succeed("ip addr show dev vlan >&2"); 444 $client2->succeed("ip addr show dev vlan >&2"); 445 ''; 446 }; 447 virtual = { 448 name = "Virtual"; 449 machine = { 450 networking.interfaces."tap0" = { 451 ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ]; 452 ipv6.addresses = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ]; 453 virtual = true; 454 }; 455 networking.interfaces."tun0" = { 456 ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; 457 ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ]; 458 virtual = true; 459 }; 460 }; 461 462 testScript = '' 463 my $targetList = <<'END'; 464 tap0: tap persist user 0 465 tun0: tun persist user 0 466 END 467 468 # Wait for networking to come up 469 $machine->start; 470 $machine->waitForUnit("network.target"); 471 472 # Test interfaces set up 473 my $list = $machine->succeed("ip tuntap list | sort"); 474 "$list" eq "$targetList" or die( 475 "The list of virtual interfaces does not match the expected one:\n", 476 "Result:\n", "$list\n", 477 "Expected:\n", "$targetList\n" 478 ); 479 480 # Test interfaces clean up 481 $machine->succeed("systemctl stop network-addresses-tap0"); 482 $machine->succeed("systemctl stop network-addresses-tun0"); 483 my $residue = $machine->succeed("ip tuntap list"); 484 $residue eq "" or die( 485 "Some virtual interface has not been properly cleaned:\n", 486 "$residue\n" 487 ); 488 ''; 489 }; 490 privacy = { 491 name = "Privacy"; 492 nodes.router = { ... }: { 493 virtualisation.vlans = [ 1 ]; 494 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; 495 networking = { 496 useNetworkd = networkd; 497 interfaces.eth1.ipv6.addresses = singleton { 498 address = "fd00:1234:5678:1::1"; 499 prefixLength = 64; 500 }; 501 }; 502 services.radvd = { 503 enable = true; 504 config = '' 505 interface eth1 { 506 AdvSendAdvert on; 507 AdvManagedFlag on; 508 AdvOtherConfigFlag on; 509 510 prefix fd00:1234:5678:1::/64 { 511 AdvAutonomous on; 512 AdvOnLink on; 513 }; 514 }; 515 ''; 516 }; 517 }; 518 nodes.client = { pkgs, ... }: with pkgs.lib; { 519 virtualisation.vlans = [ 1 ]; 520 networking = { 521 useNetworkd = networkd; 522 useDHCP = true; 523 interfaces.eth1 = { 524 preferTempAddress = true; 525 ipv4.addresses = mkOverride 0 [ ]; 526 ipv6.addresses = mkOverride 0 [ ]; 527 }; 528 }; 529 }; 530 testScript = { ... }: 531 '' 532 startAll; 533 534 $client->waitForUnit("network.target"); 535 $router->waitForUnit("network-online.target"); 536 537 # Wait until we have an ip address 538 $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'"); 539 540 # Test vlan 1 541 $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); 542 543 # Test address used is temporary 544 $client->waitUntilSucceeds("! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'"); 545 ''; 546 }; 547 routes = { 548 name = "routes"; 549 machine = { 550 networking.useDHCP = false; 551 networking.interfaces."eth0" = { 552 ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; 553 ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ]; 554 ipv6.routes = [ 555 { address = "fdfd:b3f0::"; prefixLength = 48; } 556 { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; } 557 ]; 558 ipv4.routes = [ 559 { address = "10.0.0.0"; prefixLength = 16; options = { mtu = "1500"; }; } 560 { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; } 561 ]; 562 }; 563 virtualisation.vlans = [ ]; 564 }; 565 566 testScript = '' 567 my $targetIPv4Table = <<'END'; 568 10.0.0.0/16 proto static scope link mtu 1500 569 192.168.1.0/24 proto kernel scope link src 192.168.1.2 570 192.168.2.0/24 via 192.168.1.1 proto static 571 END 572 573 my $targetIPv6Table = <<'END'; 574 2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium 575 2001:1470:fffd:2098::/64 via fdfd:b3f0::1 proto static metric 1024 pref medium 576 fdfd:b3f0::/48 proto static metric 1024 pref medium 577 END 578 579 $machine->start; 580 $machine->waitForUnit("network.target"); 581 582 # test routing tables 583 my $ipv4Table = $machine->succeed("ip -4 route list dev eth0 | head -n3"); 584 my $ipv6Table = $machine->succeed("ip -6 route list dev eth0 | head -n3"); 585 "$ipv4Table" eq "$targetIPv4Table" or die( 586 "The IPv4 routing table does not match the expected one:\n", 587 "Result:\n", "$ipv4Table\n", 588 "Expected:\n", "$targetIPv4Table\n" 589 ); 590 "$ipv6Table" eq "$targetIPv6Table" or die( 591 "The IPv6 routing table does not match the expected one:\n", 592 "Result:\n", "$ipv6Table\n", 593 "Expected:\n", "$targetIPv6Table\n" 594 ); 595 596 # test clean-up of the tables 597 $machine->succeed("systemctl stop network-addresses-eth0"); 598 my $ipv4Residue = $machine->succeed("ip -4 route list dev eth0 | head -n-3"); 599 my $ipv6Residue = $machine->succeed("ip -6 route list dev eth0 | head -n-3"); 600 $ipv4Residue eq "" or die( 601 "The IPv4 routing table has not been properly cleaned:\n", 602 "$ipv4Residue\n" 603 ); 604 $ipv6Residue eq "" or die( 605 "The IPv6 routing table has not been properly cleaned:\n", 606 "$ipv6Residue\n" 607 ); 608 ''; 609 }; 610 }; 611 612in mapAttrs (const (attrs: makeTest (attrs // { 613 name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; 614 meta = with pkgs.stdenv.lib.maintainers; { 615 maintainers = [ wkennington ]; 616 }; 617}))) testCases