From 15d6eacb1564c7c6467f9a50a91426000593dc33 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Tue, 22 Dec 2020 10:49:19 +0100 Subject: [PATCH 1/6] nixos/{networkd,dhcpcd}: remove udev-settle hack systemd-udev-settle is a terrible hack[1] and should never[2] ever[3] used, seriously it's very bad. It was used as a stop-gap solution for issue #39069, but thanks to PR #79532 it can be removed now. [1]: https://github.com/systemd/systemd/issues/7293#issuecomment-592941764 [2]: https://github.com/NixOS/nixpkgs/issues/73095 [3]: https://github.com/NixOS/nixpkgs/issues/107341 --- nixos/modules/services/networking/dhcpcd.nix | 3 +-- nixos/modules/system/boot/networkd.nix | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index d10bffd9147..31e4b6ad298 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/nixos/modules/services/networking/dhcpcd.nix @@ -191,9 +191,8 @@ in { description = "DHCP Client"; wantedBy = [ "multi-user.target" ] ++ optional (!hasDefaultGatewaySet) "network-online.target"; - wants = [ "network.target" "systemd-udev-settle.service" ]; + wants = [ "network.target" ]; before = [ "network-online.target" ]; - after = [ "systemd-udev-settle.service" ]; restartTriggers = [ exitHook ]; diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index 3b01bc00baf..914d3e62eb4 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -1553,9 +1553,6 @@ in wantedBy = [ "multi-user.target" ]; aliases = [ "dbus-org.freedesktop.network1.service" ]; restartTriggers = map (x: x.source) (attrValues unitFiles); - # prevent race condition with interface renaming (#39069) - requires = [ "systemd-udev-settle.service" ]; - after = [ "systemd-udev-settle.service" ]; }; systemd.services.systemd-networkd-wait-online = { From 65325292da4b653fa5cae1dd8a0547015cfc0205 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Thu, 18 Feb 2021 18:03:00 +0100 Subject: [PATCH 2/6] nixos/stage-1: install networkd link files Renaming an interface must be done in stage-1: otherwise udev will report the interface as ready and network daemons (networkd, dhcpcd, etc.) will bring it up. Once up the interface can't be changed and the renaming will fail. Note: link files are read directly by udev, so they can be used even without networkd enabled. --- nixos/modules/system/boot/stage-1.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 44287f3cf09..4074f2e0235 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -205,13 +205,22 @@ let ''; # */ + # Networkd link files are used early by udev to set up interfaces early. + # This must be done in stage 1 to avoid race conditions between udev and + # network daemons. linkUnits = pkgs.runCommand "link-units" { allowedReferences = [ extraUtils ]; preferLocalBuild = true; - } '' + } ('' mkdir -p $out cp -v ${udev}/lib/systemd/network/*.link $out/ - ''; + '' + ( + let + links = filterAttrs (n: v: hasSuffix ".link" n) config.systemd.network.units; + files = mapAttrsToList (n: v: "${v.unit}/${n}") links; + in + concatMapStringsSep "\n" (file: "cp -v ${file} $out/") files + )); udevRules = pkgs.runCommand "udev-rules" { allowedReferences = [ extraUtils ]; From 8e59a682a5e937b4ad6f1246ca59196b8558446d Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Thu, 18 Feb 2021 19:14:00 +0100 Subject: [PATCH 3/6] nixos/udev: add option to install rules in initrd Note: this moves the example rule used to rename network interfaces in the new udev.initrdRules option, which is required since 115cdd1c. --- nixos/modules/services/hardware/udev.nix | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix index 63027f7744d..d48b5444677 100644 --- a/nixos/modules/services/hardware/udev.nix +++ b/nixos/modules/services/hardware/udev.nix @@ -202,12 +202,26 @@ in ''; }; - extraRules = mkOption { + initrdRules = mkOption { default = ""; example = '' SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:1D:60:B9:6D:4F", KERNEL=="eth*", NAME="my_fast_network_card" ''; type = types.lines; + description = '' + udev rules to include in the initrd + only. They'll be written into file + 99-local.rules. Thus they are read and applied + after the essential initrd rules. + ''; + }; + + extraRules = mkOption { + default = ""; + example = '' + ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="0825", ENV{PULSE_IGNORE}="1" + ''; + type = types.lines; description = '' Additional udev rules. They'll be written into file 99-local.rules. Thus they are @@ -284,6 +298,13 @@ in boot.kernelParams = mkIf (!config.networking.usePredictableInterfaceNames) [ "net.ifnames=0" ]; + boot.initrd.extraUdevRulesCommands = optionalString (cfg.initrdRules != "") + '' + cat <<'EOF' > $out/99-local.rules + ${cfg.initrdRules} + EOF + ''; + environment.etc = { "udev/rules.d".source = udevRules; From 7384c81e986d27aa08c451b21b6508c1ecf767a2 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Thu, 18 Feb 2021 18:12:48 +0100 Subject: [PATCH 4/6] nixos/tests/networking: test interface renaming --- nixos/tests/networking.nix | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index 4fc5d48e0e1..62e9c2f62ad 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -672,6 +672,30 @@ let ), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue) ''; }; + rename = { + name = "RenameInterface"; + machine = { pkgs, ... }: { + virtualisation.vlans = [ 1 ]; + networking = { + useNetworkd = networkd; + useDHCP = false; + }; + } // + (if networkd + then { systemd.network.links."10-custom_name" = { + matchConfig.MACAddress = "52:54:00:12:01:01"; + linkConfig.Name = "custom_name"; + }; + } + else { services.udev.initrdRules = '' + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="custom_name" + ''; + }); + testScript = '' + machine.succeed("udevadm settle") + print(machine.succeed("ip link show dev custom_name")) + ''; + }; # even with disabled networkd, systemd.network.links should work # (as it's handled by udev, not networkd) link = { From aafaf3ba97c2b7a370d865f98bcb316ea5a044aa Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Fri, 19 Feb 2021 00:55:43 +0100 Subject: [PATCH 5/6] nixos/docs: add section on renaming interfaces --- nixos/doc/manual/configuration/networking.xml | 1 + .../configuration/renaming-interfaces.xml | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 nixos/doc/manual/configuration/renaming-interfaces.xml diff --git a/nixos/doc/manual/configuration/networking.xml b/nixos/doc/manual/configuration/networking.xml index 02cf811e0bd..8369e9c9c85 100644 --- a/nixos/doc/manual/configuration/networking.xml +++ b/nixos/doc/manual/configuration/networking.xml @@ -15,5 +15,6 @@ + diff --git a/nixos/doc/manual/configuration/renaming-interfaces.xml b/nixos/doc/manual/configuration/renaming-interfaces.xml new file mode 100644 index 00000000000..d760bb3a4da --- /dev/null +++ b/nixos/doc/manual/configuration/renaming-interfaces.xml @@ -0,0 +1,67 @@ +
+ Renaming network interfaces + + + NixOS uses the udev + predictable naming scheme + to assign names to network interfaces. This means that by default + cards are not given the traditional names like + eth0 or eth1, whose order can + change unpredictably across reboots. Instead, relying on physical + locations and firmware information, the scheme produces names like + ens1, enp2s0, etc. + + + + These names are predictable but less memorable and not necessarily + stable: for example installing new hardware or changing firmware + settings can result in a + name change. + If this is undesirable, for example if you have a single ethernet + card, you can revert to the traditional scheme by setting + to + false. + + +
+ Assigning custom names + + In case there are multiple interfaces of the same type, it’s better to + assign custom names based on the device hardware address. For + example, we assign the name wan to the interface + with MAC address 52:54:00:12:01:01 using a + netword link unit: + + + systemd.network.links."10-wan" = { + matchConfig.MACAddress = "52:54:00:12:01:01"; + linkConfig.Name = "wan"; + }; + + + Note that links are directly read by udev, not networkd, + and will work even if networkd is disabled. + + + Alternatively, we can use a plain old udev rule: + + + services.udev.initrdRules = '' + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \ + ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="wan" + ''; + + + + The rule must be installed in the initrd using + services.udev.initrdRules, not the usual + services.udev.extraRules option. This is to avoid race + conditions with other programs controlling the interface. + +
+ +
From d683d26d899c9c3011cf651d7e5ade072d4c800d Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Fri, 19 Feb 2021 00:59:16 +0100 Subject: [PATCH 6/6] nixos/release-notes: warn on interface renaming --- nixos/doc/manual/release-notes/rl-2105.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nixos/doc/manual/release-notes/rl-2105.xml b/nixos/doc/manual/release-notes/rl-2105.xml index 6dd14d6051e..ff2ce2a2163 100644 --- a/nixos/doc/manual/release-notes/rl-2105.xml +++ b/nixos/doc/manual/release-notes/rl-2105.xml @@ -91,6 +91,16 @@ + + + If you are using to assign + custom names to network interfaces, this may stop working due to a change + in the initialisation of dhcpcd and systemd networkd. To avoid this, either + move them to or see the new + Assigning custom names section + of the NixOS manual for an example using networkd links. + + systemd-journal2gelf no longer parses json and expects the receiving system to handle it. How to achieve this with Graylog is described in this GitHub issue.