diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 503dd87ad4d9..8bdd6927c466 100755 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -254,6 +254,7 @@ ./services/networking/kippo.nix ./services/networking/mailpile.nix ./services/networking/minidlna.nix + ./services/networking/mstpd.nix ./services/networking/murmur.nix ./services/networking/nat.nix ./services/networking/networkmanager.nix diff --git a/nixos/modules/services/networking/mstpd.nix b/nixos/modules/services/networking/mstpd.nix new file mode 100644 index 000000000000..5d1fc4a65427 --- /dev/null +++ b/nixos/modules/services/networking/mstpd.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.mstpd; +in +with lib; +{ + options.services.mstpd = { + + enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable the multiple spanning tree protocol daemon. + ''; + }; + + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.mstpd ]; + + systemd.services.mstpd = { + description = "Multiple Spanning Tree Protocol Daemon"; + wantedBy = [ "network.target" ]; + unitConfig.ConditionCapability = "CAP_NET_ADMIN"; + serviceConfig = { + Type = "forking"; + ExecStart = "@${pkgs.mstpd}/bin/mstpd mstpd"; + PIDFile = "/run/mstpd.pid"; + }; + }; + }; +} diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 9d61a4b05301..da0d8530241b 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -37,6 +37,8 @@ let ip link del "${i}" 2>/dev/null || true ''; + needsMstpd = any ({ rstp, ... }: rstp) (attrValues cfg.bridges); + in { @@ -185,13 +187,14 @@ in in { description = "Bridge Interface ${n}"; wantedBy = [ "network.target" (subsystemDevice n) ]; - bindsTo = deps; - after = [ "network-pre.target" ] ++ deps + bindsTo = deps ++ optional v.rstp "mstpd.service"; + partOf = optional v.rstp "mstpd.service"; + after = [ "network-pre.target" "mstpd.service" ] ++ deps ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces; before = [ "network-interfaces.target" (subsystemDevice n) ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; - path = [ pkgs.iproute ]; + path = [ pkgs.iproute ] ++ optional v.rstp pkgs.mstpd; script = '' # Remove Dead Interfaces echo "Removing old bridge ${n}..." @@ -206,6 +209,13 @@ in ip link set "${i}" up '')} + # Enable rstp on the interface + ${optionalString v.rstp '' + echo 1 >/sys/class/net/${n}/bridge/stp_state + mstpctl addbridge "${n}" + mstpctl setforcevers "${n}" rstp + ''} + ip link set "${n}" up ''; postStop = '' @@ -343,6 +353,8 @@ in KERNEL=="tun", TAG+="systemd" ''; + services.mstpd = mkIf needsMstpd { enable = true; }; + }; } diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 4a272483e549..9f72e0f0d509 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -368,6 +368,13 @@ in "The physical network interfaces connected by the bridge."; }; + rstp = mkOption { + example = true; + default = false; + type = types.bool; + description = "Whether the bridge interface should enable rstp."; + }; + }; };