# Use predictable interface names in stage-1 and stage-2.
# DOC: https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
#
# Tip: names that can be given using ID_NET_NAME_* envvars
# can be checked before hand with:
# udevadm test-builtin net_id /sys/class/net/*
{ pkgs, lib, config, ... }:
let
  udevNetSetupLinkRules = pkgs.writeTextDir "etc/udev/rules.d/79-net-setup-link.rules" ''
    SUBSYSTEM!="net", GOTO="net_setup_link_end"

    IMPORT{builtin}="path_id"

    ACTION!="add", GOTO="net_setup_link_end"

    # Load net_setup_link to setup the ID_NET_NAME_* envvars
    IMPORT{builtin}="net_setup_link"

    # Rename eth* using the "path" name policy (eg. enp1s0),
    # Note that in stage-1 the envvar ID_NET_NAME is not set,
    # hence not usable as in ''${pkgs.systemd}/lib/udev/rules.d/80-net-setup-link.rules
    # Because in stage-1 there is no /etc/systemd/network/*.link
    # nor **/systemd/network/99-default.link
    # to set NamePolicy= which is responsible to set ID_NET_NAME.
    # Not sure if ATTR{type}=="1" and KERNEL=="eth*" are equivalent or not.
    ATTR{type}=="1", KERNEL=="eth*", NAME="$env{ID_NET_NAME_PATH}"

    LABEL="net_setup_link_end"
  '';
in
{
networking = {
  # Currently no-op.
  # false would set boot.kernelParams = [ "net.ifnames=0" ];
  # to disable NamePolicy= in *.link.
  usePredictableInterfaceNames = true;
};

boot.initrd = {
  extraUdevRulesCommands = ''
    # The name set here in stage-1 by 79-net-setup-link.rules
    # will stay in stage-2 (at least until the device is removed/added).
    cp -v ${udevNetSetupLinkRules}/etc/udev/rules.d/79-net-setup-link.rules $out/
  '';
};

services.udev.packages = [
  # Only useful here in stage-2 if the device is removed and re-added
  # (eg. the network module is rmmod-ed then modprobe-d).
  # The stage-1 (or initrd) is only a pivot_root after all,
  # it does not reload the kernel, hence passing to stage-2
  # does not trigger ACTION=="add" for the net devices.
  udevNetSetupLinkRules
];

/* Useless block, only here for explanations.

# NixOS put this .link only in the root filesystem, not in the initrd
# hence it's only active in stage-2, not stage-1.
# And even in stage-2, the 80-net-setup-link.rules has priority.
# DOC: https://www.freedesktop.org/software/systemd/man/systemd.link.html
environment.etc."systemd/network/79-net-setup.link".text = ''
  [Match]
  OriginalName=*

  [Link]
  #NamePolicy=keep kernel database onboard slot path
  NamePolicy=mac
  MACAddressPolicy=persistent
'';
*/
}