1# Test of IPv6 functionality in NixOS, including whether router
2# solicication/advertisement using radvd works.
3
4import ./make-test.nix ({ pkgs, ...} : {
5 name = "ipv6";
6 meta = with pkgs.stdenv.lib.maintainers; {
7 maintainers = [ eelco chaoflow ];
8 };
9
10 nodes =
11 { client = { config, pkgs, ... }: { };
12
13 server =
14 { config, pkgs, ... }:
15 { services.httpd.enable = true;
16 services.httpd.adminAddr = "foo@example.org";
17 networking.firewall.allowedTCPPorts = [ 80 ];
18 };
19
20 router =
21 { config, pkgs, ... }:
22 { services.radvd.enable = true;
23 services.radvd.config =
24 ''
25 interface eth1 {
26 AdvSendAdvert on;
27 # ULA prefix (RFC 4193).
28 prefix fd60:cc69:b537:1::/64 { };
29 };
30 '';
31 };
32 };
33
34 testScript =
35 ''
36 # Start the router first so that it respond to router solicitations.
37 $router->waitForUnit("radvd");
38
39 startAll;
40
41 $client->waitForUnit("network.target");
42 $server->waitForUnit("network.target");
43 $server->waitForUnit("httpd.service");
44
45 # Wait until the given interface has a non-tentative address of
46 # the desired scope (i.e. has completed Duplicate Address
47 # Detection).
48 sub waitForAddress {
49 my ($machine, $iface, $scope) = @_;
50 $machine->waitUntilSucceeds("[ `ip -o -6 addr show dev $iface scope $scope | grep -v tentative | wc -l` -ge 1 ]");
51 my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev $iface scope $scope"))[3];
52 $machine->log("$scope address on $iface is $ip");
53 return $ip;
54 }
55
56 subtest "loopback address", sub {
57 $client->succeed("ping -c 1 ::1 >&2");
58 $client->fail("ping -c 1 ::2 >&2");
59 };
60
61 subtest "local link addressing", sub {
62 my $clientIp = waitForAddress $client, "eth1", "link";
63 my $serverIp = waitForAddress $server, "eth1", "link";
64 $client->succeed("ping -c 1 $clientIp%eth1 >&2");
65 $client->succeed("ping -c 1 $serverIp%eth1 >&2");
66 };
67
68 subtest "global addressing", sub {
69 my $clientIp = waitForAddress $client, "eth1", "global";
70 my $serverIp = waitForAddress $server, "eth1", "global";
71 $client->succeed("ping -c 1 $clientIp >&2");
72 $client->succeed("ping -c 1 $serverIp >&2");
73 $client->succeed("curl --fail -g http://[$serverIp]");
74 $client->fail("curl --fail -g http://[$clientIp]");
75 };
76
77 # TODO: test reachability of a machine on another network.
78 '';
79})