70 lines
2.8 KiB
Nix
70 lines
2.8 KiB
Nix
|
{ 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;
|
||
|
};
|
||
|
}
|