nixos/networkd: add [Bridge] section to netdev conf
This setting was missing from netdev. This commit additionally adds a test using the new section, ensuring that STP can be enabled.
This commit is contained in:
parent
ed817f4699
commit
ed854ed0e3
5 changed files with 153 additions and 0 deletions
|
@ -148,6 +148,10 @@ in rec {
|
|||
optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name}))
|
||||
"Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]";
|
||||
|
||||
assertRangeOrOneOf = name: min: max: values: group: attr:
|
||||
optional (attr ? ${name} && !((min <= attr.${name} && max >= attr.${name}) || elem attr.${name} values))
|
||||
"Systemd ${group} field `${name}' is not a value in range [${toString min},${toString max}], or one of ${toString values}";
|
||||
|
||||
assertMinimum = name: min: group: attr:
|
||||
optional (attr ? ${name} && attr.${name} < min)
|
||||
"Systemd ${group} field `${name}' must be greater than or equal to ${toString min}";
|
||||
|
|
|
@ -25,6 +25,9 @@ in {
|
|||
commonMatchText def + ''
|
||||
[NetDev]
|
||||
${attrsToSection def.netdevConfig}
|
||||
'' + optionalString (def.bridgeConfig != { }) ''
|
||||
[Bridge]
|
||||
${attrsToSection def.bridgeConfig}
|
||||
'' + optionalString (def.vlanConfig != { }) ''
|
||||
[VLAN]
|
||||
${attrsToSection def.vlanConfig}
|
||||
|
|
|
@ -186,6 +186,37 @@ let
|
|||
(assertNetdevMacAddress "MACAddress")
|
||||
];
|
||||
|
||||
sectionBridge = checkUnitConfig "Bridge" [
|
||||
(assertOnlyFields [
|
||||
"HelloTimeSec"
|
||||
"MaxAgeSec"
|
||||
"ForwardDelaySec"
|
||||
"AgeingTimeSec"
|
||||
"Priority"
|
||||
"GroupForwardMask"
|
||||
"DefaultPVID"
|
||||
"MulticastQuerier"
|
||||
"MulticastSnooping"
|
||||
"VLANFiltering"
|
||||
"VLANProtocol"
|
||||
"STP"
|
||||
"MulticastIGMPVersion"
|
||||
])
|
||||
(assertInt "HelloTimeSec")
|
||||
(assertInt "MaxAgeSec")
|
||||
(assertInt "ForwardDelaySec")
|
||||
(assertInt "AgeingTimeSec")
|
||||
(assertRange "Priority" 0 65535)
|
||||
(assertRange "GroupForwardMask" 0 65535)
|
||||
(assertRangeOrOneOf "DefaultPVID" 0 4094 ["none"])
|
||||
(assertValueOneOf "MulticastQuerier" boolValues)
|
||||
(assertValueOneOf "MulticastSnooping" boolValues)
|
||||
(assertValueOneOf "VLANFiltering" boolValues)
|
||||
(assertValueOneOf "VLANProtocol" ["802.1q" "802.ad"])
|
||||
(assertValueOneOf "STP" boolValues)
|
||||
(assertValueOneOf "MulticastIGMPVersion" [2 3])
|
||||
];
|
||||
|
||||
sectionVLAN = checkUnitConfig "VLAN" [
|
||||
(assertOnlyFields [
|
||||
"Id"
|
||||
|
@ -1635,6 +1666,17 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
bridgeConfig = mkOption {
|
||||
default = {};
|
||||
example = { STP = true; };
|
||||
type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionBridge;
|
||||
description = ''
|
||||
Each attribute in this set specifies an option in the
|
||||
`[Bridge]` section of the unit. See
|
||||
{manpage}`systemd.netdev(5)` for details.
|
||||
'';
|
||||
};
|
||||
|
||||
vlanConfig = mkOption {
|
||||
default = {};
|
||||
example = { Id = 4; };
|
||||
|
|
|
@ -899,6 +899,7 @@ in {
|
|||
systemd-lock-handler = runTestOn ["aarch64-linux" "x86_64-linux"] ./systemd-lock-handler.nix;
|
||||
systemd-machinectl = handleTest ./systemd-machinectl.nix {};
|
||||
systemd-networkd = handleTest ./systemd-networkd.nix {};
|
||||
systemd-networkd-bridge = handleTest ./systemd-networkd-bridge.nix {};
|
||||
systemd-networkd-dhcpserver = handleTest ./systemd-networkd-dhcpserver.nix {};
|
||||
systemd-networkd-dhcpserver-static-leases = handleTest ./systemd-networkd-dhcpserver-static-leases.nix {};
|
||||
systemd-networkd-ipv6-prefix-delegation = handleTest ./systemd-networkd-ipv6-prefix-delegation.nix {};
|
||||
|
|
103
nixos/tests/systemd-networkd-bridge.nix
Normal file
103
nixos/tests/systemd-networkd-bridge.nix
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* This test ensures that we can configure spanning-tree protocol
|
||||
across bridges using systemd-networkd.
|
||||
|
||||
Test topology:
|
||||
|
||||
1 2 3
|
||||
node1 --- sw1 --- sw2 --- node2
|
||||
\ /
|
||||
4 \ / 5
|
||||
sw3
|
||||
|
|
||||
6 |
|
||||
|
|
||||
node3
|
||||
|
||||
where switches 1, 2, and 3 bridge their links and use STP,
|
||||
and each link is labeled with the VLAN we are assigning it in
|
||||
virtualisation.vlans.
|
||||
*/
|
||||
with builtins;
|
||||
let
|
||||
commonConf = {
|
||||
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
networking.useNetworkd = true;
|
||||
networking.useDHCP = false;
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
|
||||
generateNodeConf = { octet, vlan }:
|
||||
{ lib, pkgs, config, ... }: {
|
||||
imports = [ common/user-account.nix commonConf ];
|
||||
virtualisation.vlans = [ vlan ];
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
"30-eth" = {
|
||||
matchConfig.Name = "eth1";
|
||||
address = [ "10.0.0.${toString octet}/24" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
generateSwitchConf = vlans:
|
||||
{ lib, pkgs, config, ... }: {
|
||||
imports = [ common/user-account.nix commonConf ];
|
||||
virtualisation.vlans = vlans;
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
netdevs = {
|
||||
"40-br0" = {
|
||||
netdevConfig = {
|
||||
Kind = "bridge";
|
||||
Name = "br0";
|
||||
};
|
||||
bridgeConfig.STP = "yes";
|
||||
};
|
||||
};
|
||||
networks = {
|
||||
"30-eth" = {
|
||||
matchConfig.Name = "eth*";
|
||||
networkConfig.Bridge = "br0";
|
||||
};
|
||||
"40-br0" = { matchConfig.Name = "br0"; };
|
||||
};
|
||||
};
|
||||
};
|
||||
in import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "networkd";
|
||||
meta = with pkgs.lib.maintainers; { maintainers = [ picnoir ]; };
|
||||
nodes = {
|
||||
node1 = generateNodeConf {
|
||||
octet = 1;
|
||||
vlan = 1;
|
||||
};
|
||||
node2 = generateNodeConf {
|
||||
octet = 2;
|
||||
vlan = 3;
|
||||
};
|
||||
node3 = generateNodeConf {
|
||||
octet = 3;
|
||||
vlan = 6;
|
||||
};
|
||||
sw1 = generateSwitchConf [ 1 2 4 ];
|
||||
sw2 = generateSwitchConf [ 2 3 5 ];
|
||||
sw3 = generateSwitchConf [ 4 5 6 ];
|
||||
};
|
||||
testScript = ''
|
||||
network_nodes = [node1, node2, node3]
|
||||
network_switches = [sw1, sw2, sw3]
|
||||
start_all()
|
||||
|
||||
for n in network_nodes + network_switches:
|
||||
n.wait_for_unit("systemd-networkd-wait-online.service")
|
||||
|
||||
node1.succeed("ping 10.0.0.2 -w 10 -c 1")
|
||||
node1.succeed("ping 10.0.0.3 -w 10 -c 1")
|
||||
node2.succeed("ping 10.0.0.1 -w 10 -c 1")
|
||||
node2.succeed("ping 10.0.0.3 -w 10 -c 1")
|
||||
node3.succeed("ping 10.0.0.1 -w 10 -c 1")
|
||||
node3.succeed("ping 10.0.0.2 -w 10 -c 1")
|
||||
'';
|
||||
})
|
Loading…
Reference in a new issue