2012-02-20 02:17:53 +01:00
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
with pkgs.lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
inherit (pkgs) dhcpcd;
|
|
|
|
|
|
|
|
# Don't start dhclient on explicitly configured interfaces or on
|
|
|
|
# interfaces that are part of a bridge.
|
|
|
|
ignoredInterfaces =
|
|
|
|
map (i: i.name) (filter (i: i ? ipAddress && i.ipAddress != "" ) config.networking.interfaces)
|
2012-05-08 13:46:01 +02:00
|
|
|
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
|
|
|
|
++ config.networking.dhcpcd.denyInterfaces;
|
2012-02-20 02:17:53 +01:00
|
|
|
|
2012-02-20 14:13:29 +01:00
|
|
|
# Config file adapted from the one that ships with dhcpcd.
|
|
|
|
dhcpcdConf = pkgs.writeText "dhcpcd.conf"
|
|
|
|
''
|
|
|
|
# Inform the DHCP server of our hostname for DDNS.
|
|
|
|
hostname
|
|
|
|
|
|
|
|
# A list of options to request from the DHCP server.
|
|
|
|
option domain_name_servers, domain_name, domain_search, host_name
|
|
|
|
option classless_static_routes, ntp_servers, interface_mtu
|
|
|
|
|
|
|
|
# A ServerID is required by RFC2131.
|
2012-12-05 22:52:24 +01:00
|
|
|
# Commented out because of many non-compliant DHCP servers in the wild :(
|
|
|
|
#require dhcp_server_identifier
|
2012-02-20 14:13:29 +01:00
|
|
|
|
|
|
|
# A hook script is provided to lookup the hostname if not set by
|
|
|
|
# the DHCP server, but it should not be run by default.
|
|
|
|
nohook lookup-hostname
|
|
|
|
|
|
|
|
# Ignore peth* devices; on Xen, they're renamed physical
|
|
|
|
# Ethernet cards used for bridging. Likewise for vif* and tap*
|
2012-04-30 19:46:11 +02:00
|
|
|
# (Xen) and virbr* and vnet* (libvirt).
|
|
|
|
denyinterfaces ${toString ignoredInterfaces} peth* vif* tap* tun* virbr* vnet* vboxnet*
|
2012-02-20 14:13:29 +01:00
|
|
|
'';
|
|
|
|
|
2012-02-20 16:19:46 +01:00
|
|
|
# Hook for emitting ip-up/ip-down events.
|
|
|
|
exitHook = pkgs.writeText "dhcpcd.exit-hook"
|
|
|
|
''
|
|
|
|
#exec >> /var/log/dhcpcd 2>&1
|
|
|
|
#set -x
|
2012-04-01 12:54:15 +02:00
|
|
|
|
|
|
|
params="IFACE=$interface REASON=$reason"
|
|
|
|
|
|
|
|
# only works when interface is wireless and wpa_supplicant has a control socket
|
|
|
|
# but we allow it to fail silently
|
2012-04-10 14:07:30 +02:00
|
|
|
${optionalString config.networking.wireless.enable ''
|
|
|
|
params+=" $(${pkgs.wpa_supplicant}/sbin/wpa_cli -i$interface status 2>/dev/null | grep ssid | sed 's|^b|B|;s|ssid|SSID|' | xargs)"
|
|
|
|
''}
|
2012-04-01 12:54:15 +02:00
|
|
|
|
2012-02-20 16:19:46 +01:00
|
|
|
if [ "$reason" = BOUND -o "$reason" = REBOOT ]; then
|
|
|
|
# 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.
|
|
|
|
${config.system.build.upstart}/sbin/initctl stop ntpd
|
|
|
|
|
2012-04-10 14:07:30 +02:00
|
|
|
${config.system.build.upstart}/sbin/initctl emit -n ip-up $params
|
2012-02-20 16:19:46 +01:00
|
|
|
fi
|
|
|
|
|
2012-04-05 10:20:43 +02:00
|
|
|
if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then
|
2012-04-10 14:07:30 +02:00
|
|
|
${config.system.build.upstart}/sbin/initctl emit -n ip-down $params
|
2012-02-20 16:19:46 +01:00
|
|
|
fi
|
|
|
|
'';
|
|
|
|
|
2012-02-20 02:17:53 +01:00
|
|
|
in
|
|
|
|
|
|
|
|
{
|
|
|
|
|
2012-05-08 13:46:01 +02:00
|
|
|
###### interface
|
|
|
|
|
|
|
|
options = {
|
|
|
|
|
|
|
|
networking.dhcpcd.denyInterfaces = mkOption {
|
|
|
|
default = [];
|
|
|
|
description = ''
|
|
|
|
Disable the DHCP client for any interface which's name matches
|
|
|
|
any of the shell glob patterns in this list. The purpose of
|
|
|
|
this option is blacklist virtual interfaces such as those
|
|
|
|
created by Xen, libvirt, LXC, etc.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-02-20 02:17:53 +01:00
|
|
|
###### implementation
|
|
|
|
|
|
|
|
config = mkIf config.networking.useDHCP {
|
|
|
|
|
|
|
|
jobs.dhcpcd =
|
|
|
|
{ startOn = "started network-interfaces";
|
|
|
|
|
|
|
|
path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
|
|
|
|
|
2012-03-23 22:00:32 +01:00
|
|
|
exec = "dhcpcd --config ${dhcpcdConf} --nobackground";
|
2012-02-20 02:17:53 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
environment.systemPackages = [ dhcpcd ];
|
|
|
|
|
2012-02-20 16:19:46 +01:00
|
|
|
environment.etc =
|
|
|
|
[ { source = exitHook;
|
|
|
|
target = "dhcpcd.exit-hook";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2012-02-20 02:17:53 +01:00
|
|
|
powerManagement.resumeCommands =
|
|
|
|
''
|
2012-03-23 22:00:32 +01:00
|
|
|
# Tell dhcpcd to rebind its interfaces if it's running.
|
|
|
|
status="$(${config.system.build.upstart}/sbin/status dhcpcd)"
|
|
|
|
[[ "$status" =~ start/running ]] && ${dhcpcd}/sbin/dhcpcd --rebind
|
2012-02-20 02:17:53 +01:00
|
|
|
'';
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|