diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 0c9c12962659..5451ef821425 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -414,6 +414,9 @@
./system/boot/stage-1.nix
./system/boot/stage-2.nix
./system/boot/systemd.nix
+ ./system/boot/networkd.nix
+ ./system/boot/resolved.nix
+ ./system/boot/timesyncd.nix
./system/boot/tmp.nix
./system/etc/etc.nix
./system/upstart/upstart.nix
diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix
new file mode 100644
index 000000000000..34a8b3fe0f95
--- /dev/null
+++ b/nixos/modules/system/boot/networkd.nix
@@ -0,0 +1,663 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+with import ./systemd-unit-options.nix { inherit config lib; };
+
+let
+
+ cfg = config.systemd.network;
+
+ checkLink = checkUnitConfig "Link" [
+ (assertOnlyFields [
+ "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
+ "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan"
+ ])
+ (assertValueOneOf "MACAddressPolicy" ["persistent" "random"])
+ (assertMacAddress "MACAddress")
+ (assertValueOneOf "NamePolicy" [
+ "kernel" "database" "onboard" "slot" "path" "mac"
+ ])
+ (assertByteFormat "MTUBytes")
+ (assertByteFormat "BitsPerSecond")
+ (assertValueOneOf "Duplex" ["half" "full"])
+ (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"])
+ ];
+
+ checkNetdev = checkUnitConfig "Netdev" [
+ (assertOnlyFields [
+ "Description" "Name" "Kind" "MTUBytes" "MACAddress"
+ ])
+ (assertHasField "Name")
+ (assertHasField "Kind")
+ (assertValueOneOf "Kind" [
+ "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip"
+ "gre" "sit" "vti" "veth" "tun" "tap" "dummy"
+ ])
+ (assertByteFormat "MTUBytes")
+ (assertMacAddress "MACAddress")
+ ];
+
+ checkVlan = checkUnitConfig "VLAN" [
+ (assertOnlyFields ["Id"])
+ (assertRange "Id" 0 4094)
+ ];
+
+ checkMacvlan = checkUnitConfig "MACVLAN" [
+ (assertOnlyFields ["Mode"])
+ (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
+ ];
+
+ checkVxlan = checkUnitConfig "VXLAN" [
+ (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"])
+ (assertRange "TTL" 0 255)
+ (assertValueOneOf "MacLearning" boolValues)
+ ];
+
+ checkTunnel = checkUnitConfig "Tunnel" [
+ (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"])
+ (assertRange "TTL" 0 255)
+ (assertValueOneOf "DiscoverPathMTU" boolValues)
+ ];
+
+ checkPeer = checkUnitConfig "Peer" [
+ (assertOnlyFields ["Name" "MACAddress"])
+ (assertMacAddress "MACAddress")
+ ];
+
+ tunTapChecks = [
+ (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"])
+ (assertValueOneOf "OneQueue" boolValues)
+ (assertValueOneOf "MultiQueue" boolValues)
+ (assertValueOneOf "PacketInfo" boolValues)
+ ];
+
+ checkTun = checkUnitConfig "Tun" tunTapChecks;
+
+ checkTap = checkUnitConfig "Tap" tunTapChecks;
+
+ checkBond = checkUnitConfig "Bond" [
+ (assertOnlyFields [
+ "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
+ "UpDelaySec" "DownDelaySec"
+ ])
+ (assertValueOneOf "Mode" [
+ "balance-rr" "active-backup" "balance-xor"
+ "broadcast" "802.3ad" "balance-tlb" "balance-alb"
+ ])
+ (assertValueOneOf "TransmitHashPolicy" [
+ "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4"
+ ])
+ (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
+ ];
+
+ checkNetwork = checkUnitConfig "Network" [
+ (assertOnlyFields [
+ "Description" "DHCP" "DHCPServer" "IPv4LL" "IPv4LLRoute"
+ "LLMNR" "Domains" "Bridge" "Bond"
+ ])
+ (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
+ (assertValueOneOf "DHCPServer" boolValues)
+ (assertValueOneOf "IPv4LL" boolValues)
+ (assertValueOneOf "IPv4LLRoute" boolValues)
+ (assertValueOneOf "LLMNR" boolValues)
+ ];
+
+ checkAddress = checkUnitConfig "Address" [
+ (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
+ (assertHasField "Address")
+ ];
+
+ checkRoute = checkUnitConfig "Route" [
+ (assertOnlyFields ["Gateway" "Destination" "Metric"])
+ (assertHasField "Gateway")
+ ];
+
+ checkDhcp = checkUnitConfig "DHCP" [
+ (assertOnlyFields [
+ "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
+ "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
+ "RouteMetric"
+ ])
+ (assertValueOneOf "UseDNS" boolValues)
+ (assertValueOneOf "UseMTU" boolValues)
+ (assertValueOneOf "SendHostname" boolValues)
+ (assertValueOneOf "UseHostname" boolValues)
+ (assertValueOneOf "UseDomains" boolValues)
+ (assertValueOneOf "UseRoutes" boolValues)
+ (assertValueOneOf "CriticalConnections" boolValues)
+ (assertValueOneOf "RequestBroadcast" boolValues)
+ ];
+
+ commonNetworkOptions = {
+
+ enable = mkOption {
+ default = false;
+ 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.
+ '';
+ };
+
+ };
+
+ linkOptions = commonNetworkOptions // {
+
+ linkConfig = mkOption {
+ default = {};
+ example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
+ type = types.addCheck (types.attrsOf unitOption) checkLink;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Link] section of the unit. See
+ systemd.link
+ 5 for details.
+ '';
+ };
+
+ };
+
+ netdevOptions = commonNetworkOptions // {
+
+ netdevConfig = mkOption {
+ default = {};
+ example = { Name = "mybridge"; Kind = "bridge"; };
+ type = types.addCheck (types.attrsOf unitOption) checkNetdev;
+ 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) checkVlan;
+ 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) checkMacvlan;
+ 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) checkVxlan;
+ 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) checkTunnel;
+ 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) checkPeer;
+ 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) checkTun;
+ 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) checkTap;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Tap] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ bondConfig = mkOption {
+ default = {};
+ example = { Mode = "802.3ad"; };
+ type = types.addCheck (types.attrsOf unitOption) checkBond;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Bond] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ };
+
+ addressOptions = {
+
+ addressConfig = mkOption {
+ default = {};
+ example = { Address = "192.168.0.100/24"; };
+ type = types.addCheck (types.attrsOf unitOption) checkAddress;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Address] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ };
+
+ routeOptions = {
+
+ routeConfig = mkOption {
+ default = {};
+ example = { Gateway = "192.168.0.1"; };
+ type = types.addCheck (types.attrsOf unitOption) checkRoute;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Route] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ };
+
+ networkOptions = commonNetworkOptions // {
+
+ networkConfig = mkOption {
+ default = {};
+ example = { Description = "My Network"; };
+ type = types.addCheck (types.attrsOf unitOption) checkNetwork;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Network] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ dhcpConfig = mkOption {
+ default = {};
+ example = { UseDNS = true; UseRoutes = true; };
+ type = types.addCheck (types.attrsOf unitOption) checkDhcp;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [DHCP] section of 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.
+ '';
+ };
+
+ 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.
+ '';
+ };
+
+ addresses = mkOption {
+ default = [ ];
+ type = types.listOf types.optionSet;
+ options = [ addressOptions ];
+ description = ''
+ A list of address sections to be added to the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ routes = mkOption {
+ default = [ ];
+ type = types.listOf types.optionSet;
+ options = [ routeOptions ];
+ description = ''
+ A list of route sections to be added to the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ };
+
+ networkConfig = { name, 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;
+ };
+ };
+ };
+
+ linkToUnit = name: def:
+ { inherit (def) enable;
+ text = commonMatchText def +
+ ''
+ [Link]
+ ${attrsToSection def.linkConfig}
+ '';
+ };
+
+ 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.bondConfig != { }) ''
+ [Bond]
+ ${attrsToSection def.bondConfig}
+
+ ''}
+ '';
+ };
+
+ networkToUnit = name: def:
+ { inherit (def) enable;
+ text = commonMatchText def +
+ ''
+ [Network]
+ ${attrsToSection def.networkConfig}
+ ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
+ ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
+ ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
+ ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
+ ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
+ ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
+ ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
+ ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
+
+ ${optionalString (def.dhcpConfig != { }) ''
+ [DHCP]
+ ${attrsToSection def.dhcpConfig}
+
+ ''}
+ ${flip concatMapStrings def.addresses (x: ''
+ [Address]
+ ${attrsToSection x.addressConfig}
+
+ '')}
+ ${flip concatMapStrings def.routes (x: ''
+ [Route]
+ ${attrsToSection x.routeConfig}
+
+ '')}
+ '';
+ };
+
+in
+
+{
+
+ options = {
+
+ systemd.network.enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to enable networkd or not.
+ '';
+ };
+
+ systemd.network.links = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ linkOptions ];
+ description = "Definition of systemd network links.";
+ };
+
+ systemd.network.netdevs = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ netdevOptions ];
+ description = "Definition of systemd network devices.";
+ };
+
+ systemd.network.networks = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ networkOptions networkConfig ];
+ description = "Definition of systemd networks.";
+ };
+
+ systemd.network.units = mkOption {
+ description = "Definition of networkd units.";
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = { name, config, ... }:
+ { options = concreteUnitOptions;
+ config = {
+ unit = mkDefault (makeUnit name config);
+ };
+ };
+ };
+
+ };
+
+ config = mkIf config.systemd.network.enable {
+
+ systemd.network.units =
+ mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links
+ // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
+ // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;
+
+ users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network;
+ users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network;
+
+ systemd.services.systemd-networkd = {
+ wantedBy = [ "multi-user.target" ];
+ before = [ "network-interfaces.target" ];
+ restartTriggers = [ config.environment.etc."systemd/network".source ];
+ };
+
+ systemd.services.systemd-networkd-wait-online = {
+ before = [ "network-online.target" "ip-up.target" ];
+ wantedBy = [ "network-online.target" "ip-up.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;
+ services.timesyncd.enable = mkDefault config.services.ntp.enable;
+
+ };
+
+}
diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix
new file mode 100644
index 000000000000..cdc76d59f9a8
--- /dev/null
+++ b/nixos/modules/system/boot/resolved.nix
@@ -0,0 +1,36 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+
+ options = {
+
+ services.resolved.enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to enable the systemd DNS resolver daemon.
+ '';
+ };
+
+ };
+
+ config = mkIf config.services.resolved.enable {
+
+ systemd.services.systemd-resolved = {
+ wantedBy = [ "multi-user.target" ];
+ restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
+ };
+
+ environment.etc."systemd/resolved.conf".text = ''
+ [Resolve]
+ DNS=${concatStringsSep " " config.networking.nameservers}
+ '';
+
+ users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve;
+ users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve;
+
+ };
+
+}
diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix
index 2f4786c78966..785634cbf66a 100644
--- a/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixos/modules/system/boot/systemd-unit-options.nix
@@ -62,126 +62,7 @@ let
])
];
- checkLink = checkUnitConfig "Link" [
- (assertOnlyFields [
- "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
- "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan"
- ])
- (assertValueOneOf "MACAddressPolicy" ["persistent" "random"])
- (assertMacAddress "MACAddress")
- (assertValueOneOf "NamePolicy" [
- "kernel" "database" "onboard" "slot" "path" "mac"
- ])
- (assertByteFormat "MTUBytes")
- (assertByteFormat "BitsPerSecond")
- (assertValueOneOf "Duplex" ["half" "full"])
- (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"])
- ];
-
- checkNetdev = checkUnitConfig "Netdev" [
- (assertOnlyFields [
- "Description" "Name" "Kind" "MTUBytes" "MACAddress"
- ])
- (assertHasField "Name")
- (assertHasField "Kind")
- (assertValueOneOf "Kind" [
- "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip"
- "gre" "sit" "vti" "veth" "tun" "tap" "dummy"
- ])
- (assertByteFormat "MTUBytes")
- (assertMacAddress "MACAddress")
- ];
-
- checkVlan = checkUnitConfig "VLAN" [
- (assertOnlyFields ["Id"])
- (assertRange "Id" 0 4094)
- ];
-
- checkMacvlan = checkUnitConfig "MACVLAN" [
- (assertOnlyFields ["Mode"])
- (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
- ];
-
- checkVxlan = checkUnitConfig "VXLAN" [
- (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"])
- (assertRange "TTL" 0 255)
- (assertValueOneOf "MacLearning" boolValues)
- ];
-
- checkTunnel = checkUnitConfig "Tunnel" [
- (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"])
- (assertRange "TTL" 0 255)
- (assertValueOneOf "DiscoverPathMTU" boolValues)
- ];
-
- checkPeer = checkUnitConfig "Peer" [
- (assertOnlyFields ["Name" "MACAddress"])
- (assertMacAddress "MACAddress")
- ];
-
- tunTapChecks = [
- (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"])
- (assertValueOneOf "OneQueue" boolValues)
- (assertValueOneOf "MultiQueue" boolValues)
- (assertValueOneOf "PacketInfo" boolValues)
- ];
-
- checkTun = checkUnitConfig "Tun" tunTapChecks;
-
- checkTap = checkUnitConfig "Tap" tunTapChecks;
-
- checkBond = checkUnitConfig "Bond" [
- (assertOnlyFields [
- "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
- "UpDelaySec" "DownDelaySec"
- ])
- (assertValueOneOf "Mode" [
- "balance-rr" "active-backup" "balance-xor"
- "broadcast" "802.3ad" "balance-tlb" "balance-alb"
- ])
- (assertValueOneOf "TransmitHashPolicy" [
- "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4"
- ])
- (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
- ];
-
- checkNetwork = checkUnitConfig "Network" [
- (assertOnlyFields [
- "Description" "DHCP" "DHCPServer" "IPv4LL" "IPv4LLRoute"
- "LLMNR" "Domains" "Bridge" "Bond"
- ])
- (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
- (assertValueOneOf "DHCPServer" boolValues)
- (assertValueOneOf "IPv4LL" boolValues)
- (assertValueOneOf "IPv4LLRoute" boolValues)
- (assertValueOneOf "LLMNR" boolValues)
- ];
-
- checkAddress = checkUnitConfig "Address" [
- (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
- (assertHasField "Address")
- ];
-
- checkRoute = checkUnitConfig "Route" [
- (assertOnlyFields ["Gateway" "Destination" "Metric"])
- (assertHasField "Gateway")
- ];
-
- checkDhcp = checkUnitConfig "DHCP" [
- (assertOnlyFields [
- "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
- "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
- "RouteMetric"
- ])
- (assertValueOneOf "UseDNS" boolValues)
- (assertValueOneOf "UseMTU" boolValues)
- (assertValueOneOf "SendHostname" boolValues)
- (assertValueOneOf "UseHostname" boolValues)
- (assertValueOneOf "UseDomains" boolValues)
- (assertValueOneOf "UseRoutes" boolValues)
- (assertValueOneOf "CriticalConnections" boolValues)
- (assertValueOneOf "RequestBroadcast" boolValues)
- ];
+in rec {
unitOption = mkOptionType {
name = "systemd option";
@@ -195,8 +76,6 @@ let
else mergeOneOption loc defs';
};
-in rec {
-
sharedOptions = {
enable = mkOption {
@@ -619,345 +498,4 @@ in rec {
targetOptions = commonUnitOptions;
- commonNetworkOptions = {
-
- enable = mkOption {
- default = true;
- type = types.bool;
- description = ''
- If set to false, this unit will be a symlink to
- /dev/null.
- '';
- };
-
- 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.
- '';
- };
-
- };
-
- linkOptions = commonNetworkOptions // {
-
- linkConfig = mkOption {
- default = {};
- example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
- type = types.addCheck (types.attrsOf unitOption) checkLink;
- description = ''
- Each attribute in this set specifies an option in the
- [Link] section of the unit. See
- systemd.link
- 5 for details.
- '';
- };
-
- };
-
- netdevOptions = commonNetworkOptions // {
-
- netdevConfig = mkOption {
- default = {};
- example = { Name = "mybridge"; Kind = "bridge"; };
- type = types.addCheck (types.attrsOf unitOption) checkNetdev;
- 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) checkVlan;
- 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) checkMacvlan;
- 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) checkVxlan;
- 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) checkTunnel;
- 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) checkPeer;
- 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) checkTun;
- 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) checkTap;
- description = ''
- Each attribute in this set specifies an option in the
- [Tap] section of the unit. See
- systemd.netdev
- 5 for details.
- '';
- };
-
- bondConfig = mkOption {
- default = {};
- example = { Mode = "802.3ad"; };
- type = types.addCheck (types.attrsOf unitOption) checkBond;
- description = ''
- Each attribute in this set specifies an option in the
- [Bond] section of the unit. See
- systemd.netdev
- 5 for details.
- '';
- };
-
- };
-
- addressOptions = {
-
- addressConfig = mkOption {
- default = {};
- example = { Address = "192.168.0.100/24"; };
- type = types.addCheck (types.attrsOf unitOption) checkAddress;
- description = ''
- Each attribute in this set specifies an option in the
- [Address] section of the unit. See
- systemd.network
- 5 for details.
- '';
- };
-
- };
-
- routeOptions = {
-
- routeConfig = mkOption {
- default = {};
- example = { Gateway = "192.168.0.1"; };
- type = types.addCheck (types.attrsOf unitOption) checkRoute;
- description = ''
- Each attribute in this set specifies an option in the
- [Route] section of the unit. See
- systemd.network
- 5 for details.
- '';
- };
-
- };
-
- networkOptions = commonNetworkOptions // {
-
- networkConfig = mkOption {
- default = {};
- example = { Description = "My Network"; };
- type = types.addCheck (types.attrsOf unitOption) checkNetwork;
- description = ''
- Each attribute in this set specifies an option in the
- [Network] section of the unit. See
- systemd.network
- 5 for details.
- '';
- };
-
- dhcpConfig = mkOption {
- default = {};
- example = { UseDNS = true; UseRoutes = true; };
- type = types.addCheck (types.attrsOf unitOption) checkDhcp;
- description = ''
- Each attribute in this set specifies an option in the
- [DHCP] section of 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.
- '';
- };
-
- 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.
- '';
- };
-
- addresses = mkOption {
- default = [ ];
- type = types.listOf types.optionSet;
- options = [ addressOptions ];
- description = ''
- A list of address sections to be added to the unit. See
- systemd.network
- 5 for details.
- '';
- };
-
- routes = mkOption {
- default = [ ];
- type = types.listOf types.optionSet;
- options = [ routeOptions ];
- description = ''
- A list of route sections to be added to the unit. See
- systemd.network
- 5 for details.
- '';
- };
-
- };
-
}
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 29c449d4d0be..4bd412014a54 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -301,19 +301,6 @@ let
};
};
- networkConfig = { name, 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;
- };
- };
- };
-
toOption = x:
if x == true then "true"
else if x == false then "false"
@@ -412,98 +399,6 @@ let
${attrsToSection def.matchConfig}
'';
- linkToUnit = name: def:
- { inherit (def) enable;
- text = commonMatchText def +
- ''
- [Link]
- ${attrsToSection def.linkConfig}
- '';
- };
-
- 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.bondConfig != { }) ''
- [Bond]
- ${attrsToSection def.bondConfig}
-
- ''}
- '';
- };
-
- networkToUnit = name: def:
- { inherit (def) enable;
- text = commonMatchText def +
- ''
- [Network]
- ${attrsToSection def.networkConfig}
- ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
- ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
- ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
- ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
- ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
- ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
- ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
- ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
-
- ${optionalString (def.dhcpConfig != { }) ''
- [DHCP]
- ${attrsToSection def.dhcpConfig}
-
- ''}
- ${flip concatMapStrings def.addresses (x: ''
- [Address]
- ${attrsToSection x.addressConfig}
-
- '')}
- ${flip concatMapStrings def.routes (x: ''
- [Route]
- ${attrsToSection x.routeConfig}
-
- '')}
- '';
- };
-
generateUnits = type: units: upstreamUnits: upstreamWants:
pkgs.runCommand "${type}-units" { preferLocalBuild = true; } ''
mkdir -p $out
@@ -683,47 +578,6 @@ in
'';
};
- systemd.network.enable = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Whether to enable networkd or not.
- '';
- };
-
- systemd.network.links = mkOption {
- default = {};
- type = types.attrsOf types.optionSet;
- options = [ linkOptions ];
- description = "Definition of systemd network links.";
- };
-
- systemd.network.netdevs = mkOption {
- default = {};
- type = types.attrsOf types.optionSet;
- options = [ netdevOptions ];
- description = "Definition of systemd network devices.";
- };
-
- systemd.network.networks = mkOption {
- default = {};
- type = types.attrsOf types.optionSet;
- options = [ networkOptions networkConfig ];
- description = "Definition of systemd networks.";
- };
-
- systemd.network.units = mkOption {
- description = "Definition of networkd units.";
- default = {};
- type = types.attrsOf types.optionSet;
- options = { name, config, ... }:
- { options = concreteUnitOptions;
- config = {
- unit = mkDefault (makeUnit name config);
- };
- };
- };
-
systemd.defaultUnit = mkOption {
default = "multi-user.target";
type = types.str;
@@ -807,22 +661,6 @@ in
'';
};
- services.resolved.enable = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Enables the systemd dns resolver daemon.
- '';
- };
-
- services.timesyncd.enable = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Enables the systemd ntp client daemon.
- '';
- };
-
systemd.tmpfiles.rules = mkOption {
type = types.listOf types.str;
default = [];
@@ -886,7 +724,7 @@ in
###### implementation
- config = mkMerge [ {
+ config = {
warnings = concatLists (mapAttrsToList (name: service:
optional (service.serviceConfig.Type or "" == "oneshot" && service.serviceConfig.Restart or "no" != "no")
@@ -899,6 +737,7 @@ in
environment.etc."systemd/system".source =
generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
+ # FIXME: move to networkd.nix.
environment.etc."systemd/network".source =
generateUnits "network" cfg.network.units [] [];
@@ -979,11 +818,6 @@ in
(v: let n = escapeSystemdPath v.where;
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
- systemd.network.units =
- mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.network.links
- // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.network.netdevs
- // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.network.networks;
-
systemd.user.units =
mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services
// mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets
@@ -1006,15 +840,6 @@ in
users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
- users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network;
- users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network;
-
- users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve;
- users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve;
-
- users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync;
- users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
-
# Generate timer units for all services that have a ‘startAt’ value.
systemd.timers =
mapAttrs (name: service:
@@ -1053,57 +878,6 @@ in
systemd.services.systemd-remount-fs.restartIfChanged = false;
systemd.services.systemd-journal-flush.restartIfChanged = false;
- }
- (mkIf config.systemd.network.enable {
- systemd.services.systemd-networkd = {
- wantedBy = [ "multi-user.target" ];
- before = [ "network-interfaces.target" ];
- restartTriggers = [ config.environment.etc."systemd/network".source ];
- };
+ };
- systemd.services.systemd-networkd-wait-online = {
- before = [ "network-online.target" "ip-up.target" ];
- wantedBy = [ "network-online.target" "ip-up.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;
- services.timesyncd.enable = mkDefault config.services.ntp.enable;
- })
- (mkIf config.services.resolved.enable {
- systemd.services.systemd-resolved = {
- wantedBy = [ "multi-user.target" ];
- restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
- };
-
- environment.etc."systemd/resolved.conf".text = ''
- [Resolve]
- DNS=${concatStringsSep " " config.networking.nameservers}
- '';
- })
- (mkIf config.services.timesyncd.enable {
- systemd.services.systemd-timesyncd = {
- wantedBy = [ "sysinit.target" ];
- restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ];
- };
-
- environment.etc."systemd/timesyncd.conf".text = ''
- [Time]
- NTP=${concatStringsSep " " config.services.ntp.servers}
- '';
-
- systemd.services.ntpd.enable = false;
- })
- ];
}
diff --git a/nixos/modules/system/boot/timesyncd.nix b/nixos/modules/system/boot/timesyncd.nix
new file mode 100644
index 000000000000..fd4be47ad721
--- /dev/null
+++ b/nixos/modules/system/boot/timesyncd.nix
@@ -0,0 +1,38 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+
+ options = {
+
+ services.timesyncd.enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Enables the systemd NTP client daemon.
+ '';
+ };
+
+ };
+
+ config = mkIf config.services.timesyncd.enable {
+
+ systemd.services.systemd-timesyncd = {
+ wantedBy = [ "sysinit.target" ];
+ restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ];
+ };
+
+ environment.etc."systemd/timesyncd.conf".text = ''
+ [Time]
+ NTP=${concatStringsSep " " config.services.ntp.servers}
+ '';
+
+ systemd.services.ntpd.enable = false;
+
+ users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync;
+ users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
+
+ };
+
+}