diff options
-rw-r--r-- | init.d/net.lo.in | 40 | ||||
-rw-r--r-- | net/bonding.sh | 2 | ||||
-rw-r--r-- | net/iproute2.sh | 107 | ||||
-rw-r--r-- | udev_helper/net.sh | 2 |
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}" |