I have a raspberry pi with three interfaces connected, eth0, wlan0 and ppp0, what i'm looking to achieve is having routes to the internet through all interfaces, but so far only eth0 and ppp0 gets a route.
here's outputs of route -n and ip route show (don't have a working ppp0 interface now but i know that one works)
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0 default via 192.168.1.1 dev eth0 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.39 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.243 I wrote a script that is triggered from /etc/dhcp/dhclient-exit-hooks.d/ so once the interface gets an offer from dhcp.
#!/bin/bash calculateCIDR() { nbits=0 IFS=. for dec in $1 ; do case $dec in 255) let nbits+=8;; 254) let nbits+=7;; 252) let nbits+=6;; 248) let nbits+=5;; 240) let nbits+=4;; 224) let nbits+=3;; 192) let nbits+=2;; 128) let nbits+=1;; 0);; *) echo "Error calulating CIDR exiting."; exit 1 ;; esac done echo $nbits } calculateSubnet() { IFS=. read -r i1 i2 i3 i4 <<< $1 IFS=. read -r m1 m2 m3 m4 <<< $2 echo "$((i1 & m1)).$((i2 & m2)).$((i3 & m3)).$((i4 & m4))" } # check if all parameters are there # expected parameters # $1 = iface # $2 = ip # $3 = mask # $4 = gateway if [ $# -ne 4 ] then echo "Illegal number of arguments" exit 2 fi # assign variables IFACE=$1 IP=$2 MASK=$3 GATEWAY=$4 # extract inface number and calculate table number case $IFACE in eth*) TABLEID=$(( 10 + `echo $IFACE | grep -o -E '[0-9]+'`)) METRIC=0 ;; wlan*) TABLEID=$(( 30 + `echo $IFACE | grep -o -E '[0-9]+'`)) METRIC=$(( 50 + `echo $IFACE | grep -o -E '[0-9]+'`)) ;; ppp*) TABLEID=$(( 90 + `echo $IFACE | grep -o -E '[0-9]+'`)) METRIC=$(( 100 + `echo $IFACE | grep -o -E '[0-9]+'`)) ;; *) echo "Bad interface exiting" exit 1 ;; esac # create new table for interface only if not existing there already grep -q -F "$TABLEID $IFACE" /etc/iproute2/rt_tables || echo "$TABLEID $IFACE" >> /etc/iproute2/rt_tables # remove previous rules while ip rule delete table $IFACE 2>/dev/null; do true; done # flush previous table ip route flush table $IFACE # calculate CIDR from CIDR=$(calculateCIDR $MASK) # calculate subnet address SUBNET=$(calculateSubnet $IP $MASK) # create route for local network ip route add $SUBNET/$CIDR dev $IFACE src $IP metric $METRIC table $IFACE # create route for internet ip route add default via $GATEWAY dev $IFACE metric $METRIC table $IFACE # set rules for the interface ip rule add from $IP/32 table $IFACE ip rule add to $IP/32 table $IFACE # done exit 0 this same script is used for all interfaces provided with network setup, wlan0 never gets a route to internet meaning i can't use it to ping anything outside the local network. anyone knows why ? i'm running out of ideas.
iptables'statistic --mode nth+MARKalong withip rule'sfwmarkdoes work). Anyway the solution proposed does indeed use this kind of setting: using additional routing tables