Skip to content

Commit

Permalink
nixos/networkd: respect systemd.network.links also with disabled syst…
Browse files Browse the repository at this point in the history
…emd-networkd

This mirrors the behaviour of systemd - It's udev that parses `.link`
files, not `systemd-networkd`.
  • Loading branch information
flokli committed Mar 11, 2020
1 parent 1115959 commit 36ef112
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 31 deletions.
8 changes: 8 additions & 0 deletions nixos/doc/manual/release-notes/rl-2003.xml
Expand Up @@ -712,6 +712,14 @@ auth required pam_succeed_if.so uid >= 1000 quiet
For further reference, please read <link xlink:href="https://github.com/NixOS/nixpkgs/pull/68953">#68953</link> or the corresponding <link xlink:href="https://discourse.nixos.org/t/predictable-network-interface-names-in-initrd/4055">discourse thread</link>.
</para>
</listitem>
<listitem>
<para>
The <link linkend="opt-systemd.network.links">systemd.network.links</link> option is now respected
even when <link linkend="opt-systemd.network.enable">systemd-networkd</command> is disabled.
This mirrors the behaviour of systemd - It's udev that parses <literal>.link</literal> files,
not <command>systemd-networkd</command>.
</para>
</listitem>
</itemizedlist>
</section>
</section>
75 changes: 44 additions & 31 deletions nixos/modules/system/boot/networkd.nix
Expand Up @@ -355,6 +355,14 @@ let
};

linkOptions = commonNetworkOptions // {
# overwrite enable option from above
enable = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable this .link unit. It's handled by udev no matter if <command>systemd-networkd</command> is enabled or not
'';
};

linkConfig = mkOption {
default = {};
Expand Down Expand Up @@ -1045,44 +1053,49 @@ in

};

config = mkIf config.systemd.network.enable {
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;
environment.etc = unitFiles;
}

users.users.systemd-network.group = "systemd-network";
(mkIf config.systemd.network.enable {

systemd.additionalUpstreamSystemUnits = [
"systemd-networkd.service" "systemd-networkd-wait-online.service"
];
users.users.systemd-network.group = "systemd-network";

systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links
// mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
// mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;
systemd.additionalUpstreamSystemUnits = [
"systemd-networkd.service" "systemd-networkd-wait-online.service"
];

environment.etc = unitFiles;
systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs
// mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks;

systemd.services.systemd-networkd = {
wantedBy = [ "multi-user.target" ];
restartTriggers = attrNames unitFiles;
# prevent race condition with interface renaming (#39069)
requires = [ "systemd-udev-settle.service" ];
after = [ "systemd-udev-settle.service" ];
};
systemd.services.systemd-networkd = {
wantedBy = [ "multi-user.target" ];
restartTriggers = attrNames unitFiles;
# prevent race condition with interface renaming (#39069)
requires = [ "systemd-udev-settle.service" ];
after = [ "systemd-udev-settle.service" ];
};

systemd.services.systemd-networkd-wait-online = {
wantedBy = [ "network-online.target" ];
};
systemd.services.systemd-networkd-wait-online = {
wantedBy = [ "network-online.target" ];
};

systemd.services."systemd-network-wait-online@" = {
description = "Wait for Network Interface %I to be Configured";
conflicts = [ "shutdown.target" ];
requisite = [ "systemd-networkd.service" ];
after = [ "systemd-networkd.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
systemd.services."systemd-network-wait-online@" = {
description = "Wait for Network Interface %I to be Configured";
conflicts = [ "shutdown.target" ];
requisite = [ "systemd-networkd.service" ];
after = [ "systemd-networkd.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
};
};
};

services.resolved.enable = mkDefault true;
};
services.resolved.enable = mkDefault true;
})
];
}
25 changes: 25 additions & 0 deletions nixos/tests/networking.nix
Expand Up @@ -654,6 +654,31 @@ let
), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue)
'';
};
# even with disabled networkd, systemd.network.links should work
# (as it's handled by udev, not networkd)
link = {
name = "Link";
nodes.client = { pkgs, ... }: {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
useDHCP = false;
};
systemd.network.links."50-foo" = {
matchConfig = {
Name = "foo";
Driver = "dummy";
};
linkConfig.MTUBytes = "1442";
};
};
testScript = ''
print(client.succeed("ip l add name foo type dummy"))
print(client.succeed("stat /etc/systemd/network/50-foo.link"))
client.succeed("udevadm settle")
assert "mtu 1442" in client.succeed("ip l show dummy0")
'';
};
};

in pkgs.lib.mapAttrs (pkgs.lib.const (attrs: makeTest (attrs // {
Expand Down

0 comments on commit 36ef112

Please sign in to comment.