Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/networkd: update configuration options #82026

Merged
merged 8 commits into from May 1, 2020
21 changes: 21 additions & 0 deletions nixos/doc/manual/release-notes/rl-2009.xml
Expand Up @@ -290,6 +290,27 @@ environment.systemPackages = [
has been set to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para>
The <literal>systemd-networkd</literal> option
<literal>systemd.network.networks.&lt;name&gt;.dhcp.CriticalConnection</literal>
has been removed following upstream systemd's deprecation of the same. It is recommended to use
<literal>systemd.network.networks.&lt;name&gt;.networkConfig.KeepConfiguration</literal> instead.
See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
</para>
</listitem>
<listitem>
<para>
The <literal>systemd-networkd</literal> option
<literal>systemd.network.networks._name_.dhcpConfig</literal>
has been renamed to
<xref linkend="opt-systemd.network.networks._name_.dhcpV4Config"/>
following upstream systemd's documentation change.
See <citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
</para>
</listitem>
</itemizedlist>
</section>

Expand Down
139 changes: 126 additions & 13 deletions nixos/modules/system/boot/networkd.nix
Expand Up @@ -205,7 +205,7 @@ let
"IPv6HopLimit" "IPv4ProxyARP" "IPv6ProxyNDP" "IPv6ProxyNDPAddress"
"IPv6PrefixDelegation" "IPv6MTUBytes" "Bridge" "Bond" "VRF" "VLAN"
"IPVLAN" "MACVLAN" "VXLAN" "Tunnel" "ActiveSlave" "PrimarySlave"
"ConfigureWithoutCarrier" "Xfrm"
"ConfigureWithoutCarrier" "Xfrm" "KeepConfiguration"
])
# Note: For DHCP the values both, none, v4, v6 are deprecated
(assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6" "both" "none" "v4" "v6"])
Expand All @@ -228,6 +228,7 @@ let
(assertValueOneOf "ActiveSlave" boolValues)
(assertValueOneOf "PrimarySlave" boolValues)
(assertValueOneOf "ConfigureWithoutCarrier" boolValues)
(assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"]))
];

checkAddress = checkUnitConfig "Address" [
Expand Down Expand Up @@ -274,15 +275,16 @@ let
])
];

checkDhcp = checkUnitConfig "DHCP" [
checkDhcpV4 = checkUnitConfig "DHCPv4" [
(assertOnlyFields [
"UseDNS" "UseNTP" "UseMTU" "Anonymize" "SendHostname" "UseHostname"
"Hostname" "UseDomains" "UseRoutes" "UseTimezone" "CriticalConnection"
"ClientIdentifier" "VendorClassIdentifier" "UserClass" "DUIDType"
"DUIDRawData" "IAID" "RequestBroadcast" "RouteMetric" "RouteTable"
"ListenPort" "RapidCommit"
"UseDNS" "RoutesToDNS" "UseNTP" "UseMTU" "Anonymize" "SendHostname" "UseHostname"
"Hostname" "UseDomains" "UseRoutes" "UseTimezone"
andir marked this conversation as resolved.
Show resolved Hide resolved
"ClientIdentifier" "VendorClassIdentifier" "UserClass" "MaxAttempts"
"DUIDType" "DUIDRawData" "IAID" "RequestBroadcast" "RouteMetric" "RouteTable"
"ListenPort" "SendRelease"
])
(assertValueOneOf "UseDNS" boolValues)
(assertValueOneOf "RoutesToDNS" boolValues)
(assertValueOneOf "UseNTP" boolValues)
(assertValueOneOf "UseMTU" boolValues)
(assertValueOneOf "Anonymize" boolValues)
Expand All @@ -291,13 +293,50 @@ let
(assertValueOneOf "UseDomains" ["yes" "no" "route"])
(assertValueOneOf "UseRoutes" boolValues)
(assertValueOneOf "UseTimezone" boolValues)
(assertValueOneOf "CriticalConnection" boolValues)
(assertMinimum "MaxAttempts" 0)
(assertValueOneOf "RequestBroadcast" boolValues)
(assertInt "RouteTable")
(assertMinimum "RouteTable" 0)
(assertValueOneOf "SendRelease" boolValues)
];

checkDhcpV6 = checkUnitConfig "DHCPv6" [
(assertOnlyFields [
"UseDns" "UseNTP" "RapidCommit" "ForceDHCPv6PDOtherInformation"
"PrefixDelegationHint"
andir marked this conversation as resolved.
Show resolved Hide resolved
])
(assertValueOneOf "UseDNS" boolValues)
(assertValueOneOf "UseNTP" boolValues)
(assertValueOneOf "RapidCommit" boolValues)
(assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues)
];

checkIpv6PrefixDelegation = checkUnitConfig "IPv6PrefixDelegation" [
(assertOnlyFields [
"Managed" "OtherInformation" "RouterLifetimeSec"
"RouterPreference" "EmitDNS" "DNS" "EmitDomains" "Domains"
"DNSLifetimeSec"
])
(assertValueOneOf "Managed" boolValues)
(assertValueOneOf "OtherInformation" boolValues)
(assertValueOneOf "RouterPreference" ["high" "medium" "low" "normal" "default"])
(assertValueOneOf "EmitDNS" boolValues)
(assertValueOneOf "EmitDomains" boolValues)
(assertMinimum "DNSLifetimeSec" 0)
];

checkIpv6Prefix = checkUnitConfig "IPv6Prefix" [
(assertOnlyFields [
"AddressAutoconfiguration" "OnLink" "Prefix"
"PreferredLifetimeSec" "ValidLifetimeSec"
])
(assertValueOneOf "AddressAutoconfiguration" boolValues)
(assertValueOneOf "OnLink" boolValues)
(assertMinimum "PreferredLifetimeSec" 0)
(assertMinimum "ValidLifetimeSec" 0)
];


checkDhcpServer = checkUnitConfig "DHCPServer" [
(assertOnlyFields [
"PoolOffset" "PoolSize" "DefaultLeaseTimeSec" "MaxLeaseTimeSec"
Expand Down Expand Up @@ -621,6 +660,22 @@ let
};
};

ipv6PrefixOptions = {
options = {
ipv6PrefixConfig = mkOption {
default = {};
example = { Prefix = "fd00::/64"; };
type = types.addCheck (types.attrsOf unitOption) checkIpv6Prefix;
description = ''
Each attribute in this set specifies an option in the
<literal>[IPv6Prefix]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
};


networkOptions = commonNetworkOptions // {

Expand All @@ -636,13 +691,55 @@ let
'';
};

# systemd.network.networks.*.dhcpConfig has been deprecated in favor of ….dhcpV4Config
# Produce a nice warning message so users know it is gone.
dhcpConfig = mkOption {
visible = false;
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.";
};

dhcpV4Config = mkOption {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably still want to add a mkRemovedOptionModule, and print a short summary of what's in the release notes instead of just dropping the configuration options here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried adding that but due to the nature of how those work that isn't really feasible here. We have a "wildcard" network name in between and can only really assert if someone tries to access that value.

I tried a few things:

  • traversing the config tree to see if the option is set, that does then trigger the "on access" assertion
  • traversing the option tree (as it is done in the original helper) but that doesn't seem possible for these kinds of situations..

Here is the code I ended up backing out of this changest in case anyone wants to give it a shot:

# systemd.network.networks.*.dhcpConfig has been deprecated in favor of ….dhcpV4Config
# Produce a nice warning message so users know it is gone.
{
  assertions = let
    #affectedNetworks = attrNames (filterAttrs (network: conf: conf.dhcpConfig.isDefined) options.systemd.network.networks.values);
    affectedNetworks = attrNames (filterAttrs (network: conf: conf ? dhcpConfig) config.systemd.network.networks);
  in
  [
    {
      assertion = length affectedNetworks == 0;
      message = ''
        The option definition `systemd.network.networks.*.dhcpConfig` has been deprecated in favor of `systemd.network.networks.*.dhcpV4Config`. Please update your configuration.
        The following networks are still using it:
        ${concatMapStringsSep "\n" (network: "  - `systemd.network.networks.\"${network}\"`") affectedNetworks}
      '';
    }
  ];
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I just left the "on access" throw in the code as that is the least we could do. I do not really want to make it an alias.

default = {};
example = { UseDNS = true; UseRoutes = true; };
type = types.addCheck (types.attrsOf unitOption) checkDhcpV4;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCPv4]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};

dhcpV6Config = mkOption {
default = {};
example = { UseDNS = true; UseRoutes = true; };
type = types.addCheck (types.attrsOf unitOption) checkDhcp;
type = types.addCheck (types.attrsOf unitOption) checkDhcpV6;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCPv6]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};

ipv6PrefixDelegationConfig = mkOption {
default = {};
example = { EmitDNS = true; Managed = true; OtherInformation = true; };
type = types.addCheck (types.attrsOf unitOption) checkIpv6PrefixDelegation;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCP]</literal> section of the unit. See
<literal>[IPv6PrefixDelegation]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};

ipv6Prefixes = mkOption {
default = [];
example = { AddressAutoconfiguration = true; OnLink = true; };
type = with types; listOf (submodule ipv6PrefixOptions);
description = ''
A list of ipv6Prefix sections to be added to the unit. See
<citerefentry><refentrytitle>systemd.network</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
Expand Down Expand Up @@ -973,11 +1070,26 @@ let
${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
${concatStringsSep "\n" (map (s: "Xfrm=${s}") def.xfrm)}

${optionalString (def.dhcpConfig != { }) ''
[DHCP]
${attrsToSection def.dhcpConfig}
${optionalString (def.dhcpV4Config != { }) ''
[DHCPv4]
${attrsToSection def.dhcpV4Config}

''}
${optionalString (def.dhcpV6Config != {}) ''
[DHCPv6]
${attrsToSection def.dhcpV6Config}

''}
${optionalString (def.ipv6PrefixDelegationConfig != {}) ''
[IPv6PrefixDelegation]
${attrsToSection def.ipv6PrefixDelegationConfig}

''}
${flip concatMapStrings def.ipv6Prefixes (x: ''
[IPv6Prefix]
${attrsToSection x.ipv6PrefixConfig}

'')}
${optionalString (def.dhcpServerConfig != { }) ''
[DHCPServer]
${attrsToSection def.dhcpServerConfig}
Expand Down Expand Up @@ -1054,6 +1166,7 @@ in
};

config = mkMerge [

# .link units are honored by udev, no matter if systemd-networkd is enabled or not.
{
systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links;
Expand Down
2 changes: 1 addition & 1 deletion nixos/modules/virtualisation/nixos-containers.nix
Expand Up @@ -546,7 +546,7 @@ in

Note that this option might require to do some adjustments to the container configuration,
e.g. you might want to set
<varname>systemd.network.networks.$interface.dhcpConfig.ClientIdentifier</varname> to "mac"
<varname>systemd.network.networks.$interface.dhcpV4Config.ClientIdentifier</varname> to "mac"
if you use <varname>macvlans</varname> option.
This way dhcp client identifier will be stable between the container restarts.

Expand Down