# 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. { config, lib, ... }: let cfg = config.cnx.router; mesh = import ../mesh-hosts.nix { inherit config lib; }; in { options.cnx.router.omada.enable = lib.mkEnableOption "TP-Link Omada SDN controller (podman container)"; config = lib.mkIf (cfg.enable && 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 ${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" ]; }; }