# ifplugd for automatic lan / wlan switching [SOLVED]

## Master One

I've a new IBM ThinkPad T42p with embedded IPW2200 wireless + e1000 gigabit lan. Everything is already setup fine, but I am now on the run for the perfect autoswitching between lan & wlan.

I played arround with ifplugd, which surely is the right way to go, but the standard ifplugd.action script does to perform as expected (it's a little tricky, because until eth1 ist started, no link can be detected by ifplugd, but if eth1 is running and gets stopped, the link stays up, as long as the connection to the AP is present):

- Basically on boot, either eth0 (lan) or eth1 (wlan) should be activated, depending on the check, if the link for eth0 is up (so a cable is plugged in), but not both.

- During boot, ntp-client should be able to sync the notebook clock, if either of the two network connections can be established (a little ticky due to timing / services start order).

- During use it should switch between eth0 / eth1, depending if the ethernet-cable is pulled or connected.

- If no wlan connection can be established (either on boot, or during use), the wlan interface should be disconnected (& ipw2200 modules unloaded?), to save power (I'd like to add a manual activation / deactivation of wlan, using of of the Fn-Fxx key-combinations, as well).

- As long as it is about switching between eth0 / eth1 (so at least one of the two is present), services depending on a network-connection (like sshd), should not get deactivated.

On this thread nomad- mentioned a version of ifplugd.action, which he modified just to do what I need, but his download url for the script is not working any more. It seems to be mandatory, just to let ifplugd control eth0, and not eth1, but additional tasks concerning eth1 need to be done in ifplugd.action.

Anyone has seen this or a similar script?

I searched the whole evening, but nothing useful came up, which I find a little confusing, because I assume a lot of people are in the same situation like me, and the standard installation of ifplugd really doesn't do.

----------

## troycarpenter

In short, you need to add commands in the appropriate places to load and unload your wireless drivers to get the functionality you are looking for.

Here's my current /usr/sbin/ifplugd.action:

-------------

```
#!/bin/sh

# Copyright 1999-2004 Gentoo Foundation

# Distributed under the terms of the GNU General Public License v2

# $Header: /var/cvsroot/gentoo-x86/sys-apps/ifplugd/files/gentoo-ifplugd.action-v2,v 1.3 2004/07/15 00:43:53 agriffis Exp $

#

# Gentoo-specific ifplugd.action

#

# This file gets called by ifplugd when it wants to bring an interface

# up or down.

#

#if [ -x /etc/init.d/net.$1 ]

#then

#   /etc/init.d/net.$1 --quiet $state

#   exit 0

#else

#   logger -t ifplugd.action "Error: Couldn't configure $1, no /etc/init.d/net.$1 script!"

#   exit 1

#fi

case "$2" in

   up)

           /etc/init.d/net.$1 start

                case "$1" in

            eth0)

            /etc/init.d/net.eth1 stop

                 /usr/local/bin/rmipw2100

            ;;

            eth1)

            ;;

      esac

      ;;

   down)

      /etc/init.d/net.$1 stop

                case "$1" in

                 eth0)

                       /sbin/ifconfig eth0 up

            /sbin/modprobe ipw2100

            sleep 2

            /etc/init.d/net.eth1 start

            ;;

            eth1)

                           ;;

      esac

      ;;

   *)

      echo "$0: wrong arguments"

      echo "Call with <interface> <up|down>"

      exit 1

      ;;

esac
```

----------------

You will obviously need to make any changes as necessary to handle your configuration.  In my system, the wireless interface is eth1.  The script /usr/local/bin/rmipw2100 simply removes all the ipw2100 kernel mods (ipw2100, ieee8021, ieee8021_crypt, ieee8021_crypt_wep).

Don't forget the config file.  Minus the tons of header comments, I have:

```
AUTO="no"

BEEP="yes"

IGNORE_FAIL="yes"

IGNORE_FAIL_POSITIVE="yes"

IGNORE_RETVAL="yes"

POLL_TIME="1"

DELAY_UP="0"

DELAY_DOWN="0"

API_MODE="auto"

SHUTDOWN="yes"

WAIT_ON_FORK="no"

MONITOR="no"

ARGS=""

# Additional parameters for ifplugd for the specified interface. Note that

# the global variable is ignored, when a variable like this is set for an

# interface

# MONITOR_wlan0="yes"

DELAY_UP_eth1="5"

DELAY_DOWN_eth0="5"
```

For my T41, I also had to add the following to the beginning of /etc/init.d/ifplugd:

```
/sbin/ifconfig eth0 up
```

because the ipw2100 won't detect carrier unless the interface is up.  This might be able to go in another place, like /etc/conf.d/local.start, but I haven't moved it yet.  You also see that command in the ifplugd.action script above after the interface has been shut down so cable re-inserts can be detected.

You may also want to add postup() routines to your /etc/conf.d/net file for any service that need to be restarted once the interface comes up.  For instance, I usually restart the ntp-client service to resync the time.

Now, having written all this, I am still experimenting in the ifplugd area.  My next tests are to turn on ifplugd monitoriing for eth1 also, which will require some changes to the ifplugd.action file, to see if it will automatically switch to newly found wireless networks.  That is, I'm connected to my wireless network at work, then go home.  Can ifplugd cause my laptop to automatically connect to my home network without restarting eth1 manually?  Does ifplugd view the detection of a wireless signal the same as the insertion of a cat5 cable?  That's what I intend to find out.  It may solve one other problem I didn't get into with the above script, but you will find out about it real quick when you reboot without an ethernet cable...an exercise for the reader.

Troy

----------

## Master One

It simply does not work the way it should. I played around for some days now, but the result is not what I want.

With a modified ifplugd.action and only eth0 to be monitored, it is possible to make it switch between eth0 and eth1 on cable pull/plug, it is also possible to auto-activate eth0 on boot if cable is plugged in, but it seems to be impossible to make it relieably start net.eth1 on boot if the cable on eth0 is pulled.

Is there any replacement for ifplugd arround?

Or maybe someone has a really nifty ifplugd.action and /etc/conf.d/ifplugd file, which just works?

nomad-'s ifplugd.action is most likely a lot more capable, since he also checks if eth1 could be started properly, and disables it with driver unload on no connection to an AP. I really would like to be able to get a look on nomad-'s ifplugd.action file, but as already mentioned, it's not any more available from the link of his thread.

----------

## Master One

Ok, I have to correct myself. ifplugd can handle eth0 quite well, and I can get it to do everything right, as long as the cable is plugged in.

The only real problem is now, that if the cable for eth1 is pulled on boot, eth1 does not automatically get started, which is logical, since no link beat is detected and ifplugd.action is not executed.

So the solution should probably be, to let ifplugd (or better an own script?) fire up eth1 on boot, if no link beat is detected on eth0.

Anyone has a solution for that problem?

----------

## Master One

Ok, here comes my solution, which covers the whole needed process:

- When booting with eth0 cable plugged in, eth0 gets started, eth1 stays down

- When booting with eth0 cable pulled, eth0 stays down, but eth1 gets started

- During use, switch between eth0 / eth1 on cable plug / pull

This is, what you have to do to get it work:

- emerge ifplugd

- add ifplugd to the boot runlevel

- remove eth0 / eth1 from any runlevel

- comment out the lines which start/stop interface in /etc/hotplug/net.agent (if you use coldplug/hotplug)

- do not do any changes to /etc/conf.d/ifplugd (we only let ifplugd check eth0, but not eth1, and we do not need the autostart)

- edit /usr/sbin/ifplugd.action to look like this:

```
case "$2" in

        up)

                state=start

                otherstate=stop

                ;;

        down)

                state=stop

                otherstate=start

                ;;

        *)

                echo "$0: wrong arguments"

                echo "Call with <interface> <up|down>"

                exit 1

                ;;

esac

if [ -x /etc/init.d/net.$1 ]

then

        /etc/init.d/net.$1 --quiet $state

        if [ $1 = eth0 ]; then

                /etc/init.d/net.eth1 --quiet $otherstate

                if [ $otherstate = stop ]; then

                        rmmod ipw2200

                        modprobe ipw2200

                fi

        else

                /etc/init.d/net.eth0 --quiet $otherstate

                if [ $state = stop ]; then

                        rmmod ipw2200

                        modprobe ipw2200

                fi

        fi

        exit 0

else

        logger -t ifplugd.action "Error: Couldn't configure $1, no /etc/init.d/net.$1 script!"

        exit 1

fi
```

(If you wonder, why I rmmod & modprobe the ipw2200 module: This is the simplest way to kill the connection to the AP, which is not the case by simply bringing eth1 down, and this also switches off the wireless-led)

- add the following script as /etc/init.d/ifstartup

```
#!/sbin/runscript

depend() {

        need ifplugd

        before ntp-client

}

start() {

        /sbin/ifconfig eth0 up

        if /usr/sbin/ifplugstatus | egrep -q 'eth0: link beat detected'; then

                einfo "ifplugstatus: eth0 link beat detected, starting eth0..."

                /etc/init.d/net.eth0 start

        else

                einfo "ifplugstatus: eth0 link beat not detected, starting eth1..."

                /etc/init.d/net.eth1 start

        fi

}
```

- make it executeable, tell the system about it, and add it to default runlevel:

```
chmod +x /etc/init.d/ifstartup && /sbin/depscan.sh && rc-update add ifstartup default
```

That's it! It's quick & dirty, but everything is working flawlessly now.  :Very Happy: 

I only wonder now, if there is a better way of handling eth1 and the wlan-module. Can the wlan-interface be switched off completely, to save more battery power in case no connected to an AP can be established?

----------

## boles

I'am trying your script but I have one question about:

 *Quote:*   

> - comment out the lines which start/stop interface in /etc/hotplug/net.agent (if you use coldplug/hotplug)

 

Can you tell me which lines you mean? My net.agent script is:

```
#!/bin/sh

#

# Network hotplug policy agent for Linux 2.4 kernels

#

# Kernel NET hotplug params include:

#   

#   ACTION=%s [register or unregister]

#   INTERFACE=%s

#

# HISTORY:

#

# 25-Feb-2001   Special case ppp and similar (redhat)

# 23-Jan-2001   Log invocation of "ifup" if debugging

# 04-Jan-2001   Initial version of "new" hotplug agent.

#

# $Id: net.agent,v 1.22 2004/09/20 23:02:34 kroah Exp $

#

cd /etc/hotplug

. ./hotplug.functions

# DEBUG=yes export DEBUG

if [ "$INTERFACE" = "" ]; then

    mesg Bad NET invocation: \$INTERFACE is not set

    exit 1

fi

case $ACTION in

add|register)

    # Red Hat specific hack...

    if [ -f /etc/redhat-release ]; then

   # Don't do anything if the network is stopped

   if [ ! -f /var/lock/subsys/network ]; then

       exit 0

   fi

    fi

    case $INTERFACE in

   # interfaces that are registered after being "up" (?)

   ppp*|ippp*|isdn*|plip*|lo*|irda*|dummy*|ipsec*|tun*|tap*)

       debug_mesg assuming $INTERFACE is already up

       exit 0

       ;;

   # interfaces that are registered then brought up

   *)

       # NOTE:  network configuration relies on administered state,

       # we can't do much here without distro-specific knowledge

       # such as whether/how to invoke DHCP, set up bridging, etc.

       # Run ifrename as needed - Jean II

       # Remap interface names based on MAC address. This workaround

       # the dreaded configuration problem "all my cards are 'eth0'"...

       # This needs to be done before ifup otherwise ifup will get

       # confused by the name changed and because iface need to be

       # down to change its name.

       if [ -x /usr/sbin/ifrename ] && [ -r /etc/iftab ]; then

      debug_mesg invoke ifrename for $INTERFACE

      NEWNAME=`/usr/sbin/ifrename -i $INTERFACE`

      if [ -n "$NEWNAME" ]; then

          debug_mesg iface $INTERFACE is remapped to $NEWNAME

          INTERFACE=$NEWNAME

      fi;

       fi

       # RedHat and similar

       export IN_HOTPLUG=1

       if [ -x /sbin/ifup ]; then

      debug_mesg invoke ifup $INTERFACE

      exec /sbin/ifup $INTERFACE

       # Gentoo

       elif [ -f /etc/gentoo-release ]; then

      script=/etc/init.d/net.$INTERFACE

      if [ -x "$script" ]; then

          debug_mesg invoke \"$script\" --quiet start

          exec "$script" --quiet start

      fi

       else

      mesg "how do I bring interfaces up on this distro?"

       fi

       ;;

    esac

    mesg $1 $ACTION event not handled

    ;;

remove|unregister)

    case $INTERFACE in

   # interfaces that are unregistered after being "down" (?)

   ppp*|ippp*|isdn*|plip*|lo*|irda*|dummy*|ipsec*|tun*|tap*)

       debug_mesg assuming $INTERFACE is already down

       exit 0

       ;;

   *)

       # right now it looks like only Gentoo wants to care about

       # unregistering network devices...

       if [ -f /etc/gentoo-release ]; then

          script=/etc/init.d/net.$INTERFACE

      if [ -x "$script" ]; then

          debug_mesg invoke "$script" --quiet stop

          exec "$script" --quiet stop

      fi

       fi

       ;;

    esac

    mesg $1 $ACTION event not handled

    ;;

*)

    debug_mesg NET $ACTION event for $INTERFACE not supported

    exit 1 ;;

esac

```

Thanks.

----------

## Master One

 *boles wrote:*   

> I'am trying your script but I have one question about:
> 
>  *Quote:*   - comment out the lines which start/stop interface in /etc/hotplug/net.agent (if you use coldplug/hotplug) 
> 
> Can you tell me which lines you mean?

 

It's these:

```

      if [ -x "$script" ]; then

#          debug_mesg invoke \"$script\" --quiet start

#          exec "$script" --quiet start

      fi
```

and these:

```
      if [ -x "$script" ]; then

#          debug_mesg invoke "$script" --quiet stop

#          exec "$script" --quiet stop

      fi
```

----------

## boles

I dit everything as mentioned, but I get these errors:

 *Quote:*   

> Service 'ifplugd' can't depend on itself;  continuing...

 

 *Quote:*   

> Mar  4 00:27:02 [rc-scripts] Could not get dependency info for "ifstartup"!
> 
> Mar  4 00:27:02 [rc-scripts] Please run:
> 
> Mar  4 00:27:02 [rc-scripts] # /sbin/depscan.sh
> ...

 

 *Quote:*   

> Mar  4 00:26:57 [devfsd] error calling: "unlink" in "GLOBAL"_

 

When restarting nor eth0 nor eth1 is connected.

Please help.

----------

## Master One

 *boles wrote:*   

> 
> 
> ```
> Service 'ifplugd' can't depend on itself;  continuing...
> ```
> ...

 

Looks like you did not follow my instructions step by step. The dependency "iflugd" has to be in /etc/inid.d/ifstartup, and not in /etc/init.d/ifplugd.

If you have followed my guide, the mentioned message should not have showed up.

 *boles wrote:*   

> 
> 
> ```
> Mar  4 00:27:02 [rc-scripts] Could not get dependency info for "ifstartup"!
> 
> ...

 

Hm, then you should run /sbin/depscan.sh, as I remember, this is done automatically on my system.

 *boles wrote:*   

> 
> 
> ```
> Mar  4 00:26:57 [devfsd] error calling: "unlink" in "GLOBAL"_
> ```
> ...

 

You are using devfs? Sorry, but I can't help there, I am running a pure udev system here.

BTW In the meantime I changed the startup behaviour by deactivating autostart in /etc/conf.d/ifplugd and added the start for eth0 to my ifstartup script, please see the changes in my initial post with the guide above.

----------

## tundra

I had the same ifplugd dependency error.  I found that I had to add the line

#!/sbin/runscript

at the start of the ifstartup script before everything would run cleanly.

----------

## Master One

 *tundra wrote:*   

> I had the same ifplugd dependency error.  I found that I had to add the line #!/sbin/runscript at the start of the ifstartup script before everything would run cleanly.

 

Oh yes, sorry for not mentioning that (some things get so common, you just skip it if you think everybody already has to know...). I just edited my post, so this should be no problem no more.

----------

## Otik2

I set everything up according to Master One's instructions, but ifplugd does weird things to my eth0.  Whenever I boot up my computer, whether or not the cable is plugged in, it starts eth1 (my wireless card, ipw2200).  If I disconnect eth0 and plug it back in, nothing changes: eth1 is still connected, but eth0 doesn't get connected.  I have to manually start it myself, or in some cases stop ifplugd before I can start it.  When I first start up my computer with the ethernet plugged in, ifplugstatus detecs the link beat, although it still starts eth1.  But after I disconnect eth0 and then plug it back in, igplugstatus still things it's unplugged.  Perhaps it can't detect the link beat until eth0 is started, but ifplugd doesn't start it until it detects a link beat?  Though that still doesn't explain with eth1 is always started regardless or whether the ethernet is connected.

Anyway, I'd appreciate any help.

----------

## Master One

1. Take a look, if you really commented out the correct lines in /etc/hotplug/net.agent

2. We only let ifplugd handle eth0, so no need to change the default settings in /etc/conf.d/ifplugd

3. Take a look, if you have removed eth0 & eth1 from any runlevels

This way, everything should be working. Of course I only could test it on my notebook (eth0 = e1000, eth1 = ipw2200). I assume the only weirdness could happen, if your eth0 is not supported concerning link beat detection, then you would have to play arround with the settings in /etc/conf.d/ifplugd (see also man ifplugd).

----------

## Otik2

Yes, I checked all three of those and they were all correct.  Perhaps you're right about my ethernet card not being supported; even if it works when it boots up, when I unplug it and plug it back in ifplugstatus says it's not connected until I manually start the service.  I have a Broadcom 4400 ethernet card, but after Googling it a bit it seems that other people got it to work with ifplugd.  And sometimes even when ifplugstatus says it's connected, when I restart ifplugd it says that there is no link beat, even though ifplugstatus says there is.

I just played around a bit with some settings, and it didn't help much, perhaps because I'm not sure what to change.  I am occasionally getting a weird situation where I restart ifplugd with the ethernet plugged in.  It initally fails to detect a link and so starts eth1.  But then it almost instantly detects the eth0 link and runs ifplugd.action eth0 up.  Then I get a line in /var/log/messages that dhcpd terminates on signal 10.  After that the eth0 link is detected as down and it runs ifplugd.action eth0 down again.  And all this is while the ethernet is plugged in.

As you can see, I'm rather confused.  I'd appreciate any help you could give me.

----------

## Master One

I'm sorry, but I have no idea, what the problem with your configuration could be. Are you using the latest ~x86 baselayout? This may have an effect on this matter as well. I can't tell you, which other settings you could try in the config file, it may be something with the API_MODE, if the correct detection fails with the auto mode. You may want to visit the ifplugd homepage, maybe you find some more clues there. The solution, I described, worked out of the box here on my Thinkpad T42p.

----------

## jsa

ifplug is unable to monitor eth0 unless it is manually "put online" using command: ifconfig eth0 up

only after that I get right messages if cable is un/plugged:

e1000: eth0: e1000_watchdog: NIC Link is Down

e1000: eth0: e1000_watchdog: NIC Link is Up 100 Mbps Full Duplex

ifplugd  (ethtool as well) is unable to see any change in cable being un/plugged once there is a message:

bridge-eth0: disabling the bridge

bridge-eth0: down

snow falls

everything is silent

so are the logs

i use ibm t42p, e1000 runs inside kernel not as a module. running daemons:

acpid  alsasound  coldplug  domainname  famd  hald  hotplug  local  mDNSResponder  netmount  pcmcia  samba  shorewall  sshd  syslog-ng  vixie-cron  vmware  xdm

----------

## Master One

- Compile e1000 as a module

- Take care that coldplug is in boot runlevel

- Use latetest ~x86 baselayout and take care, that all config files get updated properly -> net.eth0 and net.eth1 are only links to net.lo (you will have to create the link net.eth1 manually)

That's all, as stated, my solution worked out of the box on my T42p.

----------

## jsa

thank you! i disabled CONFIG_E1000_NAPI, enabled 100MBit network cards support and enabled CONFIG_MII. Now it seems that ifplugd will be capable of monitoring the card. Unfortunately, baselayout ~x86 demands few recompiles. I'll try ifplugd later today.

----------

## BigBaaadBob

For another opinion... :Laughing: 

I'd rather have ifplugd bring up both interfaces (wired and wireless) or whichever is available and have the traffic automatically go out the fastest link.  That is why the ifplugd author wrote ifmetric.  This is a simpler and more natural networking solution.  You get the same effect without modifying ifplugd's scripts.  One worry would that you would get dueling DHCP stuff, but if the wired/wireless are in the same network this shouldn't cause problems.

----------

## Master One

BigBadBob, that was also my first thought, but as it turned out, you can't handle the wireless connection this way, because it does not report a link beat until you established the connection for the first time, so it will always stays down unless you manually start that interface. I played around with that matter a lot, any my solution is really the only way it is working properly.

----------

## sbgskl1

Is there any way to implement Master One's ifplugd actions, but have them execute after a user logs in?  I was thinking of doing something with .bashrc, but I'm really not sure that's the best way.

----------

## RBJ1128

 *Master One wrote:*   

> Ok, here comes my solution, which covers the whole needed process:
> 
> - When booting with eth0 cable plugged in, eth0 gets started, eth1 stays down
> 
> - When booting with eth0 cable pulled, eth0 stays down, but eth1 gets started
> ...

 

Thanks, that works great.  I am running into a problem though.  DHCP seems to be broken for my wired connection (eth0) now.  On boot I get a message that there is a cable present, but it does not pull an IP from DHCP.  My wireless connection works flawlessly though.  Any ideas on this?

----------

## nadi

Hei,

Does anyone know what I need to change in the script of Master One if I have instead of eth1, I have ath0? I am not good in programming scripts.

Thanks!

Nadi

----------

## RBJ1128

 *nadi wrote:*   

> Hei,
> 
> Does anyone know what I need to change in the script of Master One if I have instead of eth1, I have ath0? I am not good in programming scripts.
> 
> Thanks!
> ...

 

Just change all of the references from eth1 to ath0.  That should do it.

----------

## tuxian

 *jsa wrote:*   

> thank you! i disabled CONFIG_E1000_NAPI, enabled 100MBit network cards support and enabled CONFIG_MII. Now it seems that ifplugd will be capable of monitoring the card. Unfortunately, baselayout ~x86 demands few recompiles. I'll try ifplugd later today.

 

Where do I find CONFIG_MII?

I have the same problem with ifplug and e1000, ifplug doesn't detect the link status.

When I start /etc/init.d/net.eth1 (for e1000) manually ifplug stops this device when i unplug the cable but it doesn't starts the device again then i plug the cable in again.

----------

