From bda1a6b603a3944223707a6d090622b574ea7505 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 29 Jul 2022 11:07:19 +0200 Subject: bump & vpn --- modules/netns.nix | 155 +++ modules/networkd/default.nix | 1687 ----------------------------- modules/networkd/systemd-lib.nix | 241 ----- modules/networkd/systemd-unit-options.nix | 536 --------- modules/yggdrasil-wg/default.nix | 11 +- 5 files changed, 158 insertions(+), 2472 deletions(-) create mode 100644 modules/netns.nix delete mode 100644 modules/networkd/default.nix delete mode 100644 modules/networkd/systemd-lib.nix delete mode 100644 modules/networkd/systemd-unit-options.nix (limited to 'modules') diff --git a/modules/netns.nix b/modules/netns.nix new file mode 100644 index 00000000..18e066e5 --- /dev/null +++ b/modules/netns.nix @@ -0,0 +1,155 @@ +{ pkgs, config, lib, ... }: + +with lib; + +let + cfg = config.networking.namespaces; + + containerOpts = { name, ... }: { + options = { + config = mkOption { + description = '' + A specification of the desired configuration of this + container, as a NixOS module. + ''; + type = let + confPkgs = if config.pkgs == null then pkgs else config.pkgs; + in mkOptionType { + name = "Toplevel NixOS config"; + merge = loc: defs: (import (pkgs.path + "/nixos/lib/eval-config.nix") { + inherit (config.nixpkgs.localSystem) system; + inherit pkgs; + baseModules = import (pkgs.path + "/nixos/modules/module-list.nix"); + inherit (pkgs) lib; + modules = + let + extraConfig = { + _file = "module at ${__curPos.file}:${toString __curPos.line}"; + config = { + boot.isContainer = true; + networking.hostName = mkDefault name; + system.stateVersion = config.system.nixos.release; # No state + }; + }; + in [ extraConfig ] ++ (map (x: x.value) defs); + prefix = [ "containers" "upstream" ]; + }).config; + }; + }; + + netns = mkOption { + example = "upstream"; + type = types.str; + description = "Name of network namespace to put the container in."; + }; + }; + + config = { + netns = mkDefault name; + }; + }; + + mkContainerService = containerName: containerCfg: nameValuePair "netns-container@${containerName}" { + after = ["network.target" "systemd-udevd.service" "systemd-sysctl.service" "netns@${containerCfg.netns}.service"]; + bindsTo = ["netns@${containerCfg.netns}.service"]; + before = ["shutdown.target"]; + wants = ["network.target"]; + conflicts = ["shutdown.target"]; + + path = with pkgs; [ iproute config.systemd.package ]; + + serviceConfig = { + SyslogIdentifier = "netns container ${containerName}"; + Type = "notify"; + + RestartForceExitStatus = "133"; + SuccessExitStatus = "133"; + + Restart = "no"; + + DevicePolicy = "closed"; + + RuntimeDirectory = ["netns-containers/${containerName}"]; + }; + unitConfig = { + ConditionCapability = ["CAP_SYS_TTY_CONFIG" "CAP_NET_ADMIN" "CAP_NET_RAW" "CAP_SYS_ADMIN"]; + }; + + script = let + containerInit = pkgs.writeScript "container-init" '' + #!${pkgs.runtimeShell} -e + exec "$1" + ''; + in '' + mkdir -p -m 0755 "''${RUNTIME_DIRECTORY}/etc" "''${RUNTIME_DIRECTORY}/var/lib" + mkdir -p -m 0700 "''${RUNTIME_DIRECTORY}/var/lib/private" "''${RUNTIME_DIRECTORY}/root" /run/containers + if ! [ -e "''${RUNTIME_DIRECTORY}/etc/os-release" ]; then + touch "''${RUNTIME_DIRECTORY}/etc/os-release" + fi + if ! [ -e "''${RUNTIME_DIRECTORY}/etc/machine-id" ]; then + touch "''${RUNTIME_DIRECTORY}/etc/machine-id" + fi + mkdir -p -m 0755 \ + "/nix/var/nix/profiles/per-container/${containerName}" \ + "/nix/var/nix/gcroots/per-container/${containerName}" + credsBind="" + if [ -n "''${CREDENTIALS_DIRECTORY}" ]; then + credsBind="--bind-ro=''${CREDENTIALS_DIRECTORY}:/run/host/credentials" + fi + # Run systemd-nspawn without startup notification (we'll + # wait for the container systemd to signal readiness). + exec ${config.systemd.package}/bin/systemd-nspawn \ + --keep-unit \ + -M "${containerName}" -D "''${RUNTIME_DIRECTORY}" \ + --notify-ready=yes \ + --bind-ro=/nix/store \ + --bind-ro=/nix/var/nix/db \ + --bind-ro=/nix/var/nix/daemon-socket \ + $credsBind \ + --bind="/nix/var/nix/profiles/per-container/${containerName}:/nix/var/nix/profiles" \ + --bind="/nix/var/nix/gcroots/per-container/${containerName}:/nix/var/nix/gcroots" \ + --setenv PATH="$PATH" \ + --capability=CAP_SYS_TTY_CONFIG,CAP_NET_ADMIN,CAP_NET_RAW,CAP_SYS_ADMIN \ + --ephemeral \ + --network-namespace-path=/run/netns/${containerCfg.netns} \ + ${containerInit} "${containerCfg.config.system.build.toplevel}/init" + ''; + }; +in { + options = { + networking.namespaces = { + enable = mkEnableOption "netns@ service template"; + + containers = mkOption { + default = {}; + type = types.attrsOf (types.submodule containerOpts); + }; + }; + }; + + config = { + assertions = [ + { assertion = cfg.containers != {} -> cfg.enable; message = "netns containers require netns@ service template"; } + ]; + + systemd.services = { + "netns@" = mkIf cfg.enable { + description = "%I network namspace"; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + path = with pkgs; [ iproute utillinux ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + PrivateNetwork = true; + ExecStart = "${pkgs.writers.writeDash "netns-up" '' + ip netns add "$1" + umount /var/run/netns/"$1" + mount --bind /proc/self/ns/net /var/run/netns/"$1" + ''} %I"; + ExecStop = "${pkgs.iproute}/bin/ip netns del %I"; + }; + }; + } // mapAttrs' mkContainerService cfg.containers; + }; +} diff --git a/modules/networkd/default.nix b/modules/networkd/default.nix deleted file mode 100644 index f78a9aee..00000000 --- a/modules/networkd/default.nix +++ /dev/null @@ -1,1687 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -with import ./systemd-unit-options.nix { inherit config lib; }; -with import ./systemd-lib.nix { inherit config lib pkgs; }; - -let - - cfg = config.systemd.network; - - check = { - - link = { - - sectionLink = checkUnitConfig "Link" [ - (assertOnlyFields [ - "Description" - "Alias" - "MACAddressPolicy" - "MACAddress" - "NamePolicy" - "Name" - "AlternativeNamesPolicy" - "AlternativeName" - "MTUBytes" - "BitsPerSecond" - "Duplex" - "AutoNegotiation" - "WakeOnLan" - "Port" - "Advertise" - "ReceiveChecksumOffload" - "TransmitChecksumOffload" - "TCPSegmentationOffload" - "TCP6SegmentationOffload" - "GenericSegmentationOffload" - "GenericReceiveOffload" - "LargeReceiveOffload" - "RxChannels" - "TxChannels" - "OtherChannels" - "CombinedChannels" - "RxBufferSize" - "TxBufferSize" - ]) - (assertValueOneOf "MACAddressPolicy" ["persistent" "random" "none"]) - (assertMacAddress "MACAddress") - (assertByteFormat "MTUBytes") - (assertByteFormat "BitsPerSecond") - (assertValueOneOf "Duplex" ["half" "full"]) - (assertValueOneOf "AutoNegotiation" boolValues) - (assertValueOneOf "WakeOnLan" ["phy" "unicast" "multicast" "broadcast" "arp" "magic" "secureon" "off"]) - (assertValueOneOf "Port" ["tp" "aui" "bnc" "mii" "fibre"]) - (assertValueOneOf "ReceiveChecksumOffload" boolValues) - (assertValueOneOf "TransmitChecksumOffload" boolValues) - (assertValueOneOf "TCPSegmentationOffload" boolValues) - (assertValueOneOf "TCP6SegmentationOffload" boolValues) - (assertValueOneOf "GenericSegmentationOffload" boolValues) - (assertValueOneOf "GenericReceiveOffload" boolValues) - (assertValueOneOf "LargeReceiveOffload" boolValues) - (assertInt "RxChannels") - (assertRange "RxChannels" 1 4294967295) - (assertInt "TxChannels") - (assertRange "TxChannels" 1 4294967295) - (assertInt "OtherChannels") - (assertRange "OtherChannels" 1 4294967295) - (assertInt "CombinedChannels") - (assertRange "CombinedChannels" 1 4294967295) - (assertInt "RxBufferSize") - (assertInt "TxBufferSize") - ]; - }; - - netdev = let - - tunChecks = [ - (assertOnlyFields [ - "MultiQueue" - "PacketInfo" - "VNetHeader" - "User" - "Group" - ]) - (assertValueOneOf "MultiQueue" boolValues) - (assertValueOneOf "PacketInfo" boolValues) - (assertValueOneOf "VNetHeader" boolValues) - ]; - in { - - sectionNetdev = checkUnitConfig "Netdev" [ - (assertOnlyFields [ - "Description" - "Name" - "Kind" - "MTUBytes" - "MACAddress" - ]) - (assertHasField "Name") - (assertMaxLength "Name" 15) - (assertHasField "Kind") - (assertValueOneOf "Kind" [ - "bond" - "bridge" - "dummy" - "gre" - "gretap" - "erspan" - "ip6gre" - "ip6tnl" - "ip6gretap" - "ipip" - "ipvlan" - "macvlan" - "macvtap" - "sit" - "tap" - "tun" - "veth" - "vlan" - "vti" - "vti6" - "vxlan" - "geneve" - "l2tp" - "macsec" - "vrf" - "vcan" - "vxcan" - "wireguard" - "netdevsim" - "nlmon" - "fou" - "xfrm" - "ifb" - "bareudp" - "batadv" - ]) - (assertByteFormat "MTUBytes") - (assertMacAddress "MACAddress") - ]; - - sectionVLAN = checkUnitConfig "VLAN" [ - (assertOnlyFields [ - "Id" - "GVRP" - "MVRP" - "LooseBinding" - "ReorderHeader" - ]) - (assertInt "Id") - (assertRange "Id" 0 4094) - (assertValueOneOf "GVRP" boolValues) - (assertValueOneOf "MVRP" boolValues) - (assertValueOneOf "LooseBinding" boolValues) - (assertValueOneOf "ReorderHeader" boolValues) - ]; - - sectionMACVLAN = checkUnitConfig "MACVLAN" [ - (assertOnlyFields [ - "Mode" - ]) - (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"]) - ]; - - sectionVXLAN = checkUnitConfig "VXLAN" [ - (assertOnlyFields [ - "VNI" - "Remote" - "Local" - "Group" - "TOS" - "TTL" - "MacLearning" - "FDBAgeingSec" - "MaximumFDBEntries" - "ReduceARPProxy" - "L2MissNotification" - "L3MissNotification" - "RouteShortCircuit" - "UDPChecksum" - "UDP6ZeroChecksumTx" - "UDP6ZeroChecksumRx" - "RemoteChecksumTx" - "RemoteChecksumRx" - "GroupPolicyExtension" - "GenericProtocolExtension" - "DestinationPort" - "PortRange" - "FlowLabel" - "IPDoNotFragment" - ]) - (assertInt "VNI") - (assertRange "VNI" 1 16777215) - (assertValueOneOf "MacLearning" boolValues) - (assertInt "MaximumFDBEntries") - (assertValueOneOf "ReduceARPProxy" boolValues) - (assertValueOneOf "L2MissNotification" boolValues) - (assertValueOneOf "L3MissNotification" boolValues) - (assertValueOneOf "RouteShortCircuit" boolValues) - (assertValueOneOf "UDPChecksum" boolValues) - (assertValueOneOf "UDP6ZeroChecksumTx" boolValues) - (assertValueOneOf "UDP6ZeroChecksumRx" boolValues) - (assertValueOneOf "RemoteChecksumTx" boolValues) - (assertValueOneOf "RemoteChecksumRx" boolValues) - (assertValueOneOf "GroupPolicyExtension" boolValues) - (assertValueOneOf "GenericProtocolExtension" boolValues) - (assertInt "FlowLabel") - (assertRange "FlowLabel" 0 1048575) - (assertValueOneOf "IPDoNotFragment" (boolValues + ["inherit"])) - ]; - - sectionTunnel = checkUnitConfig "Tunnel" [ - (assertOnlyFields [ - "Local" - "Remote" - "TOS" - "TTL" - "DiscoverPathMTU" - "IPv6FlowLabel" - "CopyDSCP" - "EncapsulationLimit" - "Key" - "InputKey" - "OutputKey" - "Mode" - "Independent" - "AssignToLoopback" - "AllowLocalRemote" - "FooOverUDP" - "FOUDestinationPort" - "FOUSourcePort" - "Encapsulation" - "IPv6RapidDeploymentPrefix" - "ISATAP" - "SerializeTunneledPackets" - "ERSPANIndex" - ]) - (assertInt "TTL") - (assertRange "TTL" 0 255) - (assertValueOneOf "DiscoverPathMTU" boolValues) - (assertValueOneOf "CopyDSCP" boolValues) - (assertValueOneOf "Mode" ["ip6ip6" "ipip6" "any"]) - (assertValueOneOf "Independent" boolValues) - (assertValueOneOf "AssignToLoopback" boolValues) - (assertValueOneOf "AllowLocalRemote" boolValues) - (assertValueOneOf "FooOverUDP" boolValues) - (assertPort "FOUDestinationPort") - (assertPort "FOUSourcePort") - (assertValueOneOf "Encapsulation" ["FooOverUDP" "GenericUDPEncapsulation"]) - (assertValueOneOf "ISATAP" boolValues) - (assertValueOneOf "SerializeTunneledPackets" boolValues) - (assertInt "ERSPANIndex") - (assertRange "ERSPANIndex" 1 1048575) - ]; - - sectionPeer = checkUnitConfig "Peer" [ - (assertOnlyFields [ - "Name" - "MACAddress" - ]) - (assertMacAddress "MACAddress") - ]; - - sectionTun = checkUnitConfig "Tun" tunChecks; - - sectionTap = checkUnitConfig "Tap" tunChecks; - - # NOTE The PrivateKey directive is missing on purpose here, please - # do not add it to this list. The nix store is world-readable let's - # refrain ourselves from providing a footgun. - sectionWireGuard = checkUnitConfig "WireGuard" [ - (assertOnlyFields [ - "PrivateKeyFile" - "ListenPort" - "FirewallMark" - ]) - (assertInt "FirewallMark") - (assertRange "FirewallMark" 1 4294967295) - ]; - - # NOTE The PresharedKey directive is missing on purpose here, please - # do not add it to this list. The nix store is world-readable,let's - # refrain ourselves from providing a footgun. - sectionWireGuardPeer = checkUnitConfig "WireGuardPeer" [ - (assertOnlyFields [ - "PublicKey" - "PresharedKeyFile" - "AllowedIPs" - "Endpoint" - "PersistentKeepalive" - ]) - (assertInt "PersistentKeepalive") - (assertRange "PersistentKeepalive" 0 65535) - ]; - - sectionBond = checkUnitConfig "Bond" [ - (assertOnlyFields [ - "Mode" - "TransmitHashPolicy" - "LACPTransmitRate" - "MIIMonitorSec" - "UpDelaySec" - "DownDelaySec" - "LearnPacketIntervalSec" - "AdSelect" - "AdActorSystemPriority" - "AdUserPortKey" - "AdActorSystem" - "FailOverMACPolicy" - "ARPValidate" - "ARPIntervalSec" - "ARPIPTargets" - "ARPAllTargets" - "PrimaryReselectPolicy" - "ResendIGMP" - "PacketsPerSlave" - "GratuitousARP" - "AllSlavesActive" - "DynamicTransmitLoadBalancing" - "MinLinks" - ]) - (assertValueOneOf "Mode" [ - "balance-rr" - "active-backup" - "balance-xor" - "broadcast" - "802.3ad" - "balance-tlb" - "balance-alb" - ]) - (assertValueOneOf "TransmitHashPolicy" [ - "layer2" - "layer3+4" - "layer2+3" - "encap2+3" - "encap3+4" - ]) - (assertValueOneOf "LACPTransmitRate" ["slow" "fast"]) - (assertValueOneOf "AdSelect" ["stable" "bandwidth" "count"]) - (assertInt "AdActorSystemPriority") - (assertRange "AdActorSystemPriority" 1 65535) - (assertInt "AdUserPortKey") - (assertRange "AdUserPortKey" 0 1023) - (assertValueOneOf "FailOverMACPolicy" ["none" "active" "follow"]) - (assertValueOneOf "ARPValidate" ["none" "active" "backup" "all"]) - (assertValueOneOf "ARPAllTargets" ["any" "all"]) - (assertValueOneOf "PrimaryReselectPolicy" ["always" "better" "failure"]) - (assertInt "ResendIGMP") - (assertRange "ResendIGMP" 0 255) - (assertInt "PacketsPerSlave") - (assertRange "PacketsPerSlave" 0 65535) - (assertInt "GratuitousARP") - (assertRange "GratuitousARP" 0 255) - (assertValueOneOf "AllSlavesActive" boolValues) - (assertValueOneOf "DynamicTransmitLoadBalancing" boolValues) - (assertInt "MinLinks") - (assertMinimum "MinLinks" 0) - ]; - - sectionXfrm = checkUnitConfig "Xfrm" [ - (assertOnlyFields [ - "InterfaceId" - "Independent" - ]) - (assertInt "InterfaceId") - (assertRange "InterfaceId" 1 4294967295) - (assertValueOneOf "Independent" boolValues) - ]; - - sectionVRF = checkUnitConfig "VRF" [ - (assertOnlyFields [ - "Table" - ]) - (assertInt "Table") - (assertMinimum "Table" 0) - ]; - }; - - network = { - - sectionLink = checkUnitConfig "Link" [ - (assertOnlyFields [ - "MACAddress" - "MTUBytes" - "ARP" - "Multicast" - "AllMulticast" - "Unmanaged" - "RequiredForOnline" - "ActivationPolicy" - ]) - (assertMacAddress "MACAddress") - (assertByteFormat "MTUBytes") - (assertValueOneOf "ARP" boolValues) - (assertValueOneOf "Multicast" boolValues) - (assertValueOneOf "AllMulticast" boolValues) - (assertValueOneOf "Unmanaged" boolValues) - (assertValueOneOf "RequiredForOnline" (boolValues ++ [ - "missing" - "off" - "no-carrier" - "dormant" - "degraded-carrier" - "carrier" - "degraded" - "enslaved" - "routable" - ])) - (assertValueOneOf "ActivationPolicy" ([ - "up" - "always-up" - "manual" - "always-down" - "down" - "bound" - ])) - ]; - - sectionNetwork = checkUnitConfig "Network" [ - (assertOnlyFields [ - "Description" - "DHCP" - "DHCPServer" - "LinkLocalAddressing" - "IPv4LLRoute" - "DefaultRouteOnDevice" - "IPv6Token" - "LLMNR" - "MulticastDNS" - "DNSOverTLS" - "DNSSEC" - "DNSSECNegativeTrustAnchors" - "LLDP" - "EmitLLDP" - "BindCarrier" - "Address" - "Gateway" - "DNS" - "Domains" - "DNSDefaultRoute" - "NTP" - "IPForward" - "IPMasquerade" - "IPv6PrivacyExtensions" - "IPv6AcceptRA" - "IPv6DuplicateAddressDetection" - "IPv6HopLimit" - "IPv4ProxyARP" - "IPv6ProxyNDP" - "IPv6ProxyNDPAddress" - "IPv6SendRA" - "DHCPv6PrefixDelegation" - "IPv6MTUBytes" - "BatmanAdvanced" - "Bridge" - "Bond" - "VRF" - "VLAN" - "IPVLAN" - "MACVLAN" - "VXLAN" - "Tunnel" - "MACsec" - "ActiveSlave" - "PrimarySlave" - "ConfigureWithoutCarrier" - "IgnoreCarrierLoss" - "Xfrm" - "KeepConfiguration" - ]) - # Note: For DHCP the values both, none, v4, v6 are deprecated - (assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6"]) - (assertValueOneOf "DHCPServer" boolValues) - (assertValueOneOf "LinkLocalAddressing" ["yes" "no" "ipv4" "ipv6" "fallback" "ipv4-fallback"]) - (assertValueOneOf "IPv4LLRoute" boolValues) - (assertValueOneOf "DefaultRouteOnDevice" boolValues) - (assertValueOneOf "LLMNR" (boolValues ++ ["resolve"])) - (assertValueOneOf "MulticastDNS" (boolValues ++ ["resolve"])) - (assertValueOneOf "DNSOverTLS" (boolValues ++ ["opportunistic"])) - (assertValueOneOf "DNSSEC" (boolValues ++ ["allow-downgrade"])) - (assertValueOneOf "LLDP" (boolValues ++ ["routers-only"])) - (assertValueOneOf "EmitLLDP" (boolValues ++ ["nearest-bridge" "non-tpmr-bridge" "customer-bridge"])) - (assertValueOneOf "DNSDefaultRoute" boolValues) - (assertValueOneOf "IPForward" (boolValues ++ ["ipv4" "ipv6"])) - (assertValueOneOf "IPMasquerade" boolValues) - (assertValueOneOf "IPv6PrivacyExtensions" (boolValues ++ ["prefer-public" "kernel"])) - (assertValueOneOf "IPv6AcceptRA" boolValues) - (assertInt "IPv6DuplicateAddressDetection") - (assertMinimum "IPv6DuplicateAddressDetection" 0) - (assertInt "IPv6HopLimit") - (assertMinimum "IPv6HopLimit" 0) - (assertValueOneOf "IPv4ProxyARP" boolValues) - (assertValueOneOf "IPv6ProxyNDP" boolValues) - (assertValueOneOf "IPv6SendRA" boolValues) - (assertValueOneOf "DHCPv6PrefixDelegation" boolValues) - (assertByteFormat "IPv6MTUBytes") - (assertValueOneOf "ActiveSlave" boolValues) - (assertValueOneOf "PrimarySlave" boolValues) - (assertValueOneOf "ConfigureWithoutCarrier" boolValues) - (assertValueOneOf "IgnoreCarrierLoss" boolValues) - (assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"])) - ]; - - sectionAddress = checkUnitConfig "Address" [ - (assertOnlyFields [ - "Address" - "Peer" - "Broadcast" - "Label" - "PreferredLifetime" - "Scope" - "HomeAddress" - "DuplicateAddressDetection" - "ManageTemporaryAddress" - "AddPrefixRoute" - "AutoJoin" - ]) - (assertHasField "Address") - (assertValueOneOf "PreferredLifetime" ["forever" "infinity" "0" 0]) - (assertValueOneOf "HomeAddress" boolValues) - (assertValueOneOf "DuplicateAddressDetection" ["ipv4" "ipv6" "both" "none"]) - (assertValueOneOf "ManageTemporaryAddress" boolValues) - (assertValueOneOf "AddPrefixRoute" boolValues) - (assertValueOneOf "AutoJoin" boolValues) - ]; - - sectionRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [ - (assertOnlyFields [ - "TypeOfService" - "From" - "To" - "FirewallMark" - "Table" - "Priority" - "IncomingInterface" - "OutgoingInterface" - "SourcePort" - "DestinationPort" - "IPProtocol" - "InvertRule" - "Family" - "User" - "SuppressPrefixLength" - ]) - (assertInt "TypeOfService") - (assertRange "TypeOfService" 0 255) - (assertInt "FirewallMark") - (assertRange "FirewallMark" 1 4294967295) - (assertInt "Priority") - (assertPort "SourcePort") - (assertPort "DestinationPort") - (assertValueOneOf "InvertRule" boolValues) - (assertValueOneOf "Family" ["ipv4" "ipv6" "both"]) - (assertInt "SuppressPrefixLength") - (assertRange "SuppressPrefixLength" 0 128) - ]; - - sectionRoute = checkUnitConfig "Route" [ - (assertOnlyFields [ - "Gateway" - "GatewayOnLink" - "Destination" - "Source" - "Metric" - "IPv6Preference" - "Scope" - "PreferredSource" - "Table" - "Protocol" - "Type" - "InitialCongestionWindow" - "InitialAdvertisedReceiveWindow" - "QuickAck" - "FastOpenNoCookie" - "TTLPropagate" - "MTUBytes" - "IPServiceType" - "MultiPathRoute" - ]) - (assertValueOneOf "GatewayOnLink" boolValues) - (assertInt "Metric") - (assertValueOneOf "IPv6Preference" ["low" "medium" "high"]) - (assertValueOneOf "Scope" ["global" "site" "link" "host" "nowhere"]) - (assertValueOneOf "Type" [ - "unicast" - "local" - "broadcast" - "anycast" - "multicast" - "blackhole" - "unreachable" - "prohibit" - "throw" - "nat" - "xresolve" - ]) - (assertValueOneOf "QuickAck" boolValues) - (assertValueOneOf "FastOpenNoCookie" boolValues) - (assertValueOneOf "TTLPropagate" boolValues) - (assertByteFormat "MTUBytes") - (assertValueOneOf "IPServiceType" ["CS6" "CS4"]) - ]; - - sectionDHCPv4 = checkUnitConfig "DHCPv4" [ - (assertOnlyFields [ - "UseDNS" - "RoutesToDNS" - "UseNTP" - "UseSIP" - "UseMTU" - "Anonymize" - "SendHostname" - "UseHostname" - "Hostname" - "UseDomains" - "UseRoutes" - "UseTimezone" - "ClientIdentifier" - "VendorClassIdentifier" - "UserClass" - "MaxAttempts" - "DUIDType" - "DUIDRawData" - "IAID" - "RequestBroadcast" - "RouteMetric" - "RouteTable" - "RouteMTUBytes" - "ListenPort" - "SendRelease" - "SendDecline" - "BlackList" - "RequestOptions" - "SendOption" - ]) - (assertValueOneOf "UseDNS" boolValues) - (assertValueOneOf "RoutesToDNS" boolValues) - (assertValueOneOf "UseNTP" boolValues) - (assertValueOneOf "UseSIP" boolValues) - (assertValueOneOf "UseMTU" boolValues) - (assertValueOneOf "Anonymize" boolValues) - (assertValueOneOf "SendHostname" boolValues) - (assertValueOneOf "UseHostname" boolValues) - (assertValueOneOf "UseDomains" (boolValues ++ ["route"])) - (assertValueOneOf "UseRoutes" boolValues) - (assertValueOneOf "UseTimezone" boolValues) - (assertValueOneOf "ClientIdentifier" ["mac" "duid" "duid-only"]) - (assertInt "IAID") - (assertValueOneOf "RequestBroadcast" boolValues) - (assertInt "RouteMetric") - (assertInt "RouteTable") - (assertRange "RouteTable" 0 4294967295) - (assertByteFormat "RouteMTUBytes") - (assertPort "ListenPort") - (assertValueOneOf "SendRelease" boolValues) - (assertValueOneOf "SendDecline" boolValues) - ]; - - sectionDHCPv6 = checkUnitConfig "DHCPv6" [ - (assertOnlyFields [ - "UseAddress" - "UseDNS" - "UseNTP" - "RouteMetric" - "RapidCommit" - "MUDURL" - "RequestOptions" - "SendVendorOption" - "ForceDHCPv6PDOtherInformation" - "PrefixDelegationHint" - "WithoutRA" - "SendOption" - "UserClass" - "VendorClass" - ]) - (assertValueOneOf "UseAddress" boolValues) - (assertValueOneOf "UseDNS" boolValues) - (assertValueOneOf "UseNTP" boolValues) - (assertInt "RouteMetric") - (assertValueOneOf "RapidCommit" boolValues) - (assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues) - (assertValueOneOf "WithoutRA" ["solicit" "information-request"]) - (assertRange "SendOption" 1 65536) - ]; - - sectionDHCPv6PrefixDelegation = checkUnitConfig "DHCPv6PrefixDelegation" [ - (assertOnlyFields [ - "SubnetId" - "Announce" - "Assign" - "Token" - ]) - (assertValueOneOf "Announce" boolValues) - (assertValueOneOf "Assign" boolValues) - ]; - - sectionIPv6AcceptRA = checkUnitConfig "IPv6AcceptRA" [ - (assertOnlyFields [ - "UseDNS" - "UseDomains" - "RouteTable" - "UseAutonomousPrefix" - "UseOnLinkPrefix" - "RouterDenyList" - "RouterAllowList" - "PrefixDenyList" - "PrefixAllowList" - "RouteDenyList" - "RouteAllowList" - "DHCPv6Client" - ]) - (assertValueOneOf "UseDNS" boolValues) - (assertValueOneOf "UseDomains" (boolValues ++ ["route"])) - (assertRange "RouteTable" 0 4294967295) - (assertValueOneOf "UseAutonomousPrefix" boolValues) - (assertValueOneOf "UseOnLinkPrefix" boolValues) - (assertValueOneOf "DHCPv6Client" (boolValues ++ ["always"])) - ]; - - sectionDHCPServer = checkUnitConfig "DHCPServer" [ - (assertOnlyFields [ - "PoolOffset" - "PoolSize" - "DefaultLeaseTimeSec" - "MaxLeaseTimeSec" - "EmitDNS" - "DNS" - "EmitNTP" - "NTP" - "EmitSIP" - "SIP" - "EmitPOP3" - "POP3" - "EmitSMTP" - "SMTP" - "EmitLPR" - "LPR" - "EmitRouter" - "EmitTimezone" - "Timezone" - "SendOption" - "SendVendorOption" - ]) - (assertInt "PoolOffset") - (assertMinimum "PoolOffset" 0) - (assertInt "PoolSize") - (assertMinimum "PoolSize" 0) - (assertValueOneOf "EmitDNS" boolValues) - (assertValueOneOf "EmitNTP" boolValues) - (assertValueOneOf "EmitSIP" boolValues) - (assertValueOneOf "EmitPOP3" boolValues) - (assertValueOneOf "EmitSMTP" boolValues) - (assertValueOneOf "EmitLPR" boolValues) - (assertValueOneOf "EmitRouter" boolValues) - (assertValueOneOf "EmitTimezone" boolValues) - ]; - - sectionIPv6SendRA = checkUnitConfig "IPv6SendRA" [ - (assertOnlyFields [ - "Managed" - "OtherInformation" - "RouterLifetimeSec" - "RouterPreference" - "EmitDNS" - "DNS" - "EmitDomains" - "Domains" - "DNSLifetimeSec" - ]) - (assertValueOneOf "Managed" boolValues) - (assertValueOneOf "OtherInformation" boolValues) - (assertValueOneOf "RouterPreference" ["high" "medium" "low" "normal" "default"]) - (assertValueOneOf "EmitDNS" boolValues) - (assertValueOneOf "EmitDomains" boolValues) - ]; - - sectionIPv6Prefix = checkUnitConfig "IPv6Prefix" [ - (assertOnlyFields [ - "AddressAutoconfiguration" - "OnLink" - "Prefix" - "PreferredLifetimeSec" - "ValidLifetimeSec" - ]) - (assertValueOneOf "AddressAutoconfiguration" boolValues) - (assertValueOneOf "OnLink" boolValues) - ]; - - }; - }; - - commonNetworkOptions = { - - enable = mkOption { - default = true; - type = types.bool; - description = '' - Whether to manage network configuration using systemd-network. - ''; - }; - - matchConfig = mkOption { - default = {}; - example = { Name = "eth0"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Match] section of the unit. See - systemd.link5 - systemd.netdev5 - systemd.network5 - for details. - ''; - }; - - extraConfig = mkOption { - default = ""; - type = types.lines; - description = "Extra configuration append to unit"; - }; - }; - - linkOptions = commonNetworkOptions // { - # overwrite enable option from above - enable = mkOption { - default = true; - type = types.bool; - description = '' - Whether to enable this .link unit. It's handled by udev no matter if systemd-networkd is enabled or not - ''; - }; - - linkConfig = mkOption { - default = {}; - example = { MACAddress = "00:ff:ee:aa:cc:dd"; }; - type = types.addCheck (types.attrsOf unitOption) check.link.sectionLink; - description = '' - Each attribute in this set specifies an option in the - [Link] section of the unit. See - systemd.link - 5 for details. - ''; - }; - - }; - - wireguardPeerOptions = { - options = { - wireguardPeerConfig = mkOption { - default = {}; - example = { }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuardPeer; - description = '' - Each attribute in this set specifies an option in the - [WireGuardPeer] section of the unit. See - systemd.network - 5 for details. - ''; - }; - }; - }; - - netdevOptions = commonNetworkOptions // { - - netdevConfig = mkOption { - default = {}; - example = { Name = "mybridge"; Kind = "bridge"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionNetdev; - description = '' - Each attribute in this set specifies an option in the - [Netdev] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - vlanConfig = mkOption { - default = {}; - example = { Id = 4; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVLAN; - description = '' - Each attribute in this set specifies an option in the - [VLAN] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - macvlanConfig = mkOption { - default = {}; - example = { Mode = "private"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionMACVLAN; - description = '' - Each attribute in this set specifies an option in the - [MACVLAN] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - vxlanConfig = mkOption { - default = {}; - example = { Id = "4"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVXLAN; - description = '' - Each attribute in this set specifies an option in the - [VXLAN] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - tunnelConfig = mkOption { - default = {}; - example = { Remote = "192.168.1.1"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTunnel; - description = '' - Each attribute in this set specifies an option in the - [Tunnel] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - peerConfig = mkOption { - default = {}; - example = { Name = "veth2"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionPeer; - description = '' - Each attribute in this set specifies an option in the - [Peer] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - tunConfig = mkOption { - default = {}; - example = { User = "openvpn"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTun; - description = '' - Each attribute in this set specifies an option in the - [Tun] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - tapConfig = mkOption { - default = {}; - example = { User = "openvpn"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTap; - description = '' - Each attribute in this set specifies an option in the - [Tap] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - wireguardConfig = mkOption { - default = {}; - example = { - PrivateKeyFile = "/etc/wireguard/secret.key"; - ListenPort = 51820; - FwMark = 42; - }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuard; - description = '' - Each attribute in this set specifies an option in the - [WireGuard] section of the unit. See - systemd.netdev - 5 for details. - Use PrivateKeyFile instead of - PrivateKey: the nix store is - world-readable. - ''; - }; - - wireguardPeers = mkOption { - default = []; - example = [ { wireguardPeerConfig={ - Endpoint = "192.168.1.1:51820"; - PublicKey = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g="; - PresharedKeyFile = "/etc/wireguard/psk.key"; - AllowedIPs = [ "10.0.0.1/32" ]; - PersistentKeepalive = 15; - };}]; - type = with types; listOf (submodule wireguardPeerOptions); - description = '' - Each item in this array specifies an option in the - [WireGuardPeer] section of the unit. See - systemd.netdev - 5 for details. - Use PresharedKeyFile instead of - PresharedKey: the nix store is - world-readable. - ''; - }; - - bondConfig = mkOption { - default = {}; - example = { Mode = "802.3ad"; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionBond; - description = '' - Each attribute in this set specifies an option in the - [Bond] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - xfrmConfig = mkOption { - default = {}; - example = { InterfaceId = 1; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionXfrm; - description = '' - Each attribute in this set specifies an option in the - [Xfrm] section of the unit. See - systemd.netdev - 5 for details. - ''; - }; - - vrfConfig = mkOption { - default = {}; - example = { Table = 2342; }; - type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVRF; - description = '' - Each attribute in this set specifies an option in the - [VRF] section of the unit. See - systemd.netdev - 5 for details. - A detailed explanation about how VRFs work can be found in the - kernel - docs. - ''; - }; - - }; - - addressOptions = { - options = { - addressConfig = mkOption { - default = {}; - example = { Address = "192.168.0.100/24"; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionAddress; - description = '' - Each attribute in this set specifies an option in the - [Address] section of the unit. See - systemd.network - 5 for details. - ''; - }; - }; - }; - - routingPolicyRulesOptions = { - options = { - routingPolicyRuleConfig = mkOption { - default = { }; - example = { routingPolicyRuleConfig = { Table = 10; IncomingInterface = "eth1"; Family = "both"; } ;}; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoutingPolicyRule; - description = '' - Each attribute in this set specifies an option in the - [RoutingPolicyRule] section of the unit. See - systemd.network - 5 for details. - ''; - }; - }; - }; - - routeOptions = { - options = { - routeConfig = mkOption { - default = {}; - example = { Gateway = "192.168.0.1"; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoute; - description = '' - Each attribute in this set specifies an option in the - [Route] section of the unit. See - systemd.network - 5 for details. - ''; - }; - }; - }; - - ipv6PrefixOptions = { - options = { - ipv6PrefixConfig = mkOption { - default = {}; - example = { Prefix = "fd00::/64"; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6Prefix; - description = '' - Each attribute in this set specifies an option in the - [IPv6Prefix] section of the unit. See - systemd.network - 5 for details. - ''; - }; - }; - }; - - networkOptions = commonNetworkOptions // { - - linkConfig = mkOption { - default = {}; - example = { Unmanaged = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionLink; - description = '' - Each attribute in this set specifies an option in the - [Link] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - networkConfig = mkOption { - default = {}; - example = { Description = "My Network"; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionNetwork; - description = '' - Each attribute in this set specifies an option in the - [Network] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - # systemd.network.networks.*.dhcpConfig has been deprecated in favor of ….dhcpV4Config - # Produce a nice warning message so users know it is gone. - dhcpConfig = mkOption { - visible = false; - apply = _: throw "The option `systemd.network.networks.*.dhcpConfig` can no longer be used since it's been removed. Please use `systemd.network.networks.*.dhcpV4Config` instead."; - }; - - dhcpV4Config = mkOption { - default = {}; - example = { UseDNS = true; UseRoutes = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv4; - description = '' - Each attribute in this set specifies an option in the - [DHCPv4] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - dhcpV6Config = mkOption { - default = {}; - example = { UseDNS = true; UseRoutes = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6; - description = '' - Each attribute in this set specifies an option in the - [DHCPv6] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - dhcpV6PrefixDelegationConfig = mkOption { - default = {}; - example = { SubnetId = "auto"; Announce = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6PrefixDelegation; - description = '' - Each attribute in this set specifies an option in the - [DHCPv6PrefixDelegation] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - ipv6AcceptRAConfig = mkOption { - default = {}; - example = { UseDNS = true; DHCPv6Client = "always"; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6AcceptRA; - description = '' - Each attribute in this set specifies an option in the - [IPv6AcceptRA] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - dhcpServerConfig = mkOption { - default = {}; - example = { PoolOffset = 50; EmitDNS = false; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPServer; - description = '' - Each attribute in this set specifies an option in the - [DHCPServer] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - # systemd.network.networks.*.ipv6PrefixDelegationConfig has been deprecated - # in 247 in favor of systemd.network.networks.*.ipv6SendRAConfig. - ipv6PrefixDelegationConfig = mkOption { - visible = false; - apply = _: throw "The option `systemd.network.networks.*.ipv6PrefixDelegationConfig` has been replaced by `systemd.network.networks.*.ipv6SendRAConfig`."; - }; - - ipv6SendRAConfig = mkOption { - default = {}; - example = { EmitDNS = true; Managed = true; OtherInformation = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6SendRA; - description = '' - Each attribute in this set specifies an option in the - [IPv6SendRA] section of the unit. See - systemd.network - 5 for details. - ''; - }; - - ipv6Prefixes = mkOption { - default = []; - example = { AddressAutoconfiguration = true; OnLink = true; }; - type = with types; listOf (submodule ipv6PrefixOptions); - description = '' - A list of ipv6Prefix sections to be added to the unit. See - systemd.network - 5 for details. - ''; - }; - - name = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The name of the network interface to match against. - ''; - }; - - DHCP = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Whether to enable DHCP on the interfaces matched. - ''; - }; - - domains = mkOption { - type = types.nullOr (types.listOf types.str); - default = null; - description = '' - A list of domains to pass to the network config. - ''; - }; - - address = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of addresses to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - gateway = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of gateways to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - dns = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of dns servers to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - ntp = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of ntp servers to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - bridge = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of bridge interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - bond = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of bond interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - vrf = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of vrf interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - vlan = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of vlan interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - macvlan = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of macvlan interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - vxlan = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of vxlan interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - tunnel = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of tunnel interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - xfrm = mkOption { - default = [ ]; - type = types.listOf types.str; - description = '' - A list of xfrm interfaces to be added to the network section of the - unit. See systemd.network - 5 for details. - ''; - }; - - addresses = mkOption { - default = [ ]; - type = with types; listOf (submodule addressOptions); - description = '' - A list of address sections to be added to the unit. See - systemd.network - 5 for details. - ''; - }; - - routingPolicyRules = mkOption { - default = [ ]; - type = with types; listOf (submodule routingPolicyRulesOptions); - description = '' - A list of routing policy rules sections to be added to the unit. See - systemd.network - 5 for details. - ''; - }; - - routes = mkOption { - default = [ ]; - type = with types; listOf (submodule routeOptions); - description = '' - A list of route sections to be added to the unit. See - systemd.network - 5 for details. - ''; - }; - - }; - - networkConfig = { config, ... }: { - config = { - matchConfig = optionalAttrs (config.name != null) { - Name = config.name; - }; - networkConfig = optionalAttrs (config.DHCP != null) { - DHCP = config.DHCP; - } // optionalAttrs (config.domains != null) { - Domains = concatStringsSep " " config.domains; - }; - }; - }; - - commonMatchText = def: optionalString (def.matchConfig != { }) '' - [Match] - ${attrsToSection def.matchConfig} - ''; - - linkToUnit = name: def: - { inherit (def) enable; - text = commonMatchText def - + '' - [Link] - ${attrsToSection def.linkConfig} - '' - + def.extraConfig; - }; - - netdevToUnit = name: def: - { inherit (def) enable; - text = commonMatchText def - + '' - [NetDev] - ${attrsToSection def.netdevConfig} - '' - + optionalString (def.vlanConfig != { }) '' - [VLAN] - ${attrsToSection def.vlanConfig} - '' - + optionalString (def.macvlanConfig != { }) '' - [MACVLAN] - ${attrsToSection def.macvlanConfig} - '' - + optionalString (def.vxlanConfig != { }) '' - [VXLAN] - ${attrsToSection def.vxlanConfig} - '' - + optionalString (def.tunnelConfig != { }) '' - [Tunnel] - ${attrsToSection def.tunnelConfig} - '' - + optionalString (def.peerConfig != { }) '' - [Peer] - ${attrsToSection def.peerConfig} - '' - + optionalString (def.tunConfig != { }) '' - [Tun] - ${attrsToSection def.tunConfig} - '' - + optionalString (def.tapConfig != { }) '' - [Tap] - ${attrsToSection def.tapConfig} - '' - + optionalString (def.wireguardConfig != { }) '' - [WireGuard] - ${attrsToSection def.wireguardConfig} - '' - + flip concatMapStrings def.wireguardPeers (x: '' - [WireGuardPeer] - ${attrsToSection x.wireguardPeerConfig} - '') - + optionalString (def.bondConfig != { }) '' - [Bond] - ${attrsToSection def.bondConfig} - '' - + optionalString (def.xfrmConfig != { }) '' - [Xfrm] - ${attrsToSection def.xfrmConfig} - '' - + optionalString (def.vrfConfig != { }) '' - [VRF] - ${attrsToSection def.vrfConfig} - '' - + def.extraConfig; - }; - - networkToUnit = name: def: - { inherit (def) enable; - text = commonMatchText def - + optionalString (def.linkConfig != { }) '' - [Link] - ${attrsToSection def.linkConfig} - '' - + '' - [Network] - '' - + attrsToSection def.networkConfig - + optionalString (def.address != [ ]) '' - ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)} - '' - + optionalString (def.gateway != [ ]) '' - ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)} - '' - + optionalString (def.dns != [ ]) '' - ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)} - '' - + optionalString (def.ntp != [ ]) '' - ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)} - '' - + optionalString (def.bridge != [ ]) '' - ${concatStringsSep "\n" (map (s: "Bridge=${s}") def.bridge)} - '' - + optionalString (def.bond != [ ]) '' - ${concatStringsSep "\n" (map (s: "Bond=${s}") def.bond)} - '' - + optionalString (def.vrf != [ ]) '' - ${concatStringsSep "\n" (map (s: "VRF=${s}") def.vrf)} - '' - + optionalString (def.vlan != [ ]) '' - ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)} - '' - + optionalString (def.macvlan != [ ]) '' - ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)} - '' - + optionalString (def.vxlan != [ ]) '' - ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)} - '' - + optionalString (def.tunnel != [ ]) '' - ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)} - '' - + optionalString (def.xfrm != [ ]) '' - ${concatStringsSep "\n" (map (s: "Xfrm=${s}") def.xfrm)} - '' - + '' - - '' - + flip concatMapStrings def.addresses (x: '' - [Address] - ${attrsToSection x.addressConfig} - '') - + flip concatMapStrings def.routingPolicyRules (x: '' - [RoutingPolicyRule] - ${attrsToSection x.routingPolicyRuleConfig} - '') - + flip concatMapStrings def.routes (x: '' - [Route] - ${attrsToSection x.routeConfig} - '') - + optionalString (def.dhcpV4Config != { }) '' - [DHCPv4] - ${attrsToSection def.dhcpV4Config} - '' - + optionalString (def.dhcpV6Config != { }) '' - [DHCPv6] - ${attrsToSection def.dhcpV6Config} - '' - + optionalString (def.dhcpV6PrefixDelegationConfig != { }) '' - [DHCPv6PrefixDelegation] - ${attrsToSection def.dhcpV6PrefixDelegationConfig} - '' - + optionalString (def.ipv6AcceptRAConfig != { }) '' - [IPv6AcceptRA] - ${attrsToSection def.ipv6AcceptRAConfig} - '' - + optionalString (def.dhcpServerConfig != { }) '' - [DHCPServer] - ${attrsToSection def.dhcpServerConfig} - '' - + optionalString (def.ipv6SendRAConfig != { }) '' - [IPv6SendRA] - ${attrsToSection def.ipv6SendRAConfig} - '' - + flip concatMapStrings def.ipv6Prefixes (x: '' - [IPv6Prefix] - ${attrsToSection x.ipv6PrefixConfig} - '') - + def.extraConfig; - }; - - unitFiles = listToAttrs (map (name: { - name = "systemd/network/${name}"; - value.source = "${cfg.units.${name}.unit}/${name}"; - }) (attrNames cfg.units)); -in - -{ - disabledModules = [ "system/boot/networkd.nix" ]; - - options = { - - systemd.network.enable = mkOption { - default = false; - type = types.bool; - description = '' - Whether to enable networkd or not. - ''; - }; - - systemd.network.links = mkOption { - default = {}; - type = with types; attrsOf (submodule [ { options = linkOptions; } ]); - description = "Definition of systemd network links."; - }; - - systemd.network.netdevs = mkOption { - default = {}; - type = with types; attrsOf (submodule [ { options = netdevOptions; } ]); - description = "Definition of systemd network devices."; - }; - - systemd.network.networks = mkOption { - default = {}; - type = with types; attrsOf (submodule [ { options = networkOptions; } networkConfig ]); - description = "Definition of systemd networks."; - }; - - systemd.network.units = mkOption { - description = "Definition of networkd units."; - default = {}; - internal = true; - type = with types; attrsOf (submodule ( - { name, config, ... }: - { options = mapAttrs (_: x: x // { internal = true; }) concreteUnitOptions; - config = { - unit = mkDefault (makeUnit name config); - }; - })); - }; - - }; - - config = mkMerge [ - - # .link units are honored by udev, no matter if systemd-networkd is enabled or not. - { - systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links; - environment.etc = unitFiles; - } - - (mkIf config.systemd.network.enable { - - users.users.systemd-network.group = "systemd-network"; - - systemd.additionalUpstreamSystemUnits = [ - "systemd-networkd-wait-online.service" - "systemd-networkd.service" - "systemd-networkd.socket" - ]; - - systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs - // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks; - - # systemd-networkd is socket-activated by kernel netlink route change - # messages. It is important to have systemd buffer those on behalf of - # networkd. - systemd.sockets.systemd-networkd.wantedBy = [ "sockets.target" ]; - - systemd.services.systemd-networkd = { - wantedBy = [ "multi-user.target" ]; - aliases = [ "dbus-org.freedesktop.network1.service" ]; - restartTriggers = map (x: x.source) (attrValues unitFiles); - }; - - systemd.services.systemd-networkd-wait-online = { - wantedBy = [ "network-online.target" ]; - }; - - systemd.services."systemd-network-wait-online@" = { - description = "Wait for Network Interface %I to be Configured"; - conflicts = [ "shutdown.target" ]; - requisite = [ "systemd-networkd.service" ]; - after = [ "systemd-networkd.service" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I"; - }; - }; - - services.resolved.enable = mkDefault true; - }) - ]; -} diff --git a/modules/networkd/systemd-lib.nix b/modules/networkd/systemd-lib.nix deleted file mode 100644 index c5b5b7cb..00000000 --- a/modules/networkd/systemd-lib.nix +++ /dev/null @@ -1,241 +0,0 @@ -{ config, lib, pkgs }: - -with lib; - -let - cfg = config.systemd; - lndir = "${pkgs.xorg.lndir}/bin/lndir"; -in rec { - - shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s); - - mkPathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""]; - - makeUnit = name: unit: - if unit.enable then - pkgs.runCommand "unit-${mkPathSafeName name}" - { preferLocalBuild = true; - allowSubstitutes = false; - inherit (unit) text; - } - '' - mkdir -p $out - echo -n "$text" > $out/${shellEscape name} - '' - else - pkgs.runCommand "unit-${mkPathSafeName name}-disabled" - { preferLocalBuild = true; - allowSubstitutes = false; - } - '' - mkdir -p $out - ln -s /dev/null $out/${shellEscape name} - ''; - - boolValues = [true false "yes" "no"]; - - digits = map toString (range 0 9); - - isByteFormat = s: - let - l = reverseList (stringToCharacters s); - suffix = head l; - nums = tail l; - in elem suffix (["K" "M" "G" "T"] ++ digits) - && all (num: elem num digits) nums; - - assertByteFormat = name: group: attr: - optional (attr ? ${name} && ! isByteFormat attr.${name}) - "Systemd ${group} field `${name}' must be in byte format [0-9]+[KMGT]."; - - hexChars = stringToCharacters "0123456789abcdefABCDEF"; - - isMacAddress = s: stringLength s == 17 - && flip all (splitString ":" s) (bytes: - all (byte: elem byte hexChars) (stringToCharacters bytes) - ); - - assertMacAddress = name: group: attr: - optional (attr ? ${name} && ! isMacAddress attr.${name}) - "Systemd ${group} field `${name}' must be a valid mac address."; - - isPort = i: i >= 0 && i <= 65535; - - assertPort = name: group: attr: - optional (attr ? ${name} && ! isPort attr.${name}) - "Error on the systemd ${group} field `${name}': ${attr.name} is not a valid port number."; - - assertValueOneOf = name: values: group: attr: - optional (attr ? ${name} && !elem attr.${name} values) - "Systemd ${group} field `${name}' cannot have value `${toString attr.${name}}'."; - - assertHasField = name: group: attr: - optional (!(attr ? ${name})) - "Systemd ${group} field `${name}' must exist."; - - assertRange = name: min: max: group: attr: - optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name})) - "Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]"; - - assertMinimum = name: min: group: attr: - optional (attr ? ${name} && attr.${name} < min) - "Systemd ${group} field `${name}' must be greater than or equal to ${toString min}"; - - assertOnlyFields = fields: group: attr: - let badFields = filter (name: ! elem name fields) (attrNames attr); in - optional (badFields != [ ]) - "Systemd ${group} has extra fields [${concatStringsSep " " badFields}]."; - - assertInt = name: group: attr: - optional (attr ? ${name} && !isInt attr.${name}) - "Systemd ${group} field `${name}' is not an integer"; - - assertMaxLength = name: max: group: attr: - optional (attr ? ${name} && stringLength attr.${name} > max) - "Systemd ${group} field `${name}' is too long (max of ${max})"; - - checkUnitConfig = group: checks: attrs: let - # We're applied at the top-level type (attrsOf unitOption), so the actual - # unit options might contain attributes from mkOverride and mkIf that we need to - # convert into single values before checking them. - defs = mapAttrs (const (v: - if v._type or "" == "override" then v.content - else if v._type or "" == "if" then v.content - else v - )) attrs; - errors = concatMap (c: c group defs) checks; - in if errors == [] then true - else builtins.trace (concatStringsSep "\n" errors) false; - - toOption = x: - if x == true then "true" - else if x == false then "false" - else toString x; - - attrsToSection = as: - concatStrings (concatLists (mapAttrsToList (name: value: - map (x: '' - ${name}=${toOption x} - '') - (if isList value then value else [value])) - as)); - - generateUnits = generateUnits' true; - - generateUnits' = allowCollisions: type: units: upstreamUnits: upstreamWants: - pkgs.runCommand "${type}-units" - { preferLocalBuild = true; - allowSubstitutes = false; - } '' - mkdir -p $out - - # Copy the upstream systemd units we're interested in. - for i in ${toString upstreamUnits}; do - fn=${cfg.package}/example/systemd/${type}/$i - if ! [ -e $fn ]; then echo "missing $fn"; false; fi - if [ -L $fn ]; then - target="$(readlink "$fn")" - if [ ''${target:0:3} = ../ ]; then - ln -s "$(readlink -f "$fn")" $out/ - else - cp -pd $fn $out/ - fi - else - ln -s $fn $out/ - fi - done - - # Copy .wants links, but only those that point to units that - # we're interested in. - for i in ${toString upstreamWants}; do - fn=${cfg.package}/example/systemd/${type}/$i - if ! [ -e $fn ]; then echo "missing $fn"; false; fi - x=$out/$(basename $fn) - mkdir $x - for i in $fn/*; do - y=$x/$(basename $i) - cp -pd $i $y - if ! [ -e $y ]; then rm $y; fi - done - done - - # Symlink all units provided listed in systemd.packages. - packages="${toString cfg.packages}" - - # Filter duplicate directories - declare -A unique_packages - for k in $packages ; do unique_packages[$k]=1 ; done - - for i in ''${!unique_packages[@]}; do - for fn in $i/etc/systemd/${type}/* $i/lib/systemd/${type}/*; do - if ! [[ "$fn" =~ .wants$ ]]; then - if [[ -d "$fn" ]]; then - targetDir="$out/$(basename "$fn")" - mkdir -p "$targetDir" - ${lndir} "$fn" "$targetDir" - else - ln -s $fn $out/ - fi - fi - done - done - - # Symlink all units defined by systemd.units. If these are also - # provided by systemd or systemd.packages, then add them as - # .d/overrides.conf, which makes them extend the - # upstream unit. - for i in ${toString (mapAttrsToList (n: v: v.unit) units)}; do - fn=$(basename $i/*) - if [ -e $out/$fn ]; then - if [ "$(readlink -f $i/$fn)" = /dev/null ]; then - ln -sfn /dev/null $out/$fn - else - ${if allowCollisions then '' - mkdir -p $out/$fn.d - ln -s $i/$fn $out/$fn.d/overrides.conf - '' else '' - echo "Found multiple derivations configuring $fn!" - exit 1 - ''} - fi - else - ln -fs $i/$fn $out/ - fi - done - - # Create service aliases from aliases option. - ${concatStrings (mapAttrsToList (name: unit: - concatMapStrings (name2: '' - ln -sfn '${name}' $out/'${name2}' - '') unit.aliases) units)} - - # Create .wants and .requires symlinks from the wantedBy and - # requiredBy options. - ${concatStrings (mapAttrsToList (name: unit: - concatMapStrings (name2: '' - mkdir -p $out/'${name2}.wants' - ln -sfn '../${name}' $out/'${name2}.wants'/ - '') unit.wantedBy) units)} - - ${concatStrings (mapAttrsToList (name: unit: - concatMapStrings (name2: '' - mkdir -p $out/'${name2}.requires' - ln -sfn '../${name}' $out/'${name2}.requires'/ - '') unit.requiredBy) units)} - - ${optionalString (type == "system") '' - # Stupid misc. symlinks. - ln -s ${cfg.defaultUnit} $out/default.target - ln -s ${cfg.ctrlAltDelUnit} $out/ctrl-alt-del.target - ln -s rescue.target $out/kbrequest.target - - mkdir -p $out/getty.target.wants/ - ln -s ../autovt@tty1.service $out/getty.target.wants/ - - ln -s ../local-fs.target ../remote-fs.target \ - ../nss-lookup.target ../nss-user-lookup.target ../swap.target \ - $out/multi-user.target.wants/ - ''} - ''; # */ - -} diff --git a/modules/networkd/systemd-unit-options.nix b/modules/networkd/systemd-unit-options.nix deleted file mode 100644 index 4154389b..00000000 --- a/modules/networkd/systemd-unit-options.nix +++ /dev/null @@ -1,536 +0,0 @@ -{ config, lib }: - -with lib; -with import ./systemd-lib.nix { inherit config lib pkgs; }; - -let - checkService = checkUnitConfig "Service" [ - (assertValueOneOf "Type" [ - "exec" "simple" "forking" "oneshot" "dbus" "notify" "idle" - ]) - (assertValueOneOf "Restart" [ - "no" "on-success" "on-failure" "on-abnormal" "on-abort" "always" - ]) - ]; - -in rec { - - unitOption = mkOptionType { - name = "systemd option"; - merge = loc: defs: - let - defs' = filterOverrides defs; - defs'' = getValues defs'; - in - if isList (head defs'') - then concatLists defs'' - else mergeEqualOption loc defs'; - }; - - sharedOptions = { - - enable = mkOption { - default = true; - type = types.bool; - description = '' - If set to false, this unit will be a symlink to - /dev/null. This is primarily useful to prevent specific - template instances - (e.g. serial-getty@ttyS0) from being - started. Note that enable=true does not - make a unit start by default at boot; if you want that, see - wantedBy. - ''; - }; - - requiredBy = mkOption { - default = []; - type = types.listOf types.str; - description = '' - Units that require (i.e. depend on and need to go down with) - this unit. The discussion under wantedBy - applies here as well: inverse .requires - symlinks are established. - ''; - }; - - wantedBy = mkOption { - default = []; - type = types.listOf types.str; - description = '' - Units that want (i.e. depend on) this unit. The standard way - to make a unit start by default at boot is to set this option - to [ "multi-user.target" ]. That's despite - the fact that the systemd.unit(5) manpage says this option - goes in the [Install] section that controls - the behaviour of systemctl enable. Since - such a process is stateful and thus contrary to the design of - NixOS, setting this option instead causes the equivalent - inverse .wants symlink to be present, - establishing the same desired relationship in a stateless way. - ''; - }; - - aliases = mkOption { - default = []; - type = types.listOf types.str; - description = "Aliases of that unit."; - }; - - }; - - concreteUnitOptions = sharedOptions // { - - text = mkOption { - type = types.nullOr types.str; - default = null; - description = "Text of this systemd unit."; - }; - - unit = mkOption { - internal = true; - description = "The generated unit."; - }; - - }; - - commonUnitOptions = sharedOptions // { - - description = mkOption { - default = ""; - type = types.str; - description = "Description of this unit used in systemd messages and progress indicators."; - }; - - documentation = mkOption { - default = []; - type = types.listOf types.str; - description = "A list of URIs referencing documentation for this unit or its configuration."; - }; - - requires = mkOption { - default = []; - type = types.listOf types.str; - description = '' - Start the specified units when this unit is started, and stop - this unit when the specified units are stopped or fail. - ''; - }; - - wants = mkOption { - default = []; - type = types.listOf types.str; - description = '' - Start the specified units when this unit is started. - ''; - }; - - after = mkOption { - default = []; - type = types.listOf types.str; - description = '' - If the specified units are started at the same time as - this unit, delay this unit until they have started. - ''; - }; - - before = mkOption { - default = []; - type = types.listOf types.str; - description = '' - If the specified units are started at the same time as - this unit, delay them until this unit has started. - ''; - }; - - bindsTo = mkOption { - default = []; - type = types.listOf types.str; - description = '' - Like ‘requires’, but in addition, if the specified units - unexpectedly disappear, this unit will be stopped as well. - ''; - }; - - partOf = mkOption { - default = []; - type = types.listOf types.str; - description = '' - If the specified units are stopped or restarted, then this - unit is stopped or restarted as well. - ''; - }; - - conflicts = mkOption { - default = []; - type = types.listOf types.str; - description = '' - If the specified units are started, then this unit is stopped - and vice versa. - ''; - }; - - requisite = mkOption { - default = []; - type = types.listOf types.str; - description = '' - Similar to requires. However if the units listed are not started, - they will not be started and the transaction will fail. - ''; - }; - - unitConfig = mkOption { - default = {}; - example = { RequiresMountsFor = "/data"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Unit] section of the unit. See - systemd.unit - 5 for details. - ''; - }; - - restartTriggers = mkOption { - default = []; - type = types.listOf types.unspecified; - description = '' - An arbitrary list of items such as derivations. If any item - in the list changes between reconfigurations, the service will - be restarted. - ''; - }; - - onFailure = mkOption { - default = []; - type = types.listOf types.str; - description = '' - A list of one or more units that are activated when - this unit enters the "failed" state. - ''; - }; - - startLimitBurst = mkOption { - type = types.int; - description = '' - Configure unit start rate limiting. Units which are started - more than startLimitBurst times within an interval time - interval are not permitted to start any more. - ''; - }; - - startLimitIntervalSec = mkOption { - type = types.int; - description = '' - Configure unit start rate limiting. Units which are started - more than startLimitBurst times within an interval time - interval are not permitted to start any more. - ''; - }; - - }; - - - serviceOptions = commonUnitOptions // { - - environment = mkOption { - default = {}; - type = with types; attrsOf (nullOr (oneOf [ str path package ])); - example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; - description = "Environment variables passed to the service's processes."; - }; - - path = mkOption { - default = []; - type = with types; listOf (oneOf [ package str ]); - description = '' - Packages added to the service's PATH - environment variable. Both the bin - and sbin subdirectories of each - package are added. - ''; - }; - - serviceConfig = mkOption { - default = {}; - example = - { RestartSec = 5; - }; - type = types.addCheck (types.attrsOf unitOption) checkService; - description = '' - Each attribute in this set specifies an option in the - [Service] section of the unit. See - systemd.service - 5 for details. - ''; - }; - - script = mkOption { - type = types.lines; - default = ""; - description = "Shell commands executed as the service's main process."; - }; - - scriptArgs = mkOption { - type = types.str; - default = ""; - description = "Arguments passed to the main process script."; - }; - - preStart = mkOption { - type = types.lines; - default = ""; - description = '' - Shell commands executed before the service's main process - is started. - ''; - }; - - postStart = mkOption { - type = types.lines; - default = ""; - description = '' - Shell commands executed after the service's main process - is started. - ''; - }; - - reload = mkOption { - type = types.lines; - default = ""; - description = '' - Shell commands executed when the service's main process - is reloaded. - ''; - }; - - preStop = mkOption { - type = types.lines; - default = ""; - description = '' - Shell commands executed to stop the service. - ''; - }; - - postStop = mkOption { - type = types.lines; - default = ""; - description = '' - Shell commands executed after the service's main process - has exited. - ''; - }; - - restartIfChanged = mkOption { - type = types.bool; - default = true; - description = '' - Whether the service should be restarted during a NixOS - configuration switch if its definition has changed. - ''; - }; - - reloadIfChanged = mkOption { - type = types.bool; - default = false; - description = '' - Whether the service should be reloaded during a NixOS - configuration switch if its definition has changed. If - enabled, the value of is - ignored. - ''; - }; - - stopIfChanged = mkOption { - type = types.bool; - default = true; - description = '' - If set, a changed unit is restarted by calling - systemctl stop in the old configuration, - then systemctl start in the new one. - Otherwise, it is restarted in a single step using - systemctl restart in the new configuration. - The latter is less correct because it runs the - ExecStop commands from the new - configuration. - ''; - }; - - startAt = mkOption { - type = with types; either str (listOf str); - default = []; - example = "Sun 14:00:00"; - description = '' - Automatically start this unit at the given date/time, which - must be in the format described in - systemd.time - 7. This is equivalent - to adding a corresponding timer unit with - set to the value given here. - ''; - apply = v: if isList v then v else [ v ]; - }; - - }; - - - socketOptions = commonUnitOptions // { - - listenStreams = mkOption { - default = []; - type = types.listOf types.str; - example = [ "0.0.0.0:993" "/run/my-socket" ]; - description = '' - For each item in this list, a ListenStream - option in the [Socket] section will be created. - ''; - }; - - listenDatagrams = mkOption { - default = []; - type = types.listOf types.str; - example = [ "0.0.0.0:993" "/run/my-socket" ]; - description = '' - For each item in this list, a ListenDatagram - option in the [Socket] section will be created. - ''; - }; - - socketConfig = mkOption { - default = {}; - example = { ListenStream = "/run/my-socket"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Socket] section of the unit. See - systemd.socket - 5 for details. - ''; - }; - - }; - - - timerOptions = commonUnitOptions // { - - timerConfig = mkOption { - default = {}; - example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Timer] section of the unit. See - systemd.timer - 5 and - systemd.time - 7 for details. - ''; - }; - - }; - - - pathOptions = commonUnitOptions // { - - pathConfig = mkOption { - default = {}; - example = { PathChanged = "/some/path"; Unit = "changedpath.service"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Path] section of the unit. See - systemd.path - 5 for details. - ''; - }; - - }; - - - mountOptions = commonUnitOptions // { - - what = mkOption { - example = "/dev/sda1"; - type = types.str; - description = "Absolute path of device node, file or other resource. (Mandatory)"; - }; - - where = mkOption { - example = "/mnt"; - type = types.str; - description = '' - Absolute path of a directory of the mount point. - Will be created if it doesn't exist. (Mandatory) - ''; - }; - - type = mkOption { - default = ""; - example = "ext4"; - type = types.str; - description = "File system type."; - }; - - options = mkOption { - default = ""; - example = "noatime"; - type = types.commas; - description = "Options used to mount the file system."; - }; - - mountConfig = mkOption { - default = {}; - example = { DirectoryMode = "0775"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Mount] section of the unit. See - systemd.mount - 5 for details. - ''; - }; - }; - - automountOptions = commonUnitOptions // { - - where = mkOption { - example = "/mnt"; - type = types.str; - description = '' - Absolute path of a directory of the mount point. - Will be created if it doesn't exist. (Mandatory) - ''; - }; - - automountConfig = mkOption { - default = {}; - example = { DirectoryMode = "0775"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Automount] section of the unit. See - systemd.automount - 5 for details. - ''; - }; - }; - - targetOptions = commonUnitOptions; - - sliceOptions = commonUnitOptions // { - - sliceConfig = mkOption { - default = {}; - example = { MemoryMax = "2G"; }; - type = types.attrsOf unitOption; - description = '' - Each attribute in this set specifies an option in the - [Slice] section of the unit. See - systemd.slice - 5 for details. - ''; - }; - - }; - -} diff --git a/modules/yggdrasil-wg/default.nix b/modules/yggdrasil-wg/default.nix index 55fb1e9d..1e52ba06 100644 --- a/modules/yggdrasil-wg/default.nix +++ b/modules/yggdrasil-wg/default.nix @@ -202,7 +202,7 @@ in { Name = "yggdrasil"; }; address = batHostIPs.${hostName}; - dns = ["[2a03:4000:52:ada:1:1::]"]; + dns = ["2a03:4000:52:ada:1:1::"]; domains = ["yggdrasil"]; routes = [ { routeConfig = { @@ -222,7 +222,7 @@ in { Table = "yggdrasil"; }; } - ] ++ (concatMap (router: map (rAddr: { routeConfig = { Destination = "::/0"; Gateway = stripSubnet rAddr; GatewayOnLink = true; Table = "yggdrasil"; }; }) batHostIPs.${router}) routers); + ] ++ (concatMap (router: map (rAddr: { routeConfig = { Destination = "::/0"; Gateway = stripSubnet rAddr; GatewayOnLink = true; Table = "yggdrasil"; }; }) batHostIPs.${router}) (filter (router: router != hostName) routers)); routingPolicyRules = map (addr: { routingPolicyRuleConfig = { Table = "yggdrasil"; From = stripSubnet addr; Priority = 1; }; }) batHostIPs.${hostName}; linkConfig = { MACAddress = "${batHostMACs.${hostName}}"; @@ -236,13 +236,8 @@ in { }; }; } // listToAttrs (map familyToYggdrasilNetwork hostFamilies) // listToAttrs (concatMap (family: imap0 (linkToGreNetwork family) hostLinks.${family}) hostFamilies); - }; - environment.etc."systemd/networkd.conf" = mkIf inNetwork { - text = '' - [Network] - RouteTable=yggdrasil:1024 - ''; + config.routeTables.yggdrasil = 1024; }; sops.secrets = listToAttrs (map familyToSopsSecret hostFamilies); -- cgit v1.2.3