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

Contents of /trunk/sh/net.sh

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20