2009-10-12 17:27:57 +00:00
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
with pkgs.lib;
|
2007-02-22 14:26:53 +00:00
|
|
|
|
2008-11-08 21:32:48 +00:00
|
|
|
let
|
|
|
|
|
|
|
|
inherit (pkgs) nettools dhcp lib;
|
2007-02-22 14:26:53 +00:00
|
|
|
|
2011-03-15 15:13:48 +00:00
|
|
|
# Don't start dhclient on explicitly configured interfaces or on
|
|
|
|
# interfaces that are part of a bridge.
|
2010-01-22 20:34:32 +00:00
|
|
|
ignoredInterfaces =
|
2011-03-15 15:13:48 +00:00
|
|
|
map (i: i.name) (lib.filter (i: i ? ipAddress && i.ipAddress != "" ) config.networking.interfaces)
|
|
|
|
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges));
|
2007-02-22 14:26:53 +00:00
|
|
|
|
2007-03-20 11:04:45 +00:00
|
|
|
stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant.
|
2009-05-27 23:30:29 +00:00
|
|
|
|
|
|
|
dhclientExitHooks = pkgs.writeText "dhclient-exit-hooks"
|
|
|
|
''
|
2010-08-05 13:32:58 +00:00
|
|
|
#echo "$reason" >> /tmp/dhcp-exit
|
|
|
|
#echo "$exit_status" >> /tmp/dhcp-exit
|
2009-05-27 23:30:29 +00:00
|
|
|
|
|
|
|
if test "$reason" = BOUND -o "$reason" = REBOOT; then
|
|
|
|
${pkgs.glibc}/sbin/nscd --invalidate hosts
|
2009-06-02 19:42:31 +00:00
|
|
|
|
|
|
|
# Restart ntpd. (The "ip-up" event below will trigger the
|
|
|
|
# restart.) 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.
|
2009-11-06 09:36:35 +00:00
|
|
|
${config.system.build.upstart}/sbin/initctl stop ntpd
|
2009-06-02 19:42:31 +00:00
|
|
|
|
2009-11-06 21:38:40 +00:00
|
|
|
${config.system.build.upstart}/sbin/initctl emit -n ip-up
|
2009-05-27 23:30:29 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
if test "$reason" = EXPIRE -o "$reason" = RELEASE; then
|
2009-11-06 21:38:40 +00:00
|
|
|
${config.system.build.upstart}/sbin/initctl emit -n ip-down
|
2009-05-27 23:30:29 +00:00
|
|
|
fi
|
|
|
|
'';
|
|
|
|
|
2007-02-22 14:26:53 +00:00
|
|
|
in
|
2006-11-19 22:05:49 +00:00
|
|
|
|
|
|
|
{
|
2008-11-08 21:32:48 +00:00
|
|
|
|
2009-07-15 11:19:11 +00:00
|
|
|
###### interface
|
2007-08-14 16:43:56 +00:00
|
|
|
|
2009-07-15 11:19:11 +00:00
|
|
|
options = {
|
|
|
|
|
|
|
|
networking.useDHCP = mkOption {
|
|
|
|
default = true;
|
|
|
|
merge = mergeEnableOption;
|
|
|
|
description = "
|
|
|
|
Whether to use DHCP to obtain an IP adress and other
|
|
|
|
configuration for all network interfaces that are not manually
|
|
|
|
configured.
|
|
|
|
";
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
2006-11-19 22:05:49 +00:00
|
|
|
|
|
|
|
|
2009-07-15 11:19:11 +00:00
|
|
|
###### implementation
|
|
|
|
|
|
|
|
config = mkIf config.networking.useDHCP {
|
2007-02-20 14:20:33 +00:00
|
|
|
|
2009-10-12 18:09:34 +00:00
|
|
|
jobs.dhclient =
|
2009-11-06 22:19:17 +00:00
|
|
|
{ startOn = "started network-interfaces";
|
|
|
|
stopOn = "stopping network-interfaces";
|
2006-11-24 16:31:01 +00:00
|
|
|
|
2009-07-24 00:31:22 +00:00
|
|
|
preStart =
|
|
|
|
''
|
|
|
|
# dhclient barfs if /proc/net/if_inet6 doesn't exist.
|
|
|
|
${config.system.sbin.modprobe}/sbin/modprobe ipv6 || true
|
|
|
|
'';
|
2006-11-24 16:38:22 +00:00
|
|
|
|
2009-07-24 00:31:22 +00:00
|
|
|
script =
|
|
|
|
''
|
2009-07-15 11:19:11 +00:00
|
|
|
# Determine the interface on which to start dhclient.
|
|
|
|
interfaces=
|
2009-05-27 23:30:29 +00:00
|
|
|
|
2009-07-15 11:19:11 +00:00
|
|
|
for i in $(cd /sys/class/net && ls -d *); do
|
2010-01-22 20:34:32 +00:00
|
|
|
# Only run dhclient on interfaces of type ARPHRD_ETHER
|
2010-09-14 11:17:48 +00:00
|
|
|
# (1), i.e. Ethernet. Ignore peth* devices; on Xen,
|
|
|
|
# they're renamed physical Ethernet cards used for
|
2011-03-15 15:30:12 +00:00
|
|
|
# bridging. Likewise for vif* and tap* (Xen) and
|
|
|
|
# virbr* and vnet* (libvirt).
|
2010-09-14 11:17:48 +00:00
|
|
|
if [ "$(cat /sys/class/net/$i/type)" = 1 ]; then
|
|
|
|
if ! for j in ${toString ignoredInterfaces}; do echo $j; done | grep -F -x -q "$i" &&
|
2011-03-15 15:30:12 +00:00
|
|
|
! echo "$i" | grep -x -q "peth.*\|vif.*\|tap.*\|virbr.*\|vnet.*";
|
2010-09-14 11:17:48 +00:00
|
|
|
then
|
2010-01-22 20:34:32 +00:00
|
|
|
echo "Running dhclient on $i"
|
|
|
|
interfaces="$interfaces $i"
|
|
|
|
fi
|
2009-07-15 11:19:11 +00:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
if test -z "$interfaces"; then
|
|
|
|
echo 'No interfaces on which to start dhclient!'
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
mkdir -m 755 -p ${stateDir}
|
|
|
|
|
2009-07-24 00:31:22 +00:00
|
|
|
exec ${dhcp}/sbin/dhclient -d $interfaces -e "PATH=$PATH" -lf ${stateDir}/dhclient.leases -sf ${dhcp}/sbin/dhclient-script
|
|
|
|
'';
|
|
|
|
};
|
2009-07-15 11:19:11 +00:00
|
|
|
|
|
|
|
environment.systemPackages = [dhcp];
|
|
|
|
|
|
|
|
environment.etc =
|
|
|
|
[ # Dhclient hooks for emitting ip-up/ip-down events.
|
|
|
|
{ source = dhclientExitHooks;
|
|
|
|
target = "dhclient-exit-hooks";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2009-11-15 20:40:41 +00:00
|
|
|
powerManagement.resumeCommands =
|
|
|
|
''
|
|
|
|
export PATH=${config.system.build.upstart}/sbin:$PATH
|
2010-12-23 11:00:20 +00:00
|
|
|
initctl restart wpa_supplicant
|
|
|
|
initctl restart dhclient
|
2009-11-15 20:40:41 +00:00
|
|
|
'';
|
|
|
|
|
2009-07-15 11:19:11 +00:00
|
|
|
};
|
2009-05-27 23:30:29 +00:00
|
|
|
|
2006-11-19 22:05:49 +00:00
|
|
|
}
|
2008-11-08 21:32:48 +00:00
|
|
|
|