157007a9ad21f32271710d6b27bcecd83c1558e8
[rrq/rrqnet.git] / rrqnet-ifupdown.sh
1 #!/bin/sh
2 #
3 # Control script for starting or stopping an rrqnet virtual cable via
4 # ifup/ifdown. To use this, you need firstly to links to this script
5 # set up as /etc/network/if-pre-up.d/rrqnet and
6 # /etc/network/if-down.d/rrqnet. Secondly, you need a stanza in
7 # /etc/network/interfaces for the cabling tap and its associated
8 # configuration settings.
9 #
10 # "rrqnet name" is the primary stanza key, which result in
11 # a creation of a tap by that name, supported by an rrqnet plug
12 # according to the setup in /etc/rrqnet/conf.d/name.conf
13
14 #echo '===========' >> /tmp/FOO
15 #env >> /tmp/FOO
16
17 # Verify that it's an rrqnet stanza
18 [ -z "$IF_RRQNET_PORT" ] && exit 0
19
20 # An rrqnet stanza may have the following settings:
21 # rrqnet_port [ notap ] <port> 
22 # rrqnet_nice <nice>
23 # rrqnet_remote <remote declaration>
24 # rrqnet_options <options>
25 # rrqnet_log <level> <pathname>
26 # rrqnet_bridge <bridge>
27 # rrqnet_dhcp <options>
28
29 : ${RRQDAEMON:=/usr/sbin/rrqnet}
30 : ${NAME:=rrqnet-${IFACE}}
31
32 NOTAP="${IF_RRQNET_PORT##notap *}" # empty if 'notap' is used
33 IF_RRQNET_PORT="${IF_RRQNET_PORT#notap }"
34
35 #function
36 configure_tap_bridge() {
37     [ -z "$IF_RRQNET_BRIDGE" ] && return 0
38     brctl show $IF_RRQNET_BRIDGE | grep -wq $IFACE && return 0
39     brctl addif $IF_RRQNET_BRIDGE $IFACE
40 }
41
42 #function
43 configure_tap_up() {
44     ( ip link show $IFACE 2>/dev/null || ip tuntap add $IFACE mode tap ) | \
45         grep -q "state UP" || ip link set dev $IFACE up
46 }
47
48 ############################################################
49 ## DHCP support
50 : ${LEASES:=/var/lib/dhcp/dhclient.$IFACE.leases}
51 : ${DHCPARGS:="-4 -cf /dev/null"}
52 : ${PIDFILE:=/var/run/dhclient.$IFACE}
53
54 #function
55 start_dhclient() {
56     shift 1
57     [ -z "$*" ] || DHCPARGS="$*"
58     /sbin/dhclient -pf $PIDFILE $DHCPARGS -lf $LEASES $IFACE
59 }
60
61 #function
62 stop_dhclient() {
63     shift 1
64     [ -z "$*" ] || DHCPARGS="$*"
65     /sbin/dhclient -x -pf $PIDFILE $DHCPARGS -lf $LEASES $IFACE 2>/dev/null
66 }
67
68 ############################################################
69 ## The action functions
70
71 QUIRK=
72 LOGFLAG=
73 LOGFILE=
74 #function
75 process_logoption() {
76     if [ -n "${1##-v*}" ] ; then
77         QUIRK="$1"
78         shift
79     fi
80     LOGFLAG="$1"
81     LOGFILE="$2"
82 }
83
84 #function
85 start_cable_pre_up() {
86     local TAP
87     TAP="-t $IFACE"
88     if [ -z "$NOTAP" ] ; then
89         echo "Note: $IFACE is an rrqnet without local interface" >&2
90         TAP=""
91     else
92         configure_tap_up || return 1
93         configure_tap_bridge || return 1
94     fi
95     [ -z "$IF_RRQNET_NICE" ] || \
96         RRQDAEMON="/usr/bin/nice -n $IF_RRQNET_NICE $RRQDAEMON"
97     process_logoption ${IF_RRQNET_LOG}
98     if [ -z "$LOGFILE" ] ; then
99         daemon -U -r -a 10 -n $NAME -- \
100                $RRQDAEMON $QUIRK $IF_RRQNET_OPTIONS \
101                $TAP $IF_RRQNET_PORT $IF_RRQNET_REMOTE
102     else
103         daemon -U -r -a 10 -n $NAME -E "$LOGFILE" -- \
104                $RRQDAEMON $QUIRK $LOGFLAG $IF_RRQNET_OPTIONS \
105                $TAP $IF_RRQNET_PORT $IF_RRQNET_REMOTE
106     fi
107 }
108
109 #function
110 start_cable_post_up() {
111     case "$IF_RRQNET_DHCP" in
112         dhclient*)
113             start_dhclient $IF_RRQNET_DHCP
114             ;;
115         *)
116             : # no or unkown dhcp option
117             ;;
118     esac
119 }
120
121 #function
122 stop_cable_pre_down() {
123     case "$IF_RRQNET_DHCP" in
124         dhclient*)
125             stop_dhclient $IF_RRQNET_DHCP
126             ;;
127         *)
128             : # no or unkown dhcp option
129             ;;
130     esac
131     daemon -n $NAME --stop
132 }
133
134 #function
135 stop_cable_post_down() {
136     [ -z "$NOTAP" ] || ip link del $IFACE
137 }
138
139 # main script body
140 case "$MODE-$PHASE" in
141     start-pre-up) start_cable_pre_up ;;
142     start-post-up) start_cable_post_up ;;
143     stop-pre-down) stop_cable_pre_down ;;
144     stop-post-down) stop_cable_post_down ;;
145 esac