# 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, ... }:
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
    '';
  */
}