{ config, lib, ... }: with lib; let intf-mod = { name, ... }: { options = { enable = mkEnableOption "The interface ${name}."; poe = mkEnableOption "The PoE on interface ${name}."; ethernet-switching = { enable = mkEnableOption "The ethernet switching on interface ${name}."; interface-mode = mkOption { type = types.enum [ "trunk" "access" ]; }; vlans = mkOption { type = types.listOf (types.either types.str types.ints.unsigned); default = [ ]; }; }; inet = { enable = mkEnableOption "The ipv4 on the interface ${name}."; address = mkOption { type = types.listOf types.str; default = [ ]; }; }; inet6 = { enable = mkEnableOption "The ipv6 on the interface ${name}."; address = mkOption { type = types.listOf types.str; default = [ ]; }; }; }; }; cfg = config.dgn-interfaces; intf-list = config.netconf.mandatoryInterfaces; in { options.dgn-interfaces = mkOption { type = types.attrsOf (types.submodule intf-mod); default = { }; }; config = { interfaces = mapAttrs (_: intf: { inherit (intf) enable; unit."0".family = { inherit (intf) inet inet6 ethernet-switching; }; }) 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.enable) cfg); }; }