From 38eb3325a1fddd6e7f253e2b0cf51c9ace91eb80 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Fri, 6 Oct 2006 07:43:31 +0000 Subject: [PATCH] updated net runlevel scripts --- .../alice/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../hosts/bob/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../carol/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../hosts/dave/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../hosts/moon/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../hosts/moon/etc/runlevels/default/net.eth1 | 1344 +++++++++++++---- .../hosts/sun/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../hosts/sun/etc/runlevels/default/net.eth1 | 1344 +++++++++++++---- .../venus/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- .../winnetou/etc/runlevels/default/net.eth0 | 1344 +++++++++++++---- 10 files changed, 10770 insertions(+), 2670 deletions(-) diff --git a/testing/hosts/alice/etc/runlevels/default/net.eth0 b/testing/hosts/alice/etc/runlevels/default/net.eth0 index fa1200242..92b3851cf 100755 --- a/testing/hosts/alice/etc/runlevels/default/net.eth0 +++ b/testing/hosts/alice/etc/runlevels/default/net.eth0 @@ -1,314 +1,1124 @@ #!/sbin/runscript -# Copyright 1999-2004 Gentoo Technologies, Inc. +# Copyright (c) 2004-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -#NB: Config is in /etc/conf.d/net +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to Aron Griffis (agriffis@gentoo.org) +# for help, ideas and patches -if [[ -n $NET_DEBUG ]]; then - set -x - devnull=/dev/stderr -else - devnull=/dev/null -fi +#NB: Config is in /etc/conf.d/net # For pcmcia users. note that pcmcia must be added to the same # runlevel as the net.* script that needs it. depend() { - use hotplug pcmcia + need localmount + after bootmisc hostname + use isapnp isdn pcmcia usb wlan + + # Load any custom depend functions for the given interface + # For example, br0 may need eth0 and eth1 + local iface="${SVCNAME#*.}" + [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface} + + if [[ ${iface} != "lo" && ${iface} != "lo0" ]] ; then + after net.lo net.lo0 + + # Support new style RC_NEED and RC_USE in one net file + local x="RC_NEED_${iface}" + [[ -n ${!x} ]] && need ${!x} + x="RC_USE_${iface}" + [[ -n ${!x} ]] && use ${!x} + fi + + return 0 } -checkconfig() { - if [[ -z "${ifconfig_IFACE}" ]]; then - eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set" - eerror "(or \$iface_$IFACE for old-style configuration)" - return 1 - fi - if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then - eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" - return 1 - fi +# Define where our modules are +MODULES_DIR="${svclib}/net" + +# Make some wrappers to fudge after/before/need/use depend flags. +# These are callbacks so MODULE will be set. +after() { + eval "${MODULE}_after() { echo \"$*\"; }" +} +before() { + eval "${MODULE}_before() { echo \"$*\"; }" +} +need() { + eval "${MODULE}_need() { echo \"$*\"; }" +} +installed() { + # We deliberately misspell this as _installed will probably be used + # at some point + eval "${MODULE}_instlled() { echo \"$*\"; }" +} +provide() { + eval "${MODULE}_provide() { echo \"$*\"; }" +} +functions() { + eval "${MODULE}_functions() { echo \"$*\"; }" +} +variables() { + eval "${MODULE}_variables() { echo \"$*\"; }" } -# Fix bug 50039 (init.d/net.eth0 localization) -# Some other commands in this script might need to be wrapped, but -# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else -# according to locale(7) -ifconfig() { - LC_ALL=C /sbin/ifconfig "$@" +is_loopback() { + [[ $1 == "lo" || $1 == "lo0" ]] } -# setup_vars: setup variables based on $1 and content of /etc/conf.d/net -# The following variables are set, which should be declared local by -# the calling routine. -# status_IFACE (up or '') -# vlans_IFACE (space-separated list) -# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE) -# dhcpcd_IFACE (command-line args for dhcpcd) -# routes_IFACE (array of route lines) -# inet6_IFACE (array of inet6 lines) -# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails) -setup_vars() { - local i iface="${1//\./_}" - - status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')" - eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\" - eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" ) - eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\" - eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" ) - eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" ) - eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" ) - - # BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array - # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) - eval local iface_IFACE=\"\$\{iface_$iface\}\" - if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then - # Make sure these get evaluated as arrays - local -a aliases broadcasts netmasks - - # Start with the primary interface - ifconfig_IFACE=( "${iface_IFACE}" ) - - # ..then add aliases - eval aliases=( \$\{alias_$iface\} ) - eval broadcasts=( \$\{broadcast_$iface\} ) - eval netmasks=( \$\{netmask_$iface\} ) - for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do - ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" - done - fi - - # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses - if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then - inet6_IFACE=( ${inet6_IFACE} ) - fi +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" } -iface_start() { - local IFACE=${1} i x retval - checkconfig || return 1 - - if [[ ${ifconfig_IFACE} != dhcp ]]; then - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Bringing ${IFACE} up (${i})" - else - ebegin "Bringing ${IFACE} up" - fi - # ifconfig does not always return failure .. - ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - # Check that eth0 was not brought up by the kernel ... - if [[ ${status_IFACE} == up ]]; then - einfo "Keeping kernel configuration for ${IFACE}" - else - ebegin "Bringing ${IFACE} up via DHCP" - /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} - retval=$? - eend $retval - if [[ $retval == 0 ]]; then - # DHCP succeeded, show address retrieved - i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' | - cut -d: -f2) - [[ -n ${i} ]] && einfo " ${IFACE} received address ${i}" - elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then - # DHCP failed, try fallback. - # Show the address, but catch if this interface will be inet6 only - i=${ifconfig_fallback_IFACE%% *} - if [[ ${i} == *.*.*.* ]]; then - ebegin "Using fallback configuration (${i}) for ${IFACE}" - else - ebegin "Using fallback configuration for ${IFACE}" - fi - ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \ - ifconfig ${IFACE} up &>${devnull} - eend $? || return $? - else - return $retval - fi - fi - fi - - if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then - einfo " Adding aliases" - for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})" - ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]} - eend $? - done - fi - - if [[ -n ${inet6_IFACE} ]]; then - einfo " Adding inet6 addresses" - for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do - ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}" - ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull} - eend $? - done - fi - - # Set static routes - if [[ -n ${routes_IFACE} ]]; then - einfo " Adding routes" - for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do - ebegin " ${routes_IFACE[i]}" - /sbin/route add ${routes_IFACE[i]} - eend $? - done - fi - - # Set default route if applicable to this interface - if [[ ${gateway} == ${IFACE}/* ]]; then - local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}') - local gw=${gateway#*/} - if [[ ${ogw} != ${gw} ]]; then - ebegin " Setting default gateway ($gw)" - - # First delete any existing route if it was setup by kernel... - /sbin/route del default dev ${IFACE} &>${devnull} - - # Second delete old gateway if it was set... - /sbin/route del default gw ${ogw} &>${devnull} - - # Third add our new default gateway - /sbin/route add default gw ${gw} >${devnull} - eend $? || { - true # need to have some command in here - # Note: This originally called stop, which is obviously - # wrong since it's calling with a local version of IFACE. - # The below code works correctly to abort configuration of - # the interface, but is commented because we're assuming - # that default route failure should not cause the interface - # to be unconfigured. - #local error=$? - #ewarn "Aborting configuration of ${IFACE}" - #iface_stop ${IFACE} - #return ${error} - } - fi - fi - - # Enabling rp_filter causes wacky packets to be auto-dropped by - # the kernel. Note that we only do this if it is not set via - # /etc/sysctl.conf ... - if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \ - -z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then - echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter - fi +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" } -# iface_stop: bring down an interface. Don't trust information in -# /etc/conf.d/net since the configuration might have changed since -# iface_start ran. Instead query for current configuration and bring -# down the interface. -iface_stop() { - local IFACE=${1} i x aliases inet6 count +# int calculate_metric(char *interface, int base) +# +# Calculates the best metric for the interface +# We use this when we add routes so we can prefer interfaces over each other +calculate_metric() { + local iface="$1" metric="$2" - # Try to do a simple down (no aliases, no inet6, no dhcp) - aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)" - inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')" - if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then - ebegin "Bringing ${IFACE} down" - ifconfig ${IFACE} down &>/dev/null - eend 0 + # Have we already got a metric? + local m=$(awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route) + if [[ -n ${m} ]] ; then + echo "${m}" return 0 fi - einfo "Bringing ${IFACE} down" + local i= dest= gw= flags= ref= u= m= mtu= metrics= + while read i dest gw flags ref u m mtu ; do + # Ignore lo + is_loopback "${i}" && continue + # We work out metrics from default routes only + [[ ${dest} != "00000000" || ${gw} == "00000000" ]] && continue + metrics="${metrics}\n${m}" + done < /proc/net/route - # Stop aliases before primary interface. - # Note this must be done in reverse order, since ifconfig eth0:1 - # will remove eth0:2, etc. It might be sufficient to simply remove - # the base interface but we're being safe here. - for i in ${aliases} ${IFACE}; do + # Now, sort our metrics + metrics=$(echo -e "${metrics}" | sort -n) - # Delete all the inet6 addresses for this interface - inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')" - if [[ -n ${inet6} ]]; then - einfo " Removing inet6 addresses" - for x in ${inet6}; do - ebegin " ${IFACE} inet6 del ${x}" - ifconfig ${i} inet6 del ${x} - eend $? - done - fi + # Now, find the lowest we can use + local gotbase=false + for m in ${metrics} ; do + [[ ${m} -lt ${metric} ]] && continue + [[ ${m} == ${metric} ]] && ((metric++)) + [[ ${m} -gt ${metric} ]] && break + done + + echo "${metric}" +} - # Stop DHCP (should be N/A for aliases) - # Don't trust current configuration... investigate ourselves - if /sbin/dhcpcd -z ${i} &>${devnull}; then - ebegin " Releasing DHCP lease for ${IFACE}" - for ((count = 0; count < 9; count = count + 1)); do - /sbin/dhcpcd -z ${i} &>${devnull} || break - sleep 1 - done - [[ ${count} -lt 9 ]] - eend $? "Timed out" - fi - ebegin " Stopping ${i}" - ifconfig ${i} down &>${devnull} - eend 0 +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary= i= bin= + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]] ; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" +} + + +# bool is_function(char* name) +# +# Returns 0 if the given name is a shell function, otherwise 1 +is_function() { + [[ -z $1 ]] && return 1 + [[ $(type -t "$1") == "function" ]] +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i= + + is_function "${2}_depend" && return + + for i in $(typeset -f | grep -o '^'"${1}"'_[^ ]*'); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x=$(eval echo ${@// /_}) + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from _