Merge pull request #167327 from lheckemann/networkd-usedhcp

nixos/networkd: reimplement useDHCP in a sensible way
main
Maximilian Bosch 2 years ago committed by GitHub
commit f0bb39d4b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
  2. 7
      nixos/doc/manual/release-notes/rl-2205.section.md
  3. 12
      nixos/modules/installer/tools/nixos-generate-config.pl
  4. 1
      nixos/modules/system/boot/networkd.nix
  5. 42
      nixos/modules/tasks/network-interfaces-systemd.nix
  6. 5
      nixos/modules/tasks/network-interfaces.nix
  7. 20
      nixos/tests/networking.nix

@ -2471,6 +2471,21 @@
hosts.
</para>
</listitem>
<listitem>
<para>
The option
<link xlink:href="options.html#opt-networking.useDHCP">networking.useDHCP</link>
isn’t deprecated anymore. When using
<link xlink:href="options.html#opt-networking.useNetworkd"><literal>systemd-networkd</literal></link>,
a generic <literal>.network</literal>-unit is added which
enables DHCP for each interface matching
<literal>en*</literal>, <literal>eth*</literal> or
<literal>wl*</literal> with priority 99 (which means that it
doesn’t have any effect if such an interface is matched by a
<literal>.network-</literal>unit with a lower priority). In
case of scripted networking, no behavior was changed.
</para>
</listitem>
</itemizedlist>
</section>
</section>

@ -877,4 +877,11 @@ In addition to numerous new and upgraded packages, this release has the followin
`true` starting with NixOS 22.11. Enable it explicitly if you need to control
Snapserver remotely or connect streamig clients from other hosts.
- The option [networking.useDHCP](options.html#opt-networking.useDHCP) isn't deprecated anymore.
When using [`systemd-networkd`](options.html#opt-networking.useNetworkd), a generic
`.network`-unit is added which enables DHCP for each interface matching `en*`, `eth*`
or `wl*` with priority 99 (which means that it doesn't have any effect if such an interface is matched
by a `.network-`unit with a lower priority). In case of scripted networking, no behavior
was changed.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

@ -581,17 +581,19 @@ ${\join "", (map { " $_\n" } (uniq @attrs))}}
EOF
sub generateNetworkingDhcpConfig {
# FIXME disable networking.useDHCP by default when switching to networkd.
my $config = <<EOF;
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = lib.mkDefault false;
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
EOF
foreach my $path (glob "/sys/class/net/*") {
my $dev = basename($path);
if ($dev ne "lo") {
$config .= " networking.interfaces.$dev.useDHCP = lib.mkDefault true;\n";
$config .= " # networking.interfaces.$dev.useDHCP = lib.mkDefault true;\n";
}
}

@ -779,6 +779,7 @@ let
"RouteDenyList"
"RouteAllowList"
"DHCPv6Client"
"RouteMetric"
])
(assertValueOneOf "UseDNS" boolValues)
(assertValueOneOf "UseDomains" (boolValues ++ ["route"]))

@ -43,12 +43,6 @@ in
} {
assertion = cfg.defaultGateway6 == null || cfg.defaultGateway6.interface == null;
message = "networking.defaultGateway6.interface is not supported by networkd.";
} {
assertion = cfg.useDHCP == false;
message = ''
networking.useDHCP is not supported by networkd.
Please use per interface configuration and set the global option to false.
'';
} ] ++ flip mapAttrsToList cfg.bridges (n: { rstp, ... }: {
assertion = !rstp;
message = "networking.bridges.${n}.rstp is not supported by networkd.";
@ -80,6 +74,42 @@ in
in mkMerge [ {
enable = true;
}
(mkIf cfg.useDHCP {
networks."99-ethernet-default-dhcp" = lib.mkIf cfg.useDHCP {
# We want to match physical ethernet interfaces as commonly
# found on laptops, desktops and servers, to provide an
# "out-of-the-box" setup that works for common cases. This
# heuristic isn't perfect (it could match interfaces with
# custom names that _happen_ to start with en or eth), but
# should be good enough to make the common case easy and can
# be overridden on a case-by-case basis using
# higher-priority networks or by disabling useDHCP.
# Type=ether matches veth interfaces as well, and this is
# more likely to result in interfaces being configured to
# use DHCP when they shouldn't.
# We set RequiredForOnline to false, because it's fairly
# common for such devices to have multiple interfaces and
# only one of them to be connected (e.g. a laptop with
# ethernet and WiFi interfaces). Maybe one day networkd will
# support "any"-style RequiredForOnline...
matchConfig.Name = ["en*" "eth*"];
DHCP = "yes";
linkConfig.RequiredForOnline = lib.mkDefault false;
};
networks."99-wireless-client-dhcp" = lib.mkIf cfg.useDHCP {
# Like above, but this is much more likely to be correct.
matchConfig.WLANInterfaceType = "station";
DHCP = "yes";
linkConfig.RequiredForOnline = lib.mkDefault false;
# We also set the route metric to one more than the default
# of 1024, so that Ethernet is preferred if both are
# available.
dhcpV4Config.RouteMetric = 1025;
ipv6AcceptRAConfig.RouteMetric = 1025;
};
})
(mkMerge (forEach interfaces (i: {
netdevs = mkIf i.virtual ({
"40-${i.name}" = {

@ -1254,11 +1254,6 @@ in
Whether to use DHCP to obtain an IP address and other
configuration for all network interfaces that are not manually
configured.
Using this option is highly discouraged and also incompatible with
<option>networking.useNetworkd</option>. Please use
<option>networking.interfaces.&lt;name&gt;.useDHCP</option> instead
and set this to false.
'';
};

@ -139,6 +139,26 @@ let
client.wait_until_succeeds("ping -c 1 192.168.3.1")
'';
};
dhcpDefault = {
name = "useDHCP-by-default";
nodes.router = router;
nodes.client = { lib, ... }: {
# Disable test driver default config
networking.interfaces = lib.mkForce {};
networking.useNetworkd = networkd;
virtualisation.vlans = [ 1 ];
};
testScript = ''
start_all()
client.wait_for_unit("multi-user.target")
client.wait_until_succeeds("ip addr show dev eth1 | grep '192.168.1'")
client.shell_interact()
client.succeed("ping -c 1 192.168.1.1")
router.succeed("ping -c 1 192.168.1.1")
router.succeed("ping -c 1 192.168.1.2")
client.succeed("ping -c 1 192.168.1.2")
'';
};
dhcpSimple = {
name = "SimpleDHCP";
nodes.router = router;

Loading…
Cancel
Save