dotfiles/system/modules/router/dhcpcd.nix

70 lines
2.8 KiB
Nix
Raw Normal View History

2023-06-20 15:11:01 +07:00
{ lib
, config
, pkgs
, utils
, ... }:
let
cfg = config.router;
exitHook = pkgs.writeText "dhcpcd.exit-hook" ''
if [ "$reason" = BOUND -o "$reason" = REBOOT ]; then
# Restart ntpd. We need to restart it to make sure that it
# will actually do something: if ntpd cannot resolve the
# server hostnames in its config file, then it will never do
# anything ever again ("couldn't resolve ..., giving up on
# it"), so we silently lose time synchronisation. This also
# applies to openntpd.
/run/current-system/systemd/bin/systemctl try-reload-or-restart ntpd.service openntpd.service chronyd.service || true
fi
'';
in {
config = lib.mkIf (cfg.enable && builtins.any (x: x.dhcpcd.enable) (builtins.attrValues cfg.interfaces)) {
users.users.dhcpcd = {
isSystemUser = true;
group = "dhcpcd";
};
users.groups.dhcpcd = {};
environment.systemPackages = [ pkgs.dhcpcd ];
environment.etc."dhcpcd.exit-hook".source = exitHook;
powerManagement.resumeCommands = builtins.concatStringsSep "\n" (lib.mapAttrsToList (interface: icfg: ''
# Tell dhcpcd to rebind its interfaces if it's running.
/run/current-system/systemd/bin/systemctl reload "dhcpcd-${utils.escapeSystemdPath interface}.service"
''));
systemd.services = lib.mapAttrs' (interface: icfg: let
escapedInterface = utils.escapeSystemdPath interface;
dhcpcdConf = pkgs.writeText "dhcpcd.conf" ''
hostname
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes, ntp_servers, interface_mtu
nohook lookup-hostname
denyinterfaces ve-* vb-* lo peth* vif* tap* tun* virbr* vnet* vboxnet* sit*
allowinterfaces ${interface}
waitip
${icfg.dhcpcd.extraConfig}
'';
in {
name = "dhcpcd-${escapedInterface}";
value = lib.mkIf icfg.dhcpcd.enable {
description = "DHCP Client";
wantedBy = [ "multi-user.target" "network-online.target" ];
wants = [ "network.target" ];
before = [ "network-online.target" ];
after = [ "sys-subsystem-net-devices-${escapedInterface}.device" ];
bindsTo = [ "sys-subsystem-net-devices-${escapedInterface}.device" ];
restartTriggers = [ exitHook ];
stopIfChanged = false;
path = [ pkgs.dhcpcd pkgs.nettools config.networking.resolvconf.package ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
serviceConfig = {
Type = "forking";
PIDFile = "/run/dhcpcd/${interface}.pid";
RuntimeDirectory = "dhcpcd";
ExecStart = "@${pkgs.dhcpcd}/sbin/dhcpcd dhcpcd --quiet --config ${dhcpcdConf} ${lib.escapeShellArg interface}";
ExecReload = "${pkgs.dhcpcd}/sbin/dhcpcd --rebind";
Restart = "always";
};
};
}) cfg.interfaces;
};
}