1{ config, lib, pkgs, ... }:
2
3with lib;
4with import ./systemd-unit-options.nix { inherit config lib; };
5with import ./systemd-lib.nix { inherit config lib pkgs; };
6
7let
8
9 cfg = config.systemd.network;
10
11 check = {
12
13 link = {
14
15 sectionLink = checkUnitConfig "Link" [
16 (assertOnlyFields [
17 "Description"
18 "Alias"
19 "MACAddressPolicy"
20 "MACAddress"
21 "NamePolicy"
22 "Name"
23 "AlternativeNamesPolicy"
24 "AlternativeName"
25 "MTUBytes"
26 "BitsPerSecond"
27 "Duplex"
28 "AutoNegotiation"
29 "WakeOnLan"
30 "Port"
31 "Advertise"
32 "ReceiveChecksumOffload"
33 "TransmitChecksumOffload"
34 "TCPSegmentationOffload"
35 "TCP6SegmentationOffload"
36 "GenericSegmentationOffload"
37 "GenericReceiveOffload"
38 "LargeReceiveOffload"
39 "RxChannels"
40 "TxChannels"
41 "OtherChannels"
42 "CombinedChannels"
43 "RxBufferSize"
44 "TxBufferSize"
45 ])
46 (assertValueOneOf "MACAddressPolicy" ["persistent" "random" "none"])
47 (assertMacAddress "MACAddress")
48 (assertByteFormat "MTUBytes")
49 (assertByteFormat "BitsPerSecond")
50 (assertValueOneOf "Duplex" ["half" "full"])
51 (assertValueOneOf "AutoNegotiation" boolValues)
52 (assertValueOneOf "WakeOnLan" ["phy" "unicast" "multicast" "broadcast" "arp" "magic" "secureon" "off"])
53 (assertValueOneOf "Port" ["tp" "aui" "bnc" "mii" "fibre"])
54 (assertValueOneOf "ReceiveChecksumOffload" boolValues)
55 (assertValueOneOf "TransmitChecksumOffload" boolValues)
56 (assertValueOneOf "TCPSegmentationOffload" boolValues)
57 (assertValueOneOf "TCP6SegmentationOffload" boolValues)
58 (assertValueOneOf "GenericSegmentationOffload" boolValues)
59 (assertValueOneOf "GenericReceiveOffload" boolValues)
60 (assertValueOneOf "LargeReceiveOffload" boolValues)
61 (assertInt "RxChannels")
62 (assertRange "RxChannels" 1 4294967295)
63 (assertInt "TxChannels")
64 (assertRange "TxChannels" 1 4294967295)
65 (assertInt "OtherChannels")
66 (assertRange "OtherChannels" 1 4294967295)
67 (assertInt "CombinedChannels")
68 (assertRange "CombinedChannels" 1 4294967295)
69 (assertInt "RxBufferSize")
70 (assertInt "TxBufferSize")
71 ];
72 };
73
74 netdev = let
75
76 tunChecks = [
77 (assertOnlyFields [
78 "MultiQueue"
79 "PacketInfo"
80 "VNetHeader"
81 "User"
82 "Group"
83 ])
84 (assertValueOneOf "MultiQueue" boolValues)
85 (assertValueOneOf "PacketInfo" boolValues)
86 (assertValueOneOf "VNetHeader" boolValues)
87 ];
88 in {
89
90 sectionNetdev = checkUnitConfig "Netdev" [
91 (assertOnlyFields [
92 "Description"
93 "Name"
94 "Kind"
95 "MTUBytes"
96 "MACAddress"
97 ])
98 (assertHasField "Name")
99 (assertHasField "Kind")
100 (assertValueOneOf "Kind" [
101 "bond"
102 "bridge"
103 "dummy"
104 "gre"
105 "gretap"
106 "erspan"
107 "ip6gre"
108 "ip6tnl"
109 "ip6gretap"
110 "ipip"
111 "ipvlan"
112 "macvlan"
113 "macvtap"
114 "sit"
115 "tap"
116 "tun"
117 "veth"
118 "vlan"
119 "vti"
120 "vti6"
121 "vxlan"
122 "geneve"
123 "l2tp"
124 "macsec"
125 "vrf"
126 "vcan"
127 "vxcan"
128 "wireguard"
129 "netdevsim"
130 "nlmon"
131 "fou"
132 "xfrm"
133 "ifb"
134 "batadv"
135 ])
136 (assertByteFormat "MTUBytes")
137 (assertMacAddress "MACAddress")
138 ];
139
140 sectionVLAN = checkUnitConfig "VLAN" [
141 (assertOnlyFields [
142 "Id"
143 "GVRP"
144 "MVRP"
145 "LooseBinding"
146 "ReorderHeader"
147 ])
148 (assertInt "Id")
149 (assertRange "Id" 0 4094)
150 (assertValueOneOf "GVRP" boolValues)
151 (assertValueOneOf "MVRP" boolValues)
152 (assertValueOneOf "LooseBinding" boolValues)
153 (assertValueOneOf "ReorderHeader" boolValues)
154 ];
155
156 sectionMACVLAN = checkUnitConfig "MACVLAN" [
157 (assertOnlyFields [
158 "Mode"
159 ])
160 (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
161 ];
162
163 sectionVXLAN = checkUnitConfig "VXLAN" [
164 (assertOnlyFields [
165 "VNI"
166 "Remote"
167 "Local"
168 "Group"
169 "TOS"
170 "TTL"
171 "MacLearning"
172 "FDBAgeingSec"
173 "MaximumFDBEntries"
174 "ReduceARPProxy"
175 "L2MissNotification"
176 "L3MissNotification"
177 "RouteShortCircuit"
178 "UDPChecksum"
179 "UDP6ZeroChecksumTx"
180 "UDP6ZeroChecksumRx"
181 "RemoteChecksumTx"
182 "RemoteChecksumRx"
183 "GroupPolicyExtension"
184 "GenericProtocolExtension"
185 "DestinationPort"
186 "PortRange"
187 "FlowLabel"
188 "IPDoNotFragment"
189 ])
190 (assertInt "VNI")
191 (assertRange "VNI" 1 16777215)
192 (assertValueOneOf "MacLearning" boolValues)
193 (assertInt "MaximumFDBEntries")
194 (assertValueOneOf "ReduceARPProxy" boolValues)
195 (assertValueOneOf "L2MissNotification" boolValues)
196 (assertValueOneOf "L3MissNotification" boolValues)
197 (assertValueOneOf "RouteShortCircuit" boolValues)
198 (assertValueOneOf "UDPChecksum" boolValues)
199 (assertValueOneOf "UDP6ZeroChecksumTx" boolValues)
200 (assertValueOneOf "UDP6ZeroChecksumRx" boolValues)
201 (assertValueOneOf "RemoteChecksumTx" boolValues)
202 (assertValueOneOf "RemoteChecksumRx" boolValues)
203 (assertValueOneOf "GroupPolicyExtension" boolValues)
204 (assertValueOneOf "GenericProtocolExtension" boolValues)
205 (assertInt "FlowLabel")
206 (assertRange "FlowLabel" 0 1048575)
207 (assertValueOneOf "IPDoNotFragment" (boolValues + ["inherit"]))
208 ];
209
210 sectionTunnel = checkUnitConfig "Tunnel" [
211 (assertOnlyFields [
212 "Local"
213 "Remote"
214 "TOS"
215 "TTL"
216 "DiscoverPathMTU"
217 "IPv6FlowLabel"
218 "CopyDSCP"
219 "EncapsulationLimit"
220 "Key"
221 "InputKey"
222 "OutputKey"
223 "Mode"
224 "Independent"
225 "AssignToLoopback"
226 "AllowLocalRemote"
227 "FooOverUDP"
228 "FOUDestinationPort"
229 "FOUSourcePort"
230 "Encapsulation"
231 "IPv6RapidDeploymentPrefix"
232 "ISATAP"
233 "SerializeTunneledPackets"
234 "ERSPANIndex"
235 ])
236 (assertInt "TTL")
237 (assertRange "TTL" 0 255)
238 (assertValueOneOf "DiscoverPathMTU" boolValues)
239 (assertValueOneOf "CopyDSCP" boolValues)
240 (assertValueOneOf "Mode" ["ip6ip6" "ipip6" "any"])
241 (assertValueOneOf "Independent" boolValues)
242 (assertValueOneOf "AssignToLoopback" boolValues)
243 (assertValueOneOf "AllowLocalRemote" boolValues)
244 (assertValueOneOf "FooOverUDP" boolValues)
245 (assertPort "FOUDestinationPort")
246 (assertPort "FOUSourcePort")
247 (assertValueOneOf "Encapsulation" ["FooOverUDP" "GenericUDPEncapsulation"])
248 (assertValueOneOf "ISATAP" boolValues)
249 (assertValueOneOf "SerializeTunneledPackets" boolValues)
250 (assertInt "ERSPANIndex")
251 (assertRange "ERSPANIndex" 1 1048575)
252 ];
253
254 sectionFooOverUDP = checkUnitConfig "FooOverUDP" [
255 (assertOnlyFields [
256 "Port"
257 "Encapsulation"
258 "Protocol"
259 ])
260 (assertPort "Port")
261 (assertValueOneOf "Encapsulation" ["FooOverUDP" "GenericUDPEncapsulation"])
262 ];
263
264 sectionPeer = checkUnitConfig "Peer" [
265 (assertOnlyFields [
266 "Name"
267 "MACAddress"
268 ])
269 (assertMacAddress "MACAddress")
270 ];
271
272 sectionTun = checkUnitConfig "Tun" tunChecks;
273
274 sectionTap = checkUnitConfig "Tap" tunChecks;
275
276 # NOTE The PrivateKey directive is missing on purpose here, please
277 # do not add it to this list. The nix store is world-readable let's
278 # refrain ourselves from providing a footgun.
279 sectionWireGuard = checkUnitConfig "WireGuard" [
280 (assertOnlyFields [
281 "PrivateKeyFile"
282 "ListenPort"
283 "FirewallMark"
284 ])
285 (assertInt "FirewallMark")
286 (assertRange "FirewallMark" 1 4294967295)
287 ];
288
289 # NOTE The PresharedKey directive is missing on purpose here, please
290 # do not add it to this list. The nix store is world-readable,let's
291 # refrain ourselves from providing a footgun.
292 sectionWireGuardPeer = checkUnitConfig "WireGuardPeer" [
293 (assertOnlyFields [
294 "PublicKey"
295 "PresharedKeyFile"
296 "AllowedIPs"
297 "Endpoint"
298 "PersistentKeepalive"
299 ])
300 (assertInt "PersistentKeepalive")
301 (assertRange "PersistentKeepalive" 0 65535)
302 ];
303
304 sectionBond = checkUnitConfig "Bond" [
305 (assertOnlyFields [
306 "Mode"
307 "TransmitHashPolicy"
308 "LACPTransmitRate"
309 "MIIMonitorSec"
310 "UpDelaySec"
311 "DownDelaySec"
312 "LearnPacketIntervalSec"
313 "AdSelect"
314 "AdActorSystemPriority"
315 "AdUserPortKey"
316 "AdActorSystem"
317 "FailOverMACPolicy"
318 "ARPValidate"
319 "ARPIntervalSec"
320 "ARPIPTargets"
321 "ARPAllTargets"
322 "PrimaryReselectPolicy"
323 "ResendIGMP"
324 "PacketsPerSlave"
325 "GratuitousARP"
326 "AllSlavesActive"
327 "DynamicTransmitLoadBalancing"
328 "MinLinks"
329 ])
330 (assertValueOneOf "Mode" [
331 "balance-rr"
332 "active-backup"
333 "balance-xor"
334 "broadcast"
335 "802.3ad"
336 "balance-tlb"
337 "balance-alb"
338 ])
339 (assertValueOneOf "TransmitHashPolicy" [
340 "layer2"
341 "layer3+4"
342 "layer2+3"
343 "encap2+3"
344 "encap3+4"
345 ])
346 (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
347 (assertValueOneOf "AdSelect" ["stable" "bandwidth" "count"])
348 (assertInt "AdActorSystemPriority")
349 (assertRange "AdActorSystemPriority" 1 65535)
350 (assertInt "AdUserPortKey")
351 (assertRange "AdUserPortKey" 0 1023)
352 (assertValueOneOf "FailOverMACPolicy" ["none" "active" "follow"])
353 (assertValueOneOf "ARPValidate" ["none" "active" "backup" "all"])
354 (assertValueOneOf "ARPAllTargets" ["any" "all"])
355 (assertValueOneOf "PrimaryReselectPolicy" ["always" "better" "failure"])
356 (assertInt "ResendIGMP")
357 (assertRange "ResendIGMP" 0 255)
358 (assertInt "PacketsPerSlave")
359 (assertRange "PacketsPerSlave" 0 65535)
360 (assertInt "GratuitousARP")
361 (assertRange "GratuitousARP" 0 255)
362 (assertValueOneOf "AllSlavesActive" boolValues)
363 (assertValueOneOf "DynamicTransmitLoadBalancing" boolValues)
364 (assertInt "MinLinks")
365 (assertMinimum "MinLinks" 0)
366 ];
367
368 sectionXfrm = checkUnitConfig "Xfrm" [
369 (assertOnlyFields [
370 "InterfaceId"
371 "Independent"
372 ])
373 (assertInt "InterfaceId")
374 (assertRange "InterfaceId" 1 4294967295)
375 (assertValueOneOf "Independent" boolValues)
376 ];
377
378 sectionVRF = checkUnitConfig "VRF" [
379 (assertOnlyFields [
380 "Table"
381 ])
382 (assertInt "Table")
383 (assertMinimum "Table" 0)
384 ];
385
386 sectionBatmanAdvanced = checkUnitConfig "BatmanAdvanced" [
387 (assertOnlyFields [
388 "GatewayMode"
389 "Aggregation"
390 "BridgeLoopAvoidance"
391 "DistributedArpTable"
392 "Fragmentation"
393 "HopPenalty"
394 "OriginatorIntervalSec"
395 "GatewayBandwithDown"
396 "GatewayBandwithUp"
397 "RoutingAlgorithm"
398 ])
399 (assertValueOneOf "GatewayMode" ["off" "client" "server"])
400 (assertValueOneOf "Aggregation" boolValues)
401 (assertValueOneOf "BridgeLoopAvoidance" boolValues)
402 (assertValueOneOf "DistributedArpTable" boolValues)
403 (assertValueOneOf "Fragmentation" boolValues)
404 (assertInt "HopPenalty")
405 (assertRange "HopPenalty" 0 255)
406 (assertValueOneOf "RoutingAlgorithm" ["batman-v" "batman-iv"])
407 ];
408 };
409
410 network = {
411
412 sectionLink = checkUnitConfig "Link" [
413 (assertOnlyFields [
414 "MACAddress"
415 "MTUBytes"
416 "ARP"
417 "Multicast"
418 "AllMulticast"
419 "Unmanaged"
420 "RequiredForOnline"
421 "ActivationPolicy"
422 ])
423 (assertMacAddress "MACAddress")
424 (assertByteFormat "MTUBytes")
425 (assertValueOneOf "ARP" boolValues)
426 (assertValueOneOf "Multicast" boolValues)
427 (assertValueOneOf "AllMulticast" boolValues)
428 (assertValueOneOf "Unmanaged" boolValues)
429 (assertValueOneOf "RequiredForOnline" (boolValues ++ [
430 "missing"
431 "off"
432 "no-carrier"
433 "dormant"
434 "degraded-carrier"
435 "carrier"
436 "degraded"
437 "enslaved"
438 "routable"
439 ]))
440 (assertValueOneOf "ActivationPolicy" ([
441 "up"
442 "always-up"
443 "manual"
444 "always-down"
445 "down"
446 "bound"
447 ]))
448 ];
449
450 sectionNetwork = checkUnitConfig "Network" [
451 (assertOnlyFields [
452 "Description"
453 "DHCP"
454 "DHCPServer"
455 "LinkLocalAddressing"
456 "IPv4LLRoute"
457 "DefaultRouteOnDevice"
458 "IPv6Token"
459 "LLMNR"
460 "MulticastDNS"
461 "DNSOverTLS"
462 "DNSSEC"
463 "DNSSECNegativeTrustAnchors"
464 "LLDP"
465 "EmitLLDP"
466 "BindCarrier"
467 "Address"
468 "Gateway"
469 "DNS"
470 "Domains"
471 "DNSDefaultRoute"
472 "NTP"
473 "IPForward"
474 "IPMasquerade"
475 "IPv6PrivacyExtensions"
476 "IPv6AcceptRA"
477 "IPv6DuplicateAddressDetection"
478 "IPv6HopLimit"
479 "IPv4ProxyARP"
480 "IPv6ProxyNDP"
481 "IPv6ProxyNDPAddress"
482 "IPv6SendRA"
483 "DHCPv6PrefixDelegation"
484 "IPv6MTUBytes"
485 "Bridge"
486 "Bond"
487 "VRF"
488 "VLAN"
489 "IPVLAN"
490 "MACVLAN"
491 "VXLAN"
492 "Tunnel"
493 "MACsec"
494 "ActiveSlave"
495 "PrimarySlave"
496 "ConfigureWithoutCarrier"
497 "IgnoreCarrierLoss"
498 "Xfrm"
499 "KeepConfiguration"
500 "BatmanAdvanced"
501 ])
502 # Note: For DHCP the values both, none, v4, v6 are deprecated
503 (assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6"])
504 (assertValueOneOf "DHCPServer" boolValues)
505 (assertValueOneOf "LinkLocalAddressing" ["yes" "no" "ipv4" "ipv6" "fallback" "ipv4-fallback"])
506 (assertValueOneOf "IPv4LLRoute" boolValues)
507 (assertValueOneOf "DefaultRouteOnDevice" boolValues)
508 (assertValueOneOf "LLMNR" (boolValues ++ ["resolve"]))
509 (assertValueOneOf "MulticastDNS" (boolValues ++ ["resolve"]))
510 (assertValueOneOf "DNSOverTLS" (boolValues ++ ["opportunistic"]))
511 (assertValueOneOf "DNSSEC" (boolValues ++ ["allow-downgrade"]))
512 (assertValueOneOf "LLDP" (boolValues ++ ["routers-only"]))
513 (assertValueOneOf "EmitLLDP" (boolValues ++ ["nearest-bridge" "non-tpmr-bridge" "customer-bridge"]))
514 (assertValueOneOf "DNSDefaultRoute" boolValues)
515 (assertValueOneOf "IPForward" (boolValues ++ ["ipv4" "ipv6"]))
516 (assertValueOneOf "IPMasquerade" boolValues)
517 (assertValueOneOf "IPv6PrivacyExtensions" (boolValues ++ ["prefer-public" "kernel"]))
518 (assertValueOneOf "IPv6AcceptRA" boolValues)
519 (assertInt "IPv6DuplicateAddressDetection")
520 (assertMinimum "IPv6DuplicateAddressDetection" 0)
521 (assertInt "IPv6HopLimit")
522 (assertMinimum "IPv6HopLimit" 0)
523 (assertValueOneOf "IPv4ProxyARP" boolValues)
524 (assertValueOneOf "IPv6ProxyNDP" boolValues)
525 (assertValueOneOf "IPv6SendRA" boolValues)
526 (assertValueOneOf "DHCPv6PrefixDelegation" boolValues)
527 (assertByteFormat "IPv6MTUBytes")
528 (assertValueOneOf "ActiveSlave" boolValues)
529 (assertValueOneOf "PrimarySlave" boolValues)
530 (assertValueOneOf "ConfigureWithoutCarrier" boolValues)
531 (assertValueOneOf "IgnoreCarrierLoss" boolValues)
532 (assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"]))
533 ];
534
535 sectionAddress = checkUnitConfig "Address" [
536 (assertOnlyFields [
537 "Address"
538 "Peer"
539 "Broadcast"
540 "Label"
541 "PreferredLifetime"
542 "Scope"
543 "HomeAddress"
544 "DuplicateAddressDetection"
545 "ManageTemporaryAddress"
546 "AddPrefixRoute"
547 "AutoJoin"
548 ])
549 (assertHasField "Address")
550 (assertValueOneOf "PreferredLifetime" ["forever" "infinity" "0" 0])
551 (assertValueOneOf "HomeAddress" boolValues)
552 (assertValueOneOf "DuplicateAddressDetection" ["ipv4" "ipv6" "both" "none"])
553 (assertValueOneOf "ManageTemporaryAddress" boolValues)
554 (assertValueOneOf "AddPrefixRoute" boolValues)
555 (assertValueOneOf "AutoJoin" boolValues)
556 ];
557
558 sectionRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [
559 (assertOnlyFields [
560 "TypeOfService"
561 "From"
562 "To"
563 "FirewallMark"
564 "Table"
565 "Priority"
566 "IncomingInterface"
567 "OutgoingInterface"
568 "SourcePort"
569 "DestinationPort"
570 "IPProtocol"
571 "InvertRule"
572 "Family"
573 "User"
574 "SuppressPrefixLength"
575 ])
576 (assertInt "TypeOfService")
577 (assertRange "TypeOfService" 0 255)
578 (assertInt "FirewallMark")
579 (assertRange "FirewallMark" 1 4294967295)
580 (assertInt "Priority")
581 (assertPort "SourcePort")
582 (assertPort "DestinationPort")
583 (assertValueOneOf "InvertRule" boolValues)
584 (assertValueOneOf "Family" ["ipv4" "ipv6" "both"])
585 (assertInt "SuppressPrefixLength")
586 (assertRange "SuppressPrefixLength" 0 128)
587 ];
588
589 sectionRoute = checkUnitConfig "Route" [
590 (assertOnlyFields [
591 "Gateway"
592 "GatewayOnLink"
593 "Destination"
594 "Source"
595 "Metric"
596 "IPv6Preference"
597 "Scope"
598 "PreferredSource"
599 "Table"
600 "Protocol"
601 "Type"
602 "InitialCongestionWindow"
603 "InitialAdvertisedReceiveWindow"
604 "QuickAck"
605 "FastOpenNoCookie"
606 "TTLPropagate"
607 "MTUBytes"
608 "IPServiceType"
609 "MultiPathRoute"
610 ])
611 (assertValueOneOf "GatewayOnLink" boolValues)
612 (assertInt "Metric")
613 (assertValueOneOf "IPv6Preference" ["low" "medium" "high"])
614 (assertValueOneOf "Scope" ["global" "site" "link" "host" "nowhere"])
615 (assertValueOneOf "Type" [
616 "unicast"
617 "local"
618 "broadcast"
619 "anycast"
620 "multicast"
621 "blackhole"
622 "unreachable"
623 "prohibit"
624 "throw"
625 "nat"
626 "xresolve"
627 ])
628 (assertValueOneOf "QuickAck" boolValues)
629 (assertValueOneOf "FastOpenNoCookie" boolValues)
630 (assertValueOneOf "TTLPropagate" boolValues)
631 (assertByteFormat "MTUBytes")
632 (assertValueOneOf "IPServiceType" ["CS6" "CS4"])
633 ];
634
635 sectionDHCPv4 = checkUnitConfig "DHCPv4" [
636 (assertOnlyFields [
637 "UseDNS"
638 "RoutesToDNS"
639 "UseNTP"
640 "UseSIP"
641 "UseMTU"
642 "Anonymize"
643 "SendHostname"
644 "UseHostname"
645 "Hostname"
646 "UseDomains"
647 "UseRoutes"
648 "UseTimezone"
649 "ClientIdentifier"
650 "VendorClassIdentifier"
651 "UserClass"
652 "MaxAttempts"
653 "DUIDType"
654 "DUIDRawData"
655 "IAID"
656 "RequestBroadcast"
657 "RouteMetric"
658 "RouteTable"
659 "RouteMTUBytes"
660 "ListenPort"
661 "SendRelease"
662 "SendDecline"
663 "BlackList"
664 "RequestOptions"
665 "SendOption"
666 ])
667 (assertValueOneOf "UseDNS" boolValues)
668 (assertValueOneOf "RoutesToDNS" boolValues)
669 (assertValueOneOf "UseNTP" boolValues)
670 (assertValueOneOf "UseSIP" boolValues)
671 (assertValueOneOf "UseMTU" boolValues)
672 (assertValueOneOf "Anonymize" boolValues)
673 (assertValueOneOf "SendHostname" boolValues)
674 (assertValueOneOf "UseHostname" boolValues)
675 (assertValueOneOf "UseDomains" (boolValues ++ ["route"]))
676 (assertValueOneOf "UseRoutes" boolValues)
677 (assertValueOneOf "UseTimezone" boolValues)
678 (assertValueOneOf "ClientIdentifier" ["mac" "duid" "duid-only"])
679 (assertInt "IAID")
680 (assertValueOneOf "RequestBroadcast" boolValues)
681 (assertInt "RouteMetric")
682 (assertInt "RouteTable")
683 (assertRange "RouteTable" 0 4294967295)
684 (assertByteFormat "RouteMTUBytes")
685 (assertPort "ListenPort")
686 (assertValueOneOf "SendRelease" boolValues)
687 (assertValueOneOf "SendDecline" boolValues)
688 ];
689
690 sectionDHCPv6 = checkUnitConfig "DHCPv6" [
691 (assertOnlyFields [
692 "UseAddress"
693 "UseDNS"
694 "UseNTP"
695 "RouteMetric"
696 "RapidCommit"
697 "MUDURL"
698 "RequestOptions"
699 "SendVendorOption"
700 "ForceDHCPv6PDOtherInformation"
701 "PrefixDelegationHint"
702 "WithoutRA"
703 "SendOption"
704 "UserClass"
705 "VendorClass"
706 "DUIDType"
707 "DUIDRawData"
708 "IAID"
709 ])
710 (assertValueOneOf "UseAddress" boolValues)
711 (assertValueOneOf "UseDNS" boolValues)
712 (assertValueOneOf "UseNTP" boolValues)
713 (assertInt "RouteMetric")
714 (assertValueOneOf "RapidCommit" boolValues)
715 (assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues)
716 (assertValueOneOf "WithoutRA" ["solicit" "information-request"])
717 (assertRange "SendOption" 1 65536)
718 (assertInt "IAID")
719 ];
720
721 sectionDHCPv6PrefixDelegation = checkUnitConfig "DHCPv6PrefixDelegation" [
722 (assertOnlyFields [
723 "SubnetId"
724 "Announce"
725 "Assign"
726 "Token"
727 ])
728 (assertValueOneOf "Announce" boolValues)
729 (assertValueOneOf "Assign" boolValues)
730 ];
731
732 sectionIPv6AcceptRA = checkUnitConfig "IPv6AcceptRA" [
733 (assertOnlyFields [
734 "UseDNS"
735 "UseDomains"
736 "RouteTable"
737 "UseAutonomousPrefix"
738 "UseOnLinkPrefix"
739 "RouterDenyList"
740 "RouterAllowList"
741 "PrefixDenyList"
742 "PrefixAllowList"
743 "RouteDenyList"
744 "RouteAllowList"
745 "DHCPv6Client"
746 ])
747 (assertValueOneOf "UseDNS" boolValues)
748 (assertValueOneOf "UseDomains" (boolValues ++ ["route"]))
749 (assertRange "RouteTable" 0 4294967295)
750 (assertValueOneOf "UseAutonomousPrefix" boolValues)
751 (assertValueOneOf "UseOnLinkPrefix" boolValues)
752 (assertValueOneOf "DHCPv6Client" (boolValues ++ ["always"]))
753 ];
754
755 sectionDHCPServer = checkUnitConfig "DHCPServer" [
756 (assertOnlyFields [
757 "PoolOffset"
758 "PoolSize"
759 "DefaultLeaseTimeSec"
760 "MaxLeaseTimeSec"
761 "EmitDNS"
762 "DNS"
763 "EmitNTP"
764 "NTP"
765 "EmitSIP"
766 "SIP"
767 "EmitPOP3"
768 "POP3"
769 "EmitSMTP"
770 "SMTP"
771 "EmitLPR"
772 "LPR"
773 "EmitRouter"
774 "EmitTimezone"
775 "Timezone"
776 "SendOption"
777 "SendVendorOption"
778 ])
779 (assertInt "PoolOffset")
780 (assertMinimum "PoolOffset" 0)
781 (assertInt "PoolSize")
782 (assertMinimum "PoolSize" 0)
783 (assertValueOneOf "EmitDNS" boolValues)
784 (assertValueOneOf "EmitNTP" boolValues)
785 (assertValueOneOf "EmitSIP" boolValues)
786 (assertValueOneOf "EmitPOP3" boolValues)
787 (assertValueOneOf "EmitSMTP" boolValues)
788 (assertValueOneOf "EmitLPR" boolValues)
789 (assertValueOneOf "EmitRouter" boolValues)
790 (assertValueOneOf "EmitTimezone" boolValues)
791 ];
792
793 sectionIPv6SendRA = checkUnitConfig "IPv6SendRA" [
794 (assertOnlyFields [
795 "Managed"
796 "OtherInformation"
797 "RouterLifetimeSec"
798 "RouterPreference"
799 "EmitDNS"
800 "DNS"
801 "EmitDomains"
802 "Domains"
803 "DNSLifetimeSec"
804 ])
805 (assertValueOneOf "Managed" boolValues)
806 (assertValueOneOf "OtherInformation" boolValues)
807 (assertValueOneOf "RouterPreference" ["high" "medium" "low" "normal" "default"])
808 (assertValueOneOf "EmitDNS" boolValues)
809 (assertValueOneOf "EmitDomains" boolValues)
810 ];
811
812 sectionIPv6Prefix = checkUnitConfig "IPv6Prefix" [
813 (assertOnlyFields [
814 "AddressAutoconfiguration"
815 "OnLink"
816 "Prefix"
817 "PreferredLifetimeSec"
818 "ValidLifetimeSec"
819 ])
820 (assertValueOneOf "AddressAutoconfiguration" boolValues)
821 (assertValueOneOf "OnLink" boolValues)
822 ];
823
824 };
825 };
826
827 commonNetworkOptions = {
828
829 enable = mkOption {
830 default = true;
831 type = types.bool;
832 description = ''
833 Whether to manage network configuration using <command>systemd-network</command>.
834 '';
835 };
836
837 matchConfig = mkOption {
838 default = {};
839 example = { Name = "eth0"; };
840 type = types.attrsOf unitOption;
841 description = ''
842 Each attribute in this set specifies an option in the
843 <literal>[Match]</literal> section of the unit. See
844 <citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>
845 <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
846 <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
847 for details.
848 '';
849 };
850
851 extraConfig = mkOption {
852 default = "";
853 type = types.lines;
854 description = "Extra configuration append to unit";
855 };
856 };
857
858 linkOptions = commonNetworkOptions // {
859 # overwrite enable option from above
860 enable = mkOption {
861 default = true;
862 type = types.bool;
863 description = ''
864 Whether to enable this .link unit. It's handled by udev no matter if <command>systemd-networkd</command> is enabled or not
865 '';
866 };
867
868 linkConfig = mkOption {
869 default = {};
870 example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
871 type = types.addCheck (types.attrsOf unitOption) check.link.sectionLink;
872 description = ''
873 Each attribute in this set specifies an option in the
874 <literal>[Link]</literal> section of the unit. See
875 <citerefentry><refentrytitle>systemd.link</refentrytitle>
876 <manvolnum>5</manvolnum></citerefentry> for details.
877 '';
878 };
879
880 };
881
882 wireguardPeerOptions = {
883 options = {
884 wireguardPeerConfig = mkOption {
885 default = {};
886 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuardPeer;
887 description = ''
888 Each attribute in this set specifies an option in the
889 <literal>[WireGuardPeer]</literal> section of the unit. See
890 <citerefentry><refentrytitle>systemd.network</refentrytitle>
891 <manvolnum>5</manvolnum></citerefentry> for details.
892 '';
893 };
894 };
895 };
896
897 netdevOptions = commonNetworkOptions // {
898
899 netdevConfig = mkOption {
900 example = { Name = "mybridge"; Kind = "bridge"; };
901 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionNetdev;
902 description = ''
903 Each attribute in this set specifies an option in the
904 <literal>[Netdev]</literal> section of the unit. See
905 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
906 <manvolnum>5</manvolnum></citerefentry> for details.
907 '';
908 };
909
910 vlanConfig = mkOption {
911 default = {};
912 example = { Id = 4; };
913 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVLAN;
914 description = ''
915 Each attribute in this set specifies an option in the
916 <literal>[VLAN]</literal> section of the unit. See
917 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
918 <manvolnum>5</manvolnum></citerefentry> for details.
919 '';
920 };
921
922 macvlanConfig = mkOption {
923 default = {};
924 example = { Mode = "private"; };
925 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionMACVLAN;
926 description = ''
927 Each attribute in this set specifies an option in the
928 <literal>[MACVLAN]</literal> section of the unit. See
929 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
930 <manvolnum>5</manvolnum></citerefentry> for details.
931 '';
932 };
933
934 vxlanConfig = mkOption {
935 default = {};
936 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVXLAN;
937 description = ''
938 Each attribute in this set specifies an option in the
939 <literal>[VXLAN]</literal> section of the unit. See
940 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
941 <manvolnum>5</manvolnum></citerefentry> for details.
942 '';
943 };
944
945 tunnelConfig = mkOption {
946 default = {};
947 example = { Remote = "192.168.1.1"; };
948 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTunnel;
949 description = ''
950 Each attribute in this set specifies an option in the
951 <literal>[Tunnel]</literal> section of the unit. See
952 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
953 <manvolnum>5</manvolnum></citerefentry> for details.
954 '';
955 };
956
957 fooOverUDPConfig = mkOption {
958 default = { };
959 example = { Port = 9001; };
960 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionFooOverUDP;
961 description = ''
962 Each attribute in this set specifies an option in the
963 <literal>[FooOverUDP]</literal> section of the unit. See
964 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
965 <manvolnum>5</manvolnum></citerefentry> for details.
966 '';
967 };
968
969 peerConfig = mkOption {
970 default = {};
971 example = { Name = "veth2"; };
972 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionPeer;
973 description = ''
974 Each attribute in this set specifies an option in the
975 <literal>[Peer]</literal> section of the unit. See
976 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
977 <manvolnum>5</manvolnum></citerefentry> for details.
978 '';
979 };
980
981 tunConfig = mkOption {
982 default = {};
983 example = { User = "openvpn"; };
984 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTun;
985 description = ''
986 Each attribute in this set specifies an option in the
987 <literal>[Tun]</literal> section of the unit. See
988 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
989 <manvolnum>5</manvolnum></citerefentry> for details.
990 '';
991 };
992
993 tapConfig = mkOption {
994 default = {};
995 example = { User = "openvpn"; };
996 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionTap;
997 description = ''
998 Each attribute in this set specifies an option in the
999 <literal>[Tap]</literal> section of the unit. See
1000 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1001 <manvolnum>5</manvolnum></citerefentry> for details.
1002 '';
1003 };
1004
1005 wireguardConfig = mkOption {
1006 default = {};
1007 example = {
1008 PrivateKeyFile = "/etc/wireguard/secret.key";
1009 ListenPort = 51820;
1010 FirewallMark = 42;
1011 };
1012 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuard;
1013 description = ''
1014 Each attribute in this set specifies an option in the
1015 <literal>[WireGuard]</literal> section of the unit. See
1016 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1017 <manvolnum>5</manvolnum></citerefentry> for details.
1018 Use <literal>PrivateKeyFile</literal> instead of
1019 <literal>PrivateKey</literal>: the nix store is
1020 world-readable.
1021 '';
1022 };
1023
1024 wireguardPeers = mkOption {
1025 default = [];
1026 example = [ { wireguardPeerConfig={
1027 Endpoint = "192.168.1.1:51820";
1028 PublicKey = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g=";
1029 PresharedKeyFile = "/etc/wireguard/psk.key";
1030 AllowedIPs = [ "10.0.0.1/32" ];
1031 PersistentKeepalive = 15;
1032 };}];
1033 type = with types; listOf (submodule wireguardPeerOptions);
1034 description = ''
1035 Each item in this array specifies an option in the
1036 <literal>[WireGuardPeer]</literal> section of the unit. See
1037 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1038 <manvolnum>5</manvolnum></citerefentry> for details.
1039 Use <literal>PresharedKeyFile</literal> instead of
1040 <literal>PresharedKey</literal>: the nix store is
1041 world-readable.
1042 '';
1043 };
1044
1045 bondConfig = mkOption {
1046 default = {};
1047 example = { Mode = "802.3ad"; };
1048 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionBond;
1049 description = ''
1050 Each attribute in this set specifies an option in the
1051 <literal>[Bond]</literal> section of the unit. See
1052 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1053 <manvolnum>5</manvolnum></citerefentry> for details.
1054 '';
1055 };
1056
1057 xfrmConfig = mkOption {
1058 default = {};
1059 example = { InterfaceId = 1; };
1060 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionXfrm;
1061 description = ''
1062 Each attribute in this set specifies an option in the
1063 <literal>[Xfrm]</literal> section of the unit. See
1064 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1065 <manvolnum>5</manvolnum></citerefentry> for details.
1066 '';
1067 };
1068
1069 vrfConfig = mkOption {
1070 default = {};
1071 example = { Table = 2342; };
1072 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionVRF;
1073 description = ''
1074 Each attribute in this set specifies an option in the
1075 <literal>[VRF]</literal> section of the unit. See
1076 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1077 <manvolnum>5</manvolnum></citerefentry> for details.
1078 A detailed explanation about how VRFs work can be found in the
1079 <link xlink:href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">kernel
1080 docs</link>.
1081 '';
1082 };
1083
1084 batmanAdvancedConfig = mkOption {
1085 default = {};
1086 example = {
1087 GatewayMode = "server";
1088 RoutingAlgorithm = "batman-v";
1089 };
1090 type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionBatmanAdvanced;
1091 description = ''
1092 Each attribute in this set specifies an option in the
1093 <literal>[BatmanAdvanced]</literal> section of the unit. See
1094 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
1095 <manvolnum>5</manvolnum></citerefentry> for details.
1096 '';
1097 };
1098
1099 };
1100
1101 addressOptions = {
1102 options = {
1103 addressConfig = mkOption {
1104 example = { Address = "192.168.0.100/24"; };
1105 type = types.addCheck (types.attrsOf unitOption) check.network.sectionAddress;
1106 description = ''
1107 Each attribute in this set specifies an option in the
1108 <literal>[Address]</literal> section of the unit. See
1109 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1110 <manvolnum>5</manvolnum></citerefentry> for details.
1111 '';
1112 };
1113 };
1114 };
1115
1116 routingPolicyRulesOptions = {
1117 options = {
1118 routingPolicyRuleConfig = mkOption {
1119 default = { };
1120 example = { Table = 10; IncomingInterface = "eth1"; Family = "both"; };
1121 type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoutingPolicyRule;
1122 description = ''
1123 Each attribute in this set specifies an option in the
1124 <literal>[RoutingPolicyRule]</literal> section of the unit. See
1125 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1126 <manvolnum>5</manvolnum></citerefentry> for details.
1127 '';
1128 };
1129 };
1130 };
1131
1132 routeOptions = {
1133 options = {
1134 routeConfig = mkOption {
1135 default = {};
1136 example = { Gateway = "192.168.0.1"; };
1137 type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoute;
1138 description = ''
1139 Each attribute in this set specifies an option in the
1140 <literal>[Route]</literal> section of the unit. See
1141 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1142 <manvolnum>5</manvolnum></citerefentry> for details.
1143 '';
1144 };
1145 };
1146 };
1147
1148 ipv6PrefixOptions = {
1149 options = {
1150 ipv6PrefixConfig = mkOption {
1151 default = {};
1152 example = { Prefix = "fd00::/64"; };
1153 type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6Prefix;
1154 description = ''
1155 Each attribute in this set specifies an option in the
1156 <literal>[IPv6Prefix]</literal> section of the unit. See
1157 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1158 <manvolnum>5</manvolnum></citerefentry> for details.
1159 '';
1160 };
1161 };
1162 };
1163
1164 networkOptions = commonNetworkOptions // {
1165
1166 linkConfig = mkOption {
1167 default = {};
1168 example = { Unmanaged = true; };
1169 type = types.addCheck (types.attrsOf unitOption) check.network.sectionLink;
1170 description = ''
1171 Each attribute in this set specifies an option in the
1172 <literal>[Link]</literal> section of the unit. See
1173 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1174 <manvolnum>5</manvolnum></citerefentry> for details.
1175 '';
1176 };
1177
1178 networkConfig = mkOption {
1179 default = {};
1180 example = { Description = "My Network"; };
1181 type = types.addCheck (types.attrsOf unitOption) check.network.sectionNetwork;
1182 description = ''
1183 Each attribute in this set specifies an option in the
1184 <literal>[Network]</literal> section of the unit. See
1185 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1186 <manvolnum>5</manvolnum></citerefentry> for details.
1187 '';
1188 };
1189
1190 # systemd.network.networks.*.dhcpConfig has been deprecated in favor of ….dhcpV4Config
1191 # Produce a nice warning message so users know it is gone.
1192 dhcpConfig = mkOption {
1193 visible = false;
1194 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.";
1195 };
1196
1197 dhcpV4Config = mkOption {
1198 default = {};
1199 example = { UseDNS = true; UseRoutes = true; };
1200 type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv4;
1201 description = ''
1202 Each attribute in this set specifies an option in the
1203 <literal>[DHCPv4]</literal> section of the unit. See
1204 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1205 <manvolnum>5</manvolnum></citerefentry> for details.
1206 '';
1207 };
1208
1209 dhcpV6Config = mkOption {
1210 default = {};
1211 example = { UseDNS = true; };
1212 type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6;
1213 description = ''
1214 Each attribute in this set specifies an option in the
1215 <literal>[DHCPv6]</literal> section of the unit. See
1216 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1217 <manvolnum>5</manvolnum></citerefentry> for details.
1218 '';
1219 };
1220
1221 dhcpV6PrefixDelegationConfig = mkOption {
1222 default = {};
1223 example = { SubnetId = "auto"; Announce = true; };
1224 type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6PrefixDelegation;
1225 description = ''
1226 Each attribute in this set specifies an option in the
1227 <literal>[DHCPv6PrefixDelegation]</literal> section of the unit. See
1228 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1229 <manvolnum>5</manvolnum></citerefentry> for details.
1230 '';
1231 };
1232
1233 ipv6AcceptRAConfig = mkOption {
1234 default = {};
1235 example = { UseDNS = true; DHCPv6Client = "always"; };
1236 type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6AcceptRA;
1237 description = ''
1238 Each attribute in this set specifies an option in the
1239 <literal>[IPv6AcceptRA]</literal> section of the unit. See
1240 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1241 <manvolnum>5</manvolnum></citerefentry> for details.
1242 '';
1243 };
1244
1245 dhcpServerConfig = mkOption {
1246 default = {};
1247 example = { PoolOffset = 50; EmitDNS = false; };
1248 type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPServer;
1249 description = ''
1250 Each attribute in this set specifies an option in the
1251 <literal>[DHCPServer]</literal> section of the unit. See
1252 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1253 <manvolnum>5</manvolnum></citerefentry> for details.
1254 '';
1255 };
1256
1257 # systemd.network.networks.*.ipv6PrefixDelegationConfig has been deprecated
1258 # in 247 in favor of systemd.network.networks.*.ipv6SendRAConfig.
1259 ipv6PrefixDelegationConfig = mkOption {
1260 visible = false;
1261 apply = _: throw "The option `systemd.network.networks.*.ipv6PrefixDelegationConfig` has been replaced by `systemd.network.networks.*.ipv6SendRAConfig`.";
1262 };
1263
1264 ipv6SendRAConfig = mkOption {
1265 default = {};
1266 example = { EmitDNS = true; Managed = true; OtherInformation = true; };
1267 type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6SendRA;
1268 description = ''
1269 Each attribute in this set specifies an option in the
1270 <literal>[IPv6SendRA]</literal> section of the unit. See
1271 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1272 <manvolnum>5</manvolnum></citerefentry> for details.
1273 '';
1274 };
1275
1276 ipv6Prefixes = mkOption {
1277 default = [];
1278 example = [ { AddressAutoconfiguration = true; OnLink = true; } ];
1279 type = with types; listOf (submodule ipv6PrefixOptions);
1280 description = ''
1281 A list of ipv6Prefix sections to be added to the unit. See
1282 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1283 <manvolnum>5</manvolnum></citerefentry> for details.
1284 '';
1285 };
1286
1287 name = mkOption {
1288 type = types.nullOr types.str;
1289 default = null;
1290 description = ''
1291 The name of the network interface to match against.
1292 '';
1293 };
1294
1295 DHCP = mkOption {
1296 type = types.nullOr types.str;
1297 default = null;
1298 description = ''
1299 Whether to enable DHCP on the interfaces matched.
1300 '';
1301 };
1302
1303 domains = mkOption {
1304 type = types.nullOr (types.listOf types.str);
1305 default = null;
1306 description = ''
1307 A list of domains to pass to the network config.
1308 '';
1309 };
1310
1311 address = mkOption {
1312 default = [ ];
1313 type = types.listOf types.str;
1314 description = ''
1315 A list of addresses to be added to the network section of the
1316 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1317 <manvolnum>5</manvolnum></citerefentry> for details.
1318 '';
1319 };
1320
1321 gateway = mkOption {
1322 default = [ ];
1323 type = types.listOf types.str;
1324 description = ''
1325 A list of gateways to be added to the network section of the
1326 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1327 <manvolnum>5</manvolnum></citerefentry> for details.
1328 '';
1329 };
1330
1331 dns = mkOption {
1332 default = [ ];
1333 type = types.listOf types.str;
1334 description = ''
1335 A list of dns servers to be added to the network section of the
1336 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1337 <manvolnum>5</manvolnum></citerefentry> for details.
1338 '';
1339 };
1340
1341 ntp = mkOption {
1342 default = [ ];
1343 type = types.listOf types.str;
1344 description = ''
1345 A list of ntp servers to be added to the network section of the
1346 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1347 <manvolnum>5</manvolnum></citerefentry> for details.
1348 '';
1349 };
1350
1351 bridge = mkOption {
1352 default = [ ];
1353 type = types.listOf types.str;
1354 description = ''
1355 A list of bridge interfaces to be added to the network section of the
1356 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1357 <manvolnum>5</manvolnum></citerefentry> for details.
1358 '';
1359 };
1360
1361 bond = mkOption {
1362 default = [ ];
1363 type = types.listOf types.str;
1364 description = ''
1365 A list of bond interfaces to be added to the network section of the
1366 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1367 <manvolnum>5</manvolnum></citerefentry> for details.
1368 '';
1369 };
1370
1371 vrf = mkOption {
1372 default = [ ];
1373 type = types.listOf types.str;
1374 description = ''
1375 A list of vrf interfaces to be added to the network section of the
1376 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1377 <manvolnum>5</manvolnum></citerefentry> for details.
1378 '';
1379 };
1380
1381 vlan = mkOption {
1382 default = [ ];
1383 type = types.listOf types.str;
1384 description = ''
1385 A list of vlan interfaces to be added to the network section of the
1386 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1387 <manvolnum>5</manvolnum></citerefentry> for details.
1388 '';
1389 };
1390
1391 macvlan = mkOption {
1392 default = [ ];
1393 type = types.listOf types.str;
1394 description = ''
1395 A list of macvlan interfaces to be added to the network section of the
1396 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1397 <manvolnum>5</manvolnum></citerefentry> for details.
1398 '';
1399 };
1400
1401 vxlan = mkOption {
1402 default = [ ];
1403 type = types.listOf types.str;
1404 description = ''
1405 A list of vxlan interfaces to be added to the network section of the
1406 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1407 <manvolnum>5</manvolnum></citerefentry> for details.
1408 '';
1409 };
1410
1411 tunnel = mkOption {
1412 default = [ ];
1413 type = types.listOf types.str;
1414 description = ''
1415 A list of tunnel interfaces to be added to the network section of the
1416 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1417 <manvolnum>5</manvolnum></citerefentry> for details.
1418 '';
1419 };
1420
1421 xfrm = mkOption {
1422 default = [ ];
1423 type = types.listOf types.str;
1424 description = ''
1425 A list of xfrm interfaces to be added to the network section of the
1426 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
1427 <manvolnum>5</manvolnum></citerefentry> for details.
1428 '';
1429 };
1430
1431 addresses = mkOption {
1432 default = [ ];
1433 type = with types; listOf (submodule addressOptions);
1434 description = ''
1435 A list of address sections to be added to the unit. See
1436 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1437 <manvolnum>5</manvolnum></citerefentry> for details.
1438 '';
1439 };
1440
1441 routingPolicyRules = mkOption {
1442 default = [ ];
1443 type = with types; listOf (submodule routingPolicyRulesOptions);
1444 description = ''
1445 A list of routing policy rules sections to be added to the unit. See
1446 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1447 <manvolnum>5</manvolnum></citerefentry> for details.
1448 '';
1449 };
1450
1451 routes = mkOption {
1452 default = [ ];
1453 type = with types; listOf (submodule routeOptions);
1454 description = ''
1455 A list of route sections to be added to the unit. See
1456 <citerefentry><refentrytitle>systemd.network</refentrytitle>
1457 <manvolnum>5</manvolnum></citerefentry> for details.
1458 '';
1459 };
1460
1461 };
1462
1463 networkConfig = { config, ... }: {
1464 config = {
1465 matchConfig = optionalAttrs (config.name != null) {
1466 Name = config.name;
1467 };
1468 networkConfig = optionalAttrs (config.DHCP != null) {
1469 DHCP = config.DHCP;
1470 } // optionalAttrs (config.domains != null) {
1471 Domains = concatStringsSep " " config.domains;
1472 };
1473 };
1474 };
1475
1476 commonMatchText = def: optionalString (def.matchConfig != { }) ''
1477 [Match]
1478 ${attrsToSection def.matchConfig}
1479 '';
1480
1481 linkToUnit = name: def:
1482 { inherit (def) enable;
1483 text = commonMatchText def
1484 + ''
1485 [Link]
1486 ${attrsToSection def.linkConfig}
1487 ''
1488 + def.extraConfig;
1489 };
1490
1491 netdevToUnit = name: def:
1492 { inherit (def) enable;
1493 text = commonMatchText def
1494 + ''
1495 [NetDev]
1496 ${attrsToSection def.netdevConfig}
1497 ''
1498 + optionalString (def.vlanConfig != { }) ''
1499 [VLAN]
1500 ${attrsToSection def.vlanConfig}
1501 ''
1502 + optionalString (def.macvlanConfig != { }) ''
1503 [MACVLAN]
1504 ${attrsToSection def.macvlanConfig}
1505 ''
1506 + optionalString (def.vxlanConfig != { }) ''
1507 [VXLAN]
1508 ${attrsToSection def.vxlanConfig}
1509 ''
1510 + optionalString (def.tunnelConfig != { }) ''
1511 [Tunnel]
1512 ${attrsToSection def.tunnelConfig}
1513 ''
1514 + optionalString (def.fooOverUDPConfig != { }) ''
1515 [FooOverUDP]
1516 ${attrsToSection def.fooOverUDPConfig}
1517 ''
1518 + optionalString (def.peerConfig != { }) ''
1519 [Peer]
1520 ${attrsToSection def.peerConfig}
1521 ''
1522 + optionalString (def.tunConfig != { }) ''
1523 [Tun]
1524 ${attrsToSection def.tunConfig}
1525 ''
1526 + optionalString (def.tapConfig != { }) ''
1527 [Tap]
1528 ${attrsToSection def.tapConfig}
1529 ''
1530 + optionalString (def.wireguardConfig != { }) ''
1531 [WireGuard]
1532 ${attrsToSection def.wireguardConfig}
1533 ''
1534 + flip concatMapStrings def.wireguardPeers (x: ''
1535 [WireGuardPeer]
1536 ${attrsToSection x.wireguardPeerConfig}
1537 '')
1538 + optionalString (def.bondConfig != { }) ''
1539 [Bond]
1540 ${attrsToSection def.bondConfig}
1541 ''
1542 + optionalString (def.xfrmConfig != { }) ''
1543 [Xfrm]
1544 ${attrsToSection def.xfrmConfig}
1545 ''
1546 + optionalString (def.vrfConfig != { }) ''
1547 [VRF]
1548 ${attrsToSection def.vrfConfig}
1549 ''
1550 + optionalString (def.batmanAdvancedConfig != { }) ''
1551 [BatmanAdvanced]
1552 ${attrsToSection def.batmanAdvancedConfig}
1553 ''
1554 + def.extraConfig;
1555 };
1556
1557 networkToUnit = name: def:
1558 { inherit (def) enable;
1559 text = commonMatchText def
1560 + optionalString (def.linkConfig != { }) ''
1561 [Link]
1562 ${attrsToSection def.linkConfig}
1563 ''
1564 + ''
1565 [Network]
1566 ''
1567 + attrsToSection def.networkConfig
1568 + optionalString (def.address != [ ]) ''
1569 ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
1570 ''
1571 + optionalString (def.gateway != [ ]) ''
1572 ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
1573 ''
1574 + optionalString (def.dns != [ ]) ''
1575 ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
1576 ''
1577 + optionalString (def.ntp != [ ]) ''
1578 ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
1579 ''
1580 + optionalString (def.bridge != [ ]) ''
1581 ${concatStringsSep "\n" (map (s: "Bridge=${s}") def.bridge)}
1582 ''
1583 + optionalString (def.bond != [ ]) ''
1584 ${concatStringsSep "\n" (map (s: "Bond=${s}") def.bond)}
1585 ''
1586 + optionalString (def.vrf != [ ]) ''
1587 ${concatStringsSep "\n" (map (s: "VRF=${s}") def.vrf)}
1588 ''
1589 + optionalString (def.vlan != [ ]) ''
1590 ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
1591 ''
1592 + optionalString (def.macvlan != [ ]) ''
1593 ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
1594 ''
1595 + optionalString (def.vxlan != [ ]) ''
1596 ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
1597 ''
1598 + optionalString (def.tunnel != [ ]) ''
1599 ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
1600 ''
1601 + optionalString (def.xfrm != [ ]) ''
1602 ${concatStringsSep "\n" (map (s: "Xfrm=${s}") def.xfrm)}
1603 ''
1604 + ''
1605
1606 ''
1607 + flip concatMapStrings def.addresses (x: ''
1608 [Address]
1609 ${attrsToSection x.addressConfig}
1610 '')
1611 + flip concatMapStrings def.routingPolicyRules (x: ''
1612 [RoutingPolicyRule]
1613 ${attrsToSection x.routingPolicyRuleConfig}
1614 '')
1615 + flip concatMapStrings def.routes (x: ''
1616 [Route]
1617 ${attrsToSection x.routeConfig}
1618 '')
1619 + optionalString (def.dhcpV4Config != { }) ''
1620 [DHCPv4]
1621 ${attrsToSection def.dhcpV4Config}
1622 ''
1623 + optionalString (def.dhcpV6Config != { }) ''
1624 [DHCPv6]
1625 ${attrsToSection def.dhcpV6Config}
1626 ''
1627 + optionalString (def.dhcpV6PrefixDelegationConfig != { }) ''
1628 [DHCPv6PrefixDelegation]
1629 ${attrsToSection def.dhcpV6PrefixDelegationConfig}
1630 ''
1631 + optionalString (def.ipv6AcceptRAConfig != { }) ''
1632 [IPv6AcceptRA]
1633 ${attrsToSection def.ipv6AcceptRAConfig}
1634 ''
1635 + optionalString (def.dhcpServerConfig != { }) ''
1636 [DHCPServer]
1637 ${attrsToSection def.dhcpServerConfig}
1638 ''
1639 + optionalString (def.ipv6SendRAConfig != { }) ''
1640 [IPv6SendRA]
1641 ${attrsToSection def.ipv6SendRAConfig}
1642 ''
1643 + flip concatMapStrings def.ipv6Prefixes (x: ''
1644 [IPv6Prefix]
1645 ${attrsToSection x.ipv6PrefixConfig}
1646 '')
1647 + def.extraConfig;
1648 };
1649
1650 unitFiles = listToAttrs (map (name: {
1651 name = "systemd/network/${name}";
1652 value.source = "${cfg.units.${name}.unit}/${name}";
1653 }) (attrNames cfg.units));
1654in
1655
1656{
1657 options = {
1658
1659 systemd.network.enable = mkOption {
1660 default = false;
1661 type = types.bool;
1662 description = ''
1663 Whether to enable networkd or not.
1664 '';
1665 };
1666
1667 systemd.network.links = mkOption {
1668 default = {};
1669 type = with types; attrsOf (submodule [ { options = linkOptions; } ]);
1670 description = "Definition of systemd network links.";
1671 };
1672
1673 systemd.network.netdevs = mkOption {
1674 default = {};
1675 type = with types; attrsOf (submodule [ { options = netdevOptions; } ]);
1676 description = "Definition of systemd network devices.";
1677 };
1678
1679 systemd.network.networks = mkOption {
1680 default = {};
1681 type = with types; attrsOf (submodule [ { options = networkOptions; } networkConfig ]);
1682 description = "Definition of systemd networks.";
1683 };
1684
1685 systemd.network.units = mkOption {
1686 description = "Definition of networkd units.";
1687 default = {};
1688 internal = true;
1689 type = with types; attrsOf (submodule (
1690 { name, config, ... }:
1691 { options = mapAttrs (_: x: x // { internal = true; }) concreteUnitOptions;
1692 config = {
1693 unit = mkDefault (makeUnit name config);
1694 };
1695 }));
1696 };
1697
1698 };
1699
1700 config = mkMerge [
1701
1702 # .link units are honored by udev, no matter if systemd-networkd is enabled or not.
1703 {
1704 systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links;
1705 environment.etc = unitFiles;
1706 }
1707
1708 (mkIf config.systemd.network.enable {
1709
1710 users.users.systemd-network.group = "systemd-network";
1711
1712 systemd.additionalUpstreamSystemUnits = [
1713 "systemd-networkd-wait-online.service"
1714 "systemd-networkd.service"
1715 "systemd-networkd.socket"
1716 ];
1717
1718 systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
1719 // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;
1720
1721 # systemd-networkd is socket-activated by kernel netlink route change
1722 # messages. It is important to have systemd buffer those on behalf of
1723 # networkd.
1724 systemd.sockets.systemd-networkd.wantedBy = [ "sockets.target" ];
1725
1726 systemd.services.systemd-networkd = {
1727 wantedBy = [ "multi-user.target" ];
1728 aliases = [ "dbus-org.freedesktop.network1.service" ];
1729 restartTriggers = map (x: x.source) (attrValues unitFiles);
1730 };
1731
1732 systemd.services.systemd-networkd-wait-online = {
1733 wantedBy = [ "network-online.target" ];
1734 };
1735
1736 systemd.services."systemd-network-wait-online@" = {
1737 description = "Wait for Network Interface %I to be Configured";
1738 conflicts = [ "shutdown.target" ];
1739 requisite = [ "systemd-networkd.service" ];
1740 after = [ "systemd-networkd.service" ];
1741 serviceConfig = {
1742 Type = "oneshot";
1743 RemainAfterExit = true;
1744 ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
1745 };
1746 };
1747
1748 services.resolved.enable = mkDefault true;
1749 })
1750 ];
1751}