nixos/network-interfaces-systemd: fix DHCP setting

The networkd backend logic for setting DHCP= on an interface is bugged
and inconsistent with the scripted logic. Consider this simple NixOS
configuration:

    {
      networking.useNetworkd = true;
      networking.interfaces.eth0.wakeOnLan.enable = true;
    }

The default value of networking.useDHCP is true, so we expect our eth0
interface to have DHCP enabled. With the scripted backend, this works.
But the networkd backend generates the following 40-eth0.network file:

    [Match]
    Name=eth0

    [Network]
    DHCP=no
    IPv6PrivacyExtensions=kernel

This is happening because the wakeOnLan configuration creates a key in
networking.interfaces, and the networkd backend erroneously checks that
instead of for explicitly configured IP addresses as in the scripted
backend. The documentation is also inconsistent across various options.

This change aligns the networkd backend and option documentation to the
actual behavior of the scripted backend, and updates a test to account
for this behavior for both backends.
This commit is contained in:
Majiir Paktu 2023-10-07 12:40:42 -04:00
parent af4598273b
commit c4228b6c8f
3 changed files with 14 additions and 10 deletions

View file

@ -92,7 +92,7 @@ let
networks."40-${i.name}" = mkMerge [ (genericNetwork id) {
name = mkDefault i.name;
DHCP = mkForce (dhcpStr
(if i.useDHCP != null then i.useDHCP else false));
(if i.useDHCP != null then i.useDHCP else (config.networking.useDHCP && i.ipv4.addresses == [ ])));
address = forEach (interfaceIps i)
(ip: "${ip.address}/${toString ip.prefixLength}");
routes = forEach (interfaceRoutes i)

View file

@ -190,9 +190,11 @@ let
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
Whether this interface should be configured with dhcp.
Null implies the old behavior which depends on whether ip addresses
are specified or not.
Whether this interface should be configured with DHCP. Overrides the
default set by {option}`networking.useDHCP`. If `null` (the default),
DHCP is enabled if the interface has no IPv4 addresses configured
with {option}`networking.interfaces.<name>.ipv4.addresses`, and
disabled otherwise.
'';
};
@ -640,9 +642,7 @@ in
} ];
};
description = lib.mdDoc ''
The configuration for each network interface. If
{option}`networking.useDHCP` is true, then every
interface not listed here will be configured using DHCP.
The configuration for each network interface.
Please note that {option}`systemd.network.netdevs` has more features
and is better maintained. When building new things, it is advised to
@ -1304,8 +1304,8 @@ in
default = true;
description = lib.mdDoc ''
Whether to use DHCP to obtain an IP address and other
configuration for all network interfaces that are not manually
configured.
configuration for all network interfaces that do not have any manually
configured IPv4 addresses.
'';
};

View file

@ -185,7 +185,11 @@ let
nodes.router = router;
nodes.client = { lib, ... }: {
# Disable test driver default config
networking.interfaces = lib.mkForce {};
networking.interfaces = lib.mkForce {
# Make sure DHCP defaults correctly even when some unrelated config
# is set on the interface (nothing, in this case).
enp1s0 = {};
};
networking.useNetworkd = networkd;
virtualisation.interfaces.enp1s0.vlan = 1;
};