baa794848a
- fix DUID calculation for virtual interfaces like pppoe-wan (#9503) - add a config option "duid" to allow users to override the DUID - use service_kill to cleanly terminate dhcp6c - bump package revision git-svn-id: svn://svn.openwrt.org/openwrt/packages@27140 3c298f89-4303-0410-b956-a3cf2f4a3e73
184 lines
4.0 KiB
Bash
184 lines
4.0 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
|
|
DHCP6C_REQUEST_OPTIONS='domain_name_servers domain_name ntp_servers sip_server_address sip_domain_name nis_server_address nis_domain_name nisp_server_address nisp_domain_name bcmcs_server_address bcmcs_domain_name'
|
|
|
|
get_ifname() {
|
|
local interface=$1
|
|
local ifname
|
|
scan_interfaces
|
|
config_get ifname "$interface" ifname
|
|
printf '%s\n' "$ifname"
|
|
return 0
|
|
}
|
|
|
|
get_device() {
|
|
local interface=$1
|
|
local ifname=$2
|
|
local device
|
|
scan_interfaces
|
|
config_get device "$interface" device
|
|
grep -qE "^ *$device:" /proc/net/dev && \
|
|
printf '%s\n' "$device" || \
|
|
printf '%s\n' "$ifname"
|
|
return 0
|
|
}
|
|
|
|
dhcp6c_write_duid() {
|
|
local mac="${1:-$(ifconfig "$client_device" | sed -ne 's/[[:space:]]*$//; s/.*HWaddr //p')}"
|
|
local pat="[0-9A-F][0-9A-F]"
|
|
|
|
case "$mac" in
|
|
$pat:$pat:$pat:$pat:$pat:$pat:$pat:$pat:$pat:$pat)
|
|
printf $(echo "$mac" | sed -e 's/^/\\x/; s/:/\\x/g')
|
|
logger -t dhcp6c "Using user provided DUID $mac"
|
|
;;
|
|
$pat:$pat:$pat:$pat:$pat:$pat)
|
|
local oIFS="$IFS"; IFS=":"; set -- $mac; IFS="$oIFS"
|
|
|
|
# low endian
|
|
if [ "$(printf \\1 | hexdump -n1 -ve '8/2 "%04x"')" = "0001" ]; then
|
|
printf \\x0a\\x00
|
|
|
|
# big endian
|
|
else
|
|
printf \\x00\\x0a
|
|
fi
|
|
|
|
printf \\x00\\x03\\x00\\x06\\x$1\\x$2\\x$3\\x$4\\x$5\\x$6
|
|
logger -t dhcp6c "Using MAC address DUID 00:03:00:06:$1:$2:$3:$4:$5:$6"
|
|
;;
|
|
*)
|
|
logger -t dhcp6c "Unable to derive DUID from interface '$client_device' and no valid user DUID given"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
dhcp6c_write_interface() {
|
|
local cfg=$1
|
|
local sla_id
|
|
local sla_len
|
|
local enabled
|
|
|
|
config_get_bool enabled "$cfg" enabled 0
|
|
|
|
if [ $enabled -ne 0 ]; then
|
|
|
|
config_get sla_id "$cfg" sla_id
|
|
config_get sla_len "$cfg" sla_len
|
|
|
|
printf '\tprefix-interface %s {\n' "$(get_ifname $cfg)"
|
|
printf '\t\tsla-id %s;\n' "$sla_id"
|
|
printf '\t\tsla-len %s;\n' "$sla_len"
|
|
printf '\t};\n'
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
dhcp6c_write_request() {
|
|
printf '\trequest %s;\n' $1 | sed -e s/_/-/g
|
|
}
|
|
|
|
dhcp6c_write_config() {
|
|
|
|
local pd
|
|
local na
|
|
config_get_bool pd basic pd 0
|
|
config_get_bool na basic na 0
|
|
|
|
printf 'interface %s {\n' "$client_ifname"
|
|
|
|
if [ $pd -ne 0 ]; then
|
|
printf '\tsend ia-pd 0;\n'
|
|
fi
|
|
|
|
if [ $na -ne 0 ]; then
|
|
printf '\tsend ia-na 0;\n'
|
|
fi
|
|
|
|
local rapid_commit
|
|
config_get_bool rapid_commit basic rapid_commit 0
|
|
[ $rapid_commit -ne 0 ] && printf '\tsend rapid-commit;\n'
|
|
|
|
local script
|
|
config_get script basic script
|
|
[ "$script" != "" ] && printf '\tscript "%s";\n' "$script"
|
|
|
|
local request
|
|
local value
|
|
for request in $DHCP6C_REQUEST_OPTIONS; do
|
|
config_get_bool value basic "$request" 0
|
|
[ $value -ne 0 ] && dhcp6c_write_request "$request"
|
|
done
|
|
|
|
printf '};\n\n'
|
|
|
|
if [ $pd -ne 0 ]; then
|
|
printf 'id-assoc pd 0 {\n'
|
|
config_foreach dhcp6c_write_interface interface
|
|
printf '};\n\n'
|
|
fi
|
|
|
|
if [ $na -ne 0 ]; then
|
|
printf 'id-assoc na 0 {\n'
|
|
printf '};\n\n'
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
start() {
|
|
|
|
[ ! -e /etc/dhcp6cctlkey ] && `dd if=/dev/urandom count=1 2> /dev/null | md5sum | cut -d" " -f1 > /etc/dhcp6cctlkey`
|
|
|
|
[ -e /var/run/dhcp6c.pid ] && return 0
|
|
|
|
include /lib/network
|
|
|
|
config_load "dhcp6c"
|
|
|
|
local enabled
|
|
config_get_bool enabled basic enabled 0
|
|
[ $enabled -eq 0 ] && return 0
|
|
|
|
local user_duid
|
|
config_get user_duid basic duid
|
|
|
|
logger -t dhcp6c starting dhcp6c
|
|
|
|
local client_interface
|
|
config_get client_interface basic interface
|
|
local client_ifname=$(get_ifname "$client_interface")
|
|
local client_device=$(get_device "$client_interface" "$client_ifname")
|
|
|
|
local config_file="/var/etc/dhcp6c.conf"
|
|
local duid_file="/var/dhcp6c_duid"
|
|
mkdir -m 755 -p /var/etc
|
|
dhcp6c_write_config > $config_file
|
|
dhcp6c_write_duid "$user_duid" > $duid_file
|
|
|
|
local debug
|
|
local debug_option
|
|
config_get_bool debug basic debug 0
|
|
[ $debug -eq 1 ] && debug_option="-D"
|
|
/usr/sbin/dhcp6c -c $config_file $debug_option $client_ifname
|
|
|
|
sleep 3
|
|
ACTION=start /sbin/hotplug-call dhcp6c
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
stop() {
|
|
|
|
logger -t dhcp6c stopping dhcp6c
|
|
service_kill dhcp6c /var/run/dhcp6c.pid
|
|
rm -f /var/etc/dhcp6c.conf /var/run/dhcp6c.pid
|
|
ACTION=stop /sbin/hotplug-call dhcp6c
|
|
return 0
|
|
|
|
}
|
|
|
|
|