From 4237ae4890c0466b4424792f120c708e0d57feac Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 5 Apr 2017 13:21:54 +0200 Subject: [PATCH] isc-dhcp: integrate IPv4 DHCP service with procd and netifd Convert init-script to procd and allow to configure isc-dhcp-server via UCI. Allow most by-network and by-host options supported by dnsmasq. User-defined dhcp-options are not supported yet, neither are tags. Existing configurations with use-edited /etc/dhcpd.conf are still respected, hence to enjoy the new features you have to migrate your configuration to UCI and delete /etc/dhcpd.conf. Signed-off-by: Daniel Golle --- net/isc-dhcp/Makefile | 5 +- net/isc-dhcp/files/dhcpd.conf | 13 -- net/isc-dhcp/files/dhcpd.defaults | 11 ++ net/isc-dhcp/files/dhcpd.init | 265 ++++++++++++++++++++++++++++-- 4 files changed, 262 insertions(+), 32 deletions(-) delete mode 100644 net/isc-dhcp/files/dhcpd.conf create mode 100644 net/isc-dhcp/files/dhcpd.defaults diff --git a/net/isc-dhcp/Makefile b/net/isc-dhcp/Makefile index e3eeb93b49..48e63da16c 100644 --- a/net/isc-dhcp/Makefile +++ b/net/isc-dhcp/Makefile @@ -200,11 +200,10 @@ define Package/isc-dhcp-relay-$(BUILD_VARIANT)/install endef define Package/isc-dhcp-server-$(BUILD_VARIANT)/install - $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc - $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/uci-defaults $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dhcpd $(1)/usr/sbin $(INSTALL_BIN) ./files/dhcpd.init $(1)/etc/init.d/dhcpd - $(INSTALL_BIN) ./files/dhcpd.conf $(1)/etc + $(INSTALL_BIN) ./files/dhcpd.defaults $(1)/etc/uci-defaults ifeq ($(BUILD_VARIANT),ipv6) $(INSTALL_BIN) ./files/dhcpd6.init $(1)/etc/init.d/dhcpd6 $(INSTALL_BIN) ./files/dhcpd6.conf $(1)/etc diff --git a/net/isc-dhcp/files/dhcpd.conf b/net/isc-dhcp/files/dhcpd.conf deleted file mode 100644 index 11985ce9e8..0000000000 --- a/net/isc-dhcp/files/dhcpd.conf +++ /dev/null @@ -1,13 +0,0 @@ -# dhcpd.conf - -authoritative; - -default-lease-time 3600; -max-lease-time 86400; - -option domain-name-servers 192.168.1.1; - -subnet 192.168.1.0 netmask 255.255.255.0 { - range 192.168.1.10 192.168.1.50; - option routers 192.168.1.1; -} diff --git a/net/isc-dhcp/files/dhcpd.defaults b/net/isc-dhcp/files/dhcpd.defaults new file mode 100644 index 0000000000..bd6f3d2b13 --- /dev/null +++ b/net/isc-dhcp/files/dhcpd.defaults @@ -0,0 +1,11 @@ +#!/bin/sh +uci -q get dhcp.isc_dhcpcd && exit 0 +touch /etc/config/dhcp + +uci batch <> 16) % 65536)) \ + $(( 0x$hex % 65536)) + )" + + return 0 } -stop() { - if [ ! -e $pid_file ]; then - return 1 +static_host_add() { + local cfg="$1" + local broadcast hostid macn macs mac name ip leasetime + + config_get macs "$cfg" "mac" + [ -n "$macs" ] || return 0 + config_get name "$cfg" "name" + [ -n "$name" ] || return 0 + config_get ip "$cfg" "ip" + [ -n "$ip" ] || return 0 + + config_get_bool broadcast "$cfg" "broadcast" 0 + config_get dns "$cfg" "dns" + config_get gateway "$cfg" "gateway" + config_get leasetime "$cfg" "leasetime" + if [ -n "$leasetime" ] ; then + leasetime="$(time2seconds "$leasetime")" + [ "$?" -ne 0 ] && return 1 + fi + + config_get hostid "$cfg" "hostid" + if [ -n "$hostid" ] ; then + hex_to_hostid hostid "$hostid" || return 1 fi - kill -9 `cat $pid_file` + macn=0 + for mac in $macs; do + macn=$(( macn + 1 )) + done - if [ $? -ne 0 ]; then - return 1 + for mac in $macs; do + local secname="$name" + if [ $macn -gt 1 ] ; then + secname="${name}-${mac//:}" + fi + echo "host $secname {" + echo " hardware ethernet $mac;" + echo " fixed-address $ip;" + echo " option host-name \"$name\";" + if [ "$broadcast" -eq 1 ] ; then + echo " always-broadcast true;" + fi + if [ -n "$leasetime" ] ; then + echo " default-lease-time $leasetime;" + echo " max-lease-time $leasetime;" + fi + if [ -n "$hostid" ] ; then + echo " option dhcp-client-identifier $hostid;" + fi + if [ -n "$dns" ] ; then + echo " option domain-name-servers $dns;" + fi + if [ -n "$gateway" ] ; then + echo " option routers $gateway;" + fi + echo "}" + done +} + +static_hosts() { + config_foreach static_host_add host "$@" +} + +gen_dhcp_subnet() { + echo "subnet $NETWORK netmask $NETMASK {" + echo " range $START $END;" + echo " option subnet-mask $netmask;" + if [ "$BROADCAST" != "0.0.0.0" ] ; then + echo " option broadcast-address $BROADCAST;" + fi + if [ "$dynamicdhcp" -eq 0 ] ; then + if [ "$authoritative" -eq 1 ] ; then + echo " deny unknown-clients;" + else + echo " ignore unknown-clients;" + fi fi + if [ -n "$leasetime" ] ; then + echo " default-lease-time $leasetime;" + echo " max-lease-time $leasetime;" + fi + echo " option routers $gateway;" + echo " option domain-name-servers $DNS;" + echo "}" +} + +dhcpd_add() { + local cfg="$1" + local dhcp6range="::" + local dynamicdhcp end gateway ifname ignore leasetime limit net netmask + local proto networkid start subnet + local IP NETMASK BROADCAST NETWORK PREFIX DNS START END + + config_get_bool ignore "$cfg" "ignore" 0 + [ "$ignore" = "0" ] || return 0 + + config_get net "$cfg" "interface" + [ -n "$net" ] || return 0 + + config_get start "$cfg" "start" + [ -n "$start" ] || return 0 + + config_get limit "$cfg" "limit" + [ -n "$limit" ] || return 0 + + network_get_subnet subnet "$net" || return 0 + network_get_device ifname "$net" || return 0 + network_get_protocol proto "$net" || return 0 + + [ static = "$proto" ] || return 0 + + config_get_bool dynamicdhcp "$cfg" "dynamicdhcp" 1 + + dhcp_ifs="$dhcp_ifs $ifname" + + eval "$(ipcalc.sh $subnet $start $limit)" + + config_get netmask "$cfg" "netmask" "$NETMASK" + config_get leasetime "$cfg" "leasetime" + if [ -n "$leasetime" ] ; then + leasetime="$(time2seconds "$leasetime")" + [ "$?" -ne 0 ] && return 1 + fi + + if network_get_dnsserver dnsserver "$net" ; then + for dnsserv in $dnsserver ; do + DNS="$DNS${DNS:+, }$dnsserv" + done + else + DNS="$IP" + fi + + if ! network_get_gateway gateway "$net" ; then + gateway="$IP" + fi + + gen_dhcp_subnet >> $config_file +} + +general_config() { + local always_broadcast boot_unknown_clients log_facility + local default_lease_time max_lease_time + config_get_bool always_broadcast "isc_dhcpd" "always_broadcast" 0 + config_get_bool authoritative "isc_dhcpd" "authoritative" 1 + config_get_bool boot_unknown_clients "isc_dhcpd" "boot_unknown_clients" 1 + config_get default_lease_time "isc_dhcpd" "default_lease_time" 3600 + config_get max_lease_time "isc_dhcpd" "max_lease_time" 86400 + config_get log_facility "isc_dhcpd" "log_facility" + + [ $always_broadcast -eq 1 ] && echo "always-broadcast true;" + [ $authoritative -eq 1 ] && echo "authoritative;" + [ $boot_unknown_clients -eq 0 ] && echo "boot-unknown-clients false;" + + default_lease_time="$(time2seconds "$default_lease_time")" + [ "$?" -ne 0 ] && return 1 + max_lease_time="$(time2seconds "$max_lease_time")" + [ "$?" -ne 0 ] && return 1 + + if [ -n "$log_facility" ] ; then + echo "log-facility $log_facility;" + fi + echo "default-lease-time $default_lease_time;" + echo "max-lease-time $max_lease_time;" +} + +start_service() { + if [ -n "$DHCPD_BOOT" ] ; then + return 0 + fi + + if [ ! -e $lease_file ] ; then + touch $lease_file + fi + + dhcp_ifs="" + + if [ -e "/etc/dhcpd.conf" ] ; then + config_file="/etc/dhcpd.conf" + else + . /lib/functions/network.sh + + config_load dhcp + local authoritative + general_config > $config_file + + config_foreach dhcpd_add dhcp + + static_hosts >> $config_file + + [ -z "$dhcp_ifs" ] && return 0 + fi + + procd_open_instance + procd_set_param command $PROG -q -f -cf $config_file -lf $lease_file $dhcp_ifs + procd_close_instance +} + +boot() { + DHCPD_BOOT=1 + start "$@" +} - rm $pid_file +service_triggers() +{ + procd_add_reload_trigger "dhcp" + procd_add_raw_trigger "interface.*" 3000 /etc/init.d/dhcpd reload } -- 2.30.2