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

Contents of /trunk/sh/net.sh

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20