Netconf-Module/dgn-module.nix
2024-12-13 14:37:43 +01:00

119 lines
3.7 KiB
Nix

{ config, lib, ... }:
let
inherit (lib)
mkEnableOption
mkOption
filterAttrs
mapAttrs
attrNames
mkIf
;
inherit (lib.types)
nullOr
enum
listOf
either
str
ints
attrsOf
submodule
;
intf-mod =
{ 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 intf-mod);
default = { };
description = ''
Unified configuration of interfaces adapted to DGNum usage:
- each interfaces have 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);
};
}