Roaming between wireless and wired

From CLUG Wiki

Jump to: navigation, search

newpage icon WARNING: This is a new page.

This is a new page, and might contain technically incorrect information. Please use at your own risk. If you are able to correct any errors or expand this document, please do so.


Debian Logo Warning: This is a Debian-centric page

This page is written by a Debian user with Debian in mind. Thus, he liberally uses apt-get, and assumes that everything will work exactly the same for you.

If you don't run Debian (or something based on it like Ubuntu), it won't, so please find the differences and add them to this page.


Contents

The Problem

You have a WiFi LAN which you use on your laptop most of the time, because it is convenient. However, you also have a much faster gigabit LAN that you want to use to transfer big files around. But you don't want to mess with bringing interfaces up and down and inevitably losing open network sessions.

Unsolved portions

While this solution carries sessions over from wifi to wifi+wired and back again, sessions started on wifi+wired will die when the wired link goes away. I don't know of any way of avoiding this...

Assumptions

I am assuming that:

  • You are using Debian / Ubuntu (or a system with /etc/network/interfaces), and already have your wired (eth0) and wireless (wlan0) interfaces set up and happy.
  • You enjoy getting this sort of thing set up on the command line.
  • Your wireless and wired networks are simply bridged somewhere (this should also work for nicely routed network separation, but I can't be bothered to think that through...)

Setting up ifplugd

The first thing we want is that when we plug in a network cable, the eth0 link should come up automatically, and vice-versa for removing it.

# apt-get install ifplugd
# vi /etc/default/ifplugd

Set INTERFACES="eth0"

You may also want to change -d10 to -d1 so that the wired interface goes down 1 second after the cable comes out instead of 10. That way your sessions will not have to hang in mid air for 10 seconds...

# vi /etc/network/interfaces

Make sure that no auto lines point to eth0 directly or not.

Turn on your sound and esp. the PC Squeaker channel, because ifplugd beeps whenever it detects a plug-in/out and again when the link is brought up/down. This is helpful debugging information.

Get it going

Unplug your wired cable.

# ifdown eth0
# /etc/init.d/ifplugd restart

iproute2 fun

Now for the routing priority bit that says eth0 should be used instead of wlan0.

We are going to do this through a script that gets called whenever an interface is brought up, via /etc/network/interfaces. We could also use if-up.d but this is more explicit, and will abort bringing the link up if something goes wrong :-)

This is a little of a hack, so you might have to fix it for your installation...

# apt-get install iproute
# vi /etc/network/interfaces

Edit your eth0 section to have this up line:

# The primary network interface
#auto eth0
iface eth0 inet dhcp
  up /usr/local/sbin/route-prios $IFACE 1

Similarly for wlan0 but this time with a priority of 10:

# WiFi
auto wlan0
iface wlan0 inet dhcp
  wireless-enc s:password
  up /usr/local/sbin/route-prios $IFACE 10

Now to create this route-prios script:

# cat > /usr/local/sbin/route-prios <<EOF
#!/bin/sh -e
# Params: $1 = Iface name
#         $2 = Preference
ip route list table 0 | grep -v " table local" | grep " dev $1" | while read line; do
  dest=`echo $line | cut -f 1 -d ' '`
  echo ip route del $dest dev $1
  ip route del $dest dev $1
  echo ip route add $line preference $2
  ip route add $line preference $2
done
EOF
# chmod 755 /usr/local/sbin/route-prios

Test

# ifdown eth0 wlan0; ifup wlan0 eth0
# ip route list table 0

You should see something like: (note the metric bits)

10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2  metric 1
10.0.0.0/24 dev wlan0  proto kernel  scope link  src 10.0.0.3  metric 10
default via 10.0.0.1 dev eth0  metric 1
default via 10.0.0.1 dev wlan0  metric 10
local 10.0.0.3 dev wlan0  table local  proto kernel  scope host  src 10.0.0.3
local 10.0.0.2 dev eth0  table local  proto kernel  scope host  src 10.0.0.2
broadcast 10.0.0.0 dev wlan0  table local  proto kernel  scope link  src 10.0.0.3
broadcast 10.0.0.0 dev eth0  table local  proto kernel  scope link  src 10.0.0.2
broadcast 10.0.0.255 dev wlan0  table local  proto kernel  scope link  src 10.0.0.3
broadcast 10.0.0.255 dev eth0  table local  proto kernel  scope link  src 10.0.0.2