{ config, lib, ... }: let # Import nodes nodes = import ./../../nodes.nix; myNode = nodes."${config.hostName}"; supportsIPv4 = nd: lib.hasAttr "ip4" nd; supportsIPv6 = nd: lib.hasAttr "ip6" nd; # configure addresses including subnet mask addr4 = if supportsIPv4 myNode then [ myNode.ip4 ] else []; addr6 = if supportsIPv6 myNode then [ myNode.ip6 ] else []; # And routes, the gateway is assumed to be in subnet, otherwise GatewayOnLink is required route4 = if supportsIPv4 myNode then [{ Gateway = myNode.gIp4; }] else []; route6 = if supportsIPv6 myNode then [{ Gateway = myNode.gIp6; }] else []; # Return route for mgmt traffic rtwg4 = if myNode.id == 1 then [] else map (node: { Gateway = "172.19.${toString node.zone}.1"; Destination = "172.19.${toString (node.zone + 127)}.0/24"; }) (lib.attrValues (lib.filterAttrs (name: node: node.id == 1) nodes)); rtwg6 = if myNode.id == 1 then [] else map (node: { Gateway = "fc00::${toString node.zone}:1"; Destination = "fc00:f::${toString (node.zone + 127)}:0/96"; }) (lib.attrValues (lib.filterAttrs (name: node: node.id == 1) nodes)); in { networking.hostName = config.hostName; systemd.network.enable = true; networking.useNetworkd = true; networking.useDHCP = false; systemd.network = { networks = { "10-wan" = { # match the interface by name matchConfig.Name = myNode.dev; address = addr4 ++ addr6; routes = route4 ++ route6; # DNS dns = [ "1.1.1.1" ]; # make the routes on this interface a dependency for network-online.target linkConfig.RequiredForOnline = "routable"; }; # This interface is generated by networkd backend for wireguard # See mesh.nix "mesh" = { routes = rtwg4 ++ rtwg6; }; }; config.addRouteTablesToIPRoute2 = true; config.routeTables = { # Act as a route bin off = 999; }; }; networking.firewall.enable = true; }