1# This test runs FRR and checks if OSPF routing works.
2#
3# Network topology:
4# [ client ]--net1--[ router1 ]--net2--[ router2 ]--net3--[ server ]
5#
6# All interfaces are in OSPF Area 0.
7
8{ pkgs, ... }:
9let
10
11 ifAddr = node: iface: (pkgs.lib.head node.networking.interfaces.${iface}.ipv4.addresses).address;
12
13 ospfConf1 = ''
14 interface eth2
15 ip ospf hello-interval 1
16 ip ospf dead-interval 5
17 !
18 router ospf
19 network 192.168.0.0/16 area 0
20 '';
21
22 ospfConf2 = ''
23 interface eth2
24 ip ospf hello-interval 1
25 ip ospf dead-interval 5
26 !
27 router ospf
28 network 192.168.0.0/16 area 0
29 '';
30
31in
32{
33 name = "frr";
34
35 meta = with pkgs.lib.maintainers; {
36 maintainers = [ ];
37 };
38
39 nodes = {
40
41 client =
42 { nodes, ... }:
43 {
44 virtualisation.vlans = [ 1 ];
45 services.frr = {
46 config = ''
47 ip route 192.168.0.0/16 ${ifAddr nodes.router1 "eth1"}
48 '';
49 };
50 };
51
52 router1 =
53 { ... }:
54 {
55 virtualisation.vlans = [
56 1
57 2
58 ];
59 boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
60 networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
61 services.frr = {
62 ospfd.enable = true;
63 config = ospfConf1;
64 };
65
66 specialisation.ospf.configuration = {
67 services.frr.config = ospfConf2;
68 };
69 };
70
71 router2 =
72 { ... }:
73 {
74 virtualisation.vlans = [
75 3
76 2
77 ];
78 boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
79 networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
80 services.frr = {
81 ospfd.enable = true;
82 config = ospfConf2;
83 };
84 };
85
86 server =
87 { nodes, ... }:
88 {
89 virtualisation.vlans = [ 3 ];
90 services.frr = {
91 config = ''
92 ip route 192.168.0.0/16 ${ifAddr nodes.router2 "eth1"}
93 '';
94 };
95 };
96 };
97
98 testScript =
99 { nodes, ... }:
100 ''
101 start_all()
102
103 # Wait for the networking to start on all machines
104 for machine in client, router1, router2, server:
105 machine.wait_for_unit("network.target")
106
107 with subtest("Wait for FRR"):
108 for gw in client, router1, router2, server:
109 gw.wait_for_unit("frr")
110
111 router1.succeed("${nodes.router1.system.build.toplevel}/specialisation/ospf/bin/switch-to-configuration test >&2")
112
113 with subtest("Wait for OSPF to form adjacencies"):
114 for gw in router1, router2:
115 gw.wait_until_succeeds("vtysh -c 'show ip ospf neighbor' | grep Full")
116 gw.wait_until_succeeds("vtysh -c 'show ip route' | grep '^O>'")
117
118 with subtest("Test ICMP"):
119 client.wait_until_succeeds("ping -4 -c 3 server >&2")
120 '';
121}