Monday, January 30, 2017

Utilize Ethernet over Wifi, When Plugged In – Linux Networking Scenario

Synopsis:

I've two network interfaces in my Laptop. Ethernet (eth0) and Wifi (wlan0). Both are bridged together through ARP_Proxying in a software Bridge (br0) using 'parprouted' utility.

Now by default I would like to use my wifi to connect to my LAN and internet. But whenever a LAN cable plugged in I would like to use my Ethernet for both LAN and Internet. This to get the optimal performance and bandwidth, as my Ethernet will work faster than Wifi. As soon as I'm about to move around with my Laptop (By unplugging LAN cable), Wifi should take over and serve both LAN and Internet once again. Now If I've plugged in my LAN cable again, Ethernet should spring back. The switch over should be smooth enough, so that applications which requires net connection should work with minimal glitches after the switch.

The big picture has given below.


wifi lan

Below is an excerpt from my '/etc/rc.local' file, that shows the bridging setup

sudo brctl addbr br0 setfd 0 stp off
sudo brctl addif br0 eth0
#
#
sudo parprouted wlan0 br0
sudo bcrelay -d -i wlan0 -o br0
#
#
sudo sysctl net.ipv4.conf.wlan0.proxy_arp=1
sudo sysctl net.ipv4.conf.br0.proxy_arp=1


Problem Statement:

But as soon as I boot up my system, wifi is the only network interface which will serve both my internet/LAN. Even if Ethernet cable has plugged in, it will never get used.

After much troubleshooting I've found that the issue has been causing by 'parprouted' utility. The tool will set the default gateway of Wifi only. It will never respect my Ethernet state (no matter if its plugged-in or not). See my routing table after the system boot. Notice the last line, it will always use 'wlan0'


sudo route
#
Kernel IP routing table
default   192.168.1.1  0.0.0.0   UG     7      0        0   wlan0


Solution:

Since opting the correct network device (interface) for the default gateway has been the solution, the fix is pretty straight forward. The abstract has been given below.

1. Whenever Ethernet cable is plugged in, Update the routing table so that, Default Gateway should use Ethernet (eth0/br0)

2. Whenever Ethernet cable is unplugged, Update the routing table so that, Default Gateway should use Wifi (wlan0)

3. On system startup, Perform both Step 1 & 2


To detect Ethernet Cable Plug In/Unplug events, we can use the utility called 'ifplugd'. Configure ethernet (eth0), so that both plugin/unplug will be monitored. We will then hook a simple bash script to this events, as to modify the network interface for the default gateway.

sudo apt-get install ifplugd
#
#
vi /etc/default/ifplugd
INTERFACES="eth0"
#
#
vi /etc/ifplugd/action.d/ifupdown
#Append the below line, which calls our custom script
sudo bash -c WatchNetwork.sh

Now my custom script (WatchNetwork.sh), given below to modify the network interface for the default gateway, as desired (on Ethernet plugin/unplug events).

#!/bin/bash
set +e   # Don't exit on error status
//Removed some code.........
#
#
#Get LAN cable Plugged in status
is_eth_plugged=$(cat /sys/class/net/eth0/carrier)
#
#
#Is Wifi is our gateway device?
is_wifi_gw=$(route | grep default.*wlan0 | tr -s ' ' | cut -d' ' -f8 | head -n1| wc -l)
#
#
#Is Ethernet is our gateway device?
is_eth_gw=$(route | grep default.*br0 | tr -s ' ' | cut -d' ' -f8 | head -n1| wc -l)
#
#
#We've already set the device properly, so exit without doing anything
[ $is_eth_plugged -eq 1 ] && [ $is_eth_gw -eq 1 ] && exit 0
[ $is_eth_plugged -ne 1 ] && [ $is_wifi_gw -eq 1 ] && exit 0
#
#
#If ethernet is plugged in the device will be eth0/br0 or it will be wifi (wlan0)
[ $is_eth_plugged -eq 1 ] && iface="br0" || iface="wlan0"
#
#
#Have a ping on the interface to see if it is actually can be set for the  gateway
ping_iface=$(ping -I $iface -c 1 $defGateway | grep "64 bytes from $defGateway" | wc -l)
[ $ping_iface -ne 1 ] && exit 0
#
#
#Now remove the exiting gateway from the routing table
while [[ $(route del default) -ne 0 ]]
do
        true
done
#
#
#Clear ARP cache
ip -s -s neigh flush all
#
#
#Now Add the default gateway with the correct device
route add -net default gw $defGateway dev $iface


 Add the same script in /etc/rc.local, so that the check will also be done on system startup

sudo bash –c WatchNetwork.sh

Now as soon as you plugin your LAN cable, Ethernet will be used as the primary device for internet/networking. If it gets unplugged, wifi will take over.

Here are my scripts for downloading.

No comments:

Post a Comment