Merge pull request #308829 from r-ryantm/auto-update/qlog
[NixPkgs.git] / nixos / tests / clatd.nix
blob00021d87ba5f4727fbf5fa94fb5c6fb2de167bb8
1 # This test verifies that we can ping an IPv4-only server from an IPv6-only
2 # client via a NAT64 router using CLAT on the client. The hosts and networks
3 # are configured as follows:
5 #        +------
6 # Client | clat    Address: 192.0.0.1/32  (configured via clatd)
7 #        |         Route:   default
8 #        |
9 #        | eth1    Address: 2001:db8::2/64
10 #        |  |      Route:   default via 2001:db8::1
11 #        +--|---
12 #           | VLAN 3
13 #        +--|---
14 #        | eth2    Address: 2001:db8::1/64
15 # Router |
16 #        | nat64   Address: 64:ff9b::1/128
17 #        |         Route:   64:ff9b::/96
18 #        |         Address: 192.0.2.0/32
19 #        |         Route:   192.0.2.0/24
20 #        |
21 #        | eth1    Address: 100.64.0.1/24
22 #        +--|---
23 #           | VLAN 2
24 #        +--|---
25 # Server | eth1    Address: 100.64.0.2/24
26 #        |         Route:   192.0.2.0/24 via 100.64.0.1
27 #        +------
29 import ./make-test-python.nix ({ pkgs, lib, ... }:
32   name = "clatd";
33   meta = with pkgs.lib.maintainers; {
34     maintainers = [ hax404 ];
35   };
37   nodes = {
38     # The server is configured with static IPv4 addresses. RFC 6052 Section 3.1
39     # disallows the mapping of non-global IPv4 addresses like RFC 1918 into the
40     # Well-Known Prefix 64:ff9b::/96. TAYGA also does not allow the mapping of
41     # documentation space (RFC 5737). To circumvent this, 100.64.0.2/24 from
42     # RFC 6589 (Carrier Grade NAT) is used here.
43     # To reach the IPv4 address pool of the NAT64 gateway, there is a static
44     # route configured. In normal cases, where the router would also source NAT
45     # the pool addresses to one IPv4 addresses, this would not be needed.
46     server = {
47       virtualisation.vlans = [
48         2 # towards router
49       ];
50       networking = {
51         useDHCP = false;
52         interfaces.eth1 = lib.mkForce {};
53       };
54       systemd.network = {
55         enable = true;
56         networks."vlan1" = {
57           matchConfig.Name = "eth1";
58           address = [
59             "100.64.0.2/24"
60           ];
61           routes = [
62             { routeConfig = { Destination = "192.0.2.0/24"; Gateway = "100.64.0.1"; }; }
63           ];
64         };
65       };
66     };
68     # The router is configured with static IPv4 addresses towards the server
69     # and IPv6 addresses towards the client. For NAT64, the Well-Known prefix
70     # 64:ff9b::/96 is used. NAT64 is done with TAYGA which provides the
71     # tun-interface nat64 and does the translation over it. The IPv6 packets
72     # are sent to this interfaces and received as IPv4 packets and vice versa.
73     # As TAYGA only translates IPv6 addresses to dedicated IPv4 addresses, it
74     # needs a pool of IPv4 addresses which must be at least as big as the
75     # expected amount of clients. In this test, the packets from the pool are
76     # directly routed towards the client. In normal cases, there would be a
77     # second source NAT44 to map all clients behind one IPv4 address.
78     router = {
79       boot.kernel.sysctl = {
80         "net.ipv4.ip_forward" = 1;
81         "net.ipv6.conf.all.forwarding" = 1;
82       };
84       virtualisation.vlans = [
85         2 # towards server
86         3 # towards client
87       ];
89       networking = {
90         useDHCP = false;
91         useNetworkd = true;
92         firewall.enable = false;
93         interfaces.eth1 = lib.mkForce {
94           ipv4 = {
95             addresses = [ { address = "100.64.0.1"; prefixLength = 24; } ];
96           };
97         };
98         interfaces.eth2 = lib.mkForce {
99           ipv6 = {
100             addresses = [ { address = "2001:db8::1"; prefixLength = 64; } ];
101           };
102         };
103       };
105       services.tayga = {
106         enable = true;
107         ipv4 = {
108           address = "192.0.2.0";
109           router = {
110             address = "192.0.2.1";
111           };
112           pool = {
113             address = "192.0.2.0";
114             prefixLength = 24;
115           };
116         };
117         ipv6 = {
118           address = "2001:db8::1";
119           router = {
120             address = "64:ff9b::1";
121           };
122           pool = {
123             address = "64:ff9b::";
124             prefixLength = 96;
125           };
126         };
127       };
128     };
130     # The client is configured with static IPv6 addresses. It has also a static
131     # default route towards the router. To reach the IPv4-only server, the
132     # client starts the clat daemon which starts and configures the local
133     # IPv4 -> IPv6 translation via Tayga.
134     client = {
135       virtualisation.vlans = [
136         3 # towards router
137       ];
139       networking = {
140         useDHCP = false;
141         interfaces.eth1 = lib.mkForce {};
142       };
144       systemd.network = {
145         enable = true;
146         networks."vlan1" = {
147           matchConfig.Name = "eth1";
148           address = [
149             "2001:db8::2/64"
150           ];
151           routes = [
152             { routeConfig = { Destination = "::/0"; Gateway = "2001:db8::1"; }; }
153           ];
154         };
155       };
157       services.clatd = {
158         enable = true;
159         settings.plat-prefix = "64:ff9b::/96";
160       };
162       environment.systemPackages = [ pkgs.mtr ];
163     };
164   };
166   testScript = ''
167     start_all()
169     # wait for all machines to start up
170     for machine in client, router, server:
171       machine.wait_for_unit("network-online.target")
173     with subtest("Wait for tayga and clatd"):
174       router.wait_for_unit("tayga.service")
175       client.wait_for_unit("clatd.service")
176       # clatd checks if this system has IPv4 connectivity for 10 seconds
177       client.wait_until_succeeds(
178         'journalctl -u clatd -e | grep -q "Starting up TAYGA, using config file"'
179       )
181     with subtest("Test ICMP"):
182       client.wait_until_succeeds("ping -c 3 100.64.0.2 >&2")
184     with subtest("Test ICMP and show a traceroute"):
185       client.wait_until_succeeds("mtr --show-ips --report-wide 100.64.0.2 >&2")
187     client.log(client.execute("systemd-analyze security clatd.service")[1])
188   '';