interfaces: { lib, config, ... }: let cfg = config; in with lib; { options = { vlans = let range_type.options = { begin = mkOption { type = types.ints.unsigned; }; end = mkOption { type = types.ints.unsigned; }; }; in mkOption { type = types.attrsOf (types.listOf (types.either types.ints.unsigned (types.submodule range_type))); }; interfaces = let template = name: { enable = mkEnableOption "the interface ${name}"; interface-mode = mkOption { type = types.nullOr (types.enum [ "trunk" "access" ]); default = null; }; vlans = mkOption { type = let vlan_type = types.either (types.strMatching "[^\n\r]+") (types.ints.unsigned); in types.listOf vlan_type; default = [ ]; }; dhcp_trusted = mkOption { type = types.bool; default = false; }; management = mkOption { type = types.bool; default = false; }; }; in builtins.listToAttrs (map (name: { inherit name; value = template name; }) interfaces); toplevel = mkOption { type = types.unspecified; visible = false; readOnly = true; }; }; config.toplevel = let intf_xmlGen = name: let disable_flag = if !cfg.interfaces.${name}.enable then "" else ""; # FIXME : need to enforce address in reality mgmt_fam = if cfg.interfaces.${name}.management then "" else ""; members = map (vlan: "${builtins.toString vlan}") cfg.interfaces.${name}.vlans; eth_switch = if builtins.isNull cfg.interfaces.${name}.interface-mode then "" else '' ${cfg.interfaces.${name}.interface-mode} ${builtins.concatStringsSep "" members} ''; in '' ${name} ${disable_flag} 0 ${mgmt_fam} ${eth_switch} ''; interface_xmls = map intf_xmlGen interfaces; vlan_trust_table = let vlan_map = inter: vlan: if builtins.isString vlan then if cfg.interfaces.${inter}.dhcp_trusted then { ${vlan}.trust = inter; } else { ${vlan}.notrust = inter; } else {}; int_map = inter: map (vlan_map inter) cfg.interfaces.${inter}.vlans; in builtins.zipAttrsWith (vlan: values: builtins.zipAttrsWith (_: ints: ints ) values) (builtins.concatMap int_map interfaces); vlans = let id_map = id: let list = if builtins.isInt id then builtins.toString id else "${builtins.toString id.begin}-${builtins.toString id.end}"; in ''${list}''; vlan_map = vlan: let ids = map id_map cfg.vlans.${vlan}; in '' ${vlan} ${builtins.concatStringsSep "\n" ids} ''; in map vlan_map (builtins.attrNames cfg.vlans); in [ '' ${builtins.concatStringsSep "\n" interface_xmls} ${builtins.concatStringsSep "\n" vlans} '' vlan_trust_table ]; }