diff --git a/modules/netconf/default.nix b/modules/netconf/default.nix index ed754d7..adb5dc0 100644 --- a/modules/netconf/default.nix +++ b/modules/netconf/default.nix @@ -2,5 +2,6 @@ imports = [ # List of modules to import ./dgn-hardware + ./dgn-interfaces.nix ]; } diff --git a/modules/netconf/dgn-interfaces.nix b/modules/netconf/dgn-interfaces.nix new file mode 100644 index 0000000..4cac980 --- /dev/null +++ b/modules/netconf/dgn-interfaces.nix @@ -0,0 +1,126 @@ +{ config, lib, ... }: + +let + inherit (lib) + attrNames + filterAttrs + mapAttrs + mkEnableOption + mkIf + mkOption + removeAttrs + ; + + inherit (lib.types) + attrsOf + either + enum + ints + listOf + nullOr + str + submodule + ; + + interfaceOption = + { config, ... }: + { + options = { + enable = mkEnableOption "this interface" // { + default = config.inet.enable || config.inet6.enable || config.ethernet-switching.enable; + defaultText = ''config.inet.enable || config.inet6.enable || config.ethernet-switching.enable''; + }; + poe = mkEnableOption "the PoE on this interface"; + ethernet-switching = { + enable = mkEnableOption "the ethernet switching on this interface" // { + default = config.ethernet-switching.interface-mode != null; + defaultText = ''config.ethernet-switching.interface-mode != null''; + }; + rstp = mkEnableOption "RSTP on this interface" // { + default = config.ethernet-switching.enable; + defaultText = ''config.ethernet-switching.enable''; + }; + interface-mode = mkOption { + type = nullOr (enum [ + "trunk" + "access" + ]); + default = null; + description = '' + Mode of operation for vlan addressing of this interface. + "trunk" means that the traffic is tagged, "access" means the + traffic is tagged by the switch. + Use null to desactivate the switching. + ''; + }; + vlans = mkOption { + type = listOf (either str ints.unsigned); + default = [ ]; + description = '' + Vlans that can be used on this interface. + Only one ID should be here for "access" mode of operation. + ''; + }; + }; + inet = { + enable = mkEnableOption "the ipv4 on this interface" // { + default = config.inet.addresses != [ ]; + defaultText = ''config.inet.addresses != [ ]''; + }; + addresses = mkOption { + type = listOf str; + default = [ ]; + description = '' + ipv4 addresses of this interface. + ''; + }; + }; + inet6 = { + enable = mkEnableOption "the ipv6 on this interface" // { + default = config.inet6.addresses != [ ]; + defaultText = ''config.inet6.addresses != [ ]''; + }; + addresses = mkOption { + type = listOf str; + default = [ ]; + description = '' + ipv6 addresses of this interface. + ''; + }; + }; + }; + }; + + cfg = config.dgn-interfaces; +in + +{ + options.dgn-interfaces = mkOption { + type = attrsOf (submodule interfaceOption); + default = { }; + description = '' + Unified configuration of interfaces adapted to DGNum usage: + + - each interface has only one logical subinterface; + - enabling ethernet-switching also enable RSTP; + - automatic enabling interface and relevant config family when configuring; + - allows enabling PoE along other configurations. + ''; + }; + + config = { + interfaces = mapAttrs (_: intf: { + inherit (intf) enable; + unit."0".family = { + inherit (intf) inet inet6; + ethernet-switching = mkIf intf.ethernet-switching.enable ( + removeAttrs intf.ethernet-switching [ "rstp" ] + ); + }; + }) cfg; + poe.interfaces = filterAttrs ( + name: _: config.netconf.mandatoryInterfaces.${name}.supportPoE or false + ) (mapAttrs (_: intf: { enable = intf.poe; }) cfg); + protocols.rstp = attrNames (filterAttrs (_: intf: intf.ethernet-switching.rstp) cfg); + }; +}