at 21.11-pre 27 kB view raw
1{ system ? builtins.currentSystem 2, config ? {} 3, pkgs ? import ../.. { inherit system config; } 4# bool: whether to use networkd in the tests 5, networkd }: 6 7with import ../lib/testing-python.nix { inherit system pkgs; }; 8with pkgs.lib; 9 10let 11 qemu-flags = import ../lib/qemu-flags.nix { inherit pkgs; }; 12 13 router = { config, pkgs, lib, ... }: 14 with pkgs.lib; 15 let 16 vlanIfs = range 1 (length config.virtualisation.vlans); 17 in { 18 environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules 19 virtualisation.vlans = [ 1 2 3 ]; 20 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; 21 networking = { 22 useDHCP = false; 23 useNetworkd = networkd; 24 firewall.checkReversePath = true; 25 firewall.allowedUDPPorts = [ 547 ]; 26 interfaces = mkOverride 0 (listToAttrs (forEach vlanIfs (n: 27 nameValuePair "eth${toString n}" { 28 ipv4.addresses = [ { address = "192.168.${toString n}.1"; prefixLength = 24; } ]; 29 ipv6.addresses = [ { address = "fd00:1234:5678:${toString n}::1"; prefixLength = 64; } ]; 30 }))); 31 }; 32 services.dhcpd4 = { 33 enable = true; 34 interfaces = map (n: "eth${toString n}") vlanIfs; 35 extraConfig = 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 range 192.168.${toString n}.3 192.168.${toString n}.254; 39 } 40 '') 41 ; 42 machines = flip map vlanIfs (vlan: 43 { 44 hostName = "client${toString vlan}"; 45 ethernetAddress = qemu-flags.qemuNicMac vlan 1; 46 ipAddress = "192.168.${toString vlan}.2"; 47 } 48 ); 49 }; 50 services.radvd = { 51 enable = true; 52 config = flip concatMapStrings vlanIfs (n: '' 53 interface eth${toString n} { 54 AdvSendAdvert on; 55 AdvManagedFlag on; 56 AdvOtherConfigFlag on; 57 58 prefix fd00:1234:5678:${toString n}::/64 { 59 AdvAutonomous off; 60 }; 61 }; 62 ''); 63 }; 64 services.dhcpd6 = { 65 enable = true; 66 interfaces = map (n: "eth${toString n}") vlanIfs; 67 extraConfig = '' 68 authoritative; 69 '' + flip concatMapStrings vlanIfs (n: '' 70 subnet6 fd00:1234:5678:${toString n}::/64 { 71 range6 fd00:1234:5678:${toString n}::2 fd00:1234:5678:${toString n}::2; 72 } 73 ''); 74 }; 75 }; 76 77 testCases = { 78 loopback = { 79 name = "Loopback"; 80 machine.networking.useDHCP = false; 81 machine.networking.useNetworkd = networkd; 82 testScript = '' 83 start_all() 84 machine.wait_for_unit("network.target") 85 loopback_addresses = machine.succeed("ip addr show lo") 86 assert "inet 127.0.0.1/8" in loopback_addresses 87 assert "inet6 ::1/128" in loopback_addresses 88 ''; 89 }; 90 static = { 91 name = "Static"; 92 nodes.router = router; 93 nodes.client = { pkgs, ... }: with pkgs.lib; { 94 virtualisation.vlans = [ 1 2 ]; 95 networking = { 96 useNetworkd = networkd; 97 useDHCP = false; 98 defaultGateway = "192.168.1.1"; 99 interfaces.eth1.ipv4.addresses = mkOverride 0 [ 100 { address = "192.168.1.2"; prefixLength = 24; } 101 { address = "192.168.1.3"; prefixLength = 32; } 102 { address = "192.168.1.10"; prefixLength = 32; } 103 ]; 104 interfaces.eth2.ipv4.addresses = mkOverride 0 [ 105 { address = "192.168.2.2"; prefixLength = 24; } 106 ]; 107 }; 108 }; 109 testScript = { ... }: 110 '' 111 start_all() 112 113 client.wait_for_unit("network.target") 114 router.wait_for_unit("network-online.target") 115 116 with subtest("Make sure dhcpcd is not started"): 117 client.fail("systemctl status dhcpcd.service") 118 119 with subtest("Test vlan 1"): 120 client.wait_until_succeeds("ping -c 1 192.168.1.1") 121 client.wait_until_succeeds("ping -c 1 192.168.1.2") 122 client.wait_until_succeeds("ping -c 1 192.168.1.3") 123 client.wait_until_succeeds("ping -c 1 192.168.1.10") 124 125 router.wait_until_succeeds("ping -c 1 192.168.1.1") 126 router.wait_until_succeeds("ping -c 1 192.168.1.2") 127 router.wait_until_succeeds("ping -c 1 192.168.1.3") 128 router.wait_until_succeeds("ping -c 1 192.168.1.10") 129 130 with subtest("Test vlan 2"): 131 client.wait_until_succeeds("ping -c 1 192.168.2.1") 132 client.wait_until_succeeds("ping -c 1 192.168.2.2") 133 134 router.wait_until_succeeds("ping -c 1 192.168.2.1") 135 router.wait_until_succeeds("ping -c 1 192.168.2.2") 136 137 with subtest("Test default gateway"): 138 router.wait_until_succeeds("ping -c 1 192.168.3.1") 139 client.wait_until_succeeds("ping -c 1 192.168.3.1") 140 ''; 141 }; 142 dhcpSimple = { 143 name = "SimpleDHCP"; 144 nodes.router = router; 145 nodes.client = { pkgs, ... }: with pkgs.lib; { 146 virtualisation.vlans = [ 1 2 ]; 147 networking = { 148 useNetworkd = networkd; 149 useDHCP = false; 150 interfaces.eth1 = { 151 ipv4.addresses = mkOverride 0 [ ]; 152 ipv6.addresses = mkOverride 0 [ ]; 153 useDHCP = true; 154 }; 155 interfaces.eth2 = { 156 ipv4.addresses = mkOverride 0 [ ]; 157 ipv6.addresses = mkOverride 0 [ ]; 158 useDHCP = true; 159 }; 160 }; 161 }; 162 testScript = { ... }: 163 '' 164 start_all() 165 166 client.wait_for_unit("network.target") 167 router.wait_for_unit("network-online.target") 168 169 with subtest("Wait until we have an ip address on each interface"): 170 client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") 171 client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") 172 client.wait_until_succeeds("ip addr show dev eth2 | grep -q '192.168.2'") 173 client.wait_until_succeeds("ip addr show dev eth2 | grep -q 'fd00:1234:5678:2:'") 174 175 with subtest("Test vlan 1"): 176 client.wait_until_succeeds("ping -c 1 192.168.1.1") 177 client.wait_until_succeeds("ping -c 1 192.168.1.2") 178 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") 179 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2") 180 181 router.wait_until_succeeds("ping -c 1 192.168.1.1") 182 router.wait_until_succeeds("ping -c 1 192.168.1.2") 183 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") 184 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::2") 185 186 with subtest("Test vlan 2"): 187 client.wait_until_succeeds("ping -c 1 192.168.2.1") 188 client.wait_until_succeeds("ping -c 1 192.168.2.2") 189 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::1") 190 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2") 191 192 router.wait_until_succeeds("ping -c 1 192.168.2.1") 193 router.wait_until_succeeds("ping -c 1 192.168.2.2") 194 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::1") 195 router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2") 196 ''; 197 }; 198 dhcpOneIf = { 199 name = "OneInterfaceDHCP"; 200 nodes.router = router; 201 nodes.client = { pkgs, ... }: with pkgs.lib; { 202 virtualisation.vlans = [ 1 2 ]; 203 networking = { 204 useNetworkd = networkd; 205 useDHCP = false; 206 interfaces.eth1 = { 207 ipv4.addresses = mkOverride 0 [ ]; 208 mtu = 1343; 209 useDHCP = true; 210 }; 211 interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; 212 }; 213 }; 214 testScript = { ... }: 215 '' 216 start_all() 217 218 with subtest("Wait for networking to come up"): 219 client.wait_for_unit("network.target") 220 router.wait_for_unit("network.target") 221 222 with subtest("Wait until we have an ip address on each interface"): 223 client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") 224 225 with subtest("ensure MTU is set"): 226 assert "mtu 1343" in client.succeed("ip link show dev eth1") 227 228 with subtest("Test vlan 1"): 229 client.wait_until_succeeds("ping -c 1 192.168.1.1") 230 client.wait_until_succeeds("ping -c 1 192.168.1.2") 231 232 router.wait_until_succeeds("ping -c 1 192.168.1.1") 233 router.wait_until_succeeds("ping -c 1 192.168.1.2") 234 235 with subtest("Test vlan 2"): 236 client.wait_until_succeeds("ping -c 1 192.168.2.1") 237 client.fail("ping -c 1 192.168.2.2") 238 239 router.wait_until_succeeds("ping -c 1 192.168.2.1") 240 router.fail("ping -c 1 192.168.2.2") 241 ''; 242 }; 243 bond = let 244 node = address: { pkgs, ... }: with pkgs.lib; { 245 virtualisation.vlans = [ 1 2 ]; 246 networking = { 247 useNetworkd = networkd; 248 useDHCP = false; 249 bonds.bond = { 250 interfaces = [ "eth1" "eth2" ]; 251 driverOptions.mode = "balance-rr"; 252 }; 253 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 254 interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; 255 interfaces.bond.ipv4.addresses = mkOverride 0 256 [ { inherit address; prefixLength = 30; } ]; 257 }; 258 }; 259 in { 260 name = "Bond"; 261 nodes.client1 = node "192.168.1.1"; 262 nodes.client2 = node "192.168.1.2"; 263 testScript = { ... }: 264 '' 265 start_all() 266 267 with subtest("Wait for networking to come up"): 268 client1.wait_for_unit("network.target") 269 client2.wait_for_unit("network.target") 270 271 with subtest("Test bonding"): 272 client1.wait_until_succeeds("ping -c 2 192.168.1.1") 273 client1.wait_until_succeeds("ping -c 2 192.168.1.2") 274 275 client2.wait_until_succeeds("ping -c 2 192.168.1.1") 276 client2.wait_until_succeeds("ping -c 2 192.168.1.2") 277 ''; 278 }; 279 bridge = let 280 node = { address, vlan }: { pkgs, ... }: with pkgs.lib; { 281 virtualisation.vlans = [ vlan ]; 282 networking = { 283 useNetworkd = networkd; 284 useDHCP = false; 285 interfaces.eth1.ipv4.addresses = mkOverride 0 286 [ { inherit address; prefixLength = 24; } ]; 287 }; 288 }; 289 in { 290 name = "Bridge"; 291 nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; 292 nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; 293 nodes.router = { pkgs, ... }: with pkgs.lib; { 294 virtualisation.vlans = [ 1 2 ]; 295 networking = { 296 useNetworkd = networkd; 297 useDHCP = false; 298 bridges.bridge.interfaces = [ "eth1" "eth2" ]; 299 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 300 interfaces.eth2.ipv4.addresses = mkOverride 0 [ ]; 301 interfaces.bridge.ipv4.addresses = mkOverride 0 302 [ { address = "192.168.1.1"; prefixLength = 24; } ]; 303 }; 304 }; 305 testScript = { ... }: 306 '' 307 start_all() 308 309 with subtest("Wait for networking to come up"): 310 for machine in client1, client2, router: 311 machine.wait_for_unit("network.target") 312 313 with subtest("Test bridging"): 314 client1.wait_until_succeeds("ping -c 1 192.168.1.1") 315 client1.wait_until_succeeds("ping -c 1 192.168.1.2") 316 client1.wait_until_succeeds("ping -c 1 192.168.1.3") 317 318 client2.wait_until_succeeds("ping -c 1 192.168.1.1") 319 client2.wait_until_succeeds("ping -c 1 192.168.1.2") 320 client2.wait_until_succeeds("ping -c 1 192.168.1.3") 321 322 router.wait_until_succeeds("ping -c 1 192.168.1.1") 323 router.wait_until_succeeds("ping -c 1 192.168.1.2") 324 router.wait_until_succeeds("ping -c 1 192.168.1.3") 325 ''; 326 }; 327 macvlan = { 328 name = "MACVLAN"; 329 nodes.router = router; 330 nodes.client = { pkgs, ... }: with pkgs.lib; { 331 environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules 332 virtualisation.vlans = [ 1 ]; 333 networking = { 334 useNetworkd = networkd; 335 useDHCP = false; 336 firewall.logReversePathDrops = true; # to debug firewall rules 337 # reverse path filtering rules for the macvlan interface seem 338 # to be incorrect, causing the test to fail. Disable temporarily. 339 firewall.checkReversePath = false; 340 macvlans.macvlan.interface = "eth1"; 341 interfaces.eth1 = { 342 ipv4.addresses = mkOverride 0 [ ]; 343 useDHCP = true; 344 }; 345 interfaces.macvlan = { 346 useDHCP = true; 347 }; 348 }; 349 }; 350 testScript = { ... }: 351 '' 352 start_all() 353 354 with subtest("Wait for networking to come up"): 355 client.wait_for_unit("network.target") 356 router.wait_for_unit("network.target") 357 358 with subtest("Wait until we have an ip address on each interface"): 359 client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'") 360 client.wait_until_succeeds("ip addr show dev macvlan | grep -q '192.168.1'") 361 362 with subtest("Print lots of diagnostic information"): 363 router.log("**********************************************") 364 router.succeed("ip addr >&2") 365 router.succeed("ip route >&2") 366 router.execute("iptables-save >&2") 367 client.log("==============================================") 368 client.succeed("ip addr >&2") 369 client.succeed("ip route >&2") 370 client.execute("iptables-save >&2") 371 client.log("##############################################") 372 373 with subtest("Test macvlan creates routable ips"): 374 client.wait_until_succeeds("ping -c 1 192.168.1.1") 375 client.wait_until_succeeds("ping -c 1 192.168.1.2") 376 client.wait_until_succeeds("ping -c 1 192.168.1.3") 377 378 router.wait_until_succeeds("ping -c 1 192.168.1.1") 379 router.wait_until_succeeds("ping -c 1 192.168.1.2") 380 router.wait_until_succeeds("ping -c 1 192.168.1.3") 381 ''; 382 }; 383 sit = let 384 node = { address4, remote, address6 }: { pkgs, ... }: with pkgs.lib; { 385 virtualisation.vlans = [ 1 ]; 386 networking = { 387 useNetworkd = networkd; 388 firewall.enable = false; 389 useDHCP = false; 390 sits.sit = { 391 inherit remote; 392 local = address4; 393 dev = "eth1"; 394 }; 395 interfaces.eth1.ipv4.addresses = mkOverride 0 396 [ { address = address4; prefixLength = 24; } ]; 397 interfaces.sit.ipv6.addresses = mkOverride 0 398 [ { address = address6; prefixLength = 64; } ]; 399 }; 400 }; 401 in { 402 name = "Sit"; 403 nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; 404 nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; 405 testScript = { ... }: 406 '' 407 start_all() 408 409 with subtest("Wait for networking to be configured"): 410 client1.wait_for_unit("network.target") 411 client2.wait_for_unit("network.target") 412 413 # Print diagnostic information 414 client1.succeed("ip addr >&2") 415 client2.succeed("ip addr >&2") 416 417 with subtest("Test ipv6"): 418 client1.wait_until_succeeds("ping -c 1 fc00::1") 419 client1.wait_until_succeeds("ping -c 1 fc00::2") 420 421 client2.wait_until_succeeds("ping -c 1 fc00::1") 422 client2.wait_until_succeeds("ping -c 1 fc00::2") 423 ''; 424 }; 425 vlan = let 426 node = address: { pkgs, ... }: with pkgs.lib; { 427 #virtualisation.vlans = [ 1 ]; 428 networking = { 429 useNetworkd = networkd; 430 useDHCP = false; 431 vlans.vlan = { 432 id = 1; 433 interface = "eth0"; 434 }; 435 interfaces.eth0.ipv4.addresses = mkOverride 0 [ ]; 436 interfaces.eth1.ipv4.addresses = mkOverride 0 [ ]; 437 interfaces.vlan.ipv4.addresses = mkOverride 0 438 [ { inherit address; prefixLength = 24; } ]; 439 }; 440 }; 441 in { 442 name = "vlan"; 443 nodes.client1 = node "192.168.1.1"; 444 nodes.client2 = node "192.168.1.2"; 445 testScript = { ... }: 446 '' 447 start_all() 448 449 with subtest("Wait for networking to be configured"): 450 client1.wait_for_unit("network.target") 451 client2.wait_for_unit("network.target") 452 453 with subtest("Test vlan is setup"): 454 client1.succeed("ip addr show dev vlan >&2") 455 client2.succeed("ip addr show dev vlan >&2") 456 ''; 457 }; 458 virtual = { 459 name = "Virtual"; 460 machine = { 461 networking.useNetworkd = networkd; 462 networking.useDHCP = false; 463 networking.interfaces.tap0 = { 464 ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ]; 465 ipv6.addresses = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ]; 466 virtual = true; 467 mtu = 1342; 468 macAddress = "02:de:ad:be:ef:01"; 469 }; 470 networking.interfaces.tun0 = { 471 ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; 472 ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ]; 473 virtual = true; 474 mtu = 1343; 475 }; 476 }; 477 478 testScript = '' 479 targetList = """ 480 tap0: tap persist user 0 481 tun0: tun persist user 0 482 """.strip() 483 484 with subtest("Wait for networking to come up"): 485 machine.start() 486 machine.wait_for_unit("network.target") 487 488 with subtest("Test interfaces set up"): 489 list = machine.succeed("ip tuntap list | sort").strip() 490 assert ( 491 list == targetList 492 ), """ 493 The list of virtual interfaces does not match the expected one: 494 Result: 495 {} 496 Expected: 497 {} 498 """.format( 499 list, targetList 500 ) 501 with subtest("Test MTU and MAC Address are configured"): 502 machine.wait_until_succeeds("ip link show dev tap0 | grep 'mtu 1342'") 503 machine.wait_until_succeeds("ip link show dev tun0 | grep 'mtu 1343'") 504 assert "02:de:ad:be:ef:01" in machine.succeed("ip link show dev tap0") 505 '' # network-addresses-* only exist in scripted networking 506 + optionalString (!networkd) '' 507 with subtest("Test interfaces clean up"): 508 machine.succeed("systemctl stop network-addresses-tap0") 509 machine.sleep(10) 510 machine.succeed("systemctl stop network-addresses-tun0") 511 machine.sleep(10) 512 residue = machine.succeed("ip tuntap list") 513 assert ( 514 residue == "" 515 ), "Some virtual interface has not been properly cleaned:\n{}".format(residue) 516 ''; 517 }; 518 privacy = { 519 name = "Privacy"; 520 nodes.router = { ... }: { 521 virtualisation.vlans = [ 1 ]; 522 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; 523 networking = { 524 useNetworkd = networkd; 525 useDHCP = false; 526 interfaces.eth1.ipv6.addresses = singleton { 527 address = "fd00:1234:5678:1::1"; 528 prefixLength = 64; 529 }; 530 }; 531 services.radvd = { 532 enable = true; 533 config = '' 534 interface eth1 { 535 AdvSendAdvert on; 536 AdvManagedFlag on; 537 AdvOtherConfigFlag on; 538 539 prefix fd00:1234:5678:1::/64 { 540 AdvAutonomous on; 541 AdvOnLink on; 542 }; 543 }; 544 ''; 545 }; 546 }; 547 nodes.client_with_privacy = { pkgs, ... }: with pkgs.lib; { 548 virtualisation.vlans = [ 1 ]; 549 networking = { 550 useNetworkd = networkd; 551 useDHCP = false; 552 interfaces.eth1 = { 553 tempAddress = "default"; 554 ipv4.addresses = mkOverride 0 [ ]; 555 ipv6.addresses = mkOverride 0 [ ]; 556 useDHCP = true; 557 }; 558 }; 559 }; 560 nodes.client = { pkgs, ... }: with pkgs.lib; { 561 virtualisation.vlans = [ 1 ]; 562 networking = { 563 useNetworkd = networkd; 564 useDHCP = false; 565 interfaces.eth1 = { 566 tempAddress = "enabled"; 567 ipv4.addresses = mkOverride 0 [ ]; 568 ipv6.addresses = mkOverride 0 [ ]; 569 useDHCP = true; 570 }; 571 }; 572 }; 573 testScript = { ... }: 574 '' 575 start_all() 576 577 client.wait_for_unit("network.target") 578 client_with_privacy.wait_for_unit("network.target") 579 router.wait_for_unit("network-online.target") 580 581 with subtest("Wait until we have an ip address"): 582 client_with_privacy.wait_until_succeeds( 583 "ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'" 584 ) 585 client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'") 586 587 with subtest("Test vlan 1"): 588 client_with_privacy.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") 589 client.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1") 590 591 with subtest("Test address used is temporary"): 592 client_with_privacy.wait_until_succeeds( 593 "! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'" 594 ) 595 596 with subtest("Test address used is EUI-64"): 597 client.wait_until_succeeds( 598 "ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'" 599 ) 600 ''; 601 }; 602 routes = { 603 name = "routes"; 604 machine = { 605 networking.useDHCP = false; 606 networking.interfaces.eth0 = { 607 ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; 608 ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ]; 609 ipv6.routes = [ 610 { address = "fdfd:b3f0::"; prefixLength = 48; } 611 { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; } 612 ]; 613 ipv4.routes = [ 614 { address = "10.0.0.0"; prefixLength = 16; options = { mtu = "1500"; }; } 615 { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; } 616 ]; 617 }; 618 virtualisation.vlans = [ ]; 619 }; 620 621 testScript = '' 622 targetIPv4Table = [ 623 "10.0.0.0/16 proto static scope link mtu 1500", 624 "192.168.1.0/24 proto kernel scope link src 192.168.1.2", 625 "192.168.2.0/24 via 192.168.1.1 proto static", 626 ] 627 628 targetIPv6Table = [ 629 "2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium", 630 "2001:1470:fffd:2098::/64 via fdfd:b3f0::1 proto static metric 1024 pref medium", 631 "fdfd:b3f0::/48 proto static metric 1024 pref medium", 632 ] 633 634 machine.start() 635 machine.wait_for_unit("network.target") 636 637 with subtest("test routing tables"): 638 ipv4Table = machine.succeed("ip -4 route list dev eth0 | head -n3").strip() 639 ipv6Table = machine.succeed("ip -6 route list dev eth0 | head -n3").strip() 640 assert [ 641 l.strip() for l in ipv4Table.splitlines() 642 ] == targetIPv4Table, """ 643 The IPv4 routing table does not match the expected one: 644 Result: 645 {} 646 Expected: 647 {} 648 """.format( 649 ipv4Table, targetIPv4Table 650 ) 651 assert [ 652 l.strip() for l in ipv6Table.splitlines() 653 ] == targetIPv6Table, """ 654 The IPv6 routing table does not match the expected one: 655 Result: 656 {} 657 Expected: 658 {} 659 """.format( 660 ipv6Table, targetIPv6Table 661 ) 662 663 with subtest("test clean-up of the tables"): 664 machine.succeed("systemctl stop network-addresses-eth0") 665 ipv4Residue = machine.succeed("ip -4 route list dev eth0 | head -n-3").strip() 666 ipv6Residue = machine.succeed("ip -6 route list dev eth0 | head -n-3").strip() 667 assert ( 668 ipv4Residue == "" 669 ), "The IPv4 routing table has not been properly cleaned:\n{}".format(ipv4Residue) 670 assert ( 671 ipv6Residue == "" 672 ), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue) 673 ''; 674 }; 675 rename = { 676 name = "RenameInterface"; 677 machine = { pkgs, ... }: { 678 virtualisation.vlans = [ 1 ]; 679 networking = { 680 useNetworkd = networkd; 681 useDHCP = false; 682 }; 683 } // 684 (if networkd 685 then { systemd.network.links."10-custom_name" = { 686 matchConfig.MACAddress = "52:54:00:12:01:01"; 687 linkConfig.Name = "custom_name"; 688 }; 689 } 690 else { services.udev.initrdRules = '' 691 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="custom_name" 692 ''; 693 }); 694 testScript = '' 695 machine.succeed("udevadm settle") 696 print(machine.succeed("ip link show dev custom_name")) 697 ''; 698 }; 699 # even with disabled networkd, systemd.network.links should work 700 # (as it's handled by udev, not networkd) 701 link = { 702 name = "Link"; 703 nodes.client = { pkgs, ... }: { 704 virtualisation.vlans = [ 1 ]; 705 networking = { 706 useNetworkd = networkd; 707 useDHCP = false; 708 }; 709 systemd.network.links."50-foo" = { 710 matchConfig = { 711 Name = "foo"; 712 Driver = "dummy"; 713 }; 714 linkConfig.MTUBytes = "1442"; 715 }; 716 }; 717 testScript = '' 718 print(client.succeed("ip l add name foo type dummy")) 719 print(client.succeed("stat /etc/systemd/network/50-foo.link")) 720 client.succeed("udevadm settle") 721 assert "mtu 1442" in client.succeed("ip l show dummy0") 722 ''; 723 }; 724 }; 725 726in mapAttrs (const (attrs: makeTest (attrs // { 727 name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; 728}))) testCases