1{
2 runTest,
3 package,
4}:
5
6let
7 makeBirdHost =
8 hostId:
9 { pkgs, ... }:
10 {
11 virtualisation.vlans = [ 1 ];
12
13 environment.systemPackages = with pkgs; [ jq ];
14
15 networking = {
16 useNetworkd = true;
17 useDHCP = false;
18 firewall.enable = false;
19 };
20
21 systemd.network.networks."01-eth1" = {
22 name = "eth1";
23 networkConfig.Address = "10.0.0.${hostId}/24";
24 };
25
26 services.bird = {
27 inherit package;
28
29 enable = true;
30
31 config = ''
32 log syslog all;
33
34 debug protocols all;
35
36 router id 10.0.0.${hostId};
37
38 protocol device {
39 }
40
41 protocol kernel kernel4 {
42 ipv4 {
43 import none;
44 export all;
45 };
46 }
47
48 protocol static static4 {
49 ipv4;
50 include "static4.conf";
51 }
52
53 protocol ospf v2 ospf4 {
54 ipv4 {
55 export all;
56 };
57 area 0 {
58 interface "eth1" {
59 hello 5;
60 wait 5;
61 };
62 };
63 }
64
65 protocol kernel kernel6 {
66 ipv6 {
67 import none;
68 export all;
69 };
70 }
71
72 protocol static static6 {
73 ipv6;
74 include "static6.conf";
75 }
76
77 protocol ospf v3 ospf6 {
78 ipv6 {
79 export all;
80 };
81 area 0 {
82 interface "eth1" {
83 hello 5;
84 wait 5;
85 };
86 };
87 }
88 '';
89
90 preCheckConfig = ''
91 echo "route 1.2.3.4/32 blackhole;" > static4.conf
92 echo "route fd00::/128 blackhole;" > static6.conf
93 '';
94 };
95
96 systemd.tmpfiles.rules = [
97 "f /etc/bird/static4.conf - - - - route 10.10.0.${hostId}/32 blackhole;"
98 "f /etc/bird/static6.conf - - - - route fdff::${hostId}/128 blackhole;"
99 ];
100 };
101in
102{
103 twoNodeOSPF = runTest {
104 name = "bird-twoNodeOSPF";
105
106 nodes.host1 = makeBirdHost "1";
107 nodes.host2 = makeBirdHost "2";
108
109 testScript = ''
110 start_all()
111
112 host1.wait_for_unit("bird.service")
113 host2.wait_for_unit("bird.service")
114
115 host1.succeed("bird --version")
116 host2.succeed("bird --version")
117
118 host1.succeed("systemctl reload bird.service")
119
120 with subtest("Waiting for advertised IPv4 routes"):
121 host1.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.2\")) | any'")
122 host2.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.1\")) | any'")
123 with subtest("Waiting for advertised IPv6 routes"):
124 host1.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::2\")) | any'")
125 host2.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::1\")) | any'")
126
127 with subtest("Check fake routes in preCheckConfig do not exist"):
128 host1.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
129 host2.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
130
131 host1.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
132 host2.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
133 '';
134 };
135}