View previous topic :: View next topic |
Author |
Message |
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Thu Jan 18, 2007 9:09 pm Post subject: Best Method ?? |
|
|
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 |
|
|
erik258 Advocate
Joined: 12 Apr 2005 Posts: 2650 Location: Twin Cities, Minnesota, USA
|
Posted: Fri Jan 19, 2007 1:23 am Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Thu Jan 25, 2007 9:03 pm Post subject: Confused!! |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Sun Apr 01, 2007 10:38 pm Post subject: All eth working but not satified |
|
|
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 |
|
|
NeddySeagoon Administrator
Joined: 05 Jul 2003 Posts: 54808 Location: 56N 3W
|
Posted: Sun Apr 01, 2007 10:50 pm Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Wed May 16, 2007 4:20 pm Post subject: |
|
|
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 |
|
|
erik258 Advocate
Joined: 12 Apr 2005 Posts: 2650 Location: Twin Cities, Minnesota, USA
|
Posted: Wed May 16, 2007 8:51 pm Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Thu May 17, 2007 8:47 pm Post subject: |
|
|
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 |
|
|
erik258 Advocate
Joined: 12 Apr 2005 Posts: 2650 Location: Twin Cities, Minnesota, USA
|
Posted: Thu May 17, 2007 10:38 pm Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Sun May 27, 2007 6:58 pm Post subject: What I have |
|
|
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 |
|
|
erik258 Advocate
Joined: 12 Apr 2005 Posts: 2650 Location: Twin Cities, Minnesota, USA
|
Posted: Tue May 29, 2007 1:37 pm Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Fri Jun 08, 2007 4:18 pm Post subject: One More |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Fri Jun 08, 2007 4:24 pm Post subject: My Real Question |
|
|
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 |
|
|
erik258 Advocate
Joined: 12 Apr 2005 Posts: 2650 Location: Twin Cities, Minnesota, USA
|
Posted: Fri Jun 08, 2007 10:05 pm Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Tue Jun 12, 2007 9:29 pm Post subject: |
|
|
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 |
|
|
OldManRiver Tux's lil' helper
Joined: 17 Jan 2007 Posts: 79
|
Posted: Wed Jun 13, 2007 1:23 am Post subject: Same |
|
|
All,
Ran diff on all the net.ethx files and they are in fact all the same.
OMR |
|
Back to top |
|
|
|
|
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
|
|