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 checkLink = checkUnitConfig "Link" [
12 (assertOnlyFields [
13 "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
14 "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan"
15 ])
16 (assertValueOneOf "MACAddressPolicy" ["persistent" "random"])
17 (assertMacAddress "MACAddress")
18 (assertValueOneOf "NamePolicy" [
19 "kernel" "database" "onboard" "slot" "path" "mac"
20 ])
21 (assertByteFormat "MTUBytes")
22 (assertByteFormat "BitsPerSecond")
23 (assertValueOneOf "Duplex" ["half" "full"])
24 (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"])
25 ];
26
27 checkNetdev = checkUnitConfig "Netdev" [
28 (assertOnlyFields [
29 "Description" "Name" "Kind" "MTUBytes" "MACAddress"
30 ])
31 (assertHasField "Name")
32 (assertHasField "Kind")
33 (assertValueOneOf "Kind" [
34 "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip"
35 "gre" "sit" "vti" "veth" "tun" "tap" "dummy"
36 ])
37 (assertByteFormat "MTUBytes")
38 (assertMacAddress "MACAddress")
39 ];
40
41 checkVlan = checkUnitConfig "VLAN" [
42 (assertOnlyFields ["Id"])
43 (assertRange "Id" 0 4094)
44 ];
45
46 checkMacvlan = checkUnitConfig "MACVLAN" [
47 (assertOnlyFields ["Mode"])
48 (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
49 ];
50
51 checkVxlan = checkUnitConfig "VXLAN" [
52 (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"])
53 (assertRange "TTL" 0 255)
54 (assertValueOneOf "MacLearning" boolValues)
55 ];
56
57 checkTunnel = checkUnitConfig "Tunnel" [
58 (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"])
59 (assertRange "TTL" 0 255)
60 (assertValueOneOf "DiscoverPathMTU" boolValues)
61 ];
62
63 checkPeer = checkUnitConfig "Peer" [
64 (assertOnlyFields ["Name" "MACAddress"])
65 (assertMacAddress "MACAddress")
66 ];
67
68 tunTapChecks = [
69 (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"])
70 (assertValueOneOf "OneQueue" boolValues)
71 (assertValueOneOf "MultiQueue" boolValues)
72 (assertValueOneOf "PacketInfo" boolValues)
73 ];
74
75 checkTun = checkUnitConfig "Tun" tunTapChecks;
76
77 checkTap = checkUnitConfig "Tap" tunTapChecks;
78
79 checkBond = checkUnitConfig "Bond" [
80 (assertOnlyFields [
81 "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
82 "UpDelaySec" "DownDelaySec" "GratuitousARP"
83 ])
84 (assertValueOneOf "Mode" [
85 "balance-rr" "active-backup" "balance-xor"
86 "broadcast" "802.3ad" "balance-tlb" "balance-alb"
87 ])
88 (assertValueOneOf "TransmitHashPolicy" [
89 "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4"
90 ])
91 (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
92 ];
93
94 checkNetwork = checkUnitConfig "Network" [
95 (assertOnlyFields [
96 "Description" "DHCP" "DHCPServer" "IPForward" "IPMasquerade" "IPv4LL" "IPv4LLRoute"
97 "LLMNR" "MulticastDNS" "Domains" "Bridge" "Bond" "IPv6PrivacyExtensions"
98 ])
99 (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
100 (assertValueOneOf "DHCPServer" boolValues)
101 (assertValueOneOf "IPForward" ["yes" "no" "ipv4" "ipv6"])
102 (assertValueOneOf "IPMasquerade" boolValues)
103 (assertValueOneOf "IPv4LL" boolValues)
104 (assertValueOneOf "IPv4LLRoute" boolValues)
105 (assertValueOneOf "LLMNR" boolValues)
106 (assertValueOneOf "MulticastDNS" boolValues)
107 (assertValueOneOf "IPv6PrivacyExtensions" ["yes" "no" "prefer-public" "kernel"])
108 ];
109
110 checkAddress = checkUnitConfig "Address" [
111 (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
112 (assertHasField "Address")
113 ];
114
115 checkRoute = checkUnitConfig "Route" [
116 (assertOnlyFields ["Gateway" "Destination" "Metric"])
117 (assertHasField "Gateway")
118 ];
119
120 checkDhcp = checkUnitConfig "DHCP" [
121 (assertOnlyFields [
122 "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
123 "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
124 "RouteMetric"
125 ])
126 (assertValueOneOf "UseDNS" boolValues)
127 (assertValueOneOf "UseMTU" boolValues)
128 (assertValueOneOf "SendHostname" boolValues)
129 (assertValueOneOf "UseHostname" boolValues)
130 (assertValueOneOf "UseDomains" boolValues)
131 (assertValueOneOf "UseRoutes" boolValues)
132 (assertValueOneOf "CriticalConnections" boolValues)
133 (assertValueOneOf "RequestBroadcast" boolValues)
134 ];
135
136 checkDhcpServer = checkUnitConfig "DHCPServer" [
137 (assertOnlyFields [
138 "PoolOffset" "PoolSize" "DefaultLeaseTimeSec" "MaxLeaseTimeSec"
139 "EmitDNS" "DNS" "EmitNTP" "NTP" "EmitTimezone" "Timezone"
140 ])
141 (assertValueOneOf "EmitDNS" boolValues)
142 (assertValueOneOf "EmitNTP" boolValues)
143 (assertValueOneOf "EmitTimezone" boolValues)
144 ];
145
146 # .network files have a [Link] section with different options than in .netlink files
147 checkNetworkLink = checkUnitConfig "Link" [
148 (assertOnlyFields [
149 "MACAddress" "MTUBytes" "ARP" "Unmanaged"
150 ])
151 (assertMacAddress "MACAddress")
152 (assertByteFormat "MTUBytes")
153 (assertValueOneOf "ARP" boolValues)
154 (assertValueOneOf "Unmanaged" boolValues)
155 ];
156
157
158 commonNetworkOptions = {
159
160 enable = mkOption {
161 default = true;
162 type = types.bool;
163 description = ''
164 Whether to manage network configuration using <command>systemd-network</command>.
165 '';
166 };
167
168 matchConfig = mkOption {
169 default = {};
170 example = { Name = "eth0"; };
171 type = types.attrsOf unitOption;
172 description = ''
173 Each attribute in this set specifies an option in the
174 <literal>[Match]</literal> section of the unit. See
175 <citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>
176 <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
177 <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
178 for details.
179 '';
180 };
181
182 extraConfig = mkOption {
183 default = "";
184 type = types.lines;
185 description = "Extra configuration append to unit";
186 };
187 };
188
189 linkOptions = commonNetworkOptions // {
190
191 linkConfig = mkOption {
192 default = {};
193 example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
194 type = types.addCheck (types.attrsOf unitOption) checkLink;
195 description = ''
196 Each attribute in this set specifies an option in the
197 <literal>[Link]</literal> section of the unit. See
198 <citerefentry><refentrytitle>systemd.link</refentrytitle>
199 <manvolnum>5</manvolnum></citerefentry> for details.
200 '';
201 };
202
203 };
204
205 netdevOptions = commonNetworkOptions // {
206
207 netdevConfig = mkOption {
208 default = {};
209 example = { Name = "mybridge"; Kind = "bridge"; };
210 type = types.addCheck (types.attrsOf unitOption) checkNetdev;
211 description = ''
212 Each attribute in this set specifies an option in the
213 <literal>[Netdev]</literal> section of the unit. See
214 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
215 <manvolnum>5</manvolnum></citerefentry> for details.
216 '';
217 };
218
219 vlanConfig = mkOption {
220 default = {};
221 example = { Id = "4"; };
222 type = types.addCheck (types.attrsOf unitOption) checkVlan;
223 description = ''
224 Each attribute in this set specifies an option in the
225 <literal>[VLAN]</literal> section of the unit. See
226 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
227 <manvolnum>5</manvolnum></citerefentry> for details.
228 '';
229 };
230
231 macvlanConfig = mkOption {
232 default = {};
233 example = { Mode = "private"; };
234 type = types.addCheck (types.attrsOf unitOption) checkMacvlan;
235 description = ''
236 Each attribute in this set specifies an option in the
237 <literal>[MACVLAN]</literal> section of the unit. See
238 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
239 <manvolnum>5</manvolnum></citerefentry> for details.
240 '';
241 };
242
243 vxlanConfig = mkOption {
244 default = {};
245 example = { Id = "4"; };
246 type = types.addCheck (types.attrsOf unitOption) checkVxlan;
247 description = ''
248 Each attribute in this set specifies an option in the
249 <literal>[VXLAN]</literal> section of the unit. See
250 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
251 <manvolnum>5</manvolnum></citerefentry> for details.
252 '';
253 };
254
255 tunnelConfig = mkOption {
256 default = {};
257 example = { Remote = "192.168.1.1"; };
258 type = types.addCheck (types.attrsOf unitOption) checkTunnel;
259 description = ''
260 Each attribute in this set specifies an option in the
261 <literal>[Tunnel]</literal> section of the unit. See
262 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
263 <manvolnum>5</manvolnum></citerefentry> for details.
264 '';
265 };
266
267 peerConfig = mkOption {
268 default = {};
269 example = { Name = "veth2"; };
270 type = types.addCheck (types.attrsOf unitOption) checkPeer;
271 description = ''
272 Each attribute in this set specifies an option in the
273 <literal>[Peer]</literal> section of the unit. See
274 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
275 <manvolnum>5</manvolnum></citerefentry> for details.
276 '';
277 };
278
279 tunConfig = mkOption {
280 default = {};
281 example = { User = "openvpn"; };
282 type = types.addCheck (types.attrsOf unitOption) checkTun;
283 description = ''
284 Each attribute in this set specifies an option in the
285 <literal>[Tun]</literal> section of the unit. See
286 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
287 <manvolnum>5</manvolnum></citerefentry> for details.
288 '';
289 };
290
291 tapConfig = mkOption {
292 default = {};
293 example = { User = "openvpn"; };
294 type = types.addCheck (types.attrsOf unitOption) checkTap;
295 description = ''
296 Each attribute in this set specifies an option in the
297 <literal>[Tap]</literal> section of the unit. See
298 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
299 <manvolnum>5</manvolnum></citerefentry> for details.
300 '';
301 };
302
303 bondConfig = mkOption {
304 default = {};
305 example = { Mode = "802.3ad"; };
306 type = types.addCheck (types.attrsOf unitOption) checkBond;
307 description = ''
308 Each attribute in this set specifies an option in the
309 <literal>[Bond]</literal> section of the unit. See
310 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
311 <manvolnum>5</manvolnum></citerefentry> for details.
312 '';
313 };
314
315 };
316
317 addressOptions = {
318 options = {
319 addressConfig = mkOption {
320 default = {};
321 example = { Address = "192.168.0.100/24"; };
322 type = types.addCheck (types.attrsOf unitOption) checkAddress;
323 description = ''
324 Each attribute in this set specifies an option in the
325 <literal>[Address]</literal> section of the unit. See
326 <citerefentry><refentrytitle>systemd.network</refentrytitle>
327 <manvolnum>5</manvolnum></citerefentry> for details.
328 '';
329 };
330 };
331 };
332
333 routeOptions = {
334 options = {
335 routeConfig = mkOption {
336 default = {};
337 example = { Gateway = "192.168.0.1"; };
338 type = types.addCheck (types.attrsOf unitOption) checkRoute;
339 description = ''
340 Each attribute in this set specifies an option in the
341 <literal>[Route]</literal> section of the unit. See
342 <citerefentry><refentrytitle>systemd.network</refentrytitle>
343 <manvolnum>5</manvolnum></citerefentry> for details.
344 '';
345 };
346 };
347 };
348
349 networkOptions = commonNetworkOptions // {
350
351 networkConfig = mkOption {
352 default = {};
353 example = { Description = "My Network"; };
354 type = types.addCheck (types.attrsOf unitOption) checkNetwork;
355 description = ''
356 Each attribute in this set specifies an option in the
357 <literal>[Network]</literal> section of the unit. See
358 <citerefentry><refentrytitle>systemd.network</refentrytitle>
359 <manvolnum>5</manvolnum></citerefentry> for details.
360 '';
361 };
362
363 dhcpConfig = mkOption {
364 default = {};
365 example = { UseDNS = true; UseRoutes = true; };
366 type = types.addCheck (types.attrsOf unitOption) checkDhcp;
367 description = ''
368 Each attribute in this set specifies an option in the
369 <literal>[DHCP]</literal> section of the unit. See
370 <citerefentry><refentrytitle>systemd.network</refentrytitle>
371 <manvolnum>5</manvolnum></citerefentry> for details.
372 '';
373 };
374
375 dhcpServerConfig = mkOption {
376 default = {};
377 example = { PoolOffset = 50; EmitDNS = false; };
378 type = types.addCheck (types.attrsOf unitOption) checkDhcpServer;
379 description = ''
380 Each attribute in this set specifies an option in the
381 <literal>[DHCPServer]</literal> section of the unit. See
382 <citerefentry><refentrytitle>systemd.network</refentrytitle>
383 <manvolnum>5</manvolnum></citerefentry> for details.
384 '';
385 };
386
387 linkConfig = mkOption {
388 default = {};
389 example = { Unmanaged = true; };
390 type = types.addCheck (types.attrsOf unitOption) checkNetworkLink;
391 description = ''
392 Each attribute in this set specifies an option in the
393 <literal>[Link]</literal> section of the unit. See
394 <citerefentry><refentrytitle>systemd.network</refentrytitle>
395 <manvolnum>5</manvolnum></citerefentry> for details.
396 '';
397 };
398
399 name = mkOption {
400 type = types.nullOr types.str;
401 default = null;
402 description = ''
403 The name of the network interface to match against.
404 '';
405 };
406
407 DHCP = mkOption {
408 type = types.nullOr types.str;
409 default = null;
410 description = ''
411 Whether to enable DHCP on the interfaces matched.
412 '';
413 };
414
415 domains = mkOption {
416 type = types.nullOr (types.listOf types.str);
417 default = null;
418 description = ''
419 A list of domains to pass to the network config.
420 '';
421 };
422
423 address = mkOption {
424 default = [ ];
425 type = types.listOf types.str;
426 description = ''
427 A list of addresses to be added to the network section of the
428 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
429 <manvolnum>5</manvolnum></citerefentry> for details.
430 '';
431 };
432
433 gateway = mkOption {
434 default = [ ];
435 type = types.listOf types.str;
436 description = ''
437 A list of gateways to be added to the network section of the
438 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
439 <manvolnum>5</manvolnum></citerefentry> for details.
440 '';
441 };
442
443 dns = mkOption {
444 default = [ ];
445 type = types.listOf types.str;
446 description = ''
447 A list of dns servers to be added to the network section of the
448 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
449 <manvolnum>5</manvolnum></citerefentry> for details.
450 '';
451 };
452
453 ntp = mkOption {
454 default = [ ];
455 type = types.listOf types.str;
456 description = ''
457 A list of ntp servers to be added to the network section of the
458 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
459 <manvolnum>5</manvolnum></citerefentry> for details.
460 '';
461 };
462
463 vlan = mkOption {
464 default = [ ];
465 type = types.listOf types.str;
466 description = ''
467 A list of vlan interfaces to be added to the network section of the
468 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
469 <manvolnum>5</manvolnum></citerefentry> for details.
470 '';
471 };
472
473 macvlan = mkOption {
474 default = [ ];
475 type = types.listOf types.str;
476 description = ''
477 A list of macvlan interfaces to be added to the network section of the
478 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
479 <manvolnum>5</manvolnum></citerefentry> for details.
480 '';
481 };
482
483 vxlan = mkOption {
484 default = [ ];
485 type = types.listOf types.str;
486 description = ''
487 A list of vxlan interfaces to be added to the network section of the
488 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
489 <manvolnum>5</manvolnum></citerefentry> for details.
490 '';
491 };
492
493 tunnel = mkOption {
494 default = [ ];
495 type = types.listOf types.str;
496 description = ''
497 A list of tunnel interfaces to be added to the network section of the
498 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
499 <manvolnum>5</manvolnum></citerefentry> for details.
500 '';
501 };
502
503 addresses = mkOption {
504 default = [ ];
505 type = with types; listOf (submodule addressOptions);
506 description = ''
507 A list of address sections to be added to the unit. See
508 <citerefentry><refentrytitle>systemd.network</refentrytitle>
509 <manvolnum>5</manvolnum></citerefentry> for details.
510 '';
511 };
512
513 routes = mkOption {
514 default = [ ];
515 type = with types; listOf (submodule routeOptions);
516 description = ''
517 A list of route sections to be added to the unit. See
518 <citerefentry><refentrytitle>systemd.network</refentrytitle>
519 <manvolnum>5</manvolnum></citerefentry> for details.
520 '';
521 };
522
523 };
524
525 networkConfig = { name, config, ... }: {
526 config = {
527 matchConfig = optionalAttrs (config.name != null) {
528 Name = config.name;
529 };
530 networkConfig = optionalAttrs (config.DHCP != null) {
531 DHCP = config.DHCP;
532 } // optionalAttrs (config.domains != null) {
533 Domains = concatStringsSep " " config.domains;
534 };
535 };
536 };
537
538 commonMatchText = def: ''
539 [Match]
540 ${attrsToSection def.matchConfig}
541 '';
542
543 linkToUnit = name: def:
544 { inherit (def) enable;
545 text = commonMatchText def +
546 ''
547 [Link]
548 ${attrsToSection def.linkConfig}
549
550 ${def.extraConfig}
551 '';
552 };
553
554 netdevToUnit = name: def:
555 { inherit (def) enable;
556 text = commonMatchText def +
557 ''
558 [NetDev]
559 ${attrsToSection def.netdevConfig}
560
561 ${optionalString (def.vlanConfig != { }) ''
562 [VLAN]
563 ${attrsToSection def.vlanConfig}
564
565 ''}
566 ${optionalString (def.macvlanConfig != { }) ''
567 [MACVLAN]
568 ${attrsToSection def.macvlanConfig}
569
570 ''}
571 ${optionalString (def.vxlanConfig != { }) ''
572 [VXLAN]
573 ${attrsToSection def.vxlanConfig}
574
575 ''}
576 ${optionalString (def.tunnelConfig != { }) ''
577 [Tunnel]
578 ${attrsToSection def.tunnelConfig}
579
580 ''}
581 ${optionalString (def.peerConfig != { }) ''
582 [Peer]
583 ${attrsToSection def.peerConfig}
584
585 ''}
586 ${optionalString (def.tunConfig != { }) ''
587 [Tun]
588 ${attrsToSection def.tunConfig}
589
590 ''}
591 ${optionalString (def.tapConfig != { }) ''
592 [Tap]
593 ${attrsToSection def.tapConfig}
594
595 ''}
596 ${optionalString (def.bondConfig != { }) ''
597 [Bond]
598 ${attrsToSection def.bondConfig}
599
600 ''}
601 ${def.extraConfig}
602 '';
603 };
604
605 networkToUnit = name: def:
606 { inherit (def) enable;
607 text = commonMatchText def +
608 ''
609 ${optionalString (def.linkConfig != { }) ''
610 [Link]
611 ${attrsToSection def.linkConfig}
612
613 ''}
614
615 [Network]
616 ${attrsToSection def.networkConfig}
617 ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
618 ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
619 ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
620 ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
621 ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
622 ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
623 ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
624 ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
625
626 ${optionalString (def.dhcpConfig != { }) ''
627 [DHCP]
628 ${attrsToSection def.dhcpConfig}
629
630 ''}
631 ${optionalString (def.dhcpServerConfig != { }) ''
632 [DHCPServer]
633 ${attrsToSection def.dhcpServerConfig}
634
635 ''}
636 ${flip concatMapStrings def.addresses (x: ''
637 [Address]
638 ${attrsToSection x.addressConfig}
639
640 '')}
641 ${flip concatMapStrings def.routes (x: ''
642 [Route]
643 ${attrsToSection x.routeConfig}
644
645 '')}
646 ${def.extraConfig}
647 '';
648 };
649
650 unitFiles = map (name: {
651 target = "systemd/network/${name}";
652 source = "${cfg.units.${name}.unit}/${name}";
653 }) (attrNames cfg.units);
654in
655
656{
657
658 options = {
659
660 systemd.network.enable = mkOption {
661 default = false;
662 type = types.bool;
663 description = ''
664 Whether to enable networkd or not.
665 '';
666 };
667
668 systemd.network.links = mkOption {
669 default = {};
670 type = with types; attrsOf (submodule [ { options = linkOptions; } ]);
671 description = "Definition of systemd network links.";
672 };
673
674 systemd.network.netdevs = mkOption {
675 default = {};
676 type = with types; attrsOf (submodule [ { options = netdevOptions; } ]);
677 description = "Definition of systemd network devices.";
678 };
679
680 systemd.network.networks = mkOption {
681 default = {};
682 type = with types; attrsOf (submodule [ { options = networkOptions; } networkConfig ]);
683 description = "Definition of systemd networks.";
684 };
685
686 systemd.network.units = mkOption {
687 description = "Definition of networkd units.";
688 default = {};
689 type = with types; attrsOf (submodule (
690 { name, config, ... }:
691 { options = concreteUnitOptions;
692 config = {
693 unit = mkDefault (makeUnit name config);
694 };
695 }));
696 };
697
698 };
699
700 config = mkIf config.systemd.network.enable {
701
702 systemd.additionalUpstreamSystemUnits = [
703 "systemd-networkd.service" "systemd-networkd-wait-online.service"
704 ];
705
706 systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links
707 // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
708 // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;
709
710 environment.etc = unitFiles;
711
712 systemd.services.systemd-networkd = {
713 wantedBy = [ "multi-user.target" ];
714 restartTriggers = map (f: f.source) (unitFiles);
715 };
716
717 systemd.services.systemd-networkd-wait-online = {
718 wantedBy = [ "network-online.target" ];
719 };
720
721 systemd.services."systemd-network-wait-online@" = {
722 description = "Wait for Network Interface %I to be Configured";
723 conflicts = [ "shutdown.target" ];
724 requisite = [ "systemd-networkd.service" ];
725 after = [ "systemd-networkd.service" ];
726 serviceConfig = {
727 Type = "oneshot";
728 RemainAfterExit = true;
729 ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
730 };
731 };
732
733 services.resolved.enable = mkDefault true;
734 };
735}