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

Contents of /trunk/sh/net.sh

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20