1/*
2 This test ensures that we can configure spanning-tree protocol
3 across bridges using systemd-networkd.
4
5 Test topology:
6
7 1 2 3
8 node1 --- sw1 --- sw2 --- node2
9 \ /
10 4 \ / 5
11 sw3
12 |
13 6 |
14 |
15 node3
16
17 where switches 1, 2, and 3 bridge their links and use STP,
18 and each link is labeled with the VLAN we are assigning it in
19 virtualisation.vlans.
20*/
21with builtins;
22let
23 commonConf = {
24 systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
25 networking.useNetworkd = true;
26 networking.useDHCP = false;
27 networking.firewall.enable = false;
28 };
29
30 generateNodeConf =
31 { octet, vlan }:
32 {
33 lib,
34 pkgs,
35 config,
36 ...
37 }:
38 {
39 imports = [
40 common/user-account.nix
41 commonConf
42 ];
43 virtualisation.vlans = [ vlan ];
44 systemd.network = {
45 enable = true;
46 networks = {
47 "30-eth" = {
48 matchConfig.Name = "eth1";
49 address = [ "10.0.0.${toString octet}/24" ];
50 };
51 };
52 };
53 };
54
55 generateSwitchConf =
56 vlans:
57 {
58 lib,
59 pkgs,
60 config,
61 ...
62 }:
63 {
64 imports = [
65 common/user-account.nix
66 commonConf
67 ];
68 virtualisation.vlans = vlans;
69 systemd.network = {
70 enable = true;
71 netdevs = {
72 "40-br0" = {
73 netdevConfig = {
74 Kind = "bridge";
75 Name = "br0";
76 };
77 bridgeConfig.STP = "yes";
78 };
79 };
80 networks = {
81 "30-eth" = {
82 matchConfig.Name = "eth*";
83 networkConfig.Bridge = "br0";
84 };
85 "40-br0" = {
86 matchConfig.Name = "br0";
87 };
88 };
89 };
90 };
91in
92import ./make-test-python.nix (
93 { pkgs, ... }:
94 {
95 name = "networkd";
96 meta = with pkgs.lib.maintainers; {
97 maintainers = [ picnoir ];
98 };
99 nodes = {
100 node1 = generateNodeConf {
101 octet = 1;
102 vlan = 1;
103 };
104 node2 = generateNodeConf {
105 octet = 2;
106 vlan = 3;
107 };
108 node3 = generateNodeConf {
109 octet = 3;
110 vlan = 6;
111 };
112 sw1 = generateSwitchConf [
113 1
114 2
115 4
116 ];
117 sw2 = generateSwitchConf [
118 2
119 3
120 5
121 ];
122 sw3 = generateSwitchConf [
123 4
124 5
125 6
126 ];
127 };
128 testScript = ''
129 network_nodes = [node1, node2, node3]
130 network_switches = [sw1, sw2, sw3]
131 start_all()
132
133 for n in network_nodes + network_switches:
134 n.systemctl("start systemd-networkd-wait-online.service")
135 n.wait_for_unit("systemd-networkd-wait-online.service")
136
137 node1.succeed("ping 10.0.0.2 -w 10 -c 1")
138 node1.succeed("ping 10.0.0.3 -w 10 -c 1")
139 node2.succeed("ping 10.0.0.1 -w 10 -c 1")
140 node2.succeed("ping 10.0.0.3 -w 10 -c 1")
141 node3.succeed("ping 10.0.0.1 -w 10 -c 1")
142 node3.succeed("ping 10.0.0.2 -w 10 -c 1")
143 '';
144 }
145)