#!/bin/sh
#
# Control script for starting or stopping an rrqnet virtual cable via
# ifup/ifdown. To use this, you need firstly to links to this script
# set up as /etc/network/if-pre-up.d/rrqnet and
# /etc/network/if-down.d/rrqnet. Secondly, you need a stanza in
# /etc/network/interfaces for the cabling tap and its associated
# configuration settings.
#
# "rrqnet name" is the primary stanza key, which result in
# a creation of a tap by that name, supported by an rrqnet plug
# according to the setup in /etc/rrqnet/conf.d/name.conf

#echo '===========' >> /tmp/FOO
#env >> /tmp/FOO

# Verify that it's an rrqnet stanza
[ -z "$IF_RRQNET_PORT" ] && exit 0

# An rrqnet stanza may have the following settings:
# rrqnet_port [ notap ] <port> 
# rrqnet_nice <nice>
# rrqnet_remote <remote declaration>
# rrqnet_options <options>
# rrqnet_log <level> <pathname>
# rrqnet_bridge <bridge>
# rrqnet_dhcp <options>

: ${RRQDAEMON:=/usr/sbin/rrqnet}
: ${NAME:=rrqnet-${IFACE}}

NOTAP="${IF_RRQNET_PORT##notap *}" # empty if 'notap' is used
IF_RRQNET_PORT="${IF_RRQNET_PORT#notap }"

#function
configure_tap_bridge() {
    [ -z "$IF_RRQNET_BRIDGE" ] && return 0
    brctl show $IF_RRQNET_BRIDGE | grep -wq $IFACE && return 0
    brctl addif $IF_RRQNET_BRIDGE $IFACE
}

#function
configure_tap_up() {
    ( ip link show $IFACE 2>/dev/null || ip tuntap add $IFACE mode tap ) | \
	grep -q "state UP" || ip link set dev $IFACE up
}

############################################################
## DHCP support
: ${LEASES:=/var/lib/dhcp/dhclient.$IFACE.leases}
: ${DHCPARGS:="-4 -cf /dev/null"}
: ${PIDFILE:=/var/run/dhclient.$IFACE}

#function
start_dhclient() {
    shift 1
    [ -z "$*" ] || DHCPARGS="$*"
    /sbin/dhclient -pf $PIDFILE $DHCPARGS -lf $LEASES $IFACE
}

#function
stop_dhclient() {
    shift 1
    [ -z "$*" ] || DHCPARGS="$*"
    /sbin/dhclient -x -pf $PIDFILE $DHCPARGS -lf $LEASES $IFACE 2>/dev/null
}

############################################################
## The action functions

#function
start_cable_pre_up() {
    local TAP
    TAP="-t $IFACE"
    if [ -z "$NOTAP" ] ; then
	echo "Note: $IFACE is an rrqnet without local interface" >&2
	TAP=""
    else
	configure_tap_up || return 1
	configure_tap_bridge || return 1
    fi
    [ -z "$IF_RRQNET_NICE" ] || \
        RRQDAEMON="/usr/bin/nice -n $IF_RRQNET_NICE $RRQDAEMON"
    if [ -z "$IF_RRQNET_LOG" ] ; then
	daemon -U -r -a 10 -n $NAME -- \
	       $RRQDAEMON $IF_RRQNET_OPTIONS \
	       $TAP $IF_RRQNET_PORT $IF_RRQNET_REMOTE
    else
        LOG=${IF_RRQNET_LOG#* }
        daemon -U -r -a 10 -n $NAME -E "$LOG" -- \
               $RRQDAEMON ${IF_RRQNET_LOG%$LOG} $IF_RRQNET_OPTIONS \
	       $TAP $IF_RRQNET_PORT $IF_RRQNET_REMOTE
    fi
}

#function
start_cable_post_up() {
    case "$IF_RRQNET_DHCP" in
	dhclient*)
	    start_dhclient $IF_RRQNET_DHCP
	    ;;
	*)
	    : # no or unkown dhcp option
	    ;;
    esac
}

#function
stop_cable_pre_down() {
    case "$IF_RRQNET_DHCP" in
	dhclient*)
	    stop_dhclient $IF_RRQNET_DHCP
	    ;;
	*)
	    : # no or unkown dhcp option
	    ;;
    esac
    daemon -n $NAME --stop
}

#function
stop_cable_post_down() {
    [ -z "$NOTAP" ] || ip link del $IFACE
}

# main script body
case "$MODE-$PHASE" in
    start-pre-up) start_cable_pre_up ;;
    start-post-up) start_cable_post_up ;;
    stop-pre-down) stop_cable_pre_down ;;
    stop-post-down) stop_cable_post_down ;;
esac
