summaryrefslogtreecommitdiffstats
path: root/nixos/tests/frr.nix
blob: 615cd3caf89f1899d4044b4cda34103d62c78a8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# This test runs FRR and checks if OSPF routing works.
#
# Network topology:
#   [ client ]--net1--[ router1 ]--net2--[ router2 ]--net3--[ server ]
#
# All interfaces are in OSPF Area 0.

{ pkgs, ... }:
let

  ifAddr = node: iface: (pkgs.lib.head node.networking.interfaces.${iface}.ipv4.addresses).address;

  ospfConf1 = ''
    interface eth2
      ip ospf hello-interval 1
      ip ospf dead-interval 5
    !
    router ospf
      network 192.168.0.0/16 area 0
  '';

  ospfConf2 = ''
    interface eth2
      ip ospf hello-interval 1
      ip ospf dead-interval 5
    !
    router ospf
      network 192.168.0.0/16 area 0
  '';

in
{
  name = "frr";

  meta = {
    maintainers = [ ];
  };

  nodes = {

    client =
      { nodes, ... }:
      {
        virtualisation.vlans = [ 1 ];
        services.frr = {
          config = ''
            ip route 192.168.0.0/16 ${ifAddr nodes.router1 "eth1"}
          '';
        };
      };

    router1 =
      { ... }:
      {
        virtualisation.vlans = [
          1
          2
        ];
        boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
        networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
        services.frr = {
          ospfd.enable = true;
          config = ospfConf1;
        };

        specialisation.ospf.configuration = {
          services.frr.config = ospfConf2;
        };
      };

    router2 =
      { ... }:
      {
        virtualisation.vlans = [
          3
          2
        ];
        boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
        networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
        services.frr = {
          ospfd.enable = true;
          config = ospfConf2;
        };
      };

    server =
      { nodes, ... }:
      {
        virtualisation.vlans = [ 3 ];
        services.frr = {
          config = ''
            ip route 192.168.0.0/16 ${ifAddr nodes.router2 "eth1"}
          '';
        };
      };
  };

  testScript =
    { nodes, ... }:
    ''
      start_all()

      # Wait for the networking to start on all machines
      for machine in client, router1, router2, server:
          machine.wait_for_unit("network.target")

      with subtest("Wait for FRR"):
          for gw in client, router1, router2, server:
              gw.wait_for_unit("frr")

      router1.succeed("${nodes.router1.system.build.toplevel}/specialisation/ospf/bin/switch-to-configuration test >&2")

      with subtest("Wait for OSPF to form adjacencies"):
          for gw in router1, router2:
              gw.wait_until_succeeds("vtysh -c 'show ip ospf neighbor' | grep Full")
              gw.wait_until_succeeds("vtysh -c 'show ip route' | grep '^O>'")

      with subtest("Test ICMP"):
          client.wait_until_succeeds("ping -4 -c 3 server >&2")
    '';
}