Marius Tomaschewski
348f524f0a
reorder config to add all global options or option declarations to the dhcpService object instead to create new service object (bsc#886094,ISC-Bugs#37876). [+ dhcp-4.2.x-contrib-conf-to-ldap-reorder.886094.patch] - Applied an upstream patch by Thomas Markwalder adding missed mapping of SHA TSIG algorithm names to their constants to enable hmac-sha1, hmac_sha224, hmac_sha256, hmac_sha384 and hmac_sha512 authenticated dynamic DNS updates (bsc#890731, ISC-Bugs#36947). [+ dhcp-4.2.x-ddns-tsig-hmac-sha-support.890731.patch] - Decline IPv6 addresses on Duplicate Address Detection failure and stop client message exchanges on reached MRD rather than at some point after it. Applied fedora patches by Jiri Popelka and added DAD reporting via exit 3 to the dhclient-script and a fix to use correct address variables in the DEPREF6 action (bsc#872609,ISC-Bugs#26735,ISC-Bugs#21238). [+ dhcp-4.2.x-dhcpv6-decline-on-DAD-failure.872609.patch, + dhcp-4.2.x-dhcpv6-retransmission-until-MRD.872609.patch] - Applied backport patch by William Preston avoiding to bind ddns socket in the server when ddns-update-style is none (bsc#891655). [+ dhcp-4.2.x-disable-unused-ddns-port-in-server.891655.patch] - Applied patch for the contrib/ldap/dhcpd-conf-to-ldap script fixing subclass statement handling (bnc#878846,[ISC-Bugs #36409]) [+ dhcp-4.2.4-P2-bnc878846-conf-to-ldap.patch] - Updated licence statement and FSF address in our scripts. - Added missed service_add_pre macro calls for dhcrelay services OBS-URL: https://build.opensuse.org/package/show/network:dhcp/dhcp?expand=0&rev=141
746 lines
23 KiB
Bash
746 lines
23 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Copyright (C) 2010-2013 SUSE LINUX Products GmbH / Novell Inc.
|
|
# Copyright (C) 2013-2014 SUSE LINUX GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# Author: Marius Tomaschewski <mt@suse.de>
|
|
#
|
|
# /sbin/dhclient-script for openSUSE / SUSE Linux Enterprise Server
|
|
# based on the scripts shipped with the ISC DHCP (4.1.1) client.
|
|
#
|
|
# Note:
|
|
# It is used by sysconfig alias netcontrol alias ifup-dhcp,
|
|
# but not by the NetworkManager that is using an own script.
|
|
#
|
|
# Wicked is using an another dhcp client (runtime conflict).
|
|
# As sysconfig-network is gone on sles12 and opensuse > 13.1,
|
|
# this script is obsolete and unsupported.
|
|
#
|
|
|
|
##
|
|
## check mandatory parameters or ignore & exit
|
|
##
|
|
test "x$reason" = x -o "x$interface" = x && exit 1
|
|
|
|
#
|
|
# source sysconfig functions
|
|
#
|
|
SYSCONFIG_CFG_DIR="/etc/sysconfig/network"
|
|
if test -f "$SYSCONFIG_CFG_DIR/scripts/functions" ; then
|
|
. "$SYSCONFIG_CFG_DIR/scripts/functions"
|
|
fi
|
|
SYSCONFIG_RUN_DIR=${SYSCONFIG_RUN_DIR:-/dev/.sysconfig/network}
|
|
|
|
#
|
|
# Debugging:
|
|
# logs entire run of dhclient-script to /var/log/${dhclient}-script.*.log,
|
|
# when DHCLIENT_DEBUG/DHCLIENT6_DEBUG are "yes" in sysconfig/network/dhcp
|
|
#
|
|
eval `grep '^DHCLIENT6\?_DEBUG=' "$SYSCONFIG_CFG_DIR/dhcp" 2>/dev/null`
|
|
case $reason in
|
|
*6) DEBUG=$DHCLIENT6_DEBUG ; dhclient=dhclient6 ; ipver=6 ;;
|
|
*) DEBUG=$DHCLIENT_DEBUG ; dhclient=dhclient ; ipver=4 ;;
|
|
esac
|
|
if [ "$DEBUG" = yes ]; then
|
|
set -a # allexport
|
|
(
|
|
echo '****************'
|
|
echo "$0 $*"
|
|
date
|
|
echo '----------------'
|
|
env
|
|
echo '----------------'
|
|
) >> /var/log/${dhclient}-script.$interface.log
|
|
exec 2>> /var/log/${dhclient}-script.$interface.log
|
|
set +a
|
|
set -x
|
|
fi
|
|
|
|
network_service_conflicts()
|
|
{
|
|
local _id=`/usr/bin/systemctl --no-pager -p Id show network.service 2>/dev/null`
|
|
case "${_id#Id=}" in
|
|
# wicked is using an another dhcp client
|
|
wicked.service) return 1 ;;
|
|
|
|
# NetworkManager is using another script
|
|
#NetworkManager.service) return 1 ;;
|
|
|
|
# sysconfig network were using it, other?
|
|
network.service|*) return 0 ;;
|
|
esac
|
|
}
|
|
|
|
network_service_conflicts || exit 1
|
|
|
|
is_ifup_controlled()
|
|
{
|
|
test -f "$SYSCONFIG_RUN_DIR/if-${interface}"
|
|
}
|
|
# netconfig makes all "additional" modifications as DNS or NTP
|
|
netconfig_modify() {
|
|
if test -x /sbin/netconfig -a -n "$interface" ; then
|
|
{
|
|
echo "INTERFACE='$interface'"
|
|
for v in ${!new_*}; do
|
|
case $ipver in
|
|
6)
|
|
case $v in
|
|
(new_ip6_address) k='IPADDR' ;;
|
|
(new_ip6_prefixlen) k='PREFIXLEN' ;;
|
|
(new_dhcp6_client_id) k='DHCP6CID' ;;
|
|
(new_dhcp6_server_id) k='DHCP6SID' ;;
|
|
(new_dhcp6_domain_search) k='DNSSEARCH' ;;
|
|
(new_dhcp6_name_servers) k='DNSSERVERS' ;;
|
|
(new_dhcp6_sntp_servers) k='NTPSERVERS' ;;
|
|
#(new_dhcp6_nis_domain) k='NISDOMAIN' ;;
|
|
#(new_dhcp6_nis_servers) k='NISSERVERS' ;;
|
|
(*) k="dhclient6_${v#new_}" ;;
|
|
esac
|
|
;;
|
|
4)
|
|
case $v in
|
|
(new_ip_address) k='IPADDR' ;;
|
|
(new_subnet_mask) k='NETMASK' ;;
|
|
(new_network_number) k='NETWORK' ;;
|
|
(new_broadcast_address) k='BROADCAST' ;;
|
|
(new_interface_mtu) k='MTU' ;;
|
|
(new_rfc3442_classless_static_routes_formatted)
|
|
k='ROUTES' ;;
|
|
# (new_static_routes) k='ROUTES' ;;
|
|
(new_routers) k='GATEWAYS' ;;
|
|
(new_host_name) k='HOSTNAME' ;;
|
|
(new_domain_search) k='DNSSEARCH' ;;
|
|
(new_domain_name) k='DNSDOMAIN' ;;
|
|
(new_domain_name_servers) k='DNSSERVERS' ;;
|
|
(new_ntp_servers) k='NTPSERVERS' ;;
|
|
(new_nis_domain) k='NISDOMAIN' ;;
|
|
(new_nis_servers) k='NISSERVERS' ;;
|
|
(new_root_path) k='ROOTPATH' ;;
|
|
(new_dhcp_server_identifier)k='DHCPSID' ;;
|
|
(new_lpr_servers) k='LPRSERVER' ;;
|
|
(new_log_servers) k='LOGSERVER' ;;
|
|
(new_netbios_dd_server) k='NETBIOSDDSERVER' ;;
|
|
(new_netbios_name_servers) k='NETBIOSNAMESERVER' ;;
|
|
(new_netbios_node_type) k='NETBIOSNODETYPE' ;;
|
|
(new_netbios_scope) k='NETBIOSSCOPE' ;;
|
|
(*) k="dhclient_${v#new_}" ;;
|
|
esac
|
|
esac
|
|
[ "k${k}" != k ] && echo "${k}='${!v}'"
|
|
done
|
|
} | /sbin/netconfig modify -s "dhclient$ipver" -i "$interface"
|
|
fi
|
|
}
|
|
netconfig_remove() {
|
|
if test -x /sbin/netconfig -a -n "$interface" ; then
|
|
/sbin/netconfig remove -s "dhclient$ipver" -i "$interface" </dev/null
|
|
fi
|
|
}
|
|
prefixlen2netmask()
|
|
{
|
|
test -n "$1" || return 1
|
|
local o i n=0 adr=() len=$(($1))
|
|
for o in 0 1 2 3; do
|
|
adr[$o]=0
|
|
for i in 128 64 32 16 8 4 2 1; do
|
|
((n++ < len)) && \
|
|
((adr[$o] = ${adr[$o]} + $i))
|
|
done
|
|
done
|
|
echo ${adr[0]}.${adr[1]}.${adr[2]}.${adr[3]}
|
|
return 0
|
|
}
|
|
parse_ipv4_classless_routes()
|
|
{
|
|
local route_regex='^[0-9]{1,3}([ ][0-9]{1,3}){4,}$'
|
|
local rfc_routes=() _routes=()
|
|
|
|
# check whether it is a list of numbers
|
|
[[ $* =~ $route_regex ]] && rfc_routes=($*)
|
|
|
|
for (( i=0; i < ${#rfc_routes[@]}; )) ; do
|
|
net_length=${rfc_routes[$i]}
|
|
test $net_length -gt 32 && return 1
|
|
|
|
((i++))
|
|
net_octets=$(($net_length / 8 + ($net_length % 8 ? 1 : 0)))
|
|
test ${#rfc_routes[@]} -lt $(( $i + $net_octets + 4 )) && \
|
|
return 1
|
|
|
|
net_netmask=$(prefixlen2netmask $net_length)
|
|
net_netmask=(${net_netmask//./ })
|
|
net_address=(0 0 0 0)
|
|
for(( j=0; j < $net_octets; j++, i++)); do
|
|
net_address[$j]=$((${rfc_routes[$i]} & ${net_netmask[$j]}))
|
|
done
|
|
|
|
gateway=(0 0 0 0)
|
|
for (( j=0; j < 4; j++, i++ )); do
|
|
gateway[$j]=${rfc_routes[$i]}
|
|
done
|
|
|
|
old_IFS=$IFS
|
|
IFS='.'
|
|
_routes+=("${net_address[*]},${net_netmask[*]},${gateway[*]}")
|
|
IFS=$old_IFS
|
|
done
|
|
|
|
echo "${_routes[*]}"
|
|
return 0
|
|
}
|
|
set_ipv4_route()
|
|
{
|
|
local dest=$1 ; shift
|
|
local mask=$1 ; shift
|
|
local gate=("$@")
|
|
local hops args
|
|
|
|
hops=()
|
|
if [ ${#gate[@]} -gt 1 ] ; then
|
|
for((g=0; g<${#gate[@]}; g++)) ; do
|
|
hops+=(nexthop ${gate[$g]:+via ${gate[$g]}}
|
|
dev $interface weight $((g+1)))
|
|
done
|
|
elif [ ${#gate[@]} -gt 0 ] ; then
|
|
hops+=(${gate[$g]:+via ${gate[$g]}} dev $interface)
|
|
fi
|
|
[ ${#hops[@]} -eq 0 ] && hops=(dev $interface)
|
|
args=("$dest${mask:+/$mask}" $metric_arg ${hops[*]})
|
|
|
|
err=`LC_ALL=C /sbin/ip route replace ${args[*]} 2>&1` && return 0
|
|
case $err in
|
|
RTNETLINK*answers:*File*exists) ;;
|
|
RTNETLINK*answers:*No*such*process)
|
|
#
|
|
# The gateway seems to be not reachable via local network
|
|
# route (implicitly created by ifconfig based on the IP
|
|
# and netmask provided by dhcp).
|
|
# Check this, set an explicit host route to the gateway
|
|
# over the current interface and try again (bnc#266215).
|
|
#
|
|
retry=0
|
|
for router in ${gate[@]} ; do
|
|
matches=$(/sbin/ip -f inet -o route list match $router | \
|
|
grep -v ^default | grep -c -v "^$" 2>/dev/null)
|
|
if [ -n "$matches" -a $(($matches)) -eq 0 ] ; then
|
|
LC_ALL=C /sbin/ip route add $router/32 dev $interface || retry=1
|
|
fi
|
|
done
|
|
if [ $retry -eq 0 ] ; then
|
|
LC_ALL=C /sbin/ip route replace ${args[*]} && return 0
|
|
fi
|
|
;;
|
|
esac
|
|
return 1
|
|
}
|
|
get_ipv4_default_gw()
|
|
{
|
|
if [ "x$new_rfc3442_classless_static_routes_formatted" != x ] ; then
|
|
local r route=() gw=()
|
|
for r in $new_rfc3442_classless_static_routes_formatted ; do
|
|
route=(${r//,/ })
|
|
case ${route[0]}/${route[1]} in
|
|
0.0.0.0/0.0.0.0)
|
|
[ "x${route[2]}" = "x0.0.0.0" ] || \
|
|
gw+=(${route[2]})
|
|
;;
|
|
esac
|
|
done
|
|
echo "${gw[*]}"
|
|
elif [ "$new_routers" != x ] ; then
|
|
echo "$new_routers"
|
|
fi
|
|
}
|
|
set_ipv4_routes()
|
|
{
|
|
if [ "x$new_rfc3442_classless_static_routes_formatted" != x ] ; then
|
|
local r route=()
|
|
# TODO: multiple gw's to one dest as in $new_routers?
|
|
for r in $new_rfc3442_classless_static_routes_formatted ; do
|
|
route=(${r//,/ })
|
|
case ${route[0]}/${route[1]} in
|
|
0.0.0.0/0.0.0.0)
|
|
[ "x$DHCLIENT_SET_DEFAULT_ROUTE" = xyes ] || continue ;;
|
|
esac
|
|
set_ipv4_route ${route[*]}
|
|
done
|
|
elif [ "$new_routers" != x ] ; then
|
|
if [ "x$DHCLIENT_SET_DEFAULT_ROUTE" = xyes ] ; then
|
|
set_ipv4_route default "" $new_routers
|
|
fi
|
|
fi
|
|
}
|
|
set_hostname()
|
|
{
|
|
rx_host='^[[:alnum:]][[:alnum:]_-]{0,62}$'
|
|
if [ "$DHCLIENT_SET_HOSTNAME" = yes ] ; then
|
|
new_host_name="${new_host_name%%.*}"
|
|
[[ ${new_host_name} =~ ${rx_host} ]] || unset new_host_name
|
|
current_hostname=`hostname`
|
|
current_hostname="${current_hostname%%.*}"
|
|
[[ ${current_hostname} =~ ${rx_host} ]] || unset current_hostname
|
|
|
|
if [ "x${current_hostname}" = "x" ] || \
|
|
[ "x${current_hostname}" = "xlocalhost" ] || \
|
|
[ "x${current_hostname}" != "x${new_host_name}" ]; then
|
|
if [ "x${new_host_name}" != "x" ]; then
|
|
hostname "${new_host_name}"
|
|
else
|
|
if [ -x /usr/bin/host ] ; then
|
|
if out=`host -W 2 "$new_ip_address" 2>/dev/null` ; then
|
|
_hostname="`echo "$out" | sed 's:^.* ::; s:\..*::; s:.*[)]::'`"
|
|
[[ ${_hostname} =~ ${rx_host} ]] || unset _hostname
|
|
if [ "x${_hostname}" != "x" -a \
|
|
"x${_hostname}" != "x${current_hostname}" ]; then
|
|
hostname "${_hostname}"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
if is_ifup_controlled ; then
|
|
# check regardless the DHCLIENT_SET_HOSTNAME setting
|
|
# and whether we've set it above or not, because when
|
|
# it changed, we've to handle it anyway...
|
|
local OLD_HOSTNAME=`read_cached_config_data hostname $interface`
|
|
local CUR_HOSTNAME=`hostname 2>/dev/null`
|
|
CUR_HOSTNAME="${CUR_HOSTNAME%%.*}"
|
|
if [[ ${CUR_HOSTNAME} =~ ${rx_host} ]] && \
|
|
[ "x$OLD_HOSTNAME" != "x$CUR_HOSTNAME" ] ; then
|
|
write_cached_config_data hostname "$CUR_HOSTNAME" $interface
|
|
commit_cached_config_data $interface
|
|
|
|
# reload syslog so it knows the new hostname
|
|
if test -x /usr/bin/systemctl ; then
|
|
/usr/bin/systemctl reload syslog.service
|
|
else
|
|
/etc/init.d/syslog reload
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
dhcp6_dad_check()
|
|
{
|
|
local ifname="$1" word i
|
|
local ipaddr="$2"
|
|
local noaddr=1 nodad=0 tentative=0 dadfailed=0
|
|
test -n "$ifname" -a -n "$ipaddr" || return 1
|
|
|
|
while read -a word ; do
|
|
test "${word[0]}" != "inet6" && continue
|
|
noaddr=0
|
|
for((i=2; i<${#word[@]}; ++i)) ; do
|
|
case ${word[$i]} in
|
|
nodad) nodad=1 ;;
|
|
tentative) tentative=1 ;;
|
|
dadfailed) dadfailed=1 ;;
|
|
flags) ((i++))
|
|
rx='^[[:xdigit:]]+$'
|
|
[[ "${word[$i]}" =~ $rx ]] || continue
|
|
hx="0x${word[$i]}"
|
|
((hx & 0x02)) && nodad=1
|
|
((hx & 0x08)) && dadfailed=1
|
|
((hx & 0x40)) && tentative=1
|
|
;;
|
|
esac
|
|
done
|
|
((nodad)) && continue
|
|
((dadfailed)) && return 3
|
|
((tentative)) && return 2
|
|
done < <(LC_ALL=C ip -6 addr show dev "${ifname}" to "${ipaddr}" 2>/dev/null)
|
|
# on dad failure of dynamic (non-persistent) address,
|
|
# the kernel deletes dad failed addresses
|
|
# that is, the address is tentative (2) and vanishes
|
|
# (4) and is not visible as dadfailed (3).
|
|
((noaddr)) && return 4 || return 0
|
|
}
|
|
dhcp6_dad_wait()
|
|
{
|
|
local ifname="$1"
|
|
local ipaddr="$2"
|
|
local -i wsecs=${3:-0}
|
|
local -i uwait=25000
|
|
local -i loops=$(((wsecs * 1000000) / uwait))
|
|
local -i loop=0 ret=0
|
|
|
|
dhcp6_dad_check "$ifname" "$ipaddr" ; ret=$?
|
|
while ((ret == 2 && loop++ < loops)) ; do
|
|
usleep $uwait
|
|
dhcp6_dad_check "$ifname" "$ipaddr" ; ret=$?
|
|
done
|
|
return $ret
|
|
}
|
|
|
|
# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
|
|
exit_with_hooks() {
|
|
exit_status=$1
|
|
if [ -f /etc/${dhclient}-exit-hooks ]; then
|
|
. /etc/${dhclient}-exit-hooks
|
|
fi
|
|
# probably should do something with exit status of the local script
|
|
exit $exit_status
|
|
}
|
|
|
|
# Invoke the local dhcp client enter hooks, if they exist.
|
|
if [ -f /etc/${dhclient}-enter-hooks ]; then
|
|
exit_status=0
|
|
. /etc/${dhclient}-enter-hooks
|
|
# allow the local script to abort processing of this state
|
|
# local script must set exit_status variable to nonzero.
|
|
if [ $exit_status -ne 0 ]; then
|
|
exit $exit_status
|
|
fi
|
|
fi
|
|
|
|
case $dhclient in
|
|
dhclient)
|
|
if is_ifup_controlled ; then
|
|
# STARTMODE
|
|
eval `grep --no-filename \
|
|
'^[[:space:]]*STARTMODE=' \
|
|
"$SYSCONFIG_CFG_DIR/ifcfg-${interface}" 2>/dev/null`
|
|
tmp_startmode=`read_cached_config_data startmode $INTERFACE`
|
|
[ -n "$tmp_startmode" ] && STARTMODE="$tmp_startmode"
|
|
|
|
# DHCLIENT_SET_HOSTNAME and DHCLIENT_SET_DEFAULT_ROUTE
|
|
if grep -qs '^primary=yes' "$SYSCONFIG_RUN_DIR/if-${interface}" 2>/dev/null ;
|
|
then
|
|
eval `grep --no-filename \
|
|
'^[[:space:]]*DHCLIENT_SET_\(HOSTNAME\|DEFAULT_ROUTE\)=' \
|
|
"$SYSCONFIG_CFG_DIR/dhcp" \
|
|
"$SYSCONFIG_CFG_DIR/ifcfg-${interface}" 2>/dev/null`
|
|
else
|
|
eval `grep --no-filename \
|
|
'^[[:space:]]*DHCLIENT_SET_\(HOSTNAME\|DEFAULT_ROUTE\)=' \
|
|
"$SYSCONFIG_CFG_DIR/ifcfg-${interface}" 2>/dev/null`
|
|
fi
|
|
else
|
|
STARTMODE=manual
|
|
eval `grep --no-filename \
|
|
'^[[:space:]]*DHCLIENT_SET_\(HOSTNAME\|DEFAULT_ROUTE\)=' \
|
|
"$SYSCONFIG_CFG_DIR/dhcp" 2>/dev/null`
|
|
fi
|
|
if [ "x$new_rfc3442_classless_static_routes" != x ] ; then
|
|
new_rfc3442_classless_static_routes_formatted=$(
|
|
parse_ipv4_classless_routes $new_rfc3442_classless_static_routes
|
|
)
|
|
else
|
|
unset new_rfc3442_classless_static_routes_formatted
|
|
fi
|
|
if [ x$new_broadcast_address != x ] ; then
|
|
new_broadcast_arg="brd $new_broadcast_address"
|
|
elif [ "x$new_subnet_mask" != "x255.255.255.255" ] ; then
|
|
new_broadcast_arg="brd +"
|
|
fi
|
|
if [ x$new_interface_mtu != x -a \
|
|
$(( $new_interface_mtu )) -le 576 ] ;
|
|
then
|
|
# 68 is the minimal legal value, but 576 the real life minimum
|
|
unset new_interface_mtu
|
|
fi
|
|
if [ x$IF_METRIC != x ]; then
|
|
metric_arg="metric $IF_METRIC"
|
|
fi
|
|
;;
|
|
dhclient6)
|
|
if is_ifup_controlled ; then
|
|
# STARTMODE
|
|
eval `grep --no-filename \
|
|
'^[[:space:]]*STARTMODE=' \
|
|
"$SYSCONFIG_CFG_DIR/ifcfg-${interface}" 2>/dev/null`
|
|
tmp_startmode=`read_cached_config_data startmode $INTERFACE`
|
|
[ -n "$tmp_startmode" ] && STARTMODE="$tmp_startmode"
|
|
else
|
|
STARTMODE=manual
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
case $reason in
|
|
######################################################################
|
|
## DHCPv4 #
|
|
######################################################################
|
|
|
|
MEDIUM)
|
|
####################################################################
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
PREINIT)
|
|
####################################################################
|
|
if [ "x$alias_ip_address" != x ]; then
|
|
/sbin/ip addr del $alias_ip_address/$alias_subnet_mask dev $interface
|
|
fi
|
|
if [ "x$STARTMODE" != "xnfsroot" ] ; then
|
|
/sbin/ip -4 addr flush dev $interface
|
|
fi
|
|
/sbin/ip link set $interface up
|
|
|
|
# We need to give the kernel some time to get the interface up.
|
|
sleep 1
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
ARPCHECK|ARPSEND)
|
|
####################################################################
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
BOUND|RENEW|REBIND|REBOOT)
|
|
####################################################################
|
|
|
|
if [ x$alias_ip_address != x -a x$alias_ip_address != x$old_ip_address -a \
|
|
x$new_ip_address != x$old_ip_address ] ;
|
|
then
|
|
# Possible new alias. Remove old alias.
|
|
/sbin/ip addr del $alias_ip_address/$alias_subnet_mask dev $interface
|
|
fi
|
|
if [ x$old_ip_address != x -a x$old_ip_address != x$new_ip_address ]; then
|
|
# IP address changed. Flush to clear routes and ARP cache.
|
|
if [ "x$STARTMODE" != "xnfsroot" ] ; then
|
|
/sbin/ip -4 addr flush dev $interface
|
|
fi
|
|
fi
|
|
|
|
if [ x$new_interface_mtu != x ] ; then
|
|
/sbin/ip link set $interface mtu $new_interface_mtu
|
|
fi
|
|
if [ x$new_ip_address != x ] && \
|
|
[ x$new_ip_address != x$old_ip_address -o \
|
|
x$reason = xBOUND -o x$reason = xREBOOT ]; then
|
|
|
|
/sbin/ip addr add $new_ip_address/${new_subnet_mask:-32} \
|
|
${new_broadcast_arg} \
|
|
dev $interface
|
|
|
|
set_ipv4_routes
|
|
fi
|
|
if [ x$new_ip_address != x$alias_ip_address -a x$alias_ip_address != x \
|
|
-a x$new_ip_address != x$old_ip_address ];
|
|
then
|
|
/sbin/ip addr add $alias_ip_address/$alias_subnet_mask \
|
|
dev $interface
|
|
fi
|
|
|
|
netconfig_modify
|
|
|
|
if [ x$old_ip_address != x -a x$old_ip_address != x$new_ip_address ]; then
|
|
if is_ifup_controlled ; then
|
|
ifdown $interface -o dhcp
|
|
|
|
write_cached_config_data dhcp4_state "up" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
else
|
|
if is_ifup_controlled ; then
|
|
write_cached_config_data dhcp4_state "new" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
fi
|
|
|
|
set_hostname
|
|
|
|
if is_ifup_controlled ; then
|
|
# execute ifservice and if-up.d scripts
|
|
ifup $interface -o dhcp
|
|
|
|
write_cached_config_data dhcp4_state "complete" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
EXPIRE|FAIL|RELEASE|STOP)
|
|
####################################################################
|
|
if [ x$old_ip_address != x ]; then
|
|
if [ "x$STARTMODE" != "xnfsroot" ] ; then
|
|
/sbin/ip -4 addr flush dev $interface
|
|
fi
|
|
fi
|
|
if [ x$alias_ip_address != x ]; then
|
|
/sbin/ip addr add $alias_ip_address/$alias_subnet_mask \
|
|
dev $interface
|
|
fi
|
|
|
|
if is_ifup_controlled ; then
|
|
write_cached_config_data dhcp4_state "down" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
netconfig_remove
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
TIMEOUT)
|
|
####################################################################
|
|
if [ x$alias_ip_address != x ]; then
|
|
/sbin/ip addr del $alias_ip_address/$alias_subnet_mask \
|
|
dev $interface
|
|
fi
|
|
|
|
if [ x$new_ip_address != x -a x$old_ip_address != x$new_ip_address ];
|
|
then
|
|
/sbin/ip addr add $new_ip_address/${new_subnet_mask:-32} \
|
|
${new_broadcast_arg} \
|
|
dev $interface
|
|
|
|
set -- $(get_ipv4_default_gw)
|
|
if [ -n "$1" ] && /sbin/arping -q -c 1 -w 5 -I $interface $1 ;
|
|
then
|
|
if [ x$new_ip_address != x$alias_ip_address ] && \
|
|
[ x$alias_ip_address != x ]; then
|
|
/sbin/ip addr add $alias_ip_address/$alias_subnet_arg
|
|
fi
|
|
|
|
set_ipv4_routes
|
|
|
|
netconfig_modify
|
|
|
|
set_hostname
|
|
if is_ifup_controlled ; then
|
|
# execute ifservice and if-up.d scripts
|
|
ifup $interface -o dhcp
|
|
|
|
write_cached_config_data dhcp4_state "complete" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
|
|
exit_with_hooks 0
|
|
else
|
|
if [ x$old_ip_address != x ]; then
|
|
if [ "x$STARTMODE" != "xnfsroot" ] ; then
|
|
/sbin/ip -4 addr flush dev $interface
|
|
fi
|
|
fi
|
|
|
|
if is_ifup_controlled ; then
|
|
write_cached_config_data dhcp4_state "down" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
netconfig_remove
|
|
|
|
exit_with_hooks 1
|
|
fi
|
|
fi
|
|
;;
|
|
|
|
|
|
######################################################################
|
|
## DHCPv6 #
|
|
######################################################################
|
|
|
|
PREINIT6)
|
|
####################################################################
|
|
if [ "x$STARTMODE" != "xnfsroot" ] ; then
|
|
/sbin/ip -6 addr flush dev $interface scope global permanent
|
|
fi
|
|
/sbin/ip link set $interface up
|
|
|
|
# We need to give the kernel some time to get the interface up.
|
|
sleep 1
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
BOUND6|RENEW6|REBIND6|REBOOT6)
|
|
####################################################################
|
|
|
|
if [ x$old_ip6_address != x -a x$old_ip6_address != x$new_ip6_address ];
|
|
then
|
|
|
|
/sbin/ip addr del "$old_ip6_address/$old_ip6_prefixlen" dev $interface
|
|
|
|
if is_ifup_controlled ; then
|
|
write_cached_config_data dhcp6_state "up" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
else
|
|
if is_ifup_controlled ; then
|
|
write_cached_config_data dhcp6_state "new" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
fi
|
|
|
|
if [ "x$new_ip6_address" != x -a "x$new_ip6_prefixlen" != x ] ; then
|
|
/sbin/ip addr replace "$new_ip6_address/$new_ip6_prefixlen" \
|
|
scope global dev $interface \
|
|
${new_max_life:+valid_lft $new_max_life} \
|
|
${new_preferred_life:+preferred_lft $new_preferred_life} \
|
|
|| exit_with_hooks 2
|
|
|
|
echo >&2 "Checking DAD results for $new_ip6_address"
|
|
|
|
if ! dhcp6_dad_wait "$interface" "$new_ip6_address/$new_ip6_prefixlen" 5 ; then
|
|
/sbin/ip addr del "$new_ip6_address/$new_ip6_prefixlen" dev $interface 2>/dev/null
|
|
exit_with_hooks 3
|
|
fi
|
|
fi
|
|
|
|
netconfig_modify
|
|
if [ x$old_ip6_address != x -a x$old_ip6_address != x$new_ip6_address ];
|
|
then
|
|
if is_ifup_controlled ; then
|
|
/sbin/ifdown $interface -o dhcp
|
|
fi
|
|
fi
|
|
|
|
#set_hostname
|
|
if is_ifup_controlled ; then
|
|
# execute ifservice and if-up.d scripts
|
|
/sbin/ifup $interface -o dhcp
|
|
|
|
write_cached_config_data dhcp6_state "complete" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
DEPREF6)
|
|
####################################################################
|
|
if [ x$cur_ip6_address = x -o x$cur_ip6_prefixlen = x ] ; then
|
|
exit_with_hooks 2
|
|
fi
|
|
|
|
/sbin/ip addr change "$cur_ip6_address/$cur_ip6_prefixlen" \
|
|
dev $interface scope global preferred_lft 0
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
|
|
EXPIRE6|RELEASE6|STOP6)
|
|
####################################################################
|
|
if [ x$old_ip6_address != x -a x$old_ip6_prefixlen != x ] ; then
|
|
/sbin/ip addr del "$old_ip6_address/$old_ip6_prefixlen" \
|
|
dev $interface
|
|
fi
|
|
|
|
if is_ifup_controlled ; then
|
|
write_cached_config_data dhcp6_state "down" $interface
|
|
commit_cached_config_data $interface
|
|
fi
|
|
netconfig_remove
|
|
|
|
exit_with_hooks 0
|
|
;;
|
|
esac
|
|
|
|
exit_with_hooks 0
|