Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Best Method ??
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Networking & Security
View previous topic :: View next topic  
Author Message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Thu Jan 18, 2007 9:09 pm    Post subject: Best Method ?? Reply with quote

All,

I'm trying to add two NIC cards to my network server to do the following:

A. Monitor which external internet connection is up,
B. Auto Switch between them when one goes down,
C. Distribute packet load when they are both up.

This is the following specs on my connections:

A. eth1 = Time Warner Cable - 4.5 MBps
B. eth2 = Wrio wireless - 40.x MBps

We were on Comcast, which was stable, then TWC bought our area and they
go down multiple time daily and will not fix their problem. Wrio is a
new company, so their link currently has no redunancy, but should later.

The server will act as DHCP Host for the rest of the network, which includes
VOIP phone service with Cisco ATAs (Vonage or equivalent). Here is a diagram
of the implementation.

Code:

                    ----------------
                    |              |
 Internet 1 - eth1  |              |
--------------------|              |
 (DHCP Rcvr)        |              |   Network - eth0
                    |   Computer   |-------------------
 Internet 2 - eth2  |              |   (DHCP Server)
--------------------|              |
 (DHCP Rcvr)        |              |
                    |              |
                    ----------------


I GenToo guru friend of mine said I could do this with "IP traf" and/or "IP route" and
sent me the following links:

http://www.linux.com.lb/wiki/index.pl?node=Load%20Balancing%20Across%20Multiple%20Links
http://lartc.org/howto/lartc.rpdb.multiple-links.html (Closest to what we are doing)

I also found the following links in the gentoo-Wiki:

http://gentoo-wiki.com/TIP_Dual-Homed_Gentoo_Server
http://gentoo-wiki.com/Dual_internet_connections
http://gentoo-wiki.com/HOWTO_add_a_static_route


My problem is that both me and my partner are such noobies, we still don't understand all this
so implementing is not clear to us. At this point I do not know if I use just one of these
solutions, a combination of them and which one or which combination is best.

I would appreciate any help in clarifying this so I can proceed.

Thanks!

OMR
Back to top
View user's profile Send private message
erik258
Advocate
Advocate


Joined: 12 Apr 2005
Posts: 2650
Location: Twin Cities, Minnesota, USA

PostPosted: Fri Jan 19, 2007 1:23 am    Post subject: Reply with quote

http://gentoo-wiki.com/Dual_internet_connections

i think that's the one you want.

a synopsis: emerge iproute2, reconfig kernel, and configure the system to set up the devices properly on boot. That last one is the only one that might be a little problematic for you, because the wiki doesn't specify exactly how to configure for the gentoo network initscripts. But read the page, maybe the point of writing a new initscript like they do is that you don't have to mess with gentoo's configuraiton.
_________________
Configuring a Firewall? Try my iptables configuration
LinuxCommando.com is my blog for linux-related scraps and tidbits. Stop by for a visit!
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Thu Jan 25, 2007 9:03 pm    Post subject: Confused!! Reply with quote

Added my 3com card an now eth0 is not working, evidently GenToo decided one of the add-in cards is now eth0, but I do not have the drivers so it does not work either.

Trying to resolve this problem now!

Addin NICs are 3Com 3c905B cards.

Found the drivers at:

http://support.3com.com/infodeli/tools/nic/linuxdownload.htm
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Sun Apr 01, 2007 10:38 pm    Post subject: All eth working but not satified Reply with quote

all,

All my eth[0-2] cards are now working, but a friend helped me with the eth2 and he used a "ln" link to the localhost def file.

I'm not happy about this and want if to operate seperate of the localhost, so need to know what I need to do here.

OMR
Back to top
View user's profile Send private message
NeddySeagoon
Administrator
Administrator


Joined: 05 Jul 2003
Posts: 54808
Location: 56N 3W

PostPosted: Sun Apr 01, 2007 10:50 pm    Post subject: Reply with quote

OldManRiver,

Your friend did
Code:
ln -s net.lo net.eth2
to create a new startup scrip for net.eth2
Its run once at startup and does not use the interface lo at all.

In short, its the Gentoo way. You could maje a copy of net.lo and rename it but thats a really bad idea because it will no longer be updated by portage when net.lo changes.
_________________
Regards,

NeddySeagoon

Computer users fall into two groups:-
those that do backups
those that have never had a hard drive fail.
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Wed May 16, 2007 4:20 pm    Post subject: Reply with quote

erik258 wrote:
http://gentoo-wiki.com/Dual_internet_connections

i think that's the one you want.

a synopsis: emerge iproute2, reconfig kernel, and configure the system to set up the devices properly on boot. That last one is the only one that might be a little problematic for you, because the wiki doesn't specify exactly how to configure for the gentoo network initscripts. But read the page, maybe the point of writing a new initscript like they do is that you don't have to mess with gentoo's configuraiton.


I started trying to install this one, but it is too cryptic, missing commands, filenames of where to do what, etc. Also since I must have the following:
Quote:
ETH1 with DHCP (rcvr) to find available incoming IP Address
ETH2 with DHCP (rcvr) to find available incoming IP Address
ETH0 as DHCP server, serving IP Address to 20 plus computer on network, without routers.
The part in this config howto, when they start talking about using DHCP is the most confusing. I looks like the script shown, is a manually operated script to manually obtain the IP address and then manually plug it back into the original script, where the script should be called inside the orignal script and find and return the IP address as a var to executed in the original script, preferrably as a function.

Most disconcerting on this Howto is I see nothing to allow the config of my ETH0 to the DHCP server, but I'm a novice, so what do I know. Anyone seeing this differently please chime in.

If anyone has anymore info on this and/or links I will appreciate it, as I need to finish on this soon.

Thanks!

OMR
Back to top
View user's profile Send private message
erik258
Advocate
Advocate


Joined: 12 Apr 2005
Posts: 2650
Location: Twin Cities, Minnesota, USA

PostPosted: Wed May 16, 2007 8:51 pm    Post subject: Reply with quote

Quote:
I started trying to install this one, but it is too cryptic, missing commands, filenames of where to do what, etc.

I recommend starting with getting this working, then implementing your DHCP server on eth0 when you have it down. Why don't you post a quote of the step on which you're getting tripped up, and then give us a short description of your problem. It looks fairly striaghtforward to me, but I've been doing this a little while now. If you let us know your specific problem(s), I'm sure we can help.

Quote:
Most disconcerting on this Howto is I see nothing to allow the config of my ETH0 to the DHCP server, but I'm a novice, so what do I know. Anyone seeing this differently please chime in.


You may have to go elsewhere for that information -- it's beyond the scope of that document. I think setting up DHCP is fairly easy with the Internet Software Consortium's DHCP server. I like the ISC's dhcpd because it's what lots of the big boys use on their networks, it's the most flexible out there (at least I've never seen another dhcp server that compares), and it's really easy on resources. My dhcpd process has run for five hundreths of a second, and is using around 3M of virtual memory, of which only 1.26M is resident. The server manages few leases, but I don't think more would change very much. I've had it managing around a dozen clients before, and I would feel perfectly confident asking it to do 20, or thirty, or even a hundred such leases or more.

I found a nice howto on DHCPd on the gentoo wiki: http://gentoo-wiki.com/HOWTO_setup_DHCP That passed an initial inspection for ease of following. If you need more help, please let us know.
_________________
Configuring a Firewall? Try my iptables configuration
LinuxCommando.com is my blog for linux-related scraps and tidbits. Stop by for a visit!
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Thu May 17, 2007 8:47 pm    Post subject: Reply with quote

erik258 wrote:
Why don't you post a quote of the step on which you're getting tripped up, and then give us a short description of your problem.


  • First step in this process is Kernel Options where the config screen is shown. There is no reference to where this utility is or how to call it,
  • Then it is suggeted that you have the manual option, but no explaination of whether this is at the command line or in the make.conf file,
  • Under the Helpful Script there is no shell version of the script and I'm not sure if I have Perl loaded on my machine.
    The person submitting this script forgot to mention how to check for absense of Perl and it's subsequent installation, if it is missing.


So this is where I'm at. I can ask my partner, who knows where the config menu is, when he gets back in the shop, but all other noobies will be also stumped at this so I think it should be corrected (violates the "No Assumptions" rule.

Thanks!

OMR
Back to top
View user's profile Send private message
erik258
Advocate
Advocate


Joined: 12 Apr 2005
Posts: 2650
Location: Twin Cities, Minnesota, USA

PostPosted: Thu May 17, 2007 10:38 pm    Post subject: Reply with quote

Quote:
Code:
Networking  --->
  Networking support  --->
    Networking options  --->
      TCP/IP networking
        [*] IP: advanced router
        [*] IP: policy routing
        [*] IP: equal cost multipath


That's a screenshot from menuconfig. First make sure you're familiar with rebuilding the kernel, then go to /usr/src/linux and type make menuconfig. You'll want to enable the options shown.


You could do the same thing manually by editing .config in the same directory, /usr/src/linux.

all my boxes seem to have perl on them already, and I don't develop in perl. I dont' think the version should matter much.
_________________
Configuring a Firewall? Try my iptables configuration
LinuxCommando.com is my blog for linux-related scraps and tidbits. Stop by for a visit!
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Sun May 27, 2007 6:58 pm    Post subject: What I have Reply with quote

All,

Went to my menuconfig and found I had the following:
Code:
Networking  --->
  Networking support  --->
    Networking options  --->
      TCP/IP networking
        [*] IP: multicasting                                                 
        [*] IP: advanced router
             Choose IP: FIB lookup algorithm (choose FIB_HASH if unsure) (
        [*] IP: policy routing
        [*] IP: use netfilter MARK value as routing key                   
        [*] IP: equal cost multipath
        [*] IP: verbose route monitoring                                   
        [*] IP: kernel level autoconfiguration                             
        [*] IP: DHCP support                                             
       <M> IP: tunneling                                                 
       <M> IP: GRE tunnels over IP         


Not sure if some of these are conflicting or not so not sure it this is correct. Would like and explaination, please!

Thanks!

OMR
Back to top
View user's profile Send private message
erik258
Advocate
Advocate


Joined: 12 Apr 2005
Posts: 2650
Location: Twin Cities, Minnesota, USA

PostPosted: Tue May 29, 2007 1:37 pm    Post subject: Reply with quote

Some options have been added since the howto was written, but that should be fine. It doesn't seem likely that they'll conflict.
_________________
Configuring a Firewall? Try my iptables configuration
LinuxCommando.com is my blog for linux-related scraps and tidbits. Stop by for a visit!
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Fri Jun 08, 2007 4:18 pm    Post subject: One More Reply with quote

All,

We had both our ISP lines go down, so ordered the third from another source, so now this is more critical than ever.

Also had so much trouble with TW that we dropped them and replaced them with SBC/Yahoo. Current config now looks like:

Code:

                                  ----------------
                                  |              |
  Internet 1 - eth1               |              |
 ---------------------------------|              |
  (DHCP Rcvr - Wrio 70Mb)         |              |
                                  |              |
  Internet 2 - eth2               |              |   Network - eth0
 ---------------------------------|   Computer   |-------------------
  (DHCP Rcvr - SBC 628K-D/293K-U) |              |  (DHCP Server)
                                  |              |
  Internet 3 - eth3               |              |
 ---------------------------------|              |
  (DHCP Rcvr - Covad 144K)        |              |
                                  |              |
                                  ----------------
ETH1-3 are all 3Com Cards, ETH0 is on-board Intel NIC. You can easily see from the speeds, which is our primary service.

Input will be appreciated.

Thanks!

OMR


Last edited by OldManRiver on Fri Jun 08, 2007 4:48 pm; edited 3 times in total
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Fri Jun 08, 2007 4:24 pm    Post subject: My Real Question Reply with quote

NeddySeagoon wrote:
Your friend did
Code:
ln -s net.lo net.eth2
to create a new startup scrip for net.eth2


I understand what my friend did, but my real question, as I understand, is localhost is set up for/as the DHCP server, so per my drawing shouldn't net.eth1, net.eth2 and net.eth3 should have their own init files, and the net.eth0 should be the one linked to the localhost?

Thanks!

OMR
Back to top
View user's profile Send private message
erik258
Advocate
Advocate


Joined: 12 Apr 2005
Posts: 2650
Location: Twin Cities, Minnesota, USA

PostPosted: Fri Jun 08, 2007 10:05 pm    Post subject: Reply with quote

The job of net.lo is to store the algorithm for reading /etc/conf.d/net and configuring the devices accordingly. Regardless of what the devices are used for, the correct way for the gentoo init scripts to initialize them is by the same algorithm as in net.lo -- therefore, to automatically update all network initscripts, they should all be linked to net.lo
_________________
Configuring a Firewall? Try my iptables configuration
LinuxCommando.com is my blog for linux-related scraps and tidbits. Stop by for a visit!
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Tue Jun 12, 2007 9:29 pm    Post subject: Reply with quote

erik258 wrote:
The job of net.lo is to store the algorithm for reading /etc/conf.d/net and configuring the devices accordingly.


I ran the following commands:
Code:
cd /etc/conf.d
ls -al
gedit net


My net file contained:
Code:
config_eth0=( "dhcp" )
config_eth1=( "dhcp" )
config_eth2=( "dhcp" )
# config_eth3=( "dhcp" )
# config_eth0=( "192.168.10.30/24" )
# config_eth1=( "192.168.10.31/24" )
# config_eth2=( "192.168.10.32/24" )
# dns_domain_lo="homenetwork"
# nis_domain_lo="my-nisdomain"

routes_eth0=( "default via 192.168.1.1" )
routes_eth1=( "default via 192.168.10.200" )
routes_eth2=( "default via 192.168.1.200" )
# routes_eth3=( "default via 192.168.7.200" )


ETH3 is not active yet.

I know I need to change ETH0 to get the DHCP outbound, but don't know what I do to change that.

My net.eth0 file reads:
Code:
#!/sbin/runscript
# Copyright (c) 2004-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# Contributed by Roy Marples (uberlord@gentoo.org)
# Many thanks to Aron Griffis (agriffis@gentoo.org)
# for help, ideas and patches

#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() {
   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
}

# 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 \"$*\"; }"
}

is_loopback() {
   [[ $1 == "lo" || $1 == "lo0" ]]
}

# 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}"
}

# char* interface_type(char* iface)
#
# Returns the base type of the interface
# eth, ippp, etc
interface_type() {
   echo "${1%%[0-9]*}"
}

# 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"

   # 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

   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

   # Now, sort our metrics
   metrics=$(echo -e "${metrics}" | sort -n)

   # 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}"
}

# 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 <variable>_<option> to <variable>_<iface>
# option2 takes precedence over option1
configure_variables() {
   local iface="$1" option1="$2" option2="$3"

   local mod= func= x= i=
   local -a ivars=() ovars1=() ovars2=()
   local ifvar=$(bash_variable "${iface}")

   for mod in ${MODULES[@]}; do
      is_function ${mod}_variables || continue
      for v in $(${mod}_variables) ; do
         x=
         [[ -n ${option2} ]] && x="${v}_${option2}[@]"
         [[ -z ${!x} ]] && x="${v}_${option1}[@]"
         [[ -n ${!x} ]] && eval "${v}_${ifvar}=( \"\${!x}\" )"
      done
   done

   return 0
}
# bool module_load_minimum(char *module)
#
# Does the minimum checking on a module - even when forcing
module_load_minimum() {
   local f="$1.sh" MODULE="${1##*/}"

   if [[ ! -f ${f} ]] ; then
      eerror "${f} does not exist"
      return 1
   fi

   if ! source "${f}" ; then
      eerror "${MODULE} failed a sanity check"
      return 1
   fi

   for f in depend; do
      is_function "${MODULE}_${f}" && continue
      eerror "${MODULE}.sh does not support the required function ${f}"
      return 1
   done

   return 0
}

# bool modules_load_auto()
#
# Load and check each module for sanity
# If the module is not installed, the functions are to be removed
modules_load_auto() {
   local i j inst

   # Populate the MODULES array
   # Basically we treat evey file in ${MODULES_DIR} as a module
   MODULES=( $( cd "${MODULES_DIR}" ; ls *.sh ) )
   j="${#MODULES[@]}"
   for (( i=0; i<j; i++ )); do
      MODULES[i]="${MODULES_DIR}/${MODULES[i]}"
      [[ ! -f ${MODULES[i]} ]] && unset MODULES[i]
   done
   MODULES=( "${MODULES[@]}" )

   # Each of these sources into the global namespace, so it's
   # important that module functions and variables are prefixed with
   # the module name, for example iproute2_

   j="${#MODULES[@]}"
   loaded_interface=false
   for (( i=0; i<j; i++ )); do
      MODULES[i]="${MODULES[i]%.sh*}"
      if [[ ${MODULES[i]##*/} == "interface" ]] ; then
         eerror "interface is a reserved name - cannot load a module called interface"
         return 1
      fi
      
      (
      u=0;
      module_load_minimum "${MODULES[i]}" || u=1;
      if [[ ${u} == 0 ]] ; then
         inst="${MODULES[i]##*/}_check_installed";
         if is_function "${inst}" ; then
            ${inst} false || u=1;
         fi
      fi
      exit "${u}";
      )

      if [[ $? == 0 ]] ; then
         source "${MODULES[i]}.sh"
         MODULES[i]="${MODULES[i]##*/}"
      else
         unset MODULES[i]
      fi
   done

   MODULES=( "${MODULES[@]}" )
   return 0
}

# bool modules_check_installed(void)
#
# Ensure that all modules have the required modules loaded
# This enables us to remove modules from the MODULES array
# Whilst other modules can still explicitly call them
# One example of this is essidnet which configures network
# settings for the specific ESSID connected to as the user
# may be using a daemon to configure wireless instead of our
# iwconfig module
modules_check_installed() {
   local i j missingdeps nmods="${#MODULES[@]}"

   for (( i=0; i<nmods; i++ )); do
      is_function "${MODULES[i]}_instlled" || continue
      for j in $( ${MODULES[i]}_instlled ); do
         missingdeps=true
         if is_function "${j}_check_installed" ; then
            ${j}_check_installed && missingdeps=false
         elif is_function "${j}_depend" ; then
            missingdeps=false
         fi
         ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break
      done
   done

   MODULES=( "${MODULES[@]}" )
   PROVIDES=( "${PROVIDES[@]}" )
}

# bool modules_check_user(void)
modules_check_user() {
   local iface="$1" ifvar=$(bash_variable "${IFACE}")
   local i= j= k= l= nmods="${#MODULES[@]}"
   local -a umods=()

   # Has the interface got any specific modules?
   umods="modules_${ifvar}[@]"
   umods=( "${!umods}" )

   # Global setting follows interface-specific setting
   umods=( "${umods[@]}" "${modules[@]}" )

   # Add our preferred modules
   local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" )
   umods=( "${umods[@]}" "${pmods[@]}" )

   # First we strip any modules that conflict from user settings
   # So if the user specifies pump then we don't use dhcpcd
   for (( i=0; i<${#umods[@]}; i++ )); do
      # Some users will inevitably put "dhcp" in their modules
      # list.  To keep users from screwing up their system this
      # way, ignore this setting so that the default dhcp
      # module will be used.
      [[ ${umods[i]} == "dhcp" ]] && continue

      # We remove any modules we explicitly don't want
      if [[ ${umods[i]} == "!"* ]] ; then
         for (( j=0; j<nmods; j++ )); do
            [[ -z ${MODULES[j]} ]] && continue
            if [[ ${umods[i]:1} == "${MODULES[j]}" \
               || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then
               # We may need to setup a class wrapper for it even though
               # we don't use it directly
               # However, we put it into an array and wrap later as
               # another module may provide the same thing
               ${MODULES[j]}_check_installed \
                  && WRAP_MODULES=(
                     "${WRAP_MODULES[@]}"
                     "${MODULES[j]} ${PROVIDES[j]}"
                  )
               unset MODULES[j]
               unset PROVIDES[j]
            fi
         done
         continue
      fi

      if ! is_function "${umods[i]}_depend" ; then
         # If the module is one of our preferred modules, then
         # ignore this error; whatever is available will be
         # used instead.
         (( i < ${#umods[@]} - ${#pmods[@]} )) || continue

         # The function may not exist because the modules software is
         # not installed. Load the module and report its error
         if [[ -e "${MODULES_DIR}/${umods[i]}.sh" ]] ; then
            source "${MODULES_DIR}/${umods[i]}.sh"
            is_function "${umods[i]}_check_installed" \
               && ${umods[i]}_check_installed true
         else
            eerror "The module \"${umods[i]}\" does not exist"
         fi
         return 1
      fi

      if is_function "${umods[i]}_provide" ; then
         mod=$(${umods[i]}_provide)
      else
         mod="${umods[i]}"
      fi
      for (( j=0; j<nmods; j++ )); do
         [[ -z ${MODULES[j]} ]] && continue
         if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then
            # We don't have a match - now ensure that we still provide an
            # alternative. This is to handle our preferred modules.
            for (( l=0; l<nmods; l++ )); do
               [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue
               if [[ ${PROVIDES[l]} == "${mod}" ]] ; then
                  unset MODULES[j]
                  unset PROVIDES[j]
                  break
               fi
            done
         fi
      done
   done

   # Then we strip conflicting modules.
   # We only need to do this for 3rd party modules that conflict with
   # our own modules and the preferred list AND the user modules
   # list doesn't specify a preference.
   for (( i=0; i<nmods-1; i++ )); do
      [[ -z ${MODULES[i]} ]] && continue         
      for (( j=i+1; j<nmods; j++)); do
         [[ -z ${MODULES[j]} ]] && continue
         [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \
         && unset MODULES[j] && unset PROVIDES[j]
      done
   done

   MODULES=( "${MODULES[@]}" )
   PROVIDES=( "${PROVIDES[@]}" )
   return 0
}

# void modules_sort(void)
#
# Sort our modules
modules_sort() {
   local i= j= nmods=${#MODULES[@]} m=
   local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=()

   # Make our provide list
   for ((i=0; i<nmods; i++)); do
      dead[i]="false"
      if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then
         local provided=false
         for ((j=0; j<${#provide[@]}; j++)); do
            if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then
               provide_list[j]="${provide_list[j]} ${MODULES[i]}"
               provided=true
            fi
         done
         if ! ${provided}; then
            provide[j]="${PROVIDES[i]}"
            provide_list[j]="${MODULES[i]}"
         fi
      fi
   done

   # Create an after array, which holds which modules the module at
   # index i must be after
   for ((i=0; i<nmods; i++)); do
      if is_function "${MODULES[i]}_after" ; then
         after[i]=" ${after[i]} $(${MODULES[i]}_after) "
      fi
      if is_function "${MODULES[i]}_before" ; then
         for m in $(${MODULES[i]}_before); do
            for ((j=0; j<nmods; j++)) ; do
               if [[ ${PROVIDES[j]} == "${m}" ]] ; then
                  after[j]=" ${after[j]} ${MODULES[i]} "
                  break
               fi
            done
         done
      fi
   done

   # Replace the after list modules with real modules
   for ((i=0; i<nmods; i++)); do
      if [[ -n ${after[i]} ]] ; then
         for ((j=0; j<${#provide[@]}; j++)); do
            after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }"
         done
      fi
   done
   
   # We then use the below code to provide a topologial sort
    module_after_visit() {
        local name="$1" i= x=

      for ((i=0; i<nmods; i++)); do
         [[ ${MODULES[i]} == "$1" ]] && break
      done

        ${dead[i]} && return
        dead[i]="true"

        for x in ${after[i]} ; do
            module_after_visit "${x}"
        done

        sorted=( "${sorted[@]}" "${MODULES[i]}" )
      sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" )
    }

   for x in ${MODULES[@]}; do
      module_after_visit "${x}"
   done

   MODULES=( "${sorted[@]}" )
   PROVIDES=( "${sortedp[@]}" )
}

# bool modules_check_depends(bool showprovides)
modules_check_depends() {
   local showprovides="${1:-false}" nmods="${#MODULES[@]}" i= j= needmod=
   local missingdeps= p= interface=false

   for (( i=0; i<nmods; i++ )); do
      if is_function "${MODULES[i]}_need" ; then
         for needmod in $(${MODULES[i]}_need); do
            missingdeps=true
            for (( j=0; j<nmods; j++ )); do
               if [[ ${needmod} == "${MODULES[j]}" \
                  || ${needmod} == "${PROVIDES[j]}" ]] ; then
                  missingdeps=false
                  break
               fi
            done
            if ${missingdeps} ; then
               eerror "${MODULES[i]} needs ${needmod} (dependency failure)"
               return 1
            fi
         done
      fi

      if is_function "${MODULES[i]}_functions" ; then
         for f in $(${MODULES[i]}_functions); do
            if ! is_function "${f}" ; then
               eerror "${MODULES[i]}: missing required function \"${f}\""
               return 1
            fi
         done
      fi

      [[ ${PROVIDES[i]} == "interface" ]] && interface=true

      if ${showprovides} ; then
         [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \
         && veinfo "${MODULES[i]} provides ${PROVIDES[i]}"
      fi
   done

   if ! ${interface} ; then
      eerror "no interface module has been loaded"
      return 1
   fi

   return 0
}

# bool modules_load(char *iface, bool starting)
#
# Loads the defined handler and modules for the interface
# Returns 0 on success, otherwise 1
modules_load()  {
   local iface="$1" starting="${2:-true}" MODULE= p=false i= j= k=
   local -a x=()
   local RC_INDENTATION="${RC_INDENTATION}"
   local -a PROVIDES=() WRAP_MODULES=()

   if ! is_loopback "${iface}" ; then
      x="modules_force_${iface}[@]"
      [[ -n ${!x} ]] && modules_force=( "${!x}" )
      if [[ -n ${modules_force} ]] ; then
         ewarn "WARNING: You are forcing modules!"
         ewarn "Do not complain or file bugs if things start breaking"
         report=true
      fi
   fi

   veinfo "Loading networking modules for ${iface}"
   eindent

   if [[ -z ${modules_force} ]] ; then
      modules_load_auto || return 1
   else
      j="${#modules_force[@]}"
      for (( i=0; i<j; i++ )); do
         module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1
         if is_function "${modules_force[i]}_check_installed" ; then
            ${modules_force[i]}_check_installed || unset modules_force[i]
         fi
      done
      MODULES=( "${modules_force[@]}" )
   fi

   j="${#MODULES[@]}"
   for (( i=0; i<j; i++ )); do
      # Now load our dependencies - we need to use the MODULE variable
      # here as the after/before/need functions use it
      MODULE="${MODULES[i]}"
      ${MODULE}_depend

      # expose does exactly the same thing as depend
      # However it is more "correct" as it exposes things to other modules
      # instead of depending on them ;)
      is_function "${MODULES[i]}_expose" && ${MODULES[i]}_expose

      # If no provide is given, assume module name
      if is_function "${MODULES[i]}_provide" ; then
         PROVIDES[i]=$(${MODULES[i]}_provide)
      else
         PROVIDES[i]="${MODULES[i]}"
      fi
   done

   if [[ -n ${modules_force[@]} ]] ; then
      # Strip any duplicate modules providing the same thing
      j="${#MODULES[@]}"
      for (( i=0; i<j-1; i++ )); do
         [[ -z ${MODULES[i]} ]] && continue
         for (( k=i+1; k<j; k++ )); do
            if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then
               unset MODULES[k]
               unset PROVIDES[k]
            fi
         done
      done
      MODULES=( "${MODULES[@]}" )
      PROVIDES=( "${PROVIDES[@]}" )
   else
      if ${starting}; then
         modules_check_user "${iface}" || return 1
      else
         # Always prefer iproute2 for taking down interfaces
         if is_function iproute2_provide ; then
            function_wrap iproute2 "$(iproute2_provide)"
         fi
      fi
   fi
   
   # Wrap our modules
   j="${#MODULES[@]}"
   for (( i=0; i<j; i++ )); do
      function_wrap "${MODULES[i]}" "${PROVIDES[i]}"
   done
   j="${#WRAP_MODULES[@]}"
   for (( i=0; i<j; i++ )); do
      function_wrap ${WRAP_MODULES[i]}
   done
   
   if [[ -z ${modules_force[@]} ]] ; then
      modules_check_installed || return 1
      modules_sort || return 1
   fi

   veinfo "modules: ${MODULES[@]}"
   eindent

   ${starting} && p=true
   modules_check_depends "${p}" || return 1
   return 0
}

# bool iface_start(char *interface)
#
# iface_start is called from start.  It's expected to start the base
# interface (for example "eth0"), aliases (for example "eth0:1") and to start
# VLAN interfaces (for example eth0.0, eth0.1).  VLAN setup is accomplished by
# calling itself recursively.
iface_start() {
   local iface="$1" mod config_counter="-1" x config_worked=false
   local RC_INDENTATION="${RC_INDENTATION}"
   local -a config=() fallback=() fallback_route=() conf=() a=() b=()
   local ifvar=$(bash_variable "$1") i= j= metric=0

   # pre Start any modules with
   for mod in ${MODULES[@]}; do
      if is_function "${mod}_pre_start" ; then
         ${mod}_pre_start "${iface}" || { eend 1; return 1; }
      fi
   done

   x="metric_${ifvar}"
   # If we don't have a metric then calculate one
   # Our modules will set the metric variable to a suitable base
   # in their pre starts.
   if [[ -z ${!x} ]] ; then
      eval "metric_${ifvar}=\"$(calculate_metric "${iface}" "${metric}")\""
   fi

   # We now expand the configuration parameters and pray that the
   # fallbacks expand to the same number as config or there will be
   # trouble!
   a="config_${ifvar}[@]"
   a=( "${!a}" )
   for (( i=0; i<${#a[@]}; i++ )); do
      eval b=( $(expand_parameters "${a[i]}") )
      config=( "${config[@]}" "${b[@]}" )
   done

   a="fallback_${ifvar}[@]"
   a=( "${!a}" )
   for (( i=0; i<${#a[@]}; i++ )); do
      eval b=( $(expand_parameters "${a[i]}") )
      fallback=( "${fallback[@]}" "${b[@]}" )
   done

   # We don't expand routes
   fallback_route="fallback_route_${ifvar}[@]"
   fallback_route=( "${!fallback_route}" )
   
   # We must support old configs
   if [[ -z ${config} ]] ; then
      interface_get_old_config "${iface}" || return 1
      if [[ -n ${config} ]] ; then
         ewarn "You are using a deprecated configuration syntax for ${iface}"
         ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly"
      fi
   fi

   # Handle "noop" correctly
   if [[ ${config[0]} == "noop" ]] ; then
      if interface_is_up "${iface}" true ; then
         einfo "Keeping current configuration for ${iface}"
         eend 0
         return 0
      fi

      # Remove noop from the config var
      config=( "${config[@]:1}" )
   fi

   # Provide a default of DHCP if no configuration is set and we're auto
   # Otherwise a default of NULL
   if [[ -z ${config} ]] ; then
      ewarn "Configuration not set for ${iface} - assuming DHCP"
      if is_function "dhcp_start" ; then
         config=( "dhcp" )
      else
         eerror "No DHCP client installed"
         return 1
      fi
   fi

   einfo "Bringing up ${iface}"
   eindent
   for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do
      # Handle null and noop correctly
      if [[ ${config[config_counter]} == "null" \
         || ${config[config_counter]} == "noop" ]] ; then
         eend 0
         config_worked=true
         continue
      fi

      # We convert it to an array - this has the added
      # bonus of trimming spaces!
      conf=( ${config[config_counter]} )
      einfo "${conf[0]}"

      # Do we have a function for our config?
      if is_function "${conf[0]}_start" ; then
         eindent
         ${conf[0]}_start "${iface}" ; x=$?
         eoutdent
         [[ ${x} == 0 ]] && config_worked=true && continue
         # We need to test to see if it's an IP address or a function
         # We do this by testing if the 1st character is a digit
      elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then
         x="0"
         if ! is_loopback "${iface}" ; then
            if [[ " ${MODULES[@]} " == *" arping "* ]] ; then
               if arping_address_exists "${iface}" "${conf[0]}" ; then
                  eerror "${conf[0]%%/*} already taken on ${iface}"
                  x="1"
               fi
            fi
         fi
         [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?"
         eend "${x}" && config_worked=true && continue
      else
         if [[ ${conf[0]} == "dhcp" ]] ; then
            eerror "No DHCP client installed"
         else
            eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
         fi
      fi

      if [[ -n ${fallback[config_counter]} ]] ; then
         einfo "Trying fallback configuration"
         config[config_counter]="${fallback[config_counter]}"
         fallback[config_counter]=""

         # Do we have a fallback route?
         if [[ -n ${fallback_route[config_counter]} ]] ; then
            x="fallback_route[config_counter]"
            eval "routes_${ifvar}=( \"\${!x}\" )"
            fallback_route[config_counter]=""
         fi

         (( config_counter-- )) # since the loop will increment it
         continue
      fi
   done
   eoutdent

   # We return failure if no configuration parameters worked
   ${config_worked} || return 1

   # Start any modules with _post_start
   for mod in ${MODULES[@]}; do
      if is_function "${mod}_post_start" ; then
         ${mod}_post_start "${iface}" || return 1
      fi
   done

   return 0
}

# bool iface_stop(char *interface)
#
# 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= aliases= need_begin=false mod=
   local RC_INDENTATION="${RC_INDENTATION}"

   # pre Stop any modules
   for mod in ${MODULES[@]}; do
      if is_function "${mod}_pre_stop" ; then
         ${mod}_pre_stop "${iface}" || return 1
      fi
   done

   einfo "Bringing down ${iface}"
   eindent

   # Collect list of aliases for this interface.
   # List will be in reverse order.
   if interface_exists "${iface}" ; then
      aliases=$(interface_get_aliases_rev "${iface}")
   fi

   # 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
      # Stop all our modules
      for mod in ${MODULES[@]}; do
         if is_function "${mod}_stop" ; then
            ${mod}_stop "${i}" || return 1
         fi
      done

      # A module may have removed the interface
      if ! interface_exists "${iface}" ; then
         eend 0
         continue
      fi

      # We don't delete ppp assigned addresses
      if ! is_function pppd_exists || ! pppd_exists "${i}" ; then
         # Delete all the addresses for this alias
         interface_del_addresses "${i}"
      fi

      # Do final shut down of this alias
      if [[ ${IN_BACKGROUND} != "true" \
         && ${RC_DOWN_INTERFACE} == "yes" ]] ; then
         ebegin "Shutting down ${i}"
         interface_iface_stop "${i}"
         eend "$?"
      fi
   done

   # post Stop any modules
   for mod in ${MODULES[@]}; do
      # We have already taken down the interface, so no need to error
      is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}"
   done

   return 0
}

# bool run_start(char *iface)
#
# Brings up ${IFACE}.  Calls preup, iface_start, then postup.
# Returns 0 (success) unless preup or iface_start returns 1 (failure).
# Ignores the return value from postup.
# We cannot check that the device exists ourselves as modules like
# tuntap make create it.
run_start() {
   local iface="$1" IFVAR=$(bash_variable "$1")

   # We do this so users can specify additional addresses for lo if they
   # need too - additional routes too
   # However, no extra modules are loaded as they are just not needed
   if [[ ${iface} == "lo" ]] ; then
      metric_lo="0"
      config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" )
      routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" )
   elif [[ ${iface} == "lo0" ]] ; then
      metric_lo0="0"
      config_lo0=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" )
      routes_lo0=( "127.0.0.0/8" "${routes_lo[@]}" )
   fi

   # We may not have a loaded module for ${iface}
   # Some users may have "alias natsemi eth0" in /etc/modules.d/foo
   # so we can work with this
   # However, if they do the same with eth1 and try to start it
   # but eth0 has not been loaded then the module gets loaded as
   # eth0.
   # Not much we can do about this :(
   # Also, we cannot error here as some modules - such as bridge
   # create interfaces
   if ! interface_exists "${iface}" ; then
      /sbin/modprobe "${iface}" &>/dev/null
   fi

   # Call user-defined preup function if it exists
   if is_function preup ; then
      einfo "Running preup function"
      eindent
      ( preup "${iface}" )
      eend "$?" "preup ${iface} failed" || return 1
      eoutdent
   fi

   # If config is set to noop and the interface is up with an address
   # then we don't start it
   local config=
   config="config_${IFVAR}[@]"
   config=( "${!config}" )
   if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then
      einfo "Keeping current configuration for ${iface}"
      eend 0
   else
      # Remove noop from the config var
      [[ ${config[0]} == "noop" ]] \
         && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )"

      # There may be existing ip address info - so we strip it
      if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \
         && ${IN_BACKGROUND} != "true" ]] ; then
         interface_del_addresses "${iface}"
      fi

      # Start the interface
      if ! iface_start "${iface}" ; then
         if [[ ${IN_BACKGROUND} != "true" ]] ; then
            interface_exists "${iface}" && interface_down "${iface}"
         fi
         eend 1
         return 1
      fi
   fi

   # Call user-defined postup function if it exists
   if is_function postup ; then
      # We need to mark the service as started incase a
      # postdown function wants to restart services that depend on us
      mark_service_started "net.${iface}"
      end_service "net.${iface}" 0
      einfo "Running postup function"
      eindent
      ( postup "${iface}" )
      eoutdent
   fi

   return 0
}

# bool run_stop(char *iface) {
#
# Brings down ${iface}.  If predown call returns non-zero, then
# stop returns non-zero to indicate failure bringing down device.
# In all other cases stop returns 0 to indicate success.
run_stop() {
   local iface="$1" IFVAR=$(bash_variable "$1") x

   # Load our ESSID variable so users can use it in predown() instead
   # of having to write code.
   local ESSID=$(get_options ESSID) ESSIDVAR=
   [[ -n ${ESSID} ]] && ESSIDVAR=$(bash_variable "${ESSID}")

   # Call user-defined predown function if it exists
   if is_function predown ; then
      einfo "Running predown function"
      eindent
      ( predown "${iface}" )
      eend $? "predown ${iface} failed" || return 1
      eoutdent
   elif is_net_fs / ; then
      eerror "root filesystem is network mounted -- can't stop ${iface}"
      return 1
   elif is_union_fs / ; then
      for x in $(unionctl "${dir}" --list \
      | sed -e 's/^\(.*\) .*/\1/') ; do
         if is_net_fs "${x}" ; then
            eerror "Part of the root filesystem is network mounted - cannot stop ${iface}"
            return 1
         fi
      done
   fi

   iface_stop "${iface}" || return 1  # always succeeds, btw

   # Release resolv.conf information.
   [[ -x /sbin/resolvconf ]] && resolvconf -d "${iface}"
   
   # Mark us as inactive if called from the background
   [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}"

   # Call user-defined postdown function if it exists
   if is_function postdown ; then
      # We need to mark the service as stopped incase a
      # postdown function wants to restart services that depend on us
      [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}"
      end_service "net.${iface}" 0
      einfo "Running postdown function"
      eindent
      ( postdown "${iface}" )
      eoutdent
   fi


   return 0
}

# bool run(char *iface, char *cmd)
#
# Main start/stop entry point
# We load modules here and remove any functions that they
# added as we may be called inside the same shell scope for another interface
run() {
   local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}"
   local starting=true
   local -a MODULES=() mods=()
   local IN_BACKGROUND="${IN_BACKGROUND}"

   if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then
      IN_BACKGROUND=true
   else
      IN_BACKGROUND=false
   fi

   # We need to override the exit function as runscript.sh now checks
   # for it. We need it so we can mark the service as inactive ourselves.
   unset -f exit

   eindent
   [[ ${cmd} == "stop" ]] && starting=false

   # We force lo to only use these modules for a major speed boost
   if is_loopback "${iface}" ; then   
      modules_force=( "iproute2" "ifconfig" "system" )
   fi

   if modules_load "${iface}" "${starting}" ; then
      if [[ ${cmd} == "stop" ]] ; then
         # Reverse the module list for stopping
         mods=( "${MODULES[@]}" )
         for ((i = 0; i < ${#mods[@]}; i++)); do
            MODULES[i]=${mods[((${#mods[@]} - i - 1))]}
         done

         run_stop "${iface}" && r=0
      else
         # Only hotplug on ethernet interfaces
         if [[ ${IN_HOTPLUG} == 1 ]] ; then
            if ! interface_is_ethernet "${iface}" ; then
               eerror "We only hotplug for ethernet interfaces"
               return 1
            fi
         fi

         run_start "${iface}" && r=0
      fi
   fi

   if [[ ${r} != "0" ]] ; then
      if [[ ${cmd} == "start" ]] ; then
         # Call user-defined failup if it exists
         if is_function failup ; then
            einfo "Running failup function"
            eindent
            ( failup "${iface}" )
            eoutdent
         fi
      else
         # Call user-defined faildown if it exists
         if is_function faildown ; then
            einfo "Running faildown function"
            eindent
            ( faildown "${iface}" )
            eoutdent
         fi
      fi
      [[ ${IN_BACKGROUND} == "true" ]] \
         && mark_service_inactive "net.${iface}"
   fi

   return "${r}"
}

# bool start(void)
#
# Start entry point so that we only have one function
# which localises variables and unsets functions
start() {
   declare -r IFACE="${SVCNAME#*.}"
   einfo "Starting ${IFACE}"
   run "${IFACE}" start
}

# bool stop(void)
#
# Stop entry point so that we only have one function
# which localises variables and unsets functions
stop() {
   declare -r IFACE="${SVCNAME#*.}"
   einfo "Stopping ${IFACE}"
   run "${IFACE}" stop
}

# vim:ts=4


It appears the other files for eth1 and eth2 are the same. Don't have a clue here!!!!

All help and explaination appreciated!!

Thanks!

OMR
Back to top
View user's profile Send private message
OldManRiver
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jan 2007
Posts: 79

PostPosted: Wed Jun 13, 2007 1:23 am    Post subject: Same Reply with quote

All,

Ran diff on all the net.ethx files and they are in fact all the same.

OMR
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Networking & Security All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum