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