infrastructure/modules/netconf/dgn-interfaces.nix

131 lines
3.9 KiB
Nix

# SPDX-FileCopyrightText: 2024 Lubin Bailly <lubin.bailly@dgnum.eu>
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
{ 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);
};
}