112 lines
3.6 KiB
Nix
112 lines
3.6 KiB
Nix
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 {
|
|
# FIXME : support ipv4 and ipv6, either static or dhcp (with the coffee)
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
};
|
|
};
|
|
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 "<disable/>" else "";
|
|
# FIXME : need to enforce address in reality
|
|
mgmt_fam = if !builtins.isNull cfg.interfaces.${name}.management then ''
|
|
<inet>
|
|
<address>
|
|
${cfg.interfaces.${name}.management}
|
|
</address>
|
|
</inet>'' else "";
|
|
members = map (vlan: "<members>${builtins.toString vlan}</members>") cfg.interfaces.${name}.vlans;
|
|
eth_switch = if builtins.isNull cfg.interfaces.${name}.interface-mode then "" else ''
|
|
<ethernet-switching>
|
|
<interface-mode>${cfg.interfaces.${name}.interface-mode}</interface-mode>
|
|
<vlan>${builtins.concatStringsSep "" members}</vlan>
|
|
</ethernet-switching>'';
|
|
in ''
|
|
<interface>
|
|
<name>${name}</name>
|
|
${disable_flag}
|
|
<unit>
|
|
<name>0</name>
|
|
<family>
|
|
${mgmt_fam}
|
|
${eth_switch}
|
|
</family>
|
|
</unit>
|
|
</interface>'';
|
|
interface_xmls = map intf_xmlGen interfaces;
|
|
vlan_trust_table = let
|
|
vlan_map = inter: vlan:
|
|
if builtins.isString vlan && cfg.interfaces.${inter}.enable 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 ''<vlan-id-list>${list}</vlan-id-list>'';
|
|
vlan_map = vlan: let
|
|
ids = map id_map cfg.vlans.${vlan};
|
|
in ''
|
|
<vlan>
|
|
<name>${vlan}</name>
|
|
${builtins.concatStringsSep "\n" ids}
|
|
</vlan>'';
|
|
in map vlan_map (builtins.attrNames cfg.vlans);
|
|
in [ ''
|
|
<interfaces>
|
|
${builtins.concatStringsSep "\n" interface_xmls}
|
|
</interfaces>
|
|
<vlans>
|
|
${builtins.concatStringsSep "\n" vlans}
|
|
</vlans>'' vlan_trust_table
|
|
];
|
|
}
|