source: freewrt/package/fwifupdown/files/main.sh@ 97c9690

Last change on this file since 97c9690 was 97c9690, checked in by Christian Fischer <spaetzle@…>, 19 years ago

dhcp pidfile fixes

git-svn-id: svn://www.freewrt.org/trunk/freewrt@2444 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100755
File size: 8.3 KB
Line 
1#!/bin/sh
2#
3# This file is part of the FreeWRT project. FreeWRT is copyrighted
4# material, please see the LICENCE file in the top-level directory
5# or at http://www.freewrt.org/licence for details.
6#
7# Christian Fischer <spaetzle@freewrt.org>
8#
9
10set -u
11
12builtin() {
13 local builtin=$1
14 local alias=$(alias $builtin)
15 unalias $builtin
16 alias $(echo $alias|sed 's/'\''//g')
17 shift
18 $builtin $@
19}
20
21config() {
22 [ "$1" != "0" ]
23}
24__ifupdown() {
25 local environ=$(cat $ENVFILE)
26
27 IFUPDOWN_ENV=$(echo -n $IFUPDOWN_ENV|sed 's/\(MDENT=\)[^ ]*[[:space:]]*//g';\
28 echo " PARENT_IFACE_TYPE=$IFACE_TYPE"; \
29 echo " PARENT_IFACE=$IFACE"; \
30 echo " MDENT=$MDENT") \
31 busybox $@
32
33 retval=$?
34 echo $environ > $ENVFILE
35 return $retval
36}
37
38__exit() {
39 [ "$1" != "0" ] && echo "H_ERR=1" >> $ENVFILE
40 exit $1
41}
42
43iface_exists() {
44 grep -q "${1:-$IFACE}:" /proc/net/dev
45}
46
47is_up() {
48 local iface=${1:-$IFACE}
49
50 if iface_exists $iface
51 then
52 ip a|grep ${iface}:[[:space:]]|grep -q UP && return
53
54 ### ifupdown netlink bug workaround ###
55 # suppress "ip: RTNETLINK answers: File exists" message in the case of
56 # iface is down but an ip address is assigned
57 ip a|grep ${iface}$|grep -q inet && ip addr flush dev $iface >/dev/null 2>&1
58 ### end workaround ###
59 fi
60 return 1
61}
62
63main_env_update() {
64 local t_mdent lastmatch=""
65
66 # get submode from calling hook script
67 SUBMODE=$(dirname $0|sed '{ s/\(.*\/\)*//; s/\.d$//}')
68
69 # create env file
70 if ! [ -f "$ENVFILE" ]
71 then
72 [ -d $(dirname $ENVFILE) ] || mkdir -p $(dirname $ENVFILE)
73 echo "MDENT=0" >> $ENVFILE
74 echo "LASTLOG=0" >> $ENVFILE
75
76 if is_up
77 then
78 IFACE_STATE="up"
79 else
80 IFACE_STATE="down"
81 fi
82 echo "IFACE_STATE=$IFACE_STATE" >> $ENVFILE
83
84 if [ "$IFACE" != "lo" ]
85 then
86 # search for existing lib files end evaluate iface type by using the appropriate
87 # function from lib file
88 for lib in ${LIBDIR}/* ${LIBDIR_OVERLAY}/*
89 do
90 if [ -f $lib ]
91 then
92 if (. $lib; iface_type 2>&-)
93 then
94 if [ "$lastmatch" != "" ]
95 then
96 if [ "$(basename $lib)" = "$(basename $lastmatch)" ]
97 then
98 mprint -s "Warning: $lib overlays $lastmatch"
99 else
100 mprint -s "Error: iface type $lib overlays $lastmatch"
101 fi
102 fi
103 lastmatch=$lib
104 fi
105 fi
106 done
107 fi
108
109 if [ "$lastmatch" != "" ]
110 then
111 IFACE_TYPE=$(basename $lastmatch)
112 else
113 # if iface type isn't evaluated type "iface" is default
114 IFACE_TYPE="iface"
115 fi
116
117 # update env
118 echo "IFACE_TYPE=${IFACE_TYPE}" >> $ENVFILE
119 fi
120
121 . $ENVFILE
122 t_mdent=$MDENT
123
124 # expand $IFUPDOWN_ENV
125 for var in $IFUPDOWN_ENV; do
126 eval $var
127 done
128
129 [ $t_mdent -gt $MDENT ] && MDENT=$t_mdent
130 main_pos_update
131}
132
133main_pos_update() {
134 if [ "${MDENT:-0}" = "0" ]
135 then
136 STARTCOL=""
137 else
138 STARTCOL="\x1B[$(expr ${MDENT:-0} \* ${TAB})C"
139 fi
140 sed 's/MDENT=[0-9]*/'MDENT=$MDENT'/' -i $ENVFILE
141}
142
143main_preup() {
144 config $RT_PREUP_PRINTING_OFF || mstart
145
146 if ! config $RT_PREUP_IFUP_CHECK_OFF && is_up
147 then
148 if ! config $RT_PREUP_PRINTING_OFF
149 then
150 mup
151 mstate 1
152 minfo "Interface already up"
153 fi
154 exit 1
155 fi
156
157 if_preup 2>&-
158 retval=$?
159
160 if [ $retval != 0 ]
161 then
162 if [ $retval != 127 ]
163 then
164 fail_preup 2>&- || exit 1
165 fi
166 fi
167
168 config $RT_PREUP_PRINTING_OFF || mup
169}
170
171main_up() {
172 if ! config $RT_UP_IFUP_CHECK_OFF
173 then
174 is_up
175 retval=$?
176
177 if [ $retval != 0 ]
178 then
179
180 if ! config $RT_UP_PRINTING_OFF
181 then
182 mstate $retval
183 [ "$METHOD" = "manual" ] && minfo "Method manual is set"
184 fi
185 exit 1
186 else
187 config $RT_UP_PRINTING_OFF || mstate $retval
188 fi
189 fi
190
191 if_up 2>&-
192 retval=$?
193
194 if [ $retval != 0 ]
195 then
196 if [ $retval != 127 ]
197 then
198 fail_up 2>&- || exit 1
199 fi
200 fi
201
202 if [ -d /tmp/ifupdown/pcode/${IFACE} ]
203 then
204 for dir in /tmp/ifupdown/pcode/${IFACE}/*
205 do
206 if [ -f ${dir}/postup ]
207 then
208 . ${dir}/postup
209 fi
210 done
211 fi
212}
213
214main_down() {
215 config $RT_DOWN_PRINTING_OFF || mstop
216
217 if [ -d /tmp/ifupdown/pcode/${IFACE} ]
218 then
219 for dir in /tmp/ifupdown/pcode/${IFACE}/*
220 do
221 if [ -f ${dir}/predown ]
222 then
223 . ${dir}/predown
224 fi
225 done
226 fi
227
228 if_down 2>&-
229 retval=$?
230
231 if [ $retval != 0 ]
232 then
233 if [ $retval != 127 ]
234 then
235 fail_down 2>&- || exit 1
236 fi
237 fi
238
239 config $RT_DOWN_PRINTING_OFF || mdown
240}
241
242main_postdown() {
243 if ! config $RT_POSTDOWN_IFDOWN_CHECK_OFF
244 then
245 if [ $IFACE_STATE = "down" ]
246 then
247 if ! config $RT_POSTDOWN_PRINTING_OFF
248 then
249 mdown
250 mstate 1
251 minfo "Interface already down"
252 fi
253 else
254 if is_up
255 then
256 if ! config $RT_POSTDOWN_PRINTING_OFF
257 then
258 mstate 1
259 [ "$METHOD" = "manual" ] && minfo "Method manual is set"
260 fi
261 return 1
262 else
263 config $RT_POSTDOWN_PRINTING_OFF || mstate 0
264 fi
265 fi
266 fi
267
268 if_postdown 2>&-
269 retval=$?
270
271 if [ $retval != 0 ]
272 then
273 if [ $retval != 127 ]
274 then
275 fail_postdown 2>&- || exit 1
276 fi
277 fi
278
279 # pcode cleanup
280 rm -rf /tmp/ifupdown/pcode/*/$IFACE 2>&- 1>&-
281}
282
283main_ifup() {
284 case $METHOD in
285 dhcp)
286 main_dhcp_up || exit 1
287
288 # don't handle any failures, it's really not my problem if that goes wrong
289 main_exec_inlinehooks
290
291 main_up || exit 1
292 RT_BB_NOEXEC=1
293 ;;
294 esac
295}
296
297main_ifdown() {
298 case $METHOD in
299 dhcp)
300 main_dhcp_down
301
302 # don't handle any failures, it's really not my problem if that goes wrong
303 main_exec_inlinehooks
304
305 main_postdown || exit 1
306 RT_BB_NOEXEC=1
307 ;;
308 esac
309}
310
311main_exec_inlinehooks() {
312 case $SUBMODE in
313 if-pre-up)
314 [ "${IF_PRE_UP:-""}" != "" ] && eval $IF_PRE_UP
315 ;;
316 if-up)
317 [ "${IF_UP:-""}" != "" ] && eval $IF_UP
318 ;;
319 if-down)
320 [ "${IF_DOWN:-""}" != "" ] && eval $IF_DOWN
321 ;;
322 if-post-down)
323 [ "${IF_POST_DOWN:-""}" != "" ] && eval $IF_POST_DOWN
324 ;;
325 esac
326}
327
328main_dhcp_up() {
329 local err
330
331 if ! err=$(ip link set $IFACE up 2>&1 1>&-)
332 then
333 mprint -s "main_dhcp_up: $err"
334 return 1
335 fi
336
337 if [ "${IF_DHCPCLIENT:-""}" != "" -a "${IF_DHCPCLIENT_OPTS:-""}" != "udhcpc" ]
338 then
339 if [ -x "$(which $IF_DHCPCLIENT)" ]
340 then
341 err=$(eval $IF_DHCPCLIENT ${IF_DHCPCLIENT_OPTS:-""} 2>&1 1>&-) || mprint -s "main_dhcp_up: $err" &
342 if [ -n ${!:-""} ]
343 then
344 mkdir -p /var/run/dhcpc
345 echo $! > /var/run/dhcpc/${IF_DHCPCLIENT}.${IFACE}.pid
346 return 0
347 else
348 mprint -s "main_dhcp_up: dhcp client start failed"
349 return 1
350 fi
351 fi
352 mprint -s "$IF_DHCPCCLIENT not found, using builtin udhcpcd"
353 fi
354
355 if ! err=$(udhcpc -b -t 0 -p /var/run/dhcpc/udhcpc.${IFACE}.pid -i $IFACE ${IF_HOSTNAME:+"-H $IF_HOSTNAME"} ${IF_CLIENTID:+"-c $IF_CLIENTID"} \
356 ${IF_SCRIPT:+"-s $IF_SCRIPT"} 2>&1 1>&-)
357 then
358 mprint -s "main_dhcp_up: $err"
359 return 1
360 fi
361
362 return 0
363}
364
365main_dhcp_down() {
366 local err pid
367
368 for pidfile in /var/run/dhcpc/*
369 do
370 if grep -q .${IFACE}. $pidfile
371 then
372 pid="$(cat $pidfile 2>&-)"
373 if [ -n "$pid" ] -a -d "/proc/$pid" ]
374 then
375 err=$(kill -TERM $pid 2>&1 1>&-) || mprint -s "main_dhcp_down: $err"
376 rm -f $pidfile 2>&-
377 fi
378 fi
379 done
380
381 if is_up
382 then
383 err=$(ip addr flush dev $IFACE 2>&1 1>&-) || mprint -s "main_dhcp_down: $err"
384 err=$(ip link set $IFACE down 2>&1 1>&-) || mprint -s "main_dhcp_down: $err"
385 fi
386}
387
388### main entry point ###
389
390CFG_PRINTING_OFF=0
391CFG_SYSLOG_OFF=0
392CFG_BUSYBOX_COMPAT=0
393
394if ! [ -f /etc/conf.d/ifupdown ]
395then
396 logger -t ifupdown "/etc/conf.d/ifupdown not found"
397 exit 1
398fi
399. /etc/conf.d/ifupdown
400
401RT_PREUP_PRINTING_OFF=0
402RT_UP_PRINTING_OFF=0
403RT_DOWN_PRINTING_OFF=0
404RT_POSTDOWN_PRINTING_OFF=0
405RT_PREUP_IFUP_CHECK_OFF=0
406RT_UP_IFUP_CHECK_OFF=0
407RT_POSTDOWN_IFDOWN_CHECK_OFF=0
408RT_BB_NOEXEC=0
409readonly ENVFILE="/tmp/ifupdown/env"
410readonly LIBDIR="/opt/ifupdown/lib"
411readonly LIBDIR_OVERLAY="/etc/network/lib"
412IFACE_TYPE="none"
413H_ERR=0
414
415alias exit="__exit"
416alias ifup="__ifupdown ifup"
417alias ifdown="__ifupdown ifdown"
418
419if ! [ -f /opt/ifupdown/bin/mfunctions.sh ]
420then
421 logger -t ifupdown "/opt/ifupdown/bin/mfunctions.sh not found"
422 exit 1
423fi
424. /opt/ifupdown/bin/mfunctions.sh
425
426main_env_update
427
428config $H_ERR && builtin exit 1
429
430if [ "$IFACE_TYPE" != "iface" ]
431then
432 if [ -f "${LIBDIR_OVERLAY}/$IFACE_TYPE" ]
433 then
434 . ${LIBDIR_OVERLAY}/$IFACE_TYPE
435 elif [ -f "${LIBDIR}/$IFACE_TYPE" ]
436 then
437 . ${LIBDIR}/$IFACE_TYPE
438 else
439 mprint -s "Error: libfile not found"
440 fi
441fi
442
443case $SUBMODE in
444 if-pre-up)
445 main_preup
446 main_ifup
447 # bypass execution of further busybox ifupdown.c code
448 config $RT_BB_NOEXEC && builtin exit 1
449 ;;
450 if-up)
451 main_up
452 ;;
453 if-down)
454 main_down
455 main_ifdown
456 # bypass execution of further busybox ifupdown.c code
457 config $RT_BB_NOEXEC && builtin exit 1
458 ;;
459 if-post-down)
460 main_postdown
461 ;;
462esac
463
464exit 0
465
466# vim:ts=4
Note: See TracBrowser for help on using the repository browser.