/[baselayout]/branches/bsd-porting/net-scripts/init.d/net.lo
Gentoo

Contents of /branches/bsd-porting/net-scripts/init.d/net.lo

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1537 - (show annotations) (download)
Wed Sep 14 11:30:45 2005 UTC (9 years ago) by uberlord
File size: 26985 byte(s)
    netplug module renamed to netplugd for consistency

    pppd module added, #53954 thanks to Alin Nastac

1 #!/sbin/runscript
2 # Copyright (c) 2004-2005 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # Contributed by Roy Marples (uberlord@gentoo.org)
6 # Many thanks to Aron Griffis (agriffis@gentoo.org)
7 # for help, ideas and patches
8
9 #NB: Config is in /etc/conf.d/net
10
11 # For pcmcia users. note that pcmcia must be added to the same
12 # runlevel as the net.* script that needs it.
13 depend() {
14 need localmount
15 use coldplug pcmcia usb isdn wlan
16
17 # Load any custom depend functions for the given interface
18 # For example, br0 may need eth0 and eth1
19 local iface="${myservice##*.}"
20 [[ $( type -t depend_${iface} ) == "function" ]] && depend_${iface}
21
22 return 0
23 }
24
25 # Define where our modules are
26 MODULES_DIR="/lib/rcscripts/net.modules.d"
27
28 # Some defaults
29 background="${background:-no}"
30
31 # Load some functions shared between ourselves and our dhcp helpers
32 source "${MODULES_DIR}/helpers.d/functions"
33
34 # Make some wrappers to fudge after/before/need/use depend flags.
35 # These are callbacks so MODULE will be set.
36 after() {
37 local x="$*"
38 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
39 eval "${MODULE}_after() { echo \"$x\"; }"
40 }
41 before() {
42 local x="$*"
43 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
44 eval "${MODULE}_before() { echo \"$x\"; }"
45 }
46 need() {
47 local x="$*"
48 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
49 eval "${MODULE}_need() { echo \"$x\"; }"
50 }
51 installed() {
52 local x="$*"
53 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
54 # We deliberately misspell this as _installed will probably be used
55 # at some point
56 eval "${MODULE}_instlled() { echo \"$x\"; }"
57 }
58
59 sort() {
60 LC_ALL=C /bin/sort "$@"
61 }
62
63 # void go_background(void)
64 #
65 # Setup for backgrounding network script
66 go_background() {
67 einfo "Backgrounding ..."
68 mark_service_inactive "net.${iface}"
69 exit 0
70 }
71
72 # bool module_load_minimum(char *module)
73 #
74 # Does the minimum checking on a module - even when forcing
75 module_load_minimum() {
76 local f="$1" MODULE="${1##*/}"
77
78 if [[ ! -f ${f} ]]; then
79 eerror "${f} does not exist"
80 return 1
81 fi
82
83 if ! source "${f}" ; then
84 eerror "${MODULE} failed a sanity check"
85 return 1
86 fi
87
88 for f in check_installed provides check_depends depend; do
89 [[ $( type -t "${MODULE}_${f}" ) == "function" ]] && continue
90 eerror "${MODULE} does not support the required function ${f}"
91 return 1
92 done
93
94 return 0
95 }
96
97 # bool modules_load_auto()
98 #
99 # Load and check each module for sanity
100 # If the module is not installed, the functions are to be removed
101 modules_load_auto() {
102 local i j
103
104 # Populate the MODULES array
105 # Basically we treat evey file in ${MODULES_DIR} as a module
106 MODULES=( $( cd "${MODULES_DIR}" ; ls ) )
107 j="${#MODULES[@]}"
108 for (( i=0; i<j; i++ )); do
109 MODULES[i]="${MODULES_DIR}/${MODULES[i]}"
110 [[ ! -f ${MODULES[i]} ]] && unset MODULES[i]
111 done
112 MODULES=( "${MODULES[@]}" )
113
114 # Each of these sources into the global namespace, so it's
115 # important that module functions and variables are prefixed with
116 # the module name, for example iproute2_
117
118 j="${#MODULES[@]}"
119 loaded_interface=false
120 for (( i=0; i<j; i++ )); do
121 if [[ ${MODULES[i]##*/} == "interface" ]]; then
122 eerror "interface is a reserved name - cannot load a module called interface"
123 return 1
124 fi
125 (
126 u=0;
127 module_load_minimum "${MODULES[i]}" || u=1;
128 [[ ${u} == 0 ]] && ${MODULES[i]##*/}_check_installed false || u=1;
129 exit "${u}";
130 )
131
132 if [[ $? == 0 ]]; then
133 source "${MODULES[i]}"
134 MODULES[i]="${MODULES[i]##*/}"
135 else
136 unset MODULES[i]
137 fi
138 done
139
140 MODULES=( "${MODULES[@]}" )
141 return 0
142 }
143
144 # bool modules_check_installed(void)
145 #
146 # Ensure that all modules have the required modules loaded
147 # This enables us to remove modules from the MODULES array
148 # Whilst other modules can still explicitly call them
149 # One example of this is essidnet which configures network
150 # settings for the specific ESSID connected to as the user
151 # may be using a daemon to configure wireless instead of our
152 # iwconfig module
153 modules_check_installed() {
154 local i j missingdeps nmods="${#MODULES[@]}"
155
156 for (( i=0; i<nmods; i++ )); do
157 [[ $( type -t "${MODULES[i]}_instlled" ) != "function" ]] && continue
158 for j in $( ${MODULES[i]}_instlled ); do
159 missingdeps=true
160 if [[ $( type -t "${j}_check_installed" ) == "function" ]]; then
161 ${j}_check_installed && missingdeps=false
162 fi
163 ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break
164 done
165 done
166
167 MODULES=( "${MODULES[@]}" )
168 PROVIDES=( "${PROVIDES[@]}" )
169 }
170
171 # bool modules_check_user(void)
172 modules_check_user() {
173 local -a umods
174 local i j k l npref nmods="${#MODULES[@]}"
175
176 # Has the interface got any specific modules?
177 eval umods=( \"\$\{modules_${iface}\[@\]\}\" )
178
179 # Global setting follows interface-specific setting
180 umods=( "${umods[@]}" "${modules[@]}" )
181
182 # Add our preferred modules
183 npref=3
184 umods=( "${umods[@]}" "iproute2" "dhcpcd" "iwconfig" "netplugd" )
185
186 # First we strip any modules that conflict from user settings
187 # So if the user specifies pump then we don't use dhcpcd
188 for (( i=0; i<${#umods[@]}; i++ )); do
189 # Some users will inevitably put "dhcp" in their modules
190 # list. To keep users from screwing up their system this
191 # way, ignore this setting so that the default dhcp
192 # module will be used.
193 [[ ${umods[i]} == "dhcp" ]] && continue
194
195 # We remove any modules we explicitly don't want
196 if [[ ${umods[i]} == !* ]]; then
197 for (( j=0; j<nmods; j++ )); do
198 [[ -z ${MODULES[j]} ]] && continue
199 if [[ ${umods[i]:1} == "${MODULES[j]}" \
200 || ${umods[i]:1} == "${PROVIDES[j]}" ]]; then
201 # We may need to setup a class wrapper for it even though
202 # we don't use it directly
203 # However, we put it into an array and wrap later as
204 # another module may provide the same thing
205 ${MODULES[j]}_check_installed \
206 && WRAP_MODULES=(
207 "${WRAP_MODULES[@]}"
208 "${MODULES[j]} ${PROVIDES[j]}"
209 )
210 unset MODULES[j]
211 unset PROVIDES[j]
212 break
213 fi
214 done
215 continue
216 fi
217
218 if [[ $( type -t "${umods[i]}_provides" ) != "function" ]]; then
219 # If the module is one of our preferred modules, then
220 # ignore this error; whatever is available will be
221 # used instead.
222 (( i < ${#umods[@]} - npref )) || continue
223
224 # The function may not exist because the modules software is
225 # not installed. Load the module and report its error
226 if [[ -e "${MODULES_DIR}/${umods[i]}" ]]; then
227 source "${MODULES_DIR}/${umods[i]}"
228 ${umods[i]}_check_installed true
229 else
230 eerror "The module \"${umods[i]}\" does not exist"
231 fi
232 return 1
233 fi
234
235 mod=$( ${umods[i]}_provides )
236 for (( j=0; j<nmods; j++ )); do
237 [[ -z ${MODULES[j]} ]] && continue
238 if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]]; then
239 # We don't have a match - now ensure that we still provide an
240 # alternative. This is to handle our preferred modules.
241 for (( l=0; l<nmods; l++ )); do
242 [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue
243 if [[ ${PROVIDES[l]} == "${mod}" ]]; then
244 unset MODULES[j]
245 unset PROVIDES[j]
246 break
247 fi
248 done
249 fi
250 done
251 done
252
253 # Then we strip conflicting modules.
254 # We only need to do this for 3rd party modules that conflict with
255 # our own modules and the preferred list AND the user modules
256 # list doesn't specify a preference.
257 for (( i=0; i<nmods-1; i++ )); do
258 [[ -z ${MODULES[i]} ]] && continue
259 for (( j=i+1; j<nmods; j++)); do
260 [[ -z ${MODULES[j]} ]] && continue
261 [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \
262 && unset MODULES[j] && unset PROVIDES[j]
263 done
264 done
265
266 MODULES=( "${MODULES[@]}" )
267 PROVIDES=( "${PROVIDES[@]}" )
268 return 0
269 }
270
271 # void modules_sort(void)
272
273 modules_sort() {
274 local -a modnums sort_history modafter modbefore
275 local i j k p changed_something nmods="${#MODULES[@]}"
276
277 # Sort our modules
278 # We do this by assigning numbers to each module
279 # We also assign modbefore and modafter so we don't
280 # shell out as much because it's expensive on CPU.
281 modnums=()
282 for (( i=0; i<nmods; i++ )); do
283 modnums[i]="${i}"
284 [[ $( type -t "${MODULES[i]}_after" ) == "function" ]] \
285 && modafter[i]=$( ${MODULES[i]}_after )
286 [[ $( type -t "${MODULES[i]}_before" ) == "function" ]] \
287 && modbefore[i]=$( ${MODULES[i]}_before )
288 done
289
290 # Then we swap numbers based on and after/before flags
291 # until we don't swap anymore. The sort_history array prevents
292 # the possibility of an infinite loop
293 sort_history[0]="${modnums[*]}"
294 for (( k=1; 1; k++ )); do
295 changed_something=false
296 for (( i=0; i<nmods; i++ )); do
297 for p in ${modafter[i]}; do
298 for (( j=0; j<nmods; j++ )); do
299 [[ ${p} != "${MODULES[j]}" && ${p} != "${PROVIDES[j]}" ]] \
300 && continue
301
302 if [[ ${modnums[i]} -lt "${modnums[j]}" ]]; then
303 tmp="${modnums[i]}"
304 modnums[i]="${modnums[j]}"
305 modnums[j]="${tmp}"
306 changed_something=true
307 fi
308 done
309 done
310 for p in ${modbefore[i]}; do
311 for (( j=0; j<nmods; j++ )); do
312 [[ ${p} != "${MODULES[j]}" && ${p} != "${PROVIDES[j]}" ]] \
313 && continue
314
315 if [[ ${modnums[i]} -gt "${modnums[j]}" ]]; then
316 tmp="${modnums[i]}"
317 modnums[i]="${modnums[j]}"
318 modnums[j]="${tmp}"
319 changed_something=true
320 fi
321 done
322 done
323 done
324 ${changed_something} || break
325
326 # Make sure we aren't repeating a previous state
327 # First time through, k=1, k/2=0
328 sort_history[k]="${modnums[*]}"
329 if [[ ${sort_history[k]} == "${sort_history[k/2]}" ]]; then
330 eerror "Detected an infinite loop sorting modules; blundering ahead"
331 break
332 fi
333 done
334
335 # Finally we sort our modules in number order
336 um=""
337 for (( i=0; i<nmods; i++ )); do
338 um="${um}${modnums[i]} ${MODULES[i]} ${PROVIDES[i]}\n"
339 done
340
341 p=( $( echo -e "${um}" | sort -n | cut -d' ' -f2,3 ) )
342 MODULES=()
343 PROVIDES=()
344 j=0
345 for (( i=0; i<${#p[@]}; i+=2 )); do
346 MODULES[j]="${p[i]}"
347 PROVIDES[j]="${p[i+1]}"
348 (( j++ ))
349 done
350 }
351
352 # bool modules_check_depends(bool showprovides)
353 modules_check_depends() {
354 local showprovides="${1:-false}" nmods="${#MODULES[@]}" i j needmod
355 local missingdeps p interface=false
356
357 for (( i=0; i<nmods; i++ )); do
358 if [[ $( type -t "${MODULES[i]}_need" ) == "function" ]]; then
359 for needmod in $( ${MODULES[i]}_need ); do
360 missingdeps=true
361 for (( j=0; j<nmods; j++ )); do
362 if [[ ${needmod} == "${MODULES[j]}" \
363 || ${needmod} == "${PROVIDES[j]}" ]]; then
364 missingdeps=false
365 break
366 fi
367 done
368 if ${missingdeps} ; then
369 eerror "${MODULES[i]} needs ${needmod} (dependency failure)"
370 return 1
371 fi
372 done
373 fi
374
375 ${MODULES[i]}_check_depends || return 1
376 [[ ${PROVIDES[i]} == "interface" ]] && interface=true
377
378 if ${showprovides} ; then
379 [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \
380 && veinfo "${MODULES[i]} provides ${PROVIDES[i]}"
381 fi
382 done
383
384 if ! ${interface} ; then
385 eerror "no interface module has been loaded"
386 return 1
387 fi
388
389 return 0
390 }
391
392 # bool modules_load(char *iface, bool starting)
393 #
394 # Loads the defined handler and modules for the interface
395 # Returns 0 on success, otherwise 1
396 modules_load() {
397 local iface="$1" starting="${2:-true}" MODULE p=false i j k
398 local -a x
399 local RC_INDENTATION="${RC_INDENTATION}"
400 local -a PROVIDES WRAP_MODULES
401
402 if [[ ${iface} != "lo" ]]; then
403 eval x=( \"\$\{modules_force_${iface}\[@\]\}\" )
404 [[ -n ${x} ]] && modules_force=( "${x[@]}" )
405 if [[ -n ${modules_force} ]]; then
406 ewarn "WARNING: You are forcing modules!"
407 ewarn "Do not complain or file bugs if things start breaking"
408 report=true
409 fi
410 fi
411
412 veinfo "Loading networking modules for ${iface}"
413 eindent
414
415 if [[ -z ${modules_force} ]]; then
416 modules_load_auto || return 1
417 else
418 j="${#modules_force[@]}"
419 for (( i=0; i<j; i++ )); do
420 module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1
421 ${modules_force[i]}_check_installed || unset modules_force[i]
422 done
423 modules_force=( "${modules_force[@]}" )
424
425 # Strip any duplicate modules providing the same thing
426 j="${#modules_force[@]}"
427 for (( i=0; i<j-1; i++ )); do
428 [[ -z ${modules_force[i]} ]] && continue
429 for (( k=i+1; k<j; k++ )); do
430 [[ -z ${modules_force[k]} ]] && continue
431 [[ $( ${modules_force[i]}_provides ) \
432 == $( ${modules_force[k]}_provides ) ]] \
433 && unset modules_force[k]
434 done
435 done
436
437 MODULES=( "${modules_force[@]}" )
438 fi
439
440 # We now buffer the _provides functions for a big speed boost
441 j="${#MODULES[@]}"
442 for (( i=0; i<j; i++ )); do
443 PROVIDES[i]=$( ${MODULES[i]}_provides )
444 done
445
446 if [[ -z ${modules_force[@]} ]]; then
447 if ${starting}; then
448 modules_check_user || return 1
449 fi
450 fi
451
452 # Setup class wrappers: interface_up -> iproute2_up, for example
453 j="${#MODULES[@]}"
454 for (( i=0; i<j; i++ )); do
455 function_wrap "${MODULES[i]}" "${PROVIDES[i]}"
456
457 # Now load our dependencies - we need to use the MODULE variable
458 # here as the after/before/need functions use it
459 if [[ -z ${modules_force[@]} ]]; then
460 MODULE="${MODULES[i]}"
461 ${MODULE}_depend
462 fi
463 done
464
465 # Some modules may be installed, but not selected by user preference
466 # so we wrap these if needed
467 j="${#WRAP_MODULES[@]}"
468 for (( i=0; i<j; i++ )); do
469 function_wrap "${WRAP_MODULES[i]}"
470 done
471
472 if [[ -z ${modules_force[@]} ]]; then
473 modules_check_installed || return 1
474 modules_sort || return 1
475 fi
476
477 veinfo "modules: ${MODULES[@]}"
478 eindent
479
480 ${starting} && p=true
481 modules_check_depends "${p}" || return 1
482 return 0
483 }
484
485 # bool iface_start(char *interface)
486 #
487 # iface_start is called from start. It's expected to start the base
488 # interface (for example "eth0"), aliases (for example "eth0:1") and to start
489 # VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by
490 # calling itself recursively.
491 iface_start() {
492 local iface="$1" mod config_counter="-1" x config_worked=false
493 local RC_INDENTATION="${RC_INDENTATION}"
494 local -a config fallback fallback_route conf a
495 local ifvar=$( bash_variable "$1" ) i j
496
497 # Try and work out a metric for the interface if we're on auto
498 eval x=\"\$\{metric_${ifvar}\}\"
499 if [[ -z ${x} ]]; then
500 if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then
501 eval "metric_${ifvar}=\""$( calculate_metric ${iface} )"\""
502 else
503 eval "metric_${ifvar}=0"
504 fi
505 fi
506
507 # pre Start any modules with
508 for mod in ${MODULES[@]}; do
509 if [[ $( type -t "${mod}_pre_start" ) == "function" ]]; then
510 ${mod}_pre_start "${iface}" || { eend 1; return 1; }
511 fi
512 done
513
514 # We now expand the configuration parameters and pray that the
515 # fallbacks expand to the same number as config or there will be
516 # trouble!
517 eval a=( \"\$\{config_${ifvar}\[@\]\}\" )
518 for (( i=0; i<${#a[@]}; i++ )); do
519 local -a b=( $( expand_parameters "${a[i]}" ) )
520 config=( "${config[@]}" "${b[@]}" )
521 done
522
523 eval a=( \"\$\{fallback_${ifvar}\[@\]\}\" )
524 for (( i=0; i<${#a[@]}; i++ )); do
525 local -a b=( $( expand_parameters "${a[i]}" ) )
526 fallback=( "${fallback[@]}" "${b[@]}" )
527 done
528
529 # We don't expand routes
530 eval fallback_route=( \"\$\{fallback_route_${ifvar}\[@\]\}\" )
531
532 # We must support old configs
533 if [[ -z ${config} ]]; then
534 interface_get_old_config "${iface}" || return 1
535 if [[ -n ${config} ]]; then
536 ewarn "You are using a depreciated configuration syntax for ${iface}"
537 ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly"
538 fi
539 fi
540
541 # Handle "noop" correctly
542 if [[ ${config[0]} == "noop" ]]; then
543 if interface_is_up "${iface}" true ; then
544 einfo "Keeping current configuration for ${iface}"
545 eend 0
546 return 0
547 fi
548
549 # Remove noop from the config var
550 config=( "${config[@]:1}" )
551 fi
552
553 # Provide a default of DHCP if no configuration is set and we're auto
554 # Otherwise a default of NULL
555 if [[ -z ${config} ]]; then
556 # if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then
557 if [[ $( type -t "dhcp_start" ) == "function" ]]; then
558 config=( "dhcp" )
559 ewarn "Configuration not set for ${iface} - assuming dhcp"
560 else
561 eerror "Cannot default to dhcp as there is no dhcp module loaded"
562 eerror "No configuration for ${iface}"
563 return 1
564 fi
565 # else
566 # config=( "null" )
567 # ewarn "Configuration not set for ${iface} - assuming null"
568 # fi
569 fi
570
571 einfo "Bringing up ${iface}"
572 eindent
573 for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do
574 # Handle null and noop correctly
575 if [[ ${config[config_counter]} == "null" \
576 || ${config[config_counter]} == "noop" ]]; then
577 eend 0
578 config_worked=true
579 continue
580 fi
581
582 # We convert it to an array - this has the added
583 # bonus of trimming spaces!
584 conf=( ${config[config_counter]} )
585 einfo "${conf[0]}"
586
587 # Do we have a function for our config?
588 if [[ $( type -t "${conf[0]}_start" ) == "function" ]]; then
589 eindent
590 ${conf[0]}_start "${iface}" ; x=$?
591 eoutdent
592 [[ ${x} == 0 ]] && config_worked=true && continue
593 # We need to test to see if it's an IP address or a function
594 # We do this by testing if the 1st character is a digit
595 elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]]; then
596 x="0"
597 if [[ ${RC_AUTO_INTERFACE} == "yes" \
598 && $(type -t address_exists ) == "function" ]]; then
599 if address_exists "${iface}" "${conf[0]}" ; then
600 eerror "${conf[0]%%/*} already taken on ${iface}"
601 x="1"
602 fi
603 fi
604 [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?"
605 eend "${x}" && config_worked=true && continue
606 else
607 eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
608 fi
609
610 if [[ -n ${fallback[config_counter]} ]]; then
611 einfo "Trying fallback configuration"
612 config[config_counter]="${fallback[config_counter]}"
613 fallback[config_counter]=""
614
615 # Do we have a fallback route?
616 if [[ -n ${fallback_route[config_counter]} ]]; then
617 eval "routes_${ifvar}=( "\"\$\{fallback_route\[${config_counter}\]\[@\]\}\"" )"
618 fallback_route[config_counter]=""
619 fi
620
621 (( config_counter-- )) # since the loop will increment it
622 continue
623 fi
624 done
625 eoutdent
626
627 # We return failure if no configuration parameters worked
628 ${config_worked} || return 1
629
630 # Start any modules with _post_start
631 for mod in ${MODULES[@]}; do
632 if [[ $( type -t "${mod}_post_start" ) == "function" ]]; then
633 ${mod}_post_start "${iface}" || return 1
634 fi
635 done
636
637 return 0
638 }
639
640 # bool iface_stop(char *interface)
641 #
642 # iface_stop: bring down an interface. Don't trust information in
643 # /etc/conf.d/net since the configuration might have changed since
644 # iface_start ran. Instead query for current configuration and bring
645 # down the interface.
646 iface_stop() {
647 local iface="$1" i aliases need_begin=false mod
648 local RC_INDENTATION="${RC_INDENTATION}"
649
650 # pre Stop any modules
651 for mod in ${MODULES[@]}; do
652 [[ $( type -t "${mod}_pre_stop" ) == "function" ]] \
653 && ${mod}_pre_stop "${iface}"
654 done
655
656 einfo "Bringing down ${iface}"
657 eindent
658
659 # Collect list of aliases for this interface.
660 # List will be in reverse order.
661 aliases=$( interface_get_aliases_rev "${iface}" )
662
663 # Stop aliases before primary interface.
664 # Note this must be done in reverse order, since ifconfig eth0:1
665 # will remove eth0:2, etc. It might be sufficient to simply remove
666 # the base interface but we're being safe here.
667 for i in ${aliases} ${iface}; do
668 # Stop all our modules
669 for mod in ${MODULES[@]}; do
670 [[ $( type -t "${mod}_stop" ) == "function" ]] && ${mod}_stop "${i}"
671 done
672
673 # A module may have removed the interface
674 if ! interface_exists "${iface}" ; then
675 eend 0
676 continue
677 fi
678
679 # Delete all the addresses for this alias
680 interface_del_addresses "${i}"
681
682 # Do final shut down of this alias
683 if ! ${IN_BACKGROUND}; then
684 ebegin "Shutting down ${i}"
685 interface_iface_stop "${i}"
686 eend "$?"
687 fi
688 done
689
690 # post Stop any modules
691 for mod in ${MODULES[@]}; do
692 # We have already taken down the interface, so no need to error
693 [[ $( type -t "${mod}_post_stop" ) == "function" ]] \
694 && ${mod}_post_stop "${iface}"
695 done
696
697 return 0
698 }
699
700 # bool run_start(char *iface)
701 #
702 # Brings up ${IFACE}. Calls preup, iface_start, then postup.
703 # Returns 0 (success) unless preup or iface_start returns 1 (failure).
704 # Ignores the return value from postup.
705 # We cannot check that the device exists ourselves as modules like
706 # tuntap make create it.
707 run_start() {
708 local iface="$1" IFVAR=$( bash_variable "$1" )
709
710 # We do this so users can specify additional addresses for lo if they
711 # need too - additional routes too
712 # However, no extra modules are loaded as they are just not needed
713 if [[ ${iface} == "lo" ]]; then
714 metric_lo="0"
715 config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" )
716 routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" )
717 fi
718
719 # We may not have a loaded module for ${iface}
720 # Some users may have "alias natsemi eth0" in /etc/modules.d/foo
721 # so we can work with this
722 # However, if they do the same with eth1 and try to start it
723 # but eth0 has not been loaded then the module gets loaded as
724 # eth0.
725 # Not much we can do about this :(
726 # Also, we cannot error here as some modules - such as bridge
727 # create interfaces
728 if ! interface_exists "${iface}" ; then
729 /sbin/modprobe "${iface}" &>/dev/null
730 fi
731
732 # Call user-defined preup function if it exists
733 if [[ $( type -t preup ) == "function" ]]; then
734 einfo "Running preup function"
735 eindent
736 ( preup "${iface}" )
737 eend "$?" "preup ${iface} failed" || return 1
738 eoutdent
739 fi
740
741 # If config is set to noop and the interface is up with an address
742 # then we don't start it
743 local config
744 eval config=( \"\$\{config_${IFVAR}\[@\]\}\" )
745 if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then
746 einfo "Keeping current configuration for ${iface}"
747 eend 0
748 else
749 # Remove noop from the config var
750 [[ ${config[0]} == "noop" ]] \
751 && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )"
752
753 # There may be existing ip address info - so we strip it
754 interface_del_addresses "${iface}"
755
756 # Start the interface
757 if ! iface_start "${iface}" ; then
758 interface_exists "${iface}" && interface_down "${iface}"
759 eend 1
760 return 1
761 fi
762 fi
763
764 # Call user-defined postup function if it exists
765 if [[ $( type -t postup ) == "function" ]]; then
766 einfo "Running postup function"
767 eindent
768 ( postup "${iface}" )
769 eoutdent
770 fi
771
772 return 0
773 }
774
775 # bool run_stop(char *iface) {
776 #
777 # Brings down ${iface}. If predown call returns non-zero, then
778 # stop returns non-zero to indicate failure bringing down device.
779 # In all other cases stop returns 0 to indicate success.
780 run_stop() {
781 local iface="$1" IFVAR=$( bash_variable "$1" ) x
782
783 # Load our ESSID variable so users can use it in predown() instead
784 # of having to write code.
785 local ESSID=$( get_options "ESSID" ) ESSIDVAR
786 [[ -n ${ESSID} ]] && ESSIDVAR=$( bash_variable "${ESSID}" )
787
788 # Call user-defined predown function if it exists
789 if [[ $( type -t predown ) == "function" ]]; then
790 einfo "Running predown function"
791 eindent
792 ( predown "${iface}" )
793 eend $? "predown ${iface} failed" || return 1
794 eoutdent
795 elif is_net_fs /; then
796 eerror "root filesystem is network mounted -- can't stop ${iface}"
797 return 1
798 fi
799
800 iface_stop "${iface}" || return 1 # always succeeds, btw
801
802 # Call user-defined postdown function if it exists
803 if [[ $( type -t postdown ) == "function" ]]; then
804 einfo "Running postdown function"
805 eindent
806 ( postdown "${iface}" )
807 eoutdent
808 fi
809
810 return 0
811 }
812
813 # bool run(char *iface, char *cmd)
814 #
815 # Main start/stop entry point
816 # We load modules here and remove any functions that they
817 # added as we may be called inside the same shell scope for another interface
818 run() {
819 local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}"
820 local starting=true
821 local -a MODULES mods
822 local IN_BACKGROUND="${IN_BACKGROUND}"
823
824 # No point in backgrounding if we're already there ...
825 # This is also required so we can select the "best" interface
826 if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]]; then
827 IN_BACKGROUND=true
828 background=false
829 else
830 IN_BACKGROUND=false
831 fi
832
833 # We need to override the exit function as runscript.sh now checks
834 # for it. We need it so we can mark the service as inactive ourselves.
835 unset -f exit
836
837 eindent
838 [[ ${cmd} == "stop" ]] && starting=false
839
840 # We force lo to only use these modules for a major speed boost
841 [[ ${iface} == "lo" ]] && modules_force=( "iproute2" "ifconfig" "system" )
842
843 if modules_load "${iface}" "${starting}" ; then
844 if [[ ${cmd} == "stop" ]]; then
845 # Reverse the module list for stopping
846 mods=( "${MODULES[@]}" )
847 for ((i = 0; i < ${#mods[@]}; i++)); do
848 MODULES[i]=${mods[((${#mods[@]} - i - 1))]}
849 done
850
851 run_stop "${iface}" && r=0
852 remove_state "${iface}"
853 else
854 run_start "${iface}" && r=0
855 fi
856 fi
857
858 # Only apply best state if we're on auto
859 if [[ ${r} == "0" ]]; then
860 local siface=""
861 if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then
862 siface=$( select_best_interface )
863 if [[ -n ${siface} ]]; then
864 einfo "Selecting best interface: ${siface}"
865 fi
866 elif [[ ${cmd} == "start" ]]; then
867 siface="${iface}"
868 fi
869 [[ -n ${siface} ]] && apply_state "${siface}"
870 else
871 if [[ ${cmd} == "start" ]]; then
872 # Call user-defined failup if it exists
873 if [[ $( type -t failup ) == "function" ]]; then
874 einfo "Running failup function"
875 eindent
876 ( failup "${iface}" )
877 eoutdent
878 fi
879 else
880 # Call user-defined faildown if it exists
881 if [[ $( type -t faildown ) == "function" ]]; then
882 einfo "Running faildown function"
883 eindent
884 ( faildown "${iface}" )
885 eoutdent
886 fi
887 fi
888 fi
889
890 return "${r}"
891 }
892
893 # void link_file(char *file)
894 #
895 # Move a config file from /etc to ${netdir} and creates a link if needed.
896 # This enables net-scripts to control the config file for interface management
897 # and allow /etc to become read only.
898 link_file() {
899 local file="$1"
900 local link=$( readlink "/etc/${file}" 2>/dev/null )
901 if [[ ${link} != "${netdir}/${file}" ]]; then
902 if [[ -f "/etc/${file}" ]]; then
903 vewarn "Moving /etc/${file} to ${netdir}/${file} and creating link"
904 mv "/etc/${file}" "${netdir}"
905 ln -snf "${netdir}/${file}" "/etc/${file}"
906 fi
907 fi
908 }
909
910 # bool start(void)
911 #
912 # Start entry point so that we only have one function
913 # which localises variables and unsets functions
914 start() {
915 if [[ ${IN_HOTPLUG} == "1" ]]; then
916 # If we've been called by hotplug, check if we have
917 # a policy for the interface for not starting
918 local x ifvar=$( bash_variable "${IFACE}" )
919 eval x=\"\$\{hotplug_${ifvar}\}\"
920 if [[ ${x} == "no" || ${x} == "false" ]]; then
921 eerror "Not starting interface ${IFACE} due to hotplug policy"
922 unset -f exit
923 mark_service_stopped "net.${IFACE}"
924 exit 1
925 fi
926 fi
927
928 if [[ ! -d "${statedir}/${IFACE}" ]]; then
929 if ! mkdir -m 0755 -p "${statedir}/${IFACE}" ; then
930 eerror "Unable to create state directory!"
931 return 1
932 fi
933 fi
934
935 if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then
936 link_file "resolv.conf"
937 link_file "ntp.conf"
938 link_file "yp.conf"
939 fi
940
941 einfo "Starting ${IFACE}"
942 run "${IFACE}" start
943 }
944
945 # bool stop(void)
946 #
947 # Stop entry point so that we only have one function
948 # which localises variables and unsets functions
949 stop() {
950 einfo "Stopping ${IFACE}"
951 run "${IFACE}" stop
952 }
953
954 # vim:ts=4

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20