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