|
| 1 | +{ |
| 2 | + lib, |
| 3 | + pkgs, |
| 4 | + ... |
| 5 | +}: |
| 6 | +{ |
| 7 | + name = "nat64-pref64"; |
| 8 | + |
| 9 | + defaults = { |
| 10 | + networking = { |
| 11 | + useDHCP = false; |
| 12 | + firewall.enable = false; |
| 13 | + }; |
| 14 | + }; |
| 15 | + |
| 16 | + nodes = { |
| 17 | + server = import ./server.nix { inherit pkgs; }; |
| 18 | + nat64gw = import ./nat64gw.nix; |
| 19 | + client = import ./client.nix { inherit lib pkgs; }; |
| 20 | + }; |
| 21 | + |
| 22 | + interactive.nodes = lib.listToAttrs ( |
| 23 | + map |
| 24 | + (name: { |
| 25 | + inherit name; |
| 26 | + value.environment.systemPackages = with pkgs; [ |
| 27 | + curl |
| 28 | + dig |
| 29 | + tcpdump |
| 30 | + pwru |
| 31 | + ]; |
| 32 | + }) |
| 33 | + [ |
| 34 | + "server" |
| 35 | + "client" |
| 36 | + "nat64gw" |
| 37 | + ] |
| 38 | + ); |
| 39 | + |
| 40 | + testScript = |
| 41 | + let |
| 42 | + curl = lib.getExe pkgs.curl; |
| 43 | + dig = lib.getExe pkgs.dig; |
| 44 | + jq = lib.getExe pkgs.jq; |
| 45 | + in |
| 46 | + '' |
| 47 | + start_all() |
| 48 | +
|
| 49 | + for m in [server, nat64gw, client]: |
| 50 | + m.wait_for_unit("network.target") |
| 51 | +
|
| 52 | + server.wait_for_unit("nginx.service") |
| 53 | + server.wait_for_unit("bind.service") |
| 54 | + nat64gw.wait_for_unit("dnsmasq.service") |
| 55 | + nat64gw.wait_for_unit("jool-nat64-eth2.service") |
| 56 | + nat64gw.wait_for_unit("radvd.service") |
| 57 | +
|
| 58 | + with subtest('ensure "public" dns server is working properly'): |
| 59 | + assert server.succeed("${dig} +short A example.com").strip() == "192.0.2.2" |
| 60 | + assert server.succeed("${dig} +short AAAA example.com").strip() == "" |
| 61 | +
|
| 62 | + with subtest('ensure http server is online'): |
| 63 | + server.succeed("${curl} -sI http://example.com") |
| 64 | +
|
| 65 | + with subtest('ensure ipv4 network between server and gateway is working'): |
| 66 | + server.succeed("ping -c 1 192.0.2.1") |
| 67 | + nat64gw.succeed("ping -c 1 192.0.2.2") |
| 68 | +
|
| 69 | + # first dig fails for whatever reason |
| 70 | + nat64gw.succeed("${dig} A example.com @2001:db8::1") |
| 71 | +
|
| 72 | + with subtest('ensure dns server on nat64gw works as expected'): |
| 73 | + assert nat64gw.succeed("${dig} +short A example.com @2001:db8::1").strip() == "192.0.2.2" |
| 74 | + assert nat64gw.succeed("${dig} +short AAAA example.com @2001:db8::1").strip() == "" |
| 75 | +
|
| 76 | + with subtest('ensure ipv6 network between gateway and client is working'): |
| 77 | + client.wait_until_succeeds(""" |
| 78 | + ip -j -6 a sh eth1 | \ |
| 79 | + ${jq} -r '.[] | .addr_info | .[] | select((.family == "inet6") and .dynamic == true) | .local' | \ |
| 80 | + grep 2001:db8 |
| 81 | + """) |
| 82 | + client.succeed("ping -6 -c 1 2001:db8::1") |
| 83 | +
|
| 84 | + with subtest('ensure dns works as expected from client, and there is no aaaa record'): |
| 85 | + assert client.succeed("${dig} +short A example.com @2001:db8::1").strip() == "192.0.2.2" |
| 86 | + assert client.succeed("${dig} +short AAAA example.com @2001:db8::1").strip() == "" |
| 87 | +
|
| 88 | + with subtest('ensure nat64 works as expected'): |
| 89 | + client.wait_until_succeeds("ping -6 -c 1 64:ff9b::192.0.2.2") |
| 90 | + client.wait_until_succeeds("${curl} -sI http://[64:ff9b::192.0.2.2] | grep 'HTTP/1.1 200 OK'") |
| 91 | +
|
| 92 | + # clat needs to be started after slaac, restarting it now should be sufficient |
| 93 | + client.succeed("systemctl restart clatd") |
| 94 | + client.wait_for_unit("clatd.service") |
| 95 | + client.wait_until_succeeds("ip link show clat") |
| 96 | +
|
| 97 | + with subtest('ensure clat uses correct address from ipv4 service continuity prefix'): |
| 98 | + client.wait_until_succeeds(""" |
| 99 | + ip -j -4 address sh clat | ${jq} -e -r '.[].addr_info.[].local == "192.0.0.1"' |
| 100 | + """) |
| 101 | +
|
| 102 | + with subtest('ensure clat created a ipv4 default route to attract ipv4 traffic'): |
| 103 | + client.wait_until_succeeds(""" |
| 104 | + ip -4 -j route show default | ${jq} -e -r '.[].dev == "clat"' |
| 105 | + """) |
| 106 | +
|
| 107 | + # for debugging purpose: |
| 108 | + print(client.succeed("${curl} -v http://example.com")) |
| 109 | + # connect to 192.0.2.2 port 80 from 192.0.0.1 port 37636 failed: No route to host |
| 110 | +
|
| 111 | + with subtest('ensure clat works as expected'): |
| 112 | + client.succeed("${curl} -sI http://example.com | grep 'HTTP/1.1 200 OK'") |
| 113 | + ''; |
| 114 | +} |
0 commit comments