diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index 914d3e62eb4..bbdd5a40706 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -436,7 +436,8 @@ let "IPv4ProxyARP" "IPv6ProxyNDP" "IPv6ProxyNDPAddress" - "IPv6PrefixDelegation" + "IPv6SendRA" + "DHCPv6PrefixDelegation" "IPv6MTUBytes" "Bridge" "Bond" @@ -477,7 +478,8 @@ let (assertMinimum "IPv6HopLimit" 0) (assertValueOneOf "IPv4ProxyARP" boolValues) (assertValueOneOf "IPv6ProxyNDP" boolValues) - (assertValueOneOf "IPv6PrefixDelegation" ["static" "dhcpv6" "yes" "false"]) + (assertValueOneOf "IPv6SendRA" boolValues) + (assertValueOneOf "DHCPv6PrefixDelegation" boolValues) (assertByteFormat "IPv6MTUBytes") (assertValueOneOf "ActiveSlave" boolValues) (assertValueOneOf "PrimarySlave" boolValues) @@ -643,18 +645,63 @@ let sectionDHCPv6 = checkUnitConfig "DHCPv6" [ (assertOnlyFields [ + "UseAddress" "UseDNS" "UseNTP" + "RouteMetric" "RapidCommit" + "MUDURL" + "RequestOptions" + "SendVendorOption" "ForceDHCPv6PDOtherInformation" "PrefixDelegationHint" - "RouteMetric" + "WithoutRA" + "SendOption" + "UserClass" + "VendorClass" ]) + (assertValueOneOf "UseAddress" boolValues) (assertValueOneOf "UseDNS" boolValues) (assertValueOneOf "UseNTP" boolValues) + (assertInt "RouteMetric") (assertValueOneOf "RapidCommit" boolValues) (assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues) - (assertInt "RouteMetric") + (assertValueOneOf "WithoutRA" ["solicit" "information-request"]) + (assertRange "SendOption" 1 65536) + ]; + + sectionDHCPv6PrefixDelegation = checkUnitConfig "DHCPv6PrefixDelegation" [ + (assertOnlyFields [ + "SubnetId" + "Announce" + "Assign" + "Token" + ]) + (assertValueOneOf "Announce" boolValues) + (assertValueOneOf "Assign" boolValues) + ]; + + sectionIPv6AcceptRA = checkUnitConfig "IPv6AcceptRA" [ + (assertOnlyFields [ + "UseDNS" + "UseDomains" + "RouteTable" + "UseAutonomousPrefix" + "UseOnLinkPrefix" + "RouterDenyList" + "RouterAllowList" + "PrefixDenyList" + "PrefixAllowList" + "RouteDenyList" + "RouteAllowList" + "DHCPv6Client" + ]) + (assertValueOneOf "UseDNS" boolValues) + (assertValueOneOf "UseDomains" (boolValues ++ ["route"])) + (assertRange "RouteTable" 0 4294967295) + (assertValueOneOf "UseAutonomousPrefix" boolValues) + (assertValueOneOf "UseOnLinkPrefix" boolValues) + (assertValueOneOf "DHCPv6Client" (boolValues ++ ["always"])) ]; sectionDHCPServer = checkUnitConfig "DHCPServer" [ @@ -685,7 +732,7 @@ let (assertValueOneOf "EmitTimezone" boolValues) ]; - sectionIPv6PrefixDelegation = checkUnitConfig "IPv6PrefixDelegation" [ + sectionIPv6SendRA = checkUnitConfig "IPv6SendRA" [ (assertOnlyFields [ "Managed" "OtherInformation" @@ -1090,6 +1137,30 @@ let ''; }; + dhcpV6PrefixDelegationConfig = mkOption { + default = {}; + example = { SubnetId = "auto"; Announce = true; }; + type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6PrefixDelegation; + description = '' + Each attribute in this set specifies an option in the + [DHCPv6PrefixDelegation] section of the unit. See + systemd.network + 5 for details. + ''; + }; + + ipv6AcceptRAConfig = mkOption { + default = {}; + example = { UseDNS = true; DHCPv6Client = "always"; }; + type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6AcceptRA; + description = '' + Each attribute in this set specifies an option in the + [IPv6AcceptRA] section of the unit. See + systemd.network + 5 for details. + ''; + }; + dhcpServerConfig = mkOption { default = {}; example = { PoolOffset = 50; EmitDNS = false; }; @@ -1102,13 +1173,20 @@ let ''; }; + # systemd.network.networks.*.ipv6PrefixDelegationConfig has been deprecated + # in 247 in favor of systemd.network.networks.*.ipv6SendRAConfig. ipv6PrefixDelegationConfig = mkOption { + visible = false; + apply = _: throw "The option `systemd.network.networks.*.ipv6PrefixDelegationConfig` has been replaced by `systemd.network.networks.*.ipv6SendRAConfig`."; + }; + + ipv6SendRAConfig = mkOption { default = {}; example = { EmitDNS = true; Managed = true; OtherInformation = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6PrefixDelegation; + type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6SendRA; description = '' Each attribute in this set specifies an option in the - [IPv6PrefixDelegation] section of the unit. See + [IPv6SendRA] section of the unit. See systemd.network 5 for details. ''; @@ -1457,13 +1535,21 @@ let [DHCPv6] ${attrsToSection def.dhcpV6Config} '' + + optionalString (def.dhcpV6PrefixDelegationConfig != { }) '' + [DHCPv6PrefixDelegation] + ${attrsToSection def.dhcpV6PrefixDelegationConfig} + '' + + optionalString (def.ipv6AcceptRAConfig != { }) '' + [IPv6AcceptRA] + ${attrsToSection def.ipv6AcceptRAConfig} + '' + optionalString (def.dhcpServerConfig != { }) '' [DHCPServer] ${attrsToSection def.dhcpServerConfig} '' - + optionalString (def.ipv6PrefixDelegationConfig != { }) '' - [IPv6PrefixDelegation] - ${attrsToSection def.ipv6PrefixDelegationConfig} + + optionalString (def.ipv6SendRAConfig != { }) '' + [IPv6SendRA] + ${attrsToSection def.ipv6SendRAConfig} '' + flip concatMapStrings def.ipv6Prefixes (x: '' [IPv6Prefix] @@ -1479,7 +1565,6 @@ let in { - options = { systemd.network.enable = mkOption { diff --git a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix index bce78f09fdc..5831c8692f6 100644 --- a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix +++ b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix @@ -165,7 +165,7 @@ import ./make-test-python.nix ({pkgs, ...}: { # accept the delegated prefix. PrefixDelegationHint = "::/48"; }; - ipv6PrefixDelegationConfig = { + ipv6SendRAConfig = { # Let networkd know that we would very much like to use DHCPv6 # to obtain the "managed" information. Not sure why they can't # just take that from the upstream RAs. @@ -179,24 +179,20 @@ import ./make-test-python.nix ({pkgs, ...}: { name = "eth2"; networkConfig = { Description = "Client interface"; - # the client shouldn't be allowed to send us RAs, that would be weird. + # The client shouldn't be allowed to send us RAs, that would be weird. IPv6AcceptRA = false; - # Just delegate prefixes from the DHCPv6 PD pool. - # If you also want to distribute a local ULA prefix you want to - # set this to `yes` as that includes both static prefixes as well - # as PD prefixes. - IPv6PrefixDelegation = "dhcpv6"; + # Delegate prefixes from the DHCPv6 PD pool. + DHCPv6PrefixDelegation = true; + IPv6SendRA = true; }; - # finally "act as router" (according to systemd.network(5)) - ipv6PrefixDelegationConfig = { - RouterLifetimeSec = 300; # required as otherwise no RA's are being emitted - # In a production environment you should consider setting these as well: + # In a production environment you should consider setting these as well: + # ipv6SendRAConfig = { #EmitDNS = true; #EmitDomains = true; #DNS= = "fe80::1"; # or whatever "well known" IP your router will have on the inside. - }; + # }; # This adds a "random" ULA prefix to the interface that is being # advertised to the clients.