# TP-Link Omada SDN controller for sites with Omada APs/switches. There is no # nixpkgs package, so it runs as a podman container (mbentley/omada-controller, # the de-facto standard image). Host networking because device adoption relies # on L2 broadcast discovery (UDP 29810) on the mgmt VLAN; the default-deny # input firewall keeps its ports unreachable from WAN and non-mgmt VLANs. { settings }: { config, lib, ... }: let cfg = settings; in { config = lib.mkIf cfg.omada.enable { virtualisation.podman.enable = true; virtualisation.oci-containers = { backend = "podman"; containers.omada = { image = "docker.io/mbentley/omada-controller:5.15"; extraOptions = [ "--network=host" ]; environment.TZ = config.time.timeZone; volumes = [ "/var/lib/omada/data:/opt/tplink/EAPController/data" "/var/lib/omada/logs:/opt/tplink/EAPController/logs" ]; }; }; # Admin UI (8043) also reachable over the mesh, like Grafana on control. networking.firewall.extraInputRules = '' ip6 saddr ${cfg.mesh.subnet} tcp dport 8043 accept comment "omada ui over the mesh" ''; # Controller state (adopted devices, site config, cert) — declared as clan # state so a borgbackup client can pick it up; backup wiring is a later step. clan.core.state.omada.folders = [ "/var/lib/omada" ]; }; }