# Server network configuration { config, lib, ... }: let # LXC containers on this host containers = lib.filterAttrs (_: { role, model, ... }: role == "container" && model == "lxc" ) config.site.hosts; # Every bridged veth network required by all containers bridgeNets = lib.lists.unique ( builtins.concatMap ({ interfaces, ... }: builtins.attrNames ( lib.filterAttrs (_: { type, ... }: type == "veth") interfaces )) (builtins.attrValues containers) ); # Every network (both veth+phys) required by all containers ctNets = lib.lists.unique ( builtins.concatMap ({ physicalInterfaces, ... }: builtins.attrNames physicalInterfaces ) (builtins.attrValues containers) ); in { networking.firewall = { enable = true; allowedTCPPorts = [ # SSH 22 ]; }; systemd.network = { enable = true; netdevs = { bond0.netdevConfig = { Kind = "bond"; Name = "bond0"; }; # LACP bond0.bondConfig.Mode = "802.3ad"; } // ( builtins.foldl' (result: net: result // { # Bridges are named just like the corresponding net. "${net}" = { netdevConfig = { Kind = "bridge"; Name = "${net}"; }; extraConfig = '' [Bridge] ForwardDelaySec=2 STP=true ''; }; }) {} bridgeNets ) // ( builtins.foldl' (result: net: result // { # External VLAN interfaces (to be attached to net bridges) are # named with an "ext-" prefix. "ext-${net}" = { netdevConfig = { Kind = "vlan"; Name = "ext-${net}"; }; vlanConfig.Id = config.site.net.${net}.vlan; }; }) {} ctNets ); networks = { en = { # physical ethernet ports matchConfig.Name = "en*"; networkConfig = { Bond = "bond0"; LLDP = true; EmitLLDP = true; }; }; bond0 = { DHCP = "no"; matchConfig.Name = "bond0"; networkConfig = { VLAN = map (net: "ext-${net}") ctNets; LinkLocalAddressing = "no"; LLDP = true; EmitLLDP = true; }; }; } // (builtins.foldl' (result: net: result // { "${net}" = { matchConfig.Name = net; networkConfig = { # Disable all automatic addressing on bridges. It will delay # networkd going into operational state. DHCP = lib.mkDefault "no"; LinkLocalAddressing = lib.mkDefault "no"; LLDP = true; EmitLLDP = true; }; }; }) {} bridgeNets) // builtins.foldl' (result: net: result // { "ext-${net}" = { matchConfig.Name = "ext-${net}"; # Attach eth*/bond0/VLAN to bridge networkConfig.Bridge = net; }; }) {} ctNets; wait-online.anyInterface = true; }; }