/[baselayout]/trunk/sh/net.sh
Gentoo

Contents of /trunk/sh/net.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2675 - (show annotations) (download) (as text)
Wed May 2 11:04:52 2007 UTC (10 years, 5 months ago) by uberlord
File MIME type: text/x-sh
File size: 12846 byte(s)
Correct tabs
1 #!/sbin/runscript
2 # Copyright 1999-2007 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 MODULESDIR="${RC_LIBDIR}/net"
6 MODULESLIST="${RC_SVCDIR}/nettree"
7 _config_vars="config routes"
8
9 [ -z "${IN_BACKGROUND}" ] && IN_BACKGROUND=false
10
11 depend() {
12 local IFACE=${SVCNAME#*.}
13 local IFVAR=$(echo -n "${IFACE}" | sed -e 's/[^[:alnum:]]/_/g')
14
15 need localmount
16 after bootmisc
17 provide net
18 case "${IFACE}" in
19 lo|lo0) ;;
20 *)
21 after net.lo net.lo0
22 local prov=
23 eval prov=\$RC_NEED_${IFVAR}
24 [ -n "${prov}" ] && need ${prov}
25 eval prov=\$RC_USE_${IFVAR}
26 [ -n "${prov}" ] && use ${prov}
27 eval prov=\$RC_BEFORE_${IFVAR}
28 [ -n "${prov}" ] && before ${prov}
29 eval prov=\$RC_AFTER_${IFVAR}
30 [ -n "${prov}" ] && after ${prov}
31 eval prov=\$RC_PROVIDE_${IFVAR}
32 [ -n "${prov}" ] && provide ${prov}
33 ;;
34 esac
35 }
36
37 _shell_var() {
38 echo -n "$1" | sed -e 's/[^[:alnum:]]/_/g'
39 }
40
41 # Credit to David Leverton for this function which handily maps a bash array
42 # structure to positional parameters so existing configs work :)
43 # We'll deprecate arrays at some point though.
44 _get_array() {
45 if [ -n "${BASH}" ] ; then
46 case "$(declare -p "$1" 2>/dev/null)" in
47 "declare -a "*)
48 echo "set -- \"\${$1[@]}\""
49 return
50 ;;
51 esac
52 fi
53
54 echo "eval set -- \"\$$1\""
55 }
56
57 _wait_for_carrier() {
58 local timeout= efunc=einfon
59
60 _has_carrier && return 0
61
62 eval timeout=\$carrier_timeout_${IFVAR}
63 timeout=${timeout:-${carrier_timeout:-5}}
64
65 # Incase users don't want this nice feature ...
66 [ ${timeout} -le 0 ] && return 0
67
68 [ -n "${RC_EBUFFER}" -o "${RC_PREFIX}" = "yes" ] && efunc=einfo
69 ${efunc} "Waiting for carrier (${timeout} seconds) "
70 while [ ${timeout} -gt 0 ] ; do
71 sleep 1
72 if _has_carrier ; then
73 [ -z "${RC_EBUFFER}" ] && echo
74 eend 0
75 return 0
76 fi
77 timeout=$((${timeout} - 1))
78 [ -z "${RC_EBUFFER}" -a "${RC_PREFIX}" != "yes" ] && printf "."
79 done
80
81 [ -z "${RC_EBUFFER}" -a "${RC_PREFIX}" != "yes" ] && echo
82 eend 1
83 return 1
84 }
85
86 _netmask2cidr() {
87 local i= len=0
88
89 local IFS=.
90 for i in $1; do
91 while [ ${i} != "0" ] ; do
92 len=$((${len} + ${i} % 2))
93 i=$((${i} >> 1))
94 done
95 done
96
97 echo "${len}"
98 }
99
100 _configure_variables() {
101 local var= v= t=
102
103 for var in ${_config_vars} ; do
104 local v=
105 for t in "$@" ; do
106 eval v=\$${var}_${t}
107 if [ -n "${v}" ] ; then
108 eval ${var}_${IFVAR}=\$${var}_${t}
109 continue 2
110 fi
111 done
112 done
113 }
114
115 _show_address() {
116 einfo "received address $(_get_inet_address "${IFACE}")"
117 }
118
119 # Basically sorts our modules into order and saves the list
120 _gen_module_list() {
121 local x= f=
122 if [ -s "${MODULESLIST}" -a "${MODULESLIST}" -nt "${MODULESDIR}" ] ; then
123 local update=false
124 for x in "${MODULESDIR}"/* ; do
125 [ -e "${x}" ] || continue
126 if [ "${x}" -nt "${MODULESLIST}" ] ; then
127 update=true
128 break
129 fi
130 done
131 ${update} || return 0
132 fi
133
134 einfo "Caching network module dependencies"
135 # Run in a subshell to protect the main script
136 (
137 after() {
138 eval ${MODULE}_after="\"\${${MODULE}_after}\${${MODULE}_after:+ }$*\""
139 }
140
141 before() {
142 local mod=${MODULE}
143 local MODULE=
144 for MODULE in "$@" ; do
145 after "${mod}"
146 done
147 }
148
149 program() {
150 if [ "$1" = "start" -o "$1" = "stop" ] ; then
151 local s="$1"
152 shift
153 eval ${MODULE}_program_${s}="\"\${${MODULE}_program_${s}}\${${MODULE}_program_${s}:+ }$*\""
154 else
155 eval ${MODULE}_program="\"\${${MODULE}_program}\${${MODULE}_program:+ }$*\""
156 fi
157 }
158
159 provide() {
160 eval ${MODULE}_provide="\"\${${MODULE}_provide}\${${MODULE}_provide:+ }$*\""
161 local x
162 for x in $* ; do
163 eval ${x}_providedby="\"\${${MODULE}_providedby}\${${MODULE}_providedby:+ }${MODULE}\""
164 done
165 }
166
167 for MODULE in "${MODULESDIR}"/* ; do
168 sh -n "${MODULE}" || continue
169 . "${MODULE}" || continue
170 MODULE=${MODULE#${MODULESDIR}/}
171 MODULE=${MODULE%.sh}
172 eval ${MODULE}_depend
173 MODULES="${MODULES} ${MODULE}"
174 done
175
176 VISITED=
177 SORTED=
178 visit() {
179 case " ${VISITED} " in
180 *" $1 "*) return ;;
181 esac
182 VISITED="${VISITED} $1"
183
184 eval AFTER=\$${1}_after
185 for MODULE in ${AFTER} ; do
186 eval PROVIDEDBY=\$${MODULE}_providedby
187 if [ -n "${PROVIDEDBY}" ] ; then
188 for MODULE in ${PROVIDEDBY} ; do
189 visit "${MODULE}"
190 done
191 else
192 visit "${MODULE}"
193 fi
194 done
195
196 eval PROVIDE=\$${1}_provide
197 for MODULE in ${PROVIDE} ; do
198 visit "${MODULE}"
199 done
200
201 eval PROVIDEDBY=\$${1}_providedby
202 [ -z "${PROVIDEDBY}" ] && SORTED="${SORTED} $1"
203 }
204
205 for MODULE in ${MODULES} ; do
206 visit "${MODULE}"
207 done
208
209 > "${MODULESLIST}"
210 i=0
211 for MODULE in ${SORTED} ; do
212 eval PROGRAM=\$${MODULE}_program
213 eval PROGRAM_START=\$${MODULE}_program_start
214 eval PROGRAM_STOP=\$${MODULE}_program_stop
215 #for x in ${PROGRAM} ; do
216 # [ -x "${x}" ] || continue 2
217 #done
218 eval PROVIDE=\$${MODULE}_provide
219 echo "module_${i}='${MODULE}'" >> "${MODULESLIST}"
220 echo "module_${i}_program='${PROGRAM}'" >> "${MODULESLIST}"
221 echo "module_${i}_program_start='${PROGRAM_START}'" >> "${MODULESLIST}"
222 echo "module_${i}_program_stop='${PROGRAM_STOP}'" >> "${MODULESLIST}"
223 echo "module_${i}_provide='${PROVIDE}'" >> "${MODULESLIST}"
224 i=$((${i} + 1))
225 done
226 echo "module_${i}=" >> "${MODULESLIST}"
227 )
228
229 return 0
230 }
231
232 _load_modules() {
233 # Ensure our list is up to date
234 _gen_module_list
235
236 local starting=$1 mymods=
237
238 MODULES=
239 if [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] ; then
240 eval mymods=\$modules_${IFVAR}
241 [ -z "${mymods}" ] && mymods=${modules}
242 fi
243
244 . "${MODULESLIST}"
245 local i=-1 x= mod= f= provides=
246 while true ; do
247 i=$((${i} + 1))
248 eval mod=\$module_${i}
249 [ -z "${mod}" ] && break
250 [ -e "${MODULESDIR}/${mod}.sh" ] || continue
251
252 eval set -- \$module_${i}_program
253 if [ -n "$1" ] ; then
254 x=
255 for x in "$@" ; do
256 [ -x "${x}" ] && break
257 done
258 [ -x "${x}" ] || continue
259 fi
260 if ${starting} ; then
261 eval set -- \$module_${i}_program_start
262 else
263 eval set -- \$module_${i}_program_stop
264 fi
265 if [ -n "$1" ] ; then
266 x=
267 for x in "$@" ; do
268 [ -x "${x}" ] && break
269 done
270 [ -x "${x}" ] || continue
271 fi
272
273 eval provides=\$module_${i}_provide
274 if ${starting} ; then
275 case " ${mymods} " in
276 *" !${mod} "*) continue ;;
277 *" !${provides} "*) [ -n "${provides}" ] && continue ;;
278 esac
279 fi
280 MODULES="${MODULES}${MODULES:+ }${mod}"
281
282 # Now load and wrap our functions
283 if ! . "${MODULESDIR}/${mod}.sh" ; then
284 eend 1 "${SVCNAME}: error loading module \`${mod}'"
285 exit 1
286 fi
287
288 [ -z "${provides}" ] && continue
289
290 # Wrap our provides
291 local f=
292 for f in pre_start start post_start ; do
293 eval "${provides}_${f}() { type ${mod}_${f} >/dev/null 2>/dev/null || return 0; ${mod}_${f} \"\$@\"; }"
294 done
295
296 eval module_${mod}_provides="${provides}"
297 eval module_${provides}_providedby="${mod}"
298 done
299
300 # Wrap our preferred modules
301 for mod in ${mymods} ; do
302 case " ${MODULES} " in
303 *" ${mod} "*)
304 eval x=\$module_${mod}_provides
305 [ -z "${x}" ] && continue
306 for f in pre_start start post_start ; do
307 eval "${x}_${f}() { type ${mod}_${f} >/dev/null 2>/dev/null || return 0; ${mod}_${f} \"\$@\"; }"
308 done
309 eval module_${x}_providedby="${mod}"
310 ;;
311 esac
312 done
313
314 # Finally remove any duplicated provides from our list if we're starting
315 # Otherwise reverse the list
316 local LIST="${MODULES}" p=
317 MODULES=
318 if ${starting} ; then
319 for mod in ${LIST} ; do
320 eval x=\$module_${mod}_provides
321 if [ -n "${x}" ] ; then
322 eval p=\$module_${x}_providedby
323 [ "${mod}" != "${p}" ] && continue
324 fi
325 MODULES="${MODULES}${MODULES:+ }${mod}"
326 done
327 else
328 for mod in ${LIST} ; do
329 MODULES="${mod}${MODULES:+ }${MODULES}"
330 done
331 fi
332
333 veinfo "Loaded modules: ${MODULES}"
334 }
335
336 _load_config() {
337 eval "$(_get_array "config_${IFVAR}")"
338 if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ] ; then
339 set -- "127.0.0.1/8" "$@"
340 else
341 if [ $# -eq 0 ] ; then
342 ewarn "No configuration specified; defaulting to DHCP"
343 set -- "dhcp"
344 fi
345 fi
346
347 # We store our config in an array like vars
348 # so modules can influence it
349 config_index=0
350 for cmd in "$@" ; do
351 eval config_${config_index}="'${cmd}'"
352 config_index=$((${config_index} + 1))
353 done
354 # Terminate the list
355 eval config_${config_index}=
356
357 config_index=0
358 eval $(_get_array fallback_${IFVAR})
359 for cmd in "$@" ; do
360 eval fallback_${config_index}="'${cmd}'"
361 config_index=$((${config_index} + 1))
362 done
363 # Terminate the list
364 eval fallback_${config_index}=
365
366 # Don't set to zero, so any net modules don't have to do anything extra
367 config_index=-1
368 }
369
370 start() {
371 local IFACE=${SVCNAME#*.} oneworked=false module=
372 local IFVAR=$(_shell_var "${IFACE}") cmd= metric=0 our_metric=$metric
373
374 einfo "Bringing up interface ${IFACE}"
375 eindent
376
377 if [ -z "${MODULES}" ] ; then
378 local MODULES=
379 _load_modules true
380 fi
381
382 _up 2>/dev/null
383
384 if type preup >/dev/null 2>/dev/null ; then
385 ebegin "Running preup"
386 eindent
387 preup || return 1
388 eoutdent
389 fi
390
391 for module in ${MODULES} ; do
392 if type "${module}_pre_start" >/dev/null 2>/dev/null ; then
393 if ! ${module}_pre_start ; then
394 eend 1
395 exit 1
396 fi
397 fi
398 done
399
400 if ! _exists ; then
401 eerror "ERROR: interface ${IFACE} does not exist"
402 eerror "Ensure that you have loaded the correct kernel module for your hardware"
403 return 1
404 fi
405
406 if ! _wait_for_carrier ; then
407 if service_started devd ; then
408 ewarn "no carrier, but devd will start us when we have one"
409 mark_service_inactive "${SVCNAME}"
410 else
411 eerror "no carrier"
412 fi
413 return 1
414 fi
415
416 local config= config_index=
417 _load_config
418 config_index=0
419
420 if [ -n "${our_metric}" ] ; then
421 metric=${our_metric}
422 elif [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] ; then
423 metric=$((${metric} + $(_ifindex)))
424 fi
425
426 while true ; do
427 eval config=\$config_${config_index}
428 [ -z "${config}" ] && break
429
430 set -- "${config}"
431 ebegin "$1"
432 eindent
433 case "$1" in
434 noop)
435 if [ -n "$(_get_inet_address)" ] ; then
436 oneworked=true
437 break
438 fi
439 ;;
440 null) : ;;
441 [0-9]*|*:*) _add_address ${config} ;;
442 *)
443 if type "${config}_start" >/dev/null 2>/dev/null ; then
444 "${config}"_start
445 else
446 eerror "nothing provides \`${config}'"
447 fi
448 ;;
449 esac
450 if eend $? ; then
451 oneworked=true
452 else
453 eval config=\$fallback_${IFVAR}
454 if [ -n "${config}" ] ; then
455 einfo "Trying fallback configuration"
456 eval config_${config_index}=\$fallback_${IFVAR}
457 eval fallback_${config_index}=
458 config_index=$((${config_index} - 1))
459 fi
460 fi
461 eoutdent
462 config_index=$((${config_index} + 1))
463 done
464
465 if ! ${oneworked} ; then
466 if type failup >/dev/null 2>/dev/null ; then
467 ebegin "Running failup"
468 eindent
469 failup
470 eoutdent
471 fi
472 return 1
473 fi
474
475 local hidefirstroute=false first=true routes=
476 eval "$(_get_array "routes_${IFVAR}")"
477 if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ] ; then
478 set -- "127.0.0.0/8 via 127.0.0.1" "$@"
479 hidefirstroute=true
480 fi
481 for cmd in "$@" ; do
482 if ${first} ; then
483 first=false
484 einfo "Adding routes"
485 fi
486 eindent
487 ebegin "${cmd}"
488 # Work out if we're a host or a net if not told
489 case "${cmd}" in
490 *" -net "*|*" -host "*) ;;
491 *" netmask "*) cmd="-net ${cmd}" ;;
492 *)
493 case "${cmd%% *}" in
494 *.*.*.*/32) cmd="-host ${cmd}" ;;
495 *.*.*.*/*|0.0.0.0|default) cmd="-net ${cmd}" ;;
496 *) cmd="-host ${cmd}" ;;
497 esac
498 ;;
499 esac
500 if ${hidefirstroute} ; then
501 _add_route ${cmd} >/dev/null 2>/dev/null
502 hidefirstroute=false
503 else
504 _add_route ${cmd} >/dev/null
505 fi
506 eend $?
507 eoutdent
508 done
509
510 for module in ${MODULES} ; do
511 if type "${module}_post_start" >/dev/null 2>/dev/null ; then
512 if ! ${module}_post_start ; then
513 eend 1
514 exit 1
515 fi
516 fi
517 done
518
519 if type postup >/dev/null 2>/dev/null ; then
520 ebegin "Running postup"
521 eindent
522 postup
523 eoutdent
524 fi
525
526 return 0
527 }
528
529 stop() {
530 local IFACE=${SVCNAME#*.} module=
531 local IFVAR=$(_shell_var "${IFACE}") opts=
532
533 einfo "Bringing down interface ${IFACE}"
534 eindent
535
536 if [ -z "${MODULES}" ] ; then
537 local MODULES=
538 _load_modules false
539 fi
540
541 if type predown >/dev/null 2>/dev/null ; then
542 ebegin "Running predown"
543 eindent
544 predown || return 1
545 eoutdent
546 fi
547
548 for module in ${MODULES} ; do
549 if type "${module}_pre_stop" >/dev/null 2>/dev/null ; then
550 if ! ${module}_pre_stop ; then
551 eend 1
552 exit 1
553 fi
554 fi
555 done
556
557 for module in ${MODULES} ; do
558 if type "${module}_stop" >/dev/null 2>/dev/null ; then
559 ${module}_stop
560 fi
561 done
562
563 # Only delete addresses for non PPP interfaces
564 if ! type is_ppp >/dev/null 2>/dev/null || ! is_ppp ; then
565 _delete_addresses "${IFACE}"
566 fi
567
568 for module in ${MODULES} ; do
569 if type "${module}_post_stop" >/dev/null 2>/dev/null ; then
570 ${module}_post_stop
571 fi
572 done
573
574 [ "${IN_BACKGROUND}" != "true" ] && \
575 [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] && \
576 _down 2>/dev/null
577
578 [ -x /sbin/resolvconf ] && resolvconf -d "${IFACE}"
579
580 if type postdown >/dev/null 2>/dev/null ; then
581 ebegin "Running postdown"
582 eindent
583 postdown
584 eoutdent
585 fi
586
587 return 0
588 }
589
590 # vim: set ts=4 sw=4 :

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20