{ config, pkgs, lib, cfg, ... }: let prefix = "meshconfig"; # function to make a peerlist suitable for wgautomesh buildPeerlist = version: hosts: let #filter out hosts that have wg.enabled set to false wgEnabledHosts = lib.filterAttrs (_: host: host.wg.enabled or false) hosts; #filter out hosts that don't support IP{$version} filteredHosts = lib.filterAttrs (_: host: host.${version}.public != "") wgEnabledHosts; in lib.mapAttrs (name: host: { pubkey = host.wg.pubkey; #if there is no public IP, make endpoint null so wgautomesh knows it unknown endpoint = if host.${version}.public == "" then null else host.${version}.public; address = host.${version}.internal; }) filteredHosts; # helper vars to prettify meshnetwork = config.${prefix}.network; currentHost = meshnetwork.hosts.${config.networking.hostName}; wireguardPort = currentHost.wg.port; in { opt.useIPv6 = lib.mkOption { type = lib.types.bool; description = "Whether to use IPv6. Defaults to true"; default = true; }; networking.wireguard.interfaces.wg0 = { ips = if cfg.useIPv6 then ["${meshnetwork.wg_subnets.IPv6}"] else ["${meshnetwork.wg_subnets.IPv4}"]; listenPort = cfg.wireguardPort; privateKeyFile = "/var/lib/wireguard-keys/private"; mtu = 1420; }; services.wgautomesh = { enable = true; services.wgautomesh.settings = { interface = "wg0"; peers = if cfg.useIPv6 then buildPeerlist "v6" meshnetwork.hosts else buildPeerlist "v4" meshnetwork.hosts; upnp_forward_external_port = wireguardPort; }; }; }