Guest User

Untitled

a guest
Jun 13th, 2025
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 20.44 KB | None | 0 0
  1. #!/sbin/openrc-run
  2. # shellcheck shell=sh disable=SC1008
  3. # Copyright (c) 2007-2009 Roy Marples <[email protected]>
  4. # Copyright (c) 2010-2016 Gentoo Foundation
  5. # Released under the 2-clause BSD license.
  6.  
  7. SHDIR="/lib/netifrc/sh"
  8. MODULESDIR="/lib/netifrc/net"
  9. _config_vars="config metric routes"
  10.  
  11. [ -z "${IN_BACKGROUND}" ] && IN_BACKGROUND="NO"
  12.  
  13. # shellcheck disable=SC2034
  14. description="Configures network interfaces."
  15.  
  16. # Handy var so we don't have to embed new lines everywhere for array splitting
  17. __IFS="
  18. "
  19.  
  20. #  Set the INIT to be openrc if this file is called directly
  21. : "${INIT:=openrc}"
  22.  
  23. if [ -f "$SHDIR/functions.sh" ]; then
  24.     # shellcheck disable=SC1090
  25.     . "$SHDIR/functions.sh"
  26. else
  27.     echo "$SHDIR/functions.sh missing. Exiting"
  28.     exit 1
  29. fi
  30.  
  31. # Create per-interface nettree ordering, avoids race conditions and allows
  32. # per-interface custom modules.
  33. MODULESLIST="${RC_SVCDIR}/nettree$(get_interface)"
  34.  
  35. depend()
  36. {
  37.     local IFACE IFVAR
  38.     IFACE=$(get_interface)
  39.     IFVAR=$(shell_var "${IFACE}")
  40.  
  41.     if [ "$RC_UNAME" = Linux ] && [ "$IFACE" != lo ]; then
  42.         need sysfs
  43.         after modules
  44.     fi
  45.     after bootmisc
  46.     keyword -jail -prefix -vserver
  47.  
  48.     case "${IFACE}" in
  49.         lo|lo0) ;;
  50.         *)
  51.             after net.lo net.lo0 dbus
  52.             need localmount
  53.             provide net
  54.             ;;
  55.     esac
  56.  
  57.     if [ "$(command -v "depend_${IFVAR}")" = "depend_${IFVAR}" ]; then
  58.         "depend_${IFVAR}"
  59.     fi
  60.  
  61.     local dep prov
  62.     for dep in need use before after provide keyword; do
  63.         eval prov=\$rc_${dep}_${IFVAR}
  64.         if [ -n "${prov}" ]; then
  65.             "${dep}" "${prov}"
  66.             ewarn "rc_${dep}_${IFVAR} is deprecated."
  67.             ewarn "Please use rc_net_${IFVAR}_${dep} instead."
  68.         fi
  69.     done
  70. }
  71.  
  72. # Support bash arrays - sigh
  73. _array_helper()
  74. {
  75.     local _a=
  76.  
  77.     eval _a=\$$1
  78.     _a=$(echo "${_a}" | sed -e 's:^[[:space:]]*::' -e 's:[[:space:]]*$::' -e '/^$/d' -e 's:[[:space:]]\{1,\}: :g')
  79.  
  80.     [ -n "${_a}" ] && printf "%s\n" "${_a}"
  81. }
  82.  
  83. _get_array()
  84. {
  85.     local _a=''
  86.     if [ -n "${BASH}" ]; then
  87.         # shellcheck disable=SC2039
  88.         case "$(declare -p "$1" 2>/dev/null)" in
  89.             "declare -a "*)
  90.                 ewarn "You are using a bash array for $1."
  91.                 ewarn "This feature will be removed in the future."
  92.                 ewarn "Please see net.example for the correct format for $1."
  93.                 eval "set -- \"\${$1[@]}\""
  94.                 for _a; do
  95.                     printf "%s\n" "${_a}"
  96.                 done
  97.                 return 0
  98.                 ;;
  99.         esac
  100.     fi
  101.  
  102.     _array_helper "$1"
  103. }
  104.  
  105. # Flatten bash arrays to simple strings
  106. _flatten_array()
  107. {
  108.     if [ -n "${BASH}" ]; then
  109.         # shellcheck disable=SC2039
  110.         case "$(declare -p "$1" 2>/dev/null)" in
  111.             "declare -a "*)
  112.                 ewarn "You are using a bash array for $1."
  113.                 ewarn "This feature will be removed in the future."
  114.                 ewarn "Please see net.example for the correct format for $1."
  115.                 eval "set -- \"\${$1[@]}\""
  116.                 for x; do
  117.                     # shellcheck disable=SC2059
  118.                     printf "'%s' " "$(printf "$x" | sed "s:':'\\\'':g")"
  119.                 done
  120.                 return 0
  121.                 ;;
  122.         esac
  123.     fi
  124.  
  125.     _array_helper "$1"
  126. }
  127.  
  128. _wait_for_presence()
  129. {
  130.     local timeout=
  131.     local rc=
  132.  
  133.     _exists && return 0
  134.  
  135.     eval timeout=\$presence_timeout_${IFVAR}
  136.     timeout=${timeout:-${presence_timeout:-0}}
  137.  
  138.     [ ${timeout} -le 0 ] && return 1
  139.  
  140.     einfon "Waiting for ${IFACE} to show up (${timeout} seconds)"
  141.     while [ ${timeout} -gt 0 ]; do
  142.         _exists
  143.         rc=$?
  144.         [ $rc -eq 0 ] && break
  145.  
  146.         sleep 1
  147.         printf "."
  148.         : $(( timeout -= 1 ))
  149.     done
  150.  
  151.     if [ ${timeout} -le 0 ]; then
  152.         _exists
  153.         rc=$?
  154.     fi
  155.     echo
  156.     eend $rc
  157. }
  158.  
  159. _wait_for_carrier()
  160. {
  161.     local timeout=
  162.  
  163.     _has_carrier  && return 0
  164.  
  165.     eval timeout=\$carrier_timeout_${IFVAR}
  166.     timeout=${timeout:-${carrier_timeout:-0}}
  167.  
  168.     # Incase users don't want this nice feature ...
  169.     [ ${timeout} -le 0 ] && return 0
  170.  
  171.     einfon "Waiting for carrier (${timeout} seconds) "
  172.     while [ ${timeout} -gt 0 ]; do
  173.         if _has_carrier; then
  174.             echo
  175.             eend 0
  176.             return 0
  177.         fi
  178.         sleep 1
  179.         : $(( timeout -= 1 ))
  180.         printf "."
  181.     done
  182.  
  183.     echo
  184.     eend 1
  185.     return 1
  186. }
  187.  
  188. _netmask2cidr()
  189. {
  190.     # Some shells cannot handle hex arithmetic, so we massage it slightly
  191.     # Buggy shells include FreeBSD sh, dash and busybox.
  192.     # bash and NetBSD sh don't need this.
  193.     case $1 in
  194.         0x*)
  195.         local hex=${1#0x*} quad=
  196.         while [ -n "${hex}" ]; do
  197.             local lastbut2=${hex#??*}
  198.             quad=${quad}${quad:+.}0x${hex%${lastbut2}*}
  199.             hex=${lastbut2}
  200.         done
  201.         # shellcheck disable=SC2086
  202.         set -- ${quad}
  203.         ;;
  204.     esac
  205.  
  206.     local i='' len=''
  207.     local IFS=.
  208.     for i in $1; do
  209.         case $i in
  210.             0x*)    i=$((i)) ;;
  211.         esac
  212.         while [ ${i} -ne 0 ]; do
  213.             : $(( len += i % 2 ))
  214.             : $(( i >>= 1 ))
  215.         done
  216.     done
  217.  
  218.     echo "${len}"
  219. }
  220.  
  221. _configure_variables()
  222. {
  223.     local var='' v='' t=''
  224.  
  225.     for var in ${_config_vars}; do
  226.         local v=
  227.         for t; do
  228.             eval v="\"\$${var}_${t}\""
  229.             if [ -n "${v}" ]; then
  230.                 eval "${var}_${IFVAR}=\"\$${var}_${t}\""
  231.                 continue 2
  232.             fi
  233.         done
  234.     done
  235. }
  236.  
  237. _which()
  238. {
  239.     local i OIFS
  240.     # Empty
  241.     [ -z "$1" ] && return
  242.     # check paths
  243.     OIFS="$IFS"
  244.     IFS=:
  245.     for i in $PATH ; do
  246.         [ -x "$i/$1" ] && echo "$i/$1" && break
  247.     done
  248.     IFS=$OIFS
  249. }
  250.  
  251. # Like _which, but also consider shell builtins, and multiple alternatives
  252. _program_available()
  253. {
  254.     [ -z "$1" ] && return 0
  255.     local x=
  256.     for x; do
  257.         case "${x}" in
  258.             /*) [ -x "${x}" ] && break;;
  259.             *) type "${x}" >/dev/null 2>&1 && break;;
  260.         esac
  261.         x=
  262.     done
  263.     [ -n "${x}" ] && echo $x && return 0
  264.     return 1
  265. }
  266.  
  267. _show_address()
  268. {
  269.     einfo "received address $(_get_inet_address "${IFACE}")"
  270. }
  271.  
  272. # Allow custom error handling behavior to be set by the user.
  273. # Known used combinations, with defaults
  274. # errh_IFVAR_address_EEXIST=warn
  275. # errh_IFVAR_route_EEXIST=warn
  276. _get_errorhandler_behavior() {
  277.     IFVAR="$1"
  278.     object="$2"
  279.     error="$3"
  280.     fallback="$4"
  281.     value=
  282.     for key in \
  283.         "errh_${IFVAR}_${object}_${error}" \
  284.         "errh_${IFVAR}_${object}_DEFAULT" \
  285.         "errh_${IFVAR}_DEFAULT_${error}" \
  286.         "errh_${IFVAR}_DEFAULT_DEFAULT" \
  287.         "errh_DEFAULT_${object}_${error}" \
  288.         "errh_DEFAULT_${object}_DEFAULT" \
  289.         "errh_DEFAULT_DEFAULT_${error}" \
  290.         "errh_DEFAULT_DEFAULT_DEFAULT" \
  291.         "errh" \
  292.         "fallback" ; do
  293.         eval value="\${${key}}"
  294.         if [ -n "$value" ]; then
  295.             echo "$value" && break
  296.         fi
  297.     done
  298. }
  299.  
  300. _show_address6()
  301. {
  302.     einfo "received address $(_get_inet6_address "${IFACE}")"
  303. }
  304.  
  305. # Basically sorts our modules into order and saves the list
  306. _gen_module_list()
  307. {
  308.     local x='' f='' force="$1"
  309.     if ! ${force} ; then
  310.         if [ -s "${MODULESLIST}" ] && [ "${MODULESLIST}" -nt /proc/$$/status ]; then
  311.             ewarn "Discarding cached module list ($MODULESLIST) as it's newer current time!"
  312.         elif [ -s "${MODULESLIST}" ] && [ "${MODULESLIST}" -nt "${MODULESDIR}" ]; then
  313.             local update=false
  314.             for x in "${MODULESDIR}"/*.sh; do
  315.                 [ -e "${x}" ] || continue
  316.                 if [ "${x}" -nt "${MODULESLIST}" ]; then
  317.                     update=true
  318.                     break
  319.                 fi
  320.             done
  321.             ${update} || return 0
  322.         fi
  323.     fi
  324.  
  325.     einfo "Caching network module dependencies"
  326.     # Run in a subshell to protect the main script
  327.     (
  328.     after() {
  329.         eval ${MODULE}_after="\"\${${MODULE}_after}\${${MODULE}_after:+ }$*\""
  330.     }
  331.  
  332.     before() {
  333.         local mod=${MODULE}
  334.         local MODULE=
  335.         for MODULE; do
  336.             after "${mod}"
  337.         done
  338.     }
  339.  
  340.     program() {
  341.         if [ "$1" = "start" ] || [ "$1" = "stop" ]; then
  342.             local s="$1"
  343.             shift
  344.             eval ${MODULE}_program_${s}="\"\${${MODULE}_program_${s}}\${${MODULE}_program_${s}:+ }$*\""
  345.         else
  346.             eval ${MODULE}_program="\"\${${MODULE}_program}\${${MODULE}_program:+ }$*\""
  347.         fi
  348.     }
  349.  
  350.     provide() {
  351.         eval ${MODULE}_provide="\"\${${MODULE}_provide}\${${MODULE}_provide:+ }$*\""
  352.         local x
  353.         for x in "$@"; do
  354.             eval ${x}_providedby="\"\${${MODULE}_providedby}\${${MODULE}_providedby:+ }${MODULE}\""
  355.         done
  356.     }
  357.  
  358.     for MODULE in "${MODULESDIR}"/*.sh; do
  359.         sh -n "${MODULE}" || continue
  360.         # shellcheck disable=SC1090
  361.         . "${MODULE}" || continue
  362.         MODULE=${MODULE#${MODULESDIR}/}
  363.         MODULE=${MODULE%.sh}
  364.         eval "${MODULE}_depend"
  365.         MODULES="${MODULES} ${MODULE}"
  366.     done
  367.  
  368.     VISITED=
  369.     SORTED=
  370.     visit() {
  371.         case " ${VISITED} " in
  372.             *" $1 "*) return;;
  373.         esac
  374.         VISITED="${VISITED} $1"
  375.  
  376.         eval AFTER=\$${1}_after
  377.         for MODULE1 in ${AFTER}; do
  378.             eval PROVIDEDBY=\$${MODULE1}_providedby
  379.             if [ -n "${PROVIDEDBY}" ]; then
  380.                 for MODULE2 in ${PROVIDEDBY}; do
  381.                     visit "${MODULE2}"
  382.                 done
  383.             else
  384.                 visit "${MODULE1}"
  385.             fi
  386.         done
  387.  
  388.         eval PROVIDE=\$${1}_provide
  389.         for MODULE in ${PROVIDE}; do
  390.             visit "${MODULE}"
  391.         done
  392.  
  393.         eval PROVIDEDBY=\$${1}_providedby
  394.         [ -z "${PROVIDEDBY}" ] && SORTED="${SORTED} $1"
  395.     }
  396.  
  397.     for MODULE in ${MODULES}; do
  398.         visit "${MODULE}"
  399.     done
  400.  
  401.     # Create atomically
  402.     TMPMODULESLIST=${MODULESLIST}.$$
  403.     printf "" > "${TMPMODULESLIST}"
  404.     i=0
  405.     for MODULE in ${SORTED}; do
  406.         eval PROGRAM=\$${MODULE}_program
  407.         eval PROGRAM_START=\$${MODULE}_program_start
  408.         eval PROGRAM_STOP=\$${MODULE}_program_stop
  409.         eval PROVIDE=\$${MODULE}_provide
  410.         echo "module_${i}='${MODULE}'"
  411.         echo "module_${i}_program='${PROGRAM}'"
  412.         echo "module_${i}_program_start='${PROGRAM_START}'"
  413.         echo "module_${i}_program_stop='${PROGRAM_STOP}'"
  414.         echo "module_${i}_provide='${PROVIDE}'"
  415.         : $(( i += 1 ))
  416.     done >> "${TMPMODULESLIST}"
  417.     echo "module_${i}=" >> "${TMPMODULESLIST}"
  418.     mv -f "${TMPMODULESLIST}" "${MODULESLIST}"
  419.     )
  420.  
  421.     return 0
  422. }
  423.  
  424. _load_modules()
  425. {
  426.     local starting=$1 mymods=
  427.  
  428.     # Ensure our list is up to date
  429.     _gen_module_list false
  430.     # shellcheck disable=SC1090
  431.     if ! . "${MODULESLIST}"; then
  432.         _gen_module_list true
  433.         # shellcheck disable=SC1090
  434.         . "${MODULESLIST}"
  435.     fi
  436.  
  437.     MODULES=
  438.     if [ "${IFACE}" != "lo" ] && [ "${IFACE}" != "lo0" ]; then
  439.         eval mymods=\$modules_${IFVAR}
  440.         # shellcheck disable=SC2154
  441.         [ -z "${mymods}" ] && mymods=${modules}
  442.     fi
  443.  
  444.     local i=-1 x='' mod='' f='' provides=''
  445.     while true; do
  446.         : $(( i += 1 ))
  447.         eval mod=\$module_${i}
  448.         [ -z "${mod}" ] && break
  449.         [ -e "${MODULESDIR}/${mod}.sh" ] || continue
  450.  
  451.         eval set -- \$module_${i}_program
  452.         if [ -n "$1" ]; then
  453.             if ! _program_available "$@" >/dev/null; then
  454.                 vewarn "Skipping module $mod due to missing program: $*"
  455.                 continue
  456.             fi
  457.         fi
  458.         if ${starting}; then
  459.             eval set -- \$module_${i}_program_start
  460.         else
  461.             eval set -- \$module_${i}_program_stop
  462.         fi
  463.         if [ -n "$1" ]; then
  464.             if ! _program_available "$@" >/dev/null; then
  465.                 vewarn "Skipping module $mod due to missing program: $*"
  466.                 continue
  467.             fi
  468.         fi
  469.  
  470.         eval provides=\$module_${i}_provide
  471.         if ${starting}; then
  472.             case " ${mymods} " in
  473.                 *" !${mod} "*) continue;;
  474.                 *" !${provides} "*) [ -n "${provides}" ] && continue;;
  475.             esac
  476.         fi
  477.         MODULES="${MODULES}${MODULES:+ }${mod}"
  478.  
  479.         # Now load and wrap our functions
  480.         # shellcheck disable=SC1090
  481.         if ! . "${MODULESDIR}/${mod}.sh"; then
  482.             eend 1 "${RC_SVCNAME}: error loading module \`${mod}'"
  483.             exit 1
  484.         fi
  485.  
  486.         [ -z "${provides}" ] && continue
  487.  
  488.         # Wrap our provides
  489.         local f=
  490.         for f in pre_start start post_start; do
  491.             inner=$(command -v "${mod}_${f}")
  492.             eval "${provides}_${f}() { [ '${inner}' = '${mod}_${f}' ] || return 0; ${mod}_${f} \"\$@\"; }"
  493.         done
  494.  
  495.         eval module_${mod}_provides="${provides}"
  496.         eval module_${provides}_providedby="${mod}"
  497.     done
  498.  
  499.     # Wrap our preferred modules
  500.     for mod in ${mymods}; do
  501.         case " ${MODULES} " in
  502.             *" ${mod} "*)
  503.             eval x=\$module_${mod}_provides
  504.             [ -z "${x}" ] && continue
  505.             for f in pre_start start post_start; do
  506.                 inner=$(command -v "${mod}_${f}")
  507.                 eval "${x}_${f}() { [ '${inner}' = '${mod}_${f}' ] || return 0; ${mod}_${f} \"\$@\"; }"
  508.             done
  509.             eval module_${x}_providedby="${mod}"
  510.             ;;
  511.         esac
  512.     done
  513.  
  514.     # Finally remove any duplicated provides from our list if we're starting
  515.     # Otherwise reverse the list
  516.     local LIST="${MODULES}" p=
  517.     MODULES=
  518.     if ${starting}; then
  519.         for mod in ${LIST}; do
  520.             eval x=\$module_${mod}_provides
  521.             if [ -n "${x}" ]; then
  522.                 eval p=\$module_${x}_providedby
  523.                 [ "${mod}" != "${p}" ] && continue
  524.             fi
  525.             MODULES="${MODULES}${MODULES:+ }${mod}"
  526.         done
  527.     else
  528.         for mod in ${LIST}; do
  529.             MODULES="${mod}${MODULES:+ }${MODULES}"
  530.         done
  531.     fi
  532.  
  533.     veinfo "Loaded modules: ${MODULES}"
  534. }
  535.  
  536. _load_config()
  537. {
  538.     local config='' fallback=''
  539.     config="$(_get_array "config_${IFVAR}")"
  540.     fallback="$(_get_array fallback_${IFVAR})"
  541.  
  542.     config_index=0
  543.     local IFS="$__IFS"
  544.     set -- ${config}
  545.  
  546.     # We should support a space separated array for cidr configs
  547.     # But only as long as they do not contain other parameters for the address
  548.     if [ $# = 1 ]; then
  549.         unset IFS
  550.         set -- ${config}
  551.         # Of course, we may have a single address added old style.
  552.         # If the NEXT argument is a v4 or v6 address, it's the next config.
  553.         # Otherwise, it's arguments to the first config...
  554.         if [ "${2#*.*}" = "${2}" ] && [  "${2#*:*}" = "${2}" ]; then
  555.             # Not an IPv4/IPv6
  556.             local IFS="$__IFS"
  557.             set -- ${config}
  558.         fi
  559.     fi
  560.  
  561.     # Ensure that loopback has the correct address
  562.     if [ "${IFACE}" = "lo" ] || [ "${IFACE}" = "lo0" ]; then
  563.         if [ "$1" != "null" ]; then
  564.             config_0="127.0.0.1/8"
  565.             config_index=1
  566.         fi
  567.     else
  568.         if [ -z "$1" ]; then
  569.             ewarn "config_${IFVAR} not specified; defaulting to DHCP"
  570.             config_0="dhcp"
  571.             config_index=1
  572.         fi
  573.     fi
  574.  
  575.  
  576.     # We store our config in an array like vars
  577.     # so modules can influence it
  578.     for cmd; do
  579.         eval config_${config_index}="'${cmd}'"
  580.         : $(( config_index += 1 ))
  581.     done
  582.     # Terminate the list
  583.     eval config_${config_index}=
  584.  
  585.     config_index=0
  586.     for cmd in ${fallback}; do
  587.         eval fallback_${config_index}="'${cmd}'"
  588.         : $(( config_index += 1 ))
  589.     done
  590.     # Terminate the list
  591.     eval fallback_${config_index}=
  592.  
  593.     # Don't set to zero, so any net modules don't have to do anything extra
  594.     config_index=-1
  595. }
  596.  
  597. # Support functions
  598. _run_if()
  599. {
  600.     local cmd=$1 iface=$2 ifr=${IFACE} ifv=${IFVAR}
  601.     # Ensure that we don't stamp on real values
  602.     local IFACE='' IFVAR=''
  603.     shift
  604.     if [ -n "${iface}" ]; then
  605.         IFACE="${iface}"
  606.         [ "${iface}" != "${ifr}" ] && IFVAR=$(shell_var "${IFACE}")
  607.     else
  608.         IFACE=${ifr}
  609.         IFVAR=${ifv}
  610.     fi
  611.     ${cmd}
  612. }
  613. interface_exists()
  614. {
  615.     _run_if _exists "$@"
  616. }
  617. interface_up()
  618. {
  619.     _run_if _up "$@"
  620. }
  621. interface_down()
  622. {
  623.     _run_if _down "$@"
  624. }
  625. set_interface_type()
  626. {
  627.     service_set_value iface_type "$@"
  628. }
  629. get_interface_type()
  630. {
  631.     ( RC_SVCNAME="net.$IFACE" service_get_value iface_type )
  632. }
  633. is_interface_type()
  634. {
  635.     [ "$(get_interface_type)" = "$1" ]
  636. }
  637.  
  638. start()
  639. {
  640.     local IFACE=''
  641.     local IFVAR=''
  642.     local oneworked=false
  643.     local fallback=false
  644.     local module=''
  645.     local cmd=''
  646.     local our_metric=''
  647.     local metric=0
  648.     local _up_before_preup=''
  649.     IFACE=$(get_interface)
  650.     IFVAR=$(shell_var "${IFACE}")
  651.     eval _up_before_preup="\$up_before_preup_${IFVAR}"
  652.     # shellcheck disable=SC2154
  653.     [ -z "${_up_before_preup}" ] && _up_before_preup=$up_before_preup
  654.  
  655.     einfo "Bringing up interface ${IFACE}"
  656.     eindent
  657.  
  658.     if [ -z "${MODULES}" ]; then
  659.         local MODULES=
  660.         _load_modules true
  661.     fi
  662.  
  663.     for module in ${MODULES}; do
  664.         if [ "$(command -v "${module}_pre_up")" = "${module}_pre_up" ]; then
  665.             ${module}_pre_up || exit $?
  666.         fi
  667.     done
  668.  
  669.     # We up the iface twice if we have a preup to ensure it's up if
  670.     # available in preup and afterwards incase the user inadvertently
  671.     # brings it down
  672.     if [ "$(command -v preup)" = "preup" ]; then
  673.         yesno "${_up_before_preup:-yes}" && _up 2>/dev/null
  674.         ebegin "Running preup"
  675.         eindent
  676.         preup || return 1
  677.         eoutdent
  678.     fi
  679.  
  680.     _up 2>/dev/null
  681.  
  682.     for module in ${MODULES}; do
  683.         if [ "$(command -v "${module}_pre_start")" = "${module}_pre_start" ]; then
  684.             ${module}_pre_start || exit $?
  685.         fi
  686.     done
  687.  
  688.     if ! _wait_for_presence; then
  689.         eerror "ERROR: interface ${IFACE} does not exist"
  690.         eerror "Ensure that you have loaded the correct kernel module for your hardware"
  691.         return 1
  692.     fi
  693.  
  694.     if ! _wait_for_carrier; then
  695.         if service_started devd; then
  696.             ewarn "no carrier, but devd will start us when we have one"
  697.             mark_service_inactive "${RC_SVCNAME}"
  698.         else
  699.             eerror "no carrier"
  700.         fi
  701.         return 1
  702.     fi
  703.  
  704.     local config='' config_index=''
  705.     _load_config
  706.     config_index=0
  707.  
  708.     eval our_metric=\$metric_${IFVAR}
  709.     if [ -n "${our_metric}" ]; then
  710.         metric=${our_metric}
  711.     elif [ "${IFACE}" != "lo" ] && [ "${IFACE}" != "lo0" ]; then
  712.         : $(( metric += $(_ifindex) ))
  713.     fi
  714.  
  715.     while true; do
  716.         eval config=\$config_${config_index}
  717.         [ -z "${config}" ] && break
  718.  
  719.         set -- ${config}
  720.         if [ "$1" != "null" ] && [ "$1" != "noop" ]; then
  721.             ebegin "$1"
  722.         fi
  723.         eindent
  724.         case "$1" in
  725.             noop)
  726.                 if [ -n "$(_get_inet_address)" ]; then
  727.                     oneworked=true
  728.                     break
  729.                 fi
  730.                 ;;
  731.             null) :;;
  732.             [0-9]*|*:*) _add_address ${config};;
  733.             *)
  734.                 if [ "$(command -v "${config}_start")" = "${config}_start" ]; then
  735.                     "${config}"_start
  736.                 else
  737.                     eerror "nothing provides \`${config}'"
  738.                 fi
  739.                 ;;
  740.         esac
  741.         if eend $?; then
  742.             oneworked=true
  743.         else
  744.             eval config=\$fallback_${config_index}
  745.             if [ -n "${config}" ]; then
  746.                 fallback=true
  747.                 eoutdent
  748.                 ewarn "Trying fallback configuration ${config}"
  749.                 eindent
  750.                 eval config_${config_index}=\$config
  751.                 unset fallback_${config_index}
  752.                 : $(( config_index -= 1 ))
  753.             fi
  754.         fi
  755.         eoutdent
  756.         : $(( config_index += 1 ))
  757.     done
  758.  
  759.     if ! ${oneworked}; then
  760.         if [ "$(command -v failup)" = "failup" ]; then
  761.             ebegin "Running failup"
  762.             eindent
  763.             failup
  764.             eoutdent
  765.         fi
  766.         return 1
  767.     fi
  768.  
  769.     local first=true routes=
  770.     if ${fallback}; then
  771.         routes="$(_get_array "fallback_routes_${IFVAR}")"
  772.     fi
  773.     if [ -z "${routes}" ]; then
  774.         routes="$(_get_array "routes_${IFVAR}")"
  775.     fi
  776.     if [ "${IFACE}" = "lo" ] || [ "${IFACE}" = "lo0" ]; then
  777.         if [ "${config_0}" != "null" ]; then
  778.             routes="127.0.0.0/8 via 127.0.0.1
  779. ${routes}"
  780.         fi
  781.     fi
  782.  
  783.     local OIFS="${IFS}" SIFS="${IFS-y}"
  784.     local IFS="$__IFS"
  785.     local fam
  786.     for cmd in ${routes}; do
  787.         unset IFS
  788.         if ${first}; then
  789.             first=false
  790.             einfo "Adding routes"
  791.         fi
  792.  
  793.         case ${cmd} in
  794.             -6" "*) fam="-6"; cmd=${cmd#-6 };;
  795.             -4" "*) fam="-4"; cmd=${cmd#-4 };;
  796.         esac
  797.  
  798.         eindent
  799.         ebegin ${cmd}
  800.         # Work out if we're a host or a net if not told
  801.         case ${cmd} in
  802.             -net\ *|-host\ *);;
  803.             *\ netmask\ *)                     cmd="-net ${cmd}";;
  804.             *.*.*.*/32*)                       cmd="-host ${cmd}";;
  805.             *.*.*.*/*|0.0.0.0|0.0.0.0\ *)     cmd="-net ${cmd}";;
  806.             default|default\ *)               cmd="-net ${cmd}";;
  807.             *:*/128*)                          cmd="-host ${cmd}";;
  808.             *:*/*)                             cmd="-net ${cmd}";;
  809.             *)                                 cmd="-host ${cmd}";;
  810.         esac
  811.         _add_route ${fam} ${cmd}
  812.         eend $?
  813.         eoutdent
  814.     done
  815.     if [ "${SIFS}" = "y" ]; then
  816.         unset IFS
  817.     else
  818.         IFS="${OIFS}"
  819.     fi
  820.  
  821.     for module in ${MODULES}; do
  822.         if [ "$(command -v "${module}_post_start")" = "${module}_post_start" ]; then
  823.             ${module}_post_start || exit $?
  824.         fi
  825.     done
  826.  
  827.     if [ "$(command -v postup)" = "postup" ]; then
  828.         ebegin "Running postup"
  829.         eindent
  830.         postup
  831.         eoutdent
  832.     fi
  833.  
  834.     return 0
  835. }
  836.  
  837. stop()
  838. {
  839.     # Don't stop the network at shutdown.
  840.     # We don't use the noshutdown keyword so that we are started again
  841.     # correctly if we go back to multiuser.
  842.     yesno ${keep_network:-YES} && yesno $RC_GOINGDOWN && return 0
  843.  
  844.     local IFACE='' module=''
  845.     local IFVAR=''
  846.     IFACE=$(get_interface)
  847.     IFVAR=$(shell_var "${IFACE}")
  848.  
  849.     einfo "Bringing down interface ${IFACE}"
  850.     eindent
  851.  
  852.     if [ -z "${MODULES}" ]; then
  853.         local MODULES=''
  854.         _load_modules false
  855.     fi
  856.  
  857.     if [ "$(command -v predown)" = "predown" ]; then
  858.         ebegin "Running predown"
  859.         eindent
  860.         predown || return 1
  861.         eoutdent
  862.     else
  863.         if is_net_fs /; then
  864.             eerror "root filesystem is network mounted -- can't stop ${IFACE}"
  865.             return 1
  866.         fi
  867.     fi
  868.  
  869.     for module in ${MODULES}; do
  870.         if [ "$(command -v "${module}_pre_stop")" = "${module}_pre_stop" ]; then
  871.             ${module}_pre_stop || exit $?
  872.         fi
  873.     done
  874.  
  875.     for module in ${MODULES}; do
  876.         if [ "$(command -v "${module}_stop")" = "${module}_stop" ]; then
  877.             ${module}_stop
  878.         fi
  879.     done
  880.  
  881.     # Only delete addresses for interfaces that exist
  882.     if _exists; then
  883.         # PPP can manage it's own addresses when IN_BACKGROUND
  884.         # Important in case "demand" set on the ppp link
  885.         if ! (yesno ${IN_BACKGROUND} && is_ppp) ; then
  886.             _delete_addresses "${IFACE}"
  887.         fi
  888.     fi
  889.  
  890.     for module in ${MODULES}; do
  891.         if [ "$(command -v "${module}_post_stop")" = "${module}_post_stop" ]; then
  892.             ${module}_post_stop
  893.         fi
  894.     done
  895.  
  896.     # If not in background, and not loopback then bring the interface down
  897.     # unless overridden.
  898.     if ! yesno ${IN_BACKGROUND} && \
  899.     [ "${IFACE}" != "lo" ] && [ "${IFACE}" != "lo0" ]; then
  900.         eval module=\$ifdown_${IFVAR}
  901.         module=${module:-${ifdown:-YES}}
  902.         yesno ${module} && _down 2>/dev/null
  903.     fi
  904.  
  905.     command -v resolvconf >/dev/null && resolvconf -d "${IFACE}" 2>/dev/null
  906.  
  907.     if [ "$(command -v "postdown")" = "postdown" ]; then
  908.         ebegin "Running postdown"
  909.         eindent
  910.         postdown
  911.         eoutdent
  912.     fi
  913.  
  914.     return 0
  915. }
  916.  
  917. # vim:filetype=gentoo-init-d:
  918.  
Advertisement
Add Comment
Please, Sign In to add comment