#!/bin/sh # # This file is part of the FreeWRT project. FreeWRT is copyrighted # material, please see the LICENCE file in the top-level directory # or at http://www.freewrt.org/licence for details. # # Christian Fischer # built_in() { local what=$1 local alias=$(alias $what) unalias $what alias $(echo $alias|sed 's/'\''//g') shift $what $@ } config() { [ x"$1" != x"0" ] } __ifupdown() { local environ=$(cat $ENVFILE) IFUPDOWN_ENV=$(echo -n $IFUPDOWN_ENV|sed 's/\(MDENT=\)[^ ]*[[:space:]]*//g';\ echo " PARENT_IFACE_TYPE=$IFACE_TYPE"; \ echo " PARENT_IFACE=$IFACE"; \ echo " MDENT=$MDENT") \ busybox "$@" retval=$? echo $environ > $ENVFILE return $retval } __exit() { [ "$1" != "0" ] && echo "H_ERR=1" >> $ENVFILE exit $1 } iface_exists() { grep -q "${1:-$IFACE}:" /proc/net/dev } is_up() { local iface=${1:-$IFACE} if iface_exists $iface then ip a|grep ${iface}:[[:space:]]|grep -q UP && return ### ifupdown netlink bug workaround ### # suppress "ip: RTNETLINK answers: File exists" message in the case of # iface is down but an ip address is assigned ip a|grep ${iface}$|grep -q inet && ip addr flush dev $iface >/dev/null 2>&1 ### end workaround ### fi return 1 } main_env_update() { local t_mdent lastmatch="" # get submode from calling hook script SUBMODE=$(dirname $0|sed '{ s/\(.*\/\)*//; s/\.d$//}') # create env file if ! [ -f "$ENVFILE" ] then [ -d $(dirname $ENVFILE) ] || mkdir -p $(dirname $ENVFILE) echo "MDENT=0" >> $ENVFILE echo "LASTLOG=0" >> $ENVFILE if is_up then IFACE_STATE="up" else IFACE_STATE="down" fi echo "IFACE_STATE=$IFACE_STATE" >> $ENVFILE if [ "$IFACE" != "lo" ] then # search for existing lib files end evaluate iface type by using the appropriate # function from lib file for lib in ${LIBDIR}/iftypes/* ${LIBDIR_OVERLAY}/iftypes/* do if [ -f $lib ] then if (. $lib; iface_type 2>&-) then if [ "$lastmatch" != "" ] then if [ "$(basename $lib)" = "$(basename $lastmatch)" ] then mprint -s "Warning: $lib overlays $lastmatch" else mprint -s "Error: iface type $lib overlays $lastmatch" fi fi lastmatch=$lib fi fi done fi if [ "$lastmatch" != "" ] then IFACE_TYPE=$(basename $lastmatch) else # if iface type isn't evaluated type "iface" is default IFACE_TYPE="iface" fi # update env echo "IFACE_TYPE=${IFACE_TYPE}" >> $ENVFILE fi . $ENVFILE t_mdent=$MDENT # expand $IFUPDOWN_ENV for var in $IFUPDOWN_ENV; do eval $var done [ $t_mdent -gt $MDENT ] && MDENT=$t_mdent main_pos_update } main_pos_update() { if [ "${MDENT:-0}" = "0" ] then STARTCOL="" else STARTCOL="[$(expr ${MDENT:-0} \* ${TAB})C" fi sed 's/MDENT=[0-9]*/'MDENT=$MDENT'/' -i $ENVFILE } main_preup() { config $RT_PREUP_PRINTING_OFF || mstart if ! config $RT_PREUP_IFUP_CHECK_OFF && is_up then if ! config $RT_PREUP_PRINTING_OFF then mup mstate 1 minfo "Interface already up" fi exit 1 fi if_preup 2>&- retval=$? if [ $retval != 0 ] then if [ $retval != 127 ] then fail_preup 2>&- || exit 1 fi fi config $RT_PREUP_PRINTING_OFF || mup } main_up() { if ! config $RT_UP_IFUP_CHECK_OFF then is_up retval=$? if [ $retval != 0 ] then if ! config $RT_UP_PRINTING_OFF then mstate $retval [ "$METHOD" = "manual" ] && minfo "Method manual is set" fi exit 1 else config $RT_UP_PRINTING_OFF || mstate $retval fi fi if_up 2>&- retval=$? if [ $retval != 0 ] then if [ $retval != 127 ] then fail_up 2>&- || exit 1 fi fi if [ -d /tmp/ifupdown/pcode/${IFACE} ] then for dir in /tmp/ifupdown/pcode/${IFACE}/* do if [ -f ${dir}/postup ] then . ${dir}/postup fi done fi } main_down() { config $RT_DOWN_PRINTING_OFF || mstop if [ -d /tmp/ifupdown/pcode/${IFACE} ] then for dir in /tmp/ifupdown/pcode/${IFACE}/* do if [ -f ${dir}/predown ] then . ${dir}/predown fi done fi if_down 2>&- retval=$? if [ $retval != 0 ] then if [ $retval != 127 ] then fail_down 2>&- || exit 1 fi fi config $RT_DOWN_PRINTING_OFF || mdown } main_postdown() { if ! config $RT_POSTDOWN_IFDOWN_CHECK_OFF then if [ $IFACE_STATE = "down" ] then if ! config $RT_POSTDOWN_PRINTING_OFF then mdown mstate 1 minfo "Interface already down" fi else if is_up then if ! config $RT_POSTDOWN_PRINTING_OFF then mstate 1 [ "$METHOD" = "manual" ] && minfo "Method manual is set" fi return 1 else config $RT_POSTDOWN_PRINTING_OFF || mstate 0 fi fi fi if_postdown 2>&- retval=$? if [ $retval != 0 ] then if [ $retval != 127 ] then fail_postdown 2>&- || exit 1 fi fi # pcode cleanup rm -rf /tmp/ifupdown/pcode/*/$IFACE 2>&- 1>&- } main_exec_dirhooks() { for hook in ${LIBDIR_OVERLAY}/${1}/${2} ${LIBDIR}/${1}/${2} do if [ -f $hook ] then . $hook eval $3 2>&- retval=$? [ $retval != 0 -a $retval != 127 ] && exit 1 return fi done } main_exec_plugins() { for plugin in ${LIBDIR_OVERLAY}/plugins/* ${LIBDIR}/plugins/*; do [ -f $plugin ] || continue . $plugin eval "${plugin##*/}_${1}" 2>&- retval=$? [ $retval != 0 -a $retval != 127 ] && exit 1 done } main_exec_inlinehooks() { case $SUBMODE in if-pre-up) [ "${IF_PRE_UP:-""}" != "" ] && eval $IF_PRE_UP ;; if-up) [ "${IF_UP:-""}" != "" ] && eval $IF_UP ;; if-down) [ "${IF_DOWN:-""}" != "" ] && eval $IF_DOWN ;; if-post-down) [ "${IF_POST_DOWN:-""}" != "" ] && eval $IF_POST_DOWN ;; esac } ### main entry point ### CFG_PRINTING_OFF=0 CFG_SYSLOG_OFF=0 CFG_FANCY=0 CFG_DEBUG=0 if ! [ -f /etc/conf.d/ifupdown ] then logger -t ifupdown "/etc/conf.d/ifupdown not found" exit 1 fi . /etc/conf.d/ifupdown config ${CFG_DEBUG:=""} && set -x RT_PREUP_PRINTING_OFF=0 RT_UP_PRINTING_OFF=0 RT_DOWN_PRINTING_OFF=0 RT_POSTDOWN_PRINTING_OFF=0 RT_PREUP_IFUP_CHECK_OFF=0 RT_UP_IFUP_CHECK_OFF=0 RT_POSTDOWN_IFDOWN_CHECK_OFF=0 RT_BB_NOEXEC=0 readonly ENVFILE="/tmp/ifupdown/env" readonly LIBDIR="/lib/network" readonly LIBDIR_OVERLAY="/etc/network/lib" IFACE_TYPE="none" H_ERR=0 alias exit="__exit" alias ifup="__ifupdown ifup" alias ifdown="__ifupdown ifdown" [ -z "${KSH_VERSION:-""}" ] || alias which='whence -p' if ! [ -f ${LIBDIR}/sh/mfunctions.sh ] then logger -t ifupdown "${LIBDIR}/sh/mfunctions.sh not found" exit 1 fi . ${LIBDIR}/sh/mfunctions.sh main_env_update config $H_ERR && built_in exit 1 if [ "$IFACE_TYPE" != "iface" ] then if [ -f "${LIBDIR_OVERLAY}/iftypes/${IFACE_TYPE}" ] then . ${LIBDIR_OVERLAY}/iftypes/${IFACE_TYPE} elif [ -f "${LIBDIR}/iftypes/${IFACE_TYPE}" ] then . ${LIBDIR}/iftypes/$IFACE_TYPE else mprint -s "Error: libfile $IFACE_TYPE not found" fi fi case $SUBMODE in if-pre-up) main_preup main_exec_dirhooks methods $METHOD method_preup main_exec_plugins preup # bypass execution of further busybox ifupdown.c code config $RT_BB_NOEXEC && built_in exit 1 ;; if-up) main_exec_plugins up main_exec_dirhooks methods $METHOD method_up main_up ;; if-down) main_down main_exec_dirhooks methods $METHOD method_down main_exec_plugins down # bypass execution of further busybox ifupdown.c code config $RT_BB_NOEXEC && built_in exit 1 ;; if-post-down) main_exec_plugins postdown main_exec_dirhooks methods $METHOD method_postdown main_postdown ;; esac exit 0 # vim:ts=4