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"
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 ];
108
109 checkAddress = checkUnitConfig "Address" [
110 (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
111 (assertHasField "Address")
112 ];
113
114 checkRoute = checkUnitConfig "Route" [
115 (assertOnlyFields ["Gateway" "Destination" "Metric"])
116 (assertHasField "Gateway")
117 ];
118
119 checkDhcp = checkUnitConfig "DHCP" [
120 (assertOnlyFields [
121 "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
122 "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
123 "RouteMetric"
124 ])
125 (assertValueOneOf "UseDNS" boolValues)
126 (assertValueOneOf "UseMTU" boolValues)
127 (assertValueOneOf "SendHostname" boolValues)
128 (assertValueOneOf "UseHostname" boolValues)
129 (assertValueOneOf "UseDomains" boolValues)
130 (assertValueOneOf "UseRoutes" boolValues)
131 (assertValueOneOf "CriticalConnections" boolValues)
132 (assertValueOneOf "RequestBroadcast" boolValues)
133 ];
134
135 checkDhcpServer = checkUnitConfig "DHCPServer" [
136 (assertOnlyFields [
137 "PoolOffset" "PoolSize" "DefaultLeaseTimeSec" "MaxLeaseTimeSec"
138 "EmitDNS" "DNS" "EmitNTP" "NTP" "EmitTimezone" "Timezone"
139 ])
140 (assertValueOneOf "EmitDNS" boolValues)
141 (assertValueOneOf "EmitNTP" boolValues)
142 (assertValueOneOf "EmitTimezone" boolValues)
143 ];
144
145 # .network files have a [Link] section with different options than in .netlink files
146 checkNetworkLink = checkUnitConfig "Link" [
147 (assertOnlyFields [
148 "MACAddress" "MTUBytes" "ARP" "Unmanaged"
149 ])
150 (assertMacAddress "MACAddress")
151 (assertByteFormat "MTUBytes")
152 (assertValueOneOf "ARP" boolValues)
153 (assertValueOneOf "Unmanaged" boolValues)
154 ];
155
156
157 commonNetworkOptions = {
158
159 enable = mkOption {
160 default = true;
161 type = types.bool;
162 description = ''
163 Whether to manage network configuration using <command>systemd-network</command>.
164 '';
165 };
166
167 matchConfig = mkOption {
168 default = {};
169 example = { Name = "eth0"; };
170 type = types.attrsOf unitOption;
171 description = ''
172 Each attribute in this set specifies an option in the
173 <literal>[Match]</literal> section of the unit. See
174 <citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>
175 <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
176 <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
177 for details.
178 '';
179 };
180
181 extraConfig = mkOption {
182 default = "";
183 type = types.lines;
184 description = "Extra configuration append to unit";
185 };
186 };
187
188 linkOptions = commonNetworkOptions // {
189
190 linkConfig = mkOption {
191 default = {};
192 example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
193 type = types.addCheck (types.attrsOf unitOption) checkLink;
194 description = ''
195 Each attribute in this set specifies an option in the
196 <literal>[Link]</literal> section of the unit. See
197 <citerefentry><refentrytitle>systemd.link</refentrytitle>
198 <manvolnum>5</manvolnum></citerefentry> for details.
199 '';
200 };
201
202 };
203
204 netdevOptions = commonNetworkOptions // {
205
206 netdevConfig = mkOption {
207 default = {};
208 example = { Name = "mybridge"; Kind = "bridge"; };
209 type = types.addCheck (types.attrsOf unitOption) checkNetdev;
210 description = ''
211 Each attribute in this set specifies an option in the
212 <literal>[Netdev]</literal> section of the unit. See
213 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
214 <manvolnum>5</manvolnum></citerefentry> for details.
215 '';
216 };
217
218 vlanConfig = mkOption {
219 default = {};
220 example = { Id = "4"; };
221 type = types.addCheck (types.attrsOf unitOption) checkVlan;
222 description = ''
223 Each attribute in this set specifies an option in the
224 <literal>[VLAN]</literal> section of the unit. See
225 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
226 <manvolnum>5</manvolnum></citerefentry> for details.
227 '';
228 };
229
230 macvlanConfig = mkOption {
231 default = {};
232 example = { Mode = "private"; };
233 type = types.addCheck (types.attrsOf unitOption) checkMacvlan;
234 description = ''
235 Each attribute in this set specifies an option in the
236 <literal>[MACVLAN]</literal> section of the unit. See
237 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
238 <manvolnum>5</manvolnum></citerefentry> for details.
239 '';
240 };
241
242 vxlanConfig = mkOption {
243 default = {};
244 example = { Id = "4"; };
245 type = types.addCheck (types.attrsOf unitOption) checkVxlan;
246 description = ''
247 Each attribute in this set specifies an option in the
248 <literal>[VXLAN]</literal> section of the unit. See
249 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
250 <manvolnum>5</manvolnum></citerefentry> for details.
251 '';
252 };
253
254 tunnelConfig = mkOption {
255 default = {};
256 example = { Remote = "192.168.1.1"; };
257 type = types.addCheck (types.attrsOf unitOption) checkTunnel;
258 description = ''
259 Each attribute in this set specifies an option in the
260 <literal>[Tunnel]</literal> section of the unit. See
261 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
262 <manvolnum>5</manvolnum></citerefentry> for details.
263 '';
264 };
265
266 peerConfig = mkOption {
267 default = {};
268 example = { Name = "veth2"; };
269 type = types.addCheck (types.attrsOf unitOption) checkPeer;
270 description = ''
271 Each attribute in this set specifies an option in the
272 <literal>[Peer]</literal> section of the unit. See
273 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
274 <manvolnum>5</manvolnum></citerefentry> for details.
275 '';
276 };
277
278 tunConfig = mkOption {
279 default = {};
280 example = { User = "openvpn"; };
281 type = types.addCheck (types.attrsOf unitOption) checkTun;
282 description = ''
283 Each attribute in this set specifies an option in the
284 <literal>[Tun]</literal> section of the unit. See
285 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
286 <manvolnum>5</manvolnum></citerefentry> for details.
287 '';
288 };
289
290 tapConfig = mkOption {
291 default = {};
292 example = { User = "openvpn"; };
293 type = types.addCheck (types.attrsOf unitOption) checkTap;
294 description = ''
295 Each attribute in this set specifies an option in the
296 <literal>[Tap]</literal> section of the unit. See
297 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
298 <manvolnum>5</manvolnum></citerefentry> for details.
299 '';
300 };
301
302 bondConfig = mkOption {
303 default = {};
304 example = { Mode = "802.3ad"; };
305 type = types.addCheck (types.attrsOf unitOption) checkBond;
306 description = ''
307 Each attribute in this set specifies an option in the
308 <literal>[Bond]</literal> section of the unit. See
309 <citerefentry><refentrytitle>systemd.netdev</refentrytitle>
310 <manvolnum>5</manvolnum></citerefentry> for details.
311 '';
312 };
313
314 };
315
316 addressOptions = {
317 options = {
318 addressConfig = mkOption {
319 default = {};
320 example = { Address = "192.168.0.100/24"; };
321 type = types.addCheck (types.attrsOf unitOption) checkAddress;
322 description = ''
323 Each attribute in this set specifies an option in the
324 <literal>[Address]</literal> section of the unit. See
325 <citerefentry><refentrytitle>systemd.network</refentrytitle>
326 <manvolnum>5</manvolnum></citerefentry> for details.
327 '';
328 };
329 };
330 };
331
332 routeOptions = {
333 options = {
334 routeConfig = mkOption {
335 default = {};
336 example = { Gateway = "192.168.0.1"; };
337 type = types.addCheck (types.attrsOf unitOption) checkRoute;
338 description = ''
339 Each attribute in this set specifies an option in the
340 <literal>[Route]</literal> section of the unit. See
341 <citerefentry><refentrytitle>systemd.network</refentrytitle>
342 <manvolnum>5</manvolnum></citerefentry> for details.
343 '';
344 };
345 };
346 };
347
348 networkOptions = commonNetworkOptions // {
349
350 networkConfig = mkOption {
351 default = {};
352 example = { Description = "My Network"; };
353 type = types.addCheck (types.attrsOf unitOption) checkNetwork;
354 description = ''
355 Each attribute in this set specifies an option in the
356 <literal>[Network]</literal> section of the unit. See
357 <citerefentry><refentrytitle>systemd.network</refentrytitle>
358 <manvolnum>5</manvolnum></citerefentry> for details.
359 '';
360 };
361
362 dhcpConfig = mkOption {
363 default = {};
364 example = { UseDNS = true; UseRoutes = true; };
365 type = types.addCheck (types.attrsOf unitOption) checkDhcp;
366 description = ''
367 Each attribute in this set specifies an option in the
368 <literal>[DHCP]</literal> section of the unit. See
369 <citerefentry><refentrytitle>systemd.network</refentrytitle>
370 <manvolnum>5</manvolnum></citerefentry> for details.
371 '';
372 };
373
374 dhcpServerConfig = mkOption {
375 default = {};
376 example = { PoolOffset = 50; EmitDNS = false; };
377 type = types.addCheck (types.attrsOf unitOption) checkDhcpServer;
378 description = ''
379 Each attribute in this set specifies an option in the
380 <literal>[DHCPServer]</literal> section of the unit. See
381 <citerefentry><refentrytitle>systemd.network</refentrytitle>
382 <manvolnum>5</manvolnum></citerefentry> for details.
383 '';
384 };
385
386 linkConfig = mkOption {
387 default = {};
388 example = { Unmanaged = true; };
389 type = types.addCheck (types.attrsOf unitOption) checkNetworkLink;
390 description = ''
391 Each attribute in this set specifies an option in the
392 <literal>[Link]</literal> section of the unit. See
393 <citerefentry><refentrytitle>systemd.network</refentrytitle>
394 <manvolnum>5</manvolnum></citerefentry> for details.
395 '';
396 };
397
398 name = mkOption {
399 type = types.nullOr types.str;
400 default = null;
401 description = ''
402 The name of the network interface to match against.
403 '';
404 };
405
406 DHCP = mkOption {
407 type = types.nullOr types.str;
408 default = null;
409 description = ''
410 Whether to enable DHCP on the interfaces matched.
411 '';
412 };
413
414 domains = mkOption {
415 type = types.nullOr (types.listOf types.str);
416 default = null;
417 description = ''
418 A list of domains to pass to the network config.
419 '';
420 };
421
422 address = mkOption {
423 default = [ ];
424 type = types.listOf types.str;
425 description = ''
426 A list of addresses to be added to the network section of the
427 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
428 <manvolnum>5</manvolnum></citerefentry> for details.
429 '';
430 };
431
432 gateway = mkOption {
433 default = [ ];
434 type = types.listOf types.str;
435 description = ''
436 A list of gateways to be added to the network section of the
437 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
438 <manvolnum>5</manvolnum></citerefentry> for details.
439 '';
440 };
441
442 dns = mkOption {
443 default = [ ];
444 type = types.listOf types.str;
445 description = ''
446 A list of dns servers to be added to the network section of the
447 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
448 <manvolnum>5</manvolnum></citerefentry> for details.
449 '';
450 };
451
452 ntp = mkOption {
453 default = [ ];
454 type = types.listOf types.str;
455 description = ''
456 A list of ntp servers to be added to the network section of the
457 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
458 <manvolnum>5</manvolnum></citerefentry> for details.
459 '';
460 };
461
462 vlan = mkOption {
463 default = [ ];
464 type = types.listOf types.str;
465 description = ''
466 A list of vlan interfaces to be added to the network section of the
467 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
468 <manvolnum>5</manvolnum></citerefentry> for details.
469 '';
470 };
471
472 macvlan = mkOption {
473 default = [ ];
474 type = types.listOf types.str;
475 description = ''
476 A list of macvlan interfaces to be added to the network section of the
477 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
478 <manvolnum>5</manvolnum></citerefentry> for details.
479 '';
480 };
481
482 vxlan = mkOption {
483 default = [ ];
484 type = types.listOf types.str;
485 description = ''
486 A list of vxlan interfaces to be added to the network section of the
487 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
488 <manvolnum>5</manvolnum></citerefentry> for details.
489 '';
490 };
491
492 tunnel = mkOption {
493 default = [ ];
494 type = types.listOf types.str;
495 description = ''
496 A list of tunnel interfaces to be added to the network section of the
497 unit. See <citerefentry><refentrytitle>systemd.network</refentrytitle>
498 <manvolnum>5</manvolnum></citerefentry> for details.
499 '';
500 };
501
502 addresses = mkOption {
503 default = [ ];
504 type = with types; listOf (submodule addressOptions);
505 description = ''
506 A list of address sections to be added to the unit. See
507 <citerefentry><refentrytitle>systemd.network</refentrytitle>
508 <manvolnum>5</manvolnum></citerefentry> for details.
509 '';
510 };
511
512 routes = mkOption {
513 default = [ ];
514 type = with types; listOf (submodule routeOptions);
515 description = ''
516 A list of route sections to be added to the unit. See
517 <citerefentry><refentrytitle>systemd.network</refentrytitle>
518 <manvolnum>5</manvolnum></citerefentry> for details.
519 '';
520 };
521
522 };
523
524 networkConfig = { name, config, ... }: {
525 config = {
526 matchConfig = optionalAttrs (config.name != null) {
527 Name = config.name;
528 };
529 networkConfig = optionalAttrs (config.DHCP != null) {
530 DHCP = config.DHCP;
531 } // optionalAttrs (config.domains != null) {
532 Domains = concatStringsSep " " config.domains;
533 };
534 };
535 };
536
537 commonMatchText = def: ''
538 [Match]
539 ${attrsToSection def.matchConfig}
540 '';
541
542 linkToUnit = name: def:
543 { inherit (def) enable;
544 text = commonMatchText def +
545 ''
546 [Link]
547 ${attrsToSection def.linkConfig}
548
549 ${def.extraConfig}
550 '';
551 };
552
553 netdevToUnit = name: def:
554 { inherit (def) enable;
555 text = commonMatchText def +
556 ''
557 [NetDev]
558 ${attrsToSection def.netdevConfig}
559
560 ${optionalString (def.vlanConfig != { }) ''
561 [VLAN]
562 ${attrsToSection def.vlanConfig}
563
564 ''}
565 ${optionalString (def.macvlanConfig != { }) ''
566 [MACVLAN]
567 ${attrsToSection def.macvlanConfig}
568
569 ''}
570 ${optionalString (def.vxlanConfig != { }) ''
571 [VXLAN]
572 ${attrsToSection def.vxlanConfig}
573
574 ''}
575 ${optionalString (def.tunnelConfig != { }) ''
576 [Tunnel]
577 ${attrsToSection def.tunnelConfig}
578
579 ''}
580 ${optionalString (def.peerConfig != { }) ''
581 [Peer]
582 ${attrsToSection def.peerConfig}
583
584 ''}
585 ${optionalString (def.tunConfig != { }) ''
586 [Tun]
587 ${attrsToSection def.tunConfig}
588
589 ''}
590 ${optionalString (def.tapConfig != { }) ''
591 [Tap]
592 ${attrsToSection def.tapConfig}
593
594 ''}
595 ${optionalString (def.bondConfig != { }) ''
596 [Bond]
597 ${attrsToSection def.bondConfig}
598
599 ''}
600 ${def.extraConfig}
601 '';
602 };
603
604 networkToUnit = name: def:
605 { inherit (def) enable;
606 text = commonMatchText def +
607 ''
608 ${optionalString (def.linkConfig != { }) ''
609 [Link]
610 ${attrsToSection def.linkConfig}
611
612 ''}
613
614 [Network]
615 ${attrsToSection def.networkConfig}
616 ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
617 ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
618 ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
619 ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
620 ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
621 ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
622 ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
623 ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
624
625 ${optionalString (def.dhcpConfig != { }) ''
626 [DHCP]
627 ${attrsToSection def.dhcpConfig}
628
629 ''}
630 ${optionalString (def.dhcpServerConfig != { }) ''
631 [DHCPServer]
632 ${attrsToSection def.dhcpServerConfig}
633
634 ''}
635 ${flip concatMapStrings def.addresses (x: ''
636 [Address]
637 ${attrsToSection x.addressConfig}
638
639 '')}
640 ${flip concatMapStrings def.routes (x: ''
641 [Route]
642 ${attrsToSection x.routeConfig}
643
644 '')}
645 ${def.extraConfig}
646 '';
647 };
648
649 unitFiles = map (name: {
650 target = "systemd/network/${name}";
651 source = "${cfg.units.${name}.unit}/${name}";
652 }) (attrNames cfg.units);
653in
654
655{
656
657 options = {
658
659 systemd.network.enable = mkOption {
660 default = false;
661 type = types.bool;
662 description = ''
663 Whether to enable networkd or not.
664 '';
665 };
666
667 systemd.network.links = mkOption {
668 default = {};
669 type = with types; attrsOf (submodule [ { options = linkOptions; } ]);
670 description = "Definition of systemd network links.";
671 };
672
673 systemd.network.netdevs = mkOption {
674 default = {};
675 type = with types; attrsOf (submodule [ { options = netdevOptions; } ]);
676 description = "Definition of systemd network devices.";
677 };
678
679 systemd.network.networks = mkOption {
680 default = {};
681 type = with types; attrsOf (submodule [ { options = networkOptions; } networkConfig ]);
682 description = "Definition of systemd networks.";
683 };
684
685 systemd.network.units = mkOption {
686 description = "Definition of networkd units.";
687 default = {};
688 type = with types; attrsOf (submodule (
689 { name, config, ... }:
690 { options = concreteUnitOptions;
691 config = {
692 unit = mkDefault (makeUnit name config);
693 };
694 }));
695 };
696
697 };
698
699 config = mkIf config.systemd.network.enable {
700
701 systemd.additionalUpstreamSystemUnits = [
702 "systemd-networkd.service" "systemd-networkd-wait-online.service"
703 "org.freedesktop.network1.busname"
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}