aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init.d/net.lo.in40
-rw-r--r--net/bonding.sh2
-rw-r--r--net/iproute2.sh107
-rw-r--r--udev_helper/net.sh2
4 files changed, 125 insertions, 26 deletions
diff --git a/init.d/net.lo.in b/init.d/net.lo.in
index a8e19dd..72a5427 100644
--- a/init.d/net.lo.in
+++ b/init.d/net.lo.in
@@ -227,6 +227,34 @@ _show_address()
einfo "received address $(_get_inet_address "${IFACE}")"
}
+# Allow custom error handling behavior to be set by the user.
+# Known used combinations, with defaults
+# errh_IFVAR_address_EEXIST=warn
+# errh_IFVAR_route_EEXIST=warn
+_get_errorhandler_behavior() {
+ IFVAR="$1"
+ object="$2"
+ error="$3"
+ fallback="$4"
+ value=
+ for key in \
+ "errh_${IFVAR}_${object}_${error}" \
+ "errh_${IFVAR}_${object}_DEFAULT" \
+ "errh_${IFVAR}_DEFAULT_${error}" \
+ "errh_${IFVAR}_DEFAULT_DEFAULT" \
+ "errh_DEFAULT_${object}_${error}" \
+ "errh_DEFAULT_${object}_DEFAULT" \
+ "errh_DEFAULT_DEFAULT_${error}" \
+ "errh_DEFAULT_DEFAULT_DEFAULT" \
+ "errh" \
+ "fallback" ; do
+ eval value="\${${key}}"
+ if [ -n "$value" ]; then
+ echo "$value" && break
+ fi
+ done
+}
+
# Basically sorts our modules into order and saves the list
_gen_module_list()
{
@@ -665,7 +693,7 @@ start()
return 1
fi
- local hideFirstroute=false first=true routes=
+ local first=true routes=
if ${fallback}; then
routes="$(_get_array "fallback_routes_${IFVAR}")"
fi
@@ -676,7 +704,6 @@ start()
if [ "${config_0}" != "null" ]; then
routes="127.0.0.0/8 via 127.0.0.1
${routes}"
- hideFirstroute=true
fi
fi
@@ -708,12 +735,7 @@ ${routes}"
*:*/*) cmd="-net ${cmd}";;
*) cmd="-host ${cmd}";;
esac
- if ${hideFirstroute}; then
- _add_route ${fam} ${cmd} >/dev/null 2>&1
- hideFirstroute=false
- else
- _add_route ${fam} ${cmd} >/dev/null
- fi
+ _add_route ${fam} ${cmd}
eend $?
eoutdent
done
@@ -816,3 +838,5 @@ stop()
return 0
}
+
+# vim:filetype=gentoo-init-d:
diff --git a/net/bonding.sh b/net/bonding.sh
index ba75239..d0ed319 100644
--- a/net/bonding.sh
+++ b/net/bonding.sh
@@ -82,7 +82,7 @@ bonding_pre_start()
n=${x##*/}
eval s=\$${n}_${IFVAR}
# skip mode and miimon
- [ "${n}" == "mode" -o "${n}" == "miimon" ] && continue
+ [ "${n}" = "mode" -o "${n}" = "miimon" ] && continue
if [ -n "${s}" ]; then
einfo "Setting ${n}: ${s}"
echo "${s}" >"${x}" || \
diff --git a/net/iproute2.sh b/net/iproute2.sh
index d74bc29..32d3c88 100644
--- a/net/iproute2.sh
+++ b/net/iproute2.sh
@@ -109,13 +109,32 @@ _add_address()
local x
local address netmask broadcast peer anycast label scope
local valid_lft preferred_lft home nodad
- local confflaglist
- address="$1" ; shift
+ local confflaglist family raw_address family_maxnetmask
+ raw_address="$1" ; shift
+ # Extract the netmask on address if present.
+ if [ "${raw_address%\/*}" != "${raw_address}" ]; then
+ address="${raw_address%\/*}"
+ netmask="${raw_address#*\/}"
+ else
+ address="$raw_address"
+ fi
+
+ # Some options are not valid for one family or the other.
+ case ${address} in
+ *:*) family=6 family_maxnetmask=128 ;;
+ *) family=4 family_maxnetmask=32 ;;
+ esac
+
while [ -n "$*" ]; do
x=$1 ; shift
case "$x" in
netmask|ne*)
- netmask="/$(_netmask2cidr "$1")" ; shift ;;
+ if [ -n "${netmask}" ]; then
+ eerror "Too many netmasks: $raw_address netmask $1"
+ return 1
+ fi
+ netmask="/$(_netmask2cidr "$1")"
+ shift ;;
broadcast|brd|br*)
broadcast="$1" ; shift ;;
pointopoint|pointtopoint|peer|po*|pe*)
@@ -150,17 +169,44 @@ _add_address()
# figure out the broadcast address if it is not specified
# This must NOT be set for IPv6 addresses
- if [ "${address#*:}" = "${address}" ]; then
- [ -z "$broadcast" ] && broadcast="+"
- elif [ -n "$broadcast" ]; then
- eerror "Broadcast keywords are not valid with IPv6 addresses"
- return 1
- fi
+ case $family in
+ 4) [ -z "$broadcast" ] && broadcast="+" ;;
+ 6) [ -n "$broadcast" ] && eerror "Broadcast keywords are not valid with IPv6 addresses" && return 1 ;;
+ esac
+
+ # Always have a netmask
+ [ -z "$netmask" ] && netmask=$family_maxnetmask
+
+ # Check for address already existing:
+ ip addr show to "${address}/${family_maxnetmask}" dev "${IFACE}" 2>/dev/null | \
+ fgrep -sq "${address}"
+ address_already_exists=$?
# This must appear on a single line, continuations cannot be used
- set -- "${address}${netmask}" ${peer:+peer} ${peer} ${broadcast:+broadcast} ${broadcast} ${anycast:+anycast} ${anycast} ${label:+label} ${label} ${scope:+scope} ${scope} dev "${IFACE}" ${valid_lft:+valid_lft} $valid_lft ${preferred_lft:+preferred_lft} $preferred_lft $confflaglist
+ set -- "${address}${netmask:+/}${netmask}" ${peer:+peer} ${peer} ${broadcast:+broadcast} ${broadcast} ${anycast:+anycast} ${anycast} ${label:+label} ${label} ${scope:+scope} ${scope} dev "${IFACE}" ${valid_lft:+valid_lft} $valid_lft ${preferred_lft:+preferred_lft} $preferred_lft $confflaglist
veinfo ip addr add "$@"
ip addr add "$@"
+ rc=$?
+ # Check return code in some cases
+ if [ $rc -ne 0 ]; then
+ # If the address already exists, our default behavior is to WARN but continue.
+ # You can completely silence this with: errh_IFVAR_address_EEXIST=continue
+ if [ $address_already_exists -eq 0 ]; then
+ eh_behavior=$(_get_errorhandler_behavior "$IFVAR" "address" "EEXIST" "warn")
+ case $eh_behavior in
+ continue) msgfunc=true rc=0 ;;
+ info) msgfunc=einfo rc=0 ;;
+ warn) msgfunc=ewarn rc=0 ;;
+ error|fatal) msgfunc=eerror rc=1;;
+ *) msgfunc=eerror rc=1 ; eerror "Unknown error behavior: $eh_behavior" ;;
+ esac
+ eval $msgfunc "Address ${address}${netmask:+/}${netmask} already existed!"
+ eval $msgfunc \"$(ip addr show to "${address}/${family_maxnetmask}" dev "${IFACE}" 2>&1)\"
+ else
+ : # TODO: Handle other errors
+ fi
+ fi
+ return $rc
}
_add_route()
@@ -186,13 +232,13 @@ _add_route()
set -- "${one}" "${two}" via "$@"
fi
- local cmd= have_metric=false
+ local cmd= cmd_nometric= have_metric=false
while [ -n "$1" ]; do
case "$1" in
- metric) cmd="${cmd} $1"; have_metric=true;;
- netmask) cmd="${cmd}/$(_netmask2cidr "$2")"; shift;;
+ metric) metric=$2 ; cmd="${cmd} metric $2" ; shift ; have_metric=true ;;
+ netmask) x="/$(_netmask2cidr "$2")" ; cmd="${cmd}${x}" ; cmd_nometric="${cmd}${x}" ; shift;;
-host|-net);;
- *) cmd="${cmd} $1";;
+ *) cmd="${cmd} ${1}" ; cmd_nometric="${cmd_nometric} ${1}" ;;
esac
shift
done
@@ -205,9 +251,34 @@ _add_route()
cmd="${cmd} metric ${metric}"
fi
+ # Check for route already existing:
+ ip ${family} route show ${cmd_nometric} dev "${IFACE}" 2>/dev/null | \
+ fgrep -sq "${cmd%% *}"
+ route_already_exists=$?
+
veinfo ip ${family} route append ${cmd} dev "${IFACE}"
ip ${family} route append ${cmd} dev "${IFACE}"
- eend $?
+ rc=$?
+ # Check return code in some cases
+ if [ $rc -ne 0 ]; then
+ # If the route already exists, our default behavior is to WARN but continue.
+ # You can completely silence this with: errh_IFVAR_route_EEXIST=continue
+ if [ $route_already_exists -eq 0 ]; then
+ eh_behavior=$(_get_errorhandler_behavior "$IFVAR" "route" "EEXIST" "warn")
+ case $eh_behavior in
+ continue) msgfunc=true rc=0 ;;
+ info) msgfunc=einfo rc=0 ;;
+ warn) msgfunc=ewarn rc=0 ;;
+ error|fatal) msgfunc=eerror rc=1;;
+ *) msgfunc=eerror rc=1 ; eerror "Unknown error behavior: $eh_behavior" ;;
+ esac
+ eval $msgfunc "Route '$cmd_nometric' already existed:"
+ eval $msgfunc \"$(ip $family route show ${cmd_nometric} dev "${IFACE}" 2>&1)\"
+ else
+ : # TODO: Handle other errors
+ fi
+ fi
+ eend $rc
}
_delete_addresses()
@@ -232,6 +303,9 @@ _tunnel()
{
veinfo ip tunnel "$@"
ip tunnel "$@"
+ rc=$?
+ # TODO: check return code in some cases
+ return $rc
}
# This is just to trim whitespace, do not add any quoting!
@@ -367,6 +441,8 @@ iproute2_post_start()
[ -z "$policyroute_order" ] && policyroute_order=${policy_rules_before_routes:-no}
yesno "$policyroute_order" || _iproute2_policy_routing
+ # This block must be non-fatal, otherwise the interface will not be
+ # recorded as starting, and later services may be blocked.
if _iproute2_ipv6_tentative; then
einfon "Waiting for IPv6 addresses (${_dad_timeout} seconds) "
while [ $_dad_timeout -gt 0 ]; do
@@ -380,7 +456,6 @@ iproute2_post_start()
if [ $_dad_timeout -le 0 ]; then
eend 1
- return 1
else
eend 0
fi
diff --git a/udev_helper/net.sh b/udev_helper/net.sh
index 85b304b..b15b187 100644
--- a/udev_helper/net.sh
+++ b/udev_helper/net.sh
@@ -48,6 +48,6 @@ fi
# If we're stopping then sleep for a bit in-case a daemon is monitoring
# the interface. This to try and ensure we stop after they do.
-[ "${ACTION}" == "stop" ] && sleep 2
+[ "${ACTION}" = "stop" ] && sleep 2
IN_HOTPLUG=1 "${SCRIPT}" --quiet "${ACTION}"