+++ /dev/null
-#!/sbin/openrc-run
-# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
-# Copyright (c) 2010-2016 Gentoo Foundation
-# Released under the 2-clause BSD license.
-
-SHDIR="/lib/netifrc/sh"
-MODULESDIR="/lib/netifrc/net"
-MODULESLIST="${RC_SVCDIR}/nettree"
-_config_vars="config metric routes"
-
-[ -z "${IN_BACKGROUND}" ] && IN_BACKGROUND="NO"
-
-description="Configures network interfaces."
-
-# Handy var so we don't have to embed new lines everywhere for array splitting
-__IFS="
-"
-
-# Set the INIT to be openrc if this file is called directly
-: ${INIT:=openrc}
-
-if [ -f "$SHDIR/functions.sh" ]; then
- . "$SHDIR/functions.sh"
-else
- echo "$SHDIR/functions.sh missing. Exiting"
- exit 1
-fi
-
-depend()
-{
- local IFACE=$(get_interface)
- local IFVAR=$(shell_var "${IFACE}")
-
- if [ "$RC_UNAME" = Linux -a "$IFACE" != lo ]; then
- need sysfs
- after modules
- fi
- after bootmisc
- keyword -jail -prefix -vserver
-
- case "${IFACE}" in
- lo|lo0) ;;
- *)
- after net.lo net.lo0 dbus
- need localmount
- provide net
- ;;
- esac
-
- if [ "$(command -v "depend_${IFVAR}")" = "depend_${IFVAR}" ]; then
- depend_${IFVAR}
- fi
-
- local dep= prov=
- for dep in need use before after provide keyword; do
- eval prov=\$rc_${dep}_${IFVAR}
- if [ -n "${prov}" ]; then
- ${dep} ${prov}
- ewarn "rc_${dep}_${IFVAR} is deprecated."
- ewarn "Please use rc_net_${IFVAR}_${dep} instead."
- fi
- done
-}
-
-# Support bash arrays - sigh
-_array_helper()
-{
- local _a=
-
- eval _a=\$$1
- _a=$(echo "${_a}" | sed -e 's:^[[:space:]]*::' -e 's:[[:space:]]*$::' -e '/^$/d' -e 's:[[:space:]]\{1,\}: :g')
-
- [ -n "${_a}" ] && printf "%s\n" "${_a}"
-}
-
-_get_array()
-{
- local _a=
- if [ -n "${BASH}" ]; then
- case "$(declare -p "$1" 2>/dev/null)" in
- "declare -a "*)
- ewarn "You are using a bash array for $1."
- ewarn "This feature will be removed in the future."
- ewarn "Please see net.example for the correct format for $1."
- eval "set -- \"\${$1[@]}\""
- for _a; do
- printf "%s\n" "${_a}"
- done
- return 0
- ;;
- esac
- fi
-
- _array_helper $1
-}
-
-# Flatten bash arrays to simple strings
-_flatten_array()
-{
- if [ -n "${BASH}" ]; then
- case "$(declare -p "$1" 2>/dev/null)" in
- "declare -a "*)
- ewarn "You are using a bash array for $1."
- ewarn "This feature will be removed in the future."
- ewarn "Please see net.example for the correct format for $1."
- eval "set -- \"\${$1[@]}\""
- for x; do
- printf "'%s' " "$(printf "$x" | sed "s:':'\\\'':g")"
- done
- return 0
- ;;
- esac
- fi
-
- _array_helper $1
-}
-
-_wait_for_carrier()
-{
- local timeout=
-
- _has_carrier && return 0
-
- eval timeout=\$carrier_timeout_${IFVAR}
- timeout=${timeout:-${carrier_timeout:-0}}
-
- # Incase users don't want this nice feature ...
- [ ${timeout} -le 0 ] && return 0
-
- einfon "Waiting for carrier (${timeout} seconds) "
- while [ ${timeout} -gt 0 ]; do
- if _has_carrier; then
- echo
- eend 0
- return 0
- fi
- sleep 1
- : $(( timeout -= 1 ))
- printf "."
- done
-
- echo
- eend 1
- return 1
-}
-
-_netmask2cidr()
-{
- # Some shells cannot handle hex arithmetic, so we massage it slightly
- # Buggy shells include FreeBSD sh, dash and busybox.
- # bash and NetBSD sh don't need this.
- case $1 in
- 0x*)
- local hex=${1#0x*} quad=
- while [ -n "${hex}" ]; do
- local lastbut2=${hex#??*}
- quad=${quad}${quad:+.}0x${hex%${lastbut2}*}
- hex=${lastbut2}
- done
- set -- ${quad}
- ;;
- esac
-
- local i= len=
- local IFS=.
- for i in $1; do
- case $i in
- 0x*) i=$((i)) ;;
- esac
- while [ ${i} -ne 0 ]; do
- : $(( len += i % 2 ))
- : $(( i >>= 1 ))
- done
- done
-
- echo "${len}"
-}
-
-_configure_variables()
-{
- local var= v= t=
-
- for var in ${_config_vars}; do
- local v=
- for t; do
- eval v=\$${var}_${t}
- if [ -n "${v}" ]; then
- eval ${var}_${IFVAR}=\$${var}_${t}
- continue 2
- fi
- done
- done
-}
-
-_which()
-{
- local i OIFS
- # Empty
- [ -z "$1" ] && return
- # check paths
- OIFS="$IFS"
- IFS=:
- for i in $PATH ; do
- [ -x $i/$1 ] && echo $i/$1 && break
- done
- IFS=$OIFS
-}
-
-# Like _which, but also consider shell builtins, and multiple alternatives
-_program_available()
-{
- [ -z "$1" ] && return 0
- local x=
- for x; do
- case "${x}" in
- /*) [ -x "${x}" ] && break;;
- *) type "${x}" >/dev/null 2>&1 && break;;
- esac
- x=
- done
- [ -n "${x}" ] && echo $x && return 0
- return 1
-}
-
-_show_address()
-{
- einfo "received address $(_get_inet_address "${IFACE}")"
-}
-
-# Allow custom error handling behavior to be set by the user.
-# Known used combinations, with defaults
-# errh_IFVAR_address_EEXIST=warn
-# errh_IFVAR_route_EEXIST=warn
-_get_errorhandler_behavior() {
- IFVAR="$1"
- object="$2"
- error="$3"
- fallback="$4"
- value=
- for key in \
- "errh_${IFVAR}_${object}_${error}" \
- "errh_${IFVAR}_${object}_DEFAULT" \
- "errh_${IFVAR}_DEFAULT_${error}" \
- "errh_${IFVAR}_DEFAULT_DEFAULT" \
- "errh_DEFAULT_${object}_${error}" \
- "errh_DEFAULT_${object}_DEFAULT" \
- "errh_DEFAULT_DEFAULT_${error}" \
- "errh_DEFAULT_DEFAULT_DEFAULT" \
- "errh" \
- "fallback" ; do
- eval value="\${${key}}"
- if [ -n "$value" ]; then
- echo "$value" && break
- fi
- done
-}
-
-# Basically sorts our modules into order and saves the list
-_gen_module_list()
-{
- local x= f= force=$1
- if ! ${force} ; then
- if [ -s "${MODULESLIST}" -a "${MODULESLIST}" -nt /proc/$$/status ]; then
- ewarn "Discarding cached module list ($MODULESLIST) as it's newer current time!"
- elif [ -s "${MODULESLIST}" -a "${MODULESLIST}" -nt "${MODULESDIR}" ]; then
- local update=false
- for x in "${MODULESDIR}"/*.sh; do
- [ -e "${x}" ] || continue
- if [ "${x}" -nt "${MODULESLIST}" ]; then
- update=true
- break
- fi
- done
- ${update} || return 0
- fi
- fi
-
- einfo "Caching network module dependencies"
- # Run in a subshell to protect the main script
- (
- after() {
- eval ${MODULE}_after="\"\${${MODULE}_after}\${${MODULE}_after:+ }$*\""
- }
-
- before() {
- local mod=${MODULE}
- local MODULE=
- for MODULE; do
- after "${mod}"
- done
- }
-
- program() {
- if [ "$1" = "start" -o "$1" = "stop" ]; then
- local s="$1"
- shift
- eval ${MODULE}_program_${s}="\"\${${MODULE}_program_${s}}\${${MODULE}_program_${s}:+ }$*\""
- else
- eval ${MODULE}_program="\"\${${MODULE}_program}\${${MODULE}_program:+ }$*\""
- fi
- }
-
- provide() {
- eval ${MODULE}_provide="\"\${${MODULE}_provide}\${${MODULE}_provide:+ }$*\""
- local x
- for x in $*; do
- eval ${x}_providedby="\"\${${MODULE}_providedby}\${${MODULE}_providedby:+ }${MODULE}\""
- done
- }
-
- for MODULE in "${MODULESDIR}"/*.sh; do
- sh -n "${MODULE}" || continue
- . "${MODULE}" || continue
- MODULE=${MODULE#${MODULESDIR}/}
- MODULE=${MODULE%.sh}
- eval ${MODULE}_depend
- MODULES="${MODULES} ${MODULE}"
- done
-
- VISITED=
- SORTED=
- visit() {
- case " ${VISITED} " in
- *" $1 "*) return;;
- esac
- VISITED="${VISITED} $1"
-
- eval AFTER=\$${1}_after
- for MODULE in ${AFTER}; do
- eval PROVIDEDBY=\$${MODULE}_providedby
- if [ -n "${PROVIDEDBY}" ]; then
- for MODULE in ${PROVIDEDBY}; do
- visit "${MODULE}"
- done
- else
- visit "${MODULE}"
- fi
- done
-
- eval PROVIDE=\$${1}_provide
- for MODULE in ${PROVIDE}; do
- visit "${MODULE}"
- done
-
- eval PROVIDEDBY=\$${1}_providedby
- [ -z "${PROVIDEDBY}" ] && SORTED="${SORTED} $1"
- }
-
- for MODULE in ${MODULES}; do
- visit "${MODULE}"
- done
-
- printf "" > "${MODULESLIST}"
- i=0
- for MODULE in ${SORTED}; do
- eval PROGRAM=\$${MODULE}_program
- eval PROGRAM_START=\$${MODULE}_program_start
- eval PROGRAM_STOP=\$${MODULE}_program_stop
- eval PROVIDE=\$${MODULE}_provide
- echo "module_${i}='${MODULE}'" >> "${MODULESLIST}"
- echo "module_${i}_program='${PROGRAM}'" >> "${MODULESLIST}"
- echo "module_${i}_program_start='${PROGRAM_START}'" >> "${MODULESLIST}"
- echo "module_${i}_program_stop='${PROGRAM_STOP}'" >> "${MODULESLIST}"
- echo "module_${i}_provide='${PROVIDE}'" >> "${MODULESLIST}"
- : $(( i += 1 ))
- done
- echo "module_${i}=" >> "${MODULESLIST}"
- )
-
- return 0
-}
-
-_load_modules()
-{
- local starting=$1 mymods=
-
- # Ensure our list is up to date
- _gen_module_list false
- if ! . "${MODULESLIST}"; then
- _gen_module_list true
- . "${MODULESLIST}"
- fi
-
- MODULES=
- if [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then
- eval mymods=\$modules_${IFVAR}
- [ -z "${mymods}" ] && mymods=${modules}
- fi
-
- local i=-1 x= mod= f= provides=
- while true; do
- : $(( i += 1 ))
- eval mod=\$module_${i}
- [ -z "${mod}" ] && break
- [ -e "${MODULESDIR}/${mod}.sh" ] || continue
-
- eval set -- \$module_${i}_program
- if [ -n "$1" ]; then
- if ! _program_available "$@" >/dev/null; then
- vewarn "Skipping module $mod due to missing program: $@"
- continue
- fi
- fi
- if ${starting}; then
- eval set -- \$module_${i}_program_start
- else
- eval set -- \$module_${i}_program_stop
- fi
- if [ -n "$1" ]; then
- if ! _program_available "$@" >/dev/null; then
- vewarn "Skipping module $mod due to missing program: $@"
- continue
- fi
- fi
-
- eval provides=\$module_${i}_provide
- if ${starting}; then
- case " ${mymods} " in
- *" !${mod} "*) continue;;
- *" !${provides} "*) [ -n "${provides}" ] && continue;;
- esac
- fi
- MODULES="${MODULES}${MODULES:+ }${mod}"
-
- # Now load and wrap our functions
- if ! . "${MODULESDIR}/${mod}.sh"; then
- eend 1 "${RC_SVCNAME}: error loading module \`${mod}'"
- exit 1
- fi
-
- [ -z "${provides}" ] && continue
-
- # Wrap our provides
- local f=
- for f in pre_start start post_start; do
- eval "${provides}_${f}() { [ "$(command -v "${mod}_${f}")" = "${mod}_${f}" ] || return 0; ${mod}_${f} \"\$@\"; }"
- done
-
- eval module_${mod}_provides="${provides}"
- eval module_${provides}_providedby="${mod}"
- done
-
- # Wrap our preferred modules
- for mod in ${mymods}; do
- case " ${MODULES} " in
- *" ${mod} "*)
- eval x=\$module_${mod}_provides
- [ -z "${x}" ] && continue
- for f in pre_start start post_start; do
- eval "${x}_${f}() { [ "$(command -v "${mod}_${f}")" = "${mod}_${f}" ] || return 0; ${mod}_${f} \"\$@\"; }"
- done
- eval module_${x}_providedby="${mod}"
- ;;
- esac
- done
-
- # Finally remove any duplicated provides from our list if we're starting
- # Otherwise reverse the list
- local LIST="${MODULES}" p=
- MODULES=
- if ${starting}; then
- for mod in ${LIST}; do
- eval x=\$module_${mod}_provides
- if [ -n "${x}" ]; then
- eval p=\$module_${x}_providedby
- [ "${mod}" != "${p}" ] && continue
- fi
- MODULES="${MODULES}${MODULES:+ }${mod}"
- done
- else
- for mod in ${LIST}; do
- MODULES="${mod}${MODULES:+ }${MODULES}"
- done
- fi
-
- veinfo "Loaded modules: ${MODULES}"
-}
-
-_load_config()
-{
- local config="$(_get_array "config_${IFVAR}")"
- local fallback="$(_get_array fallback_${IFVAR})"
-
- config_index=0
- local IFS="$__IFS"
- set -- ${config}
-
- # We should support a space separated array for cidr configs
- # But only as long as they do not contain other parameters for the address
- if [ $# = 1 ]; then
- unset IFS
- set -- ${config}
- # Of course, we may have a single address added old style.
- # If the NEXT argument is a v4 or v6 address, it's the next config.
- # Otherwise, it's arguments to the first config...
- if [ "${2#*.*}" = "${2}" -a "${2#*:*}" = "${2}" ]; then
- # Not an IPv4/IPv6
- local IFS="$__IFS"
- set -- ${config}
- fi
- fi
-
- # Ensure that loopback has the correct address
- if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ]; then
- if [ "$1" != "null" ]; then
- config_0="127.0.0.1/8"
- config_index=1
- fi
- else
- if [ -z "$1" ]; then
- ewarn "config_${IFVAR} not specified; defaulting to DHCP"
- config_0="dhcp"
- config_index=1
- fi
- fi
-
-
- # We store our config in an array like vars
- # so modules can influence it
- for cmd; do
- eval config_${config_index}="'${cmd}'"
- : $(( config_index += 1 ))
- done
- # Terminate the list
- eval config_${config_index}=
-
- config_index=0
- for cmd in ${fallback}; do
- eval fallback_${config_index}="'${cmd}'"
- : $(( config_index += 1 ))
- done
- # Terminate the list
- eval fallback_${config_index}=
-
- # Don't set to zero, so any net modules don't have to do anything extra
- config_index=-1
-}
-
-# Support functions
-_run_if()
-{
- local cmd=$1 iface=$2 ifr=${IFACE} ifv=${IFVAR}
- # Ensure that we don't stamp on real values
- local IFACE= IFVAR=
- shift
- if [ -n "${iface}" ]; then
- IFACE="${iface}"
- [ "${iface}" != "${ifr}" ] && IFVAR=$(shell_var "${IFACE}")
- else
- IFACE=${ifr}
- IFVAR=${ifv}
- fi
- ${cmd}
-}
-interface_exists()
-{
- _run_if _exists "$@"
-}
-interface_up()
-{
- _run_if _up "$@"
-}
-interface_down()
-{
- _run_if _down "$@"
-}
-set_interface_type()
-{
- service_set_value iface_type "$@"
-}
-get_interface_type()
-{
- ( RC_SVCNAME="net.$IFACE" service_get_value iface_type )
-}
-is_interface_type()
-{
- [ "$(get_interface_type)" = "$1" ]
-}
-
-start()
-{
- local IFACE=$(get_interface) oneworked=false fallback=false module=
- local IFVAR=$(shell_var "${IFACE}") cmd= our_metric=
- local metric=0 _up_before_preup
- eval _up_before_preup="\$up_before_preup_${IFVAR}"
- [ -z "${_up_before_preup}" ] && _up_before_preup=$up_before_preup
-
- einfo "Bringing up interface ${IFACE}"
- eindent
-
- if [ -z "${MODULES}" ]; then
- local MODULES=
- _load_modules true
- fi
-
- # We up the iface twice if we have a preup to ensure it's up if
- # available in preup and afterwards incase the user inadvertently
- # brings it down
- if [ "$(command -v preup)" = "preup" ]; then
- yesno "${_up_before_preup:-yes}" && _up 2>/dev/null
- ebegin "Running preup"
- eindent
- preup || return 1
- eoutdent
- fi
-
- _up 2>/dev/null
-
- for module in ${MODULES}; do
- if [ "$(command -v "${module}_pre_start")" = "${module}_pre_start" ]; then
- ${module}_pre_start || exit $?
- fi
- done
-
- if ! _exists; then
- eerror "ERROR: interface ${IFACE} does not exist"
- eerror "Ensure that you have loaded the correct kernel module for your hardware"
- return 1
- fi
-
- if ! _wait_for_carrier; then
- if service_started devd; then
- ewarn "no carrier, but devd will start us when we have one"
- mark_service_inactive "${RC_SVCNAME}"
- else
- eerror "no carrier"
- fi
- return 1
- fi
-
- local config= config_index=
- _load_config
- config_index=0
-
- eval our_metric=\$metric_${IFVAR}
- if [ -n "${our_metric}" ]; then
- metric=${our_metric}
- elif [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then
- : $(( metric += $(_ifindex) ))
- fi
-
- while true; do
- eval config=\$config_${config_index}
- [ -z "${config}" ] && break
-
- set -- ${config}
- if [ "$1" != "null" -a "$1" != "noop" ]; then
- ebegin "$1"
- fi
- eindent
- case "$1" in
- noop)
- if [ -n "$(_get_inet_address)" ]; then
- oneworked=true
- break
- fi
- ;;
- null) :;;
- [0-9]*|*:*) _add_address ${config};;
- *)
- if [ "$(command -v "${config}_start")" = "${config}_start" ]; then
- "${config}"_start
- else
- eerror "nothing provides \`${config}'"
- fi
- ;;
- esac
- if eend $?; then
- oneworked=true
- else
- eval config=\$fallback_${config_index}
- if [ -n "${config}" ]; then
- fallback=true
- eoutdent
- ewarn "Trying fallback configuration ${config}"
- eindent
- eval config_${config_index}=\$config
- unset fallback_${config_index}
- : $(( config_index -= 1 ))
- fi
- fi
- eoutdent
- : $(( config_index += 1 ))
- done
-
- if ! ${oneworked}; then
- if [ "$(command -v failup)" = "failup" ]; then
- ebegin "Running failup"
- eindent
- failup
- eoutdent
- fi
- return 1
- fi
-
- local first=true routes=
- if ${fallback}; then
- routes="$(_get_array "fallback_routes_${IFVAR}")"
- fi
- if [ -z "${routes}" ]; then
- routes="$(_get_array "routes_${IFVAR}")"
- fi
- if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ]; then
- if [ "${config_0}" != "null" ]; then
- routes="127.0.0.0/8 via 127.0.0.1
-${routes}"
- fi
- fi
-
- local OIFS="${IFS}" SIFS="${IFS-y}"
- local IFS="$__IFS"
- local fam
- for cmd in ${routes}; do
- unset IFS
- if ${first}; then
- first=false
- einfo "Adding routes"
- fi
-
- case ${cmd} in
- -6" "*) fam="-6"; cmd=${cmd#-6 };;
- -4" "*) fam="-4"; cmd=${cmd#-4 };;
- esac
-
- eindent
- ebegin ${cmd}
- # Work out if we're a host or a net if not told
- case ${cmd} in
- -net" "*|-host" "*);;
- *" "netmask" "*) cmd="-net ${cmd}";;
- *.*.*.*/32*) cmd="-host ${cmd}";;
- *.*.*.*/*|0.0.0.0|0.0.0.0" "*) cmd="-net ${cmd}";;
- default|default" "*) cmd="-net ${cmd}";;
- *:*/128*) cmd="-host ${cmd}";;
- *:*/*) cmd="-net ${cmd}";;
- *) cmd="-host ${cmd}";;
- esac
- _add_route ${fam} ${cmd}
- eend $?
- eoutdent
- done
- if [ "${SIFS}" = "y" ]; then
- unset IFS
- else
- IFS="${OIFS}"
- fi
-
- for module in ${MODULES}; do
- if [ "$(command -v "${module}_post_start")" = "${module}_post_start" ]; then
- ${module}_post_start || exit $?
- fi
- done
-
- if [ "$(command -v postup)" = "postup" ]; then
- ebegin "Running postup"
- eindent
- postup
- eoutdent
- fi
-
- return 0
-}
-
-stop()
-{
- # Don't stop the network at shutdown.
- # We don't use the noshutdown keyword so that we are started again
- # correctly if we go back to multiuser.
- yesno ${keep_network:-YES} && yesno $RC_GOINGDOWN && return 0
-
- local IFACE=$(get_interface) module=
- local IFVAR=$(shell_var "${IFACE}") opts=
-
- einfo "Bringing down interface ${IFACE}"
- eindent
-
- if [ -z "${MODULES}" ]; then
- local MODULES=
- _load_modules false
- fi
-
- if [ "$(command -v predown)" = "predown" ]; then
- ebegin "Running predown"
- eindent
- predown || return 1
- eoutdent
- else
- if is_net_fs /; then
- eerror "root filesystem is network mounted -- can't stop ${IFACE}"
- return 1
- fi
- fi
-
- for module in ${MODULES}; do
- if [ "$(command -v "${module}_pre_stop")" = "${module}_pre_stop" ]; then
- ${module}_pre_stop || exit $?
- fi
- done
-
- for module in ${MODULES}; do
- if [ "$(command -v "${module}_stop")" = "${module}_stop" ]; then
- ${module}_stop
- fi
- done
-
- # Only delete addresses for interfaces that exist
- if _exists; then
- # PPP can manage it's own addresses when IN_BACKGROUND
- # Important in case "demand" set on the ppp link
- if ! (yesno ${IN_BACKGROUND} && is_ppp) ; then
- _delete_addresses "${IFACE}"
- fi
- fi
-
- for module in ${MODULES}; do
- if [ "$(command -v "${module}_post_stop")" = "${module}_post_stop" ]; then
- ${module}_post_stop
- fi
- done
-
- # If not in background, and not loopback then bring the interface down
- # unless overridden.
- if ! yesno ${IN_BACKGROUND} && \
- [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then
- eval module=\$ifdown_${IFVAR}
- module=${module:-${ifdown:-YES}}
- yesno ${module} && _down 2>/dev/null
- fi
-
- type resolvconf >/dev/null 2>&1 && resolvconf -d "${IFACE}" 2>/dev/null
-
- if [ "$(command -v "postdown")" = "postdown" ]; then
- ebegin "Running postdown"
- eindent
- postdown
- eoutdent
- fi
-
- return 0
-}
-
-# vim:filetype=gentoo-init-d: