{ config, pkgs, lib, cfg, ... }: let prefix = "lyn"; # 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 = 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; }; config = { 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; settings = { interface = "wg0"; peers = if cfg.useIPv6 then buildPeerlist "v6" meshnetwork.hosts else buildPeerlist "v4" meshnetwork.hosts; upnp_forward_external_port = wireguardPort; }; }; }; }