1

My raspberry 3 is connected to Wi-Fi, Ethernet, and ppp0 (configured using UC20 GSM). All three connections work perfectly individually.

But when I combine all three networks on the Pi 3 it will get the data from Ethernet but when I drop the Ethernet connection, (not removing the Ethernet cable but from a slow down on the router side) the Pi does not switch to Wi-Fi or ppp0.

In my application a strong internet connection is required so I will use the three networks and if one or two networks slow or drop out then the connection should be automatically switched to the second or third network.

My primary network is Ethernet. If my Ethernet slows down my Pi should switch to Wi-Fi and Ethernet. If Wi-Fi and Ethernet both slow down then the Pi should switch to ppp0 so my application runs without any internet connectivity problems.

Any suggestions on how to solve this problem?

pragnesh
  • 11
  • 2
  • Hello and welcome to the site! I've taken a considerable amount of time to decipher your question and to write it up more clearly. In its current format it lacks *specific* detail on your current setup. E.g. what operating system the Pi is running and how you are trying to detect what networks it is connected to. I recommend you edit this information into your question so users are able to help you. Since you are new here I suggest you take the [Tour](https://raspberrypi.stackexchange.com//tour) to find out how the site works. – Darth Vader Sep 01 '20 at 10:00
  • @DarthVader I have voted to reopen the question. I would have an answer using bonding. – Ingo Sep 04 '20 at 11:08
  • @Ingo FYI after you last voted to reopen this the community voted to leave it closed. Unless the OP makes a significant effort to improve the question I'm inclined not to wield the mod hammer to reopen this. – Darth Vader Sep 05 '20 at 13:57
  • @DarthVader That isn't fair. The question wasn't closed by 5 votes, only by your intervention as admin. So it should be acceptable that you also reopen it without 5 votes. I haven't never seen a question that was reopened by 5 votes. The OP could get an answer. – Ingo Sep 05 '20 at 16:11
  • @Ingo the problem I have is the OP is not engaging with the question. I suggest you leave a comment briefly outlining a possible solution to see if it has the potential to solve their problem. If so I'd be happy to reopen the question, but with the information the OP has given so far this question has the potential to be very open ended. – Darth Vader Sep 05 '20 at 17:17
  • 1
    @DarthVader The problem explained by the OP is a well known general networking issue, known as **dynamic failover**. There is no need to explain it in more details in the question to know that this is meant. Linux supports it with its **bonding** driver and I have an example at [systemd-networkd with dynamic failover](https://raspberrypi.stackexchange.com/a/78788/79866). This is somewhat older and need to be adapted to this question in an answer. – Ingo Sep 05 '20 at 17:58
  • @Ingo feel free to answer – Darth Vader Sep 05 '20 at 20:35

1 Answers1

2

Your problem is well known as dynamic failover and supported by Linux with its bonding driver. It will switch to the next connection as long as it is connected.

The first step is to bring up all connections. I prefer to use systemd-networkd so Use systemd-networkd for general networking. You will find examples in section ♦ Create interface file for a wired connection and in section ♦ Create interface file for a WiFi connection. For the ppp connection you have an interface ppp0 when it is connected. You know how to do it. For the *.network file to this interface, modify the example for the wired connection. I assume you have now interfaces eth0, wlan0 and ppp0. Be sure you can ping each connection:

rpi ~$ ping -c3 -I eth0 google.com
rpi ~$ ping -c3 -I wlan0 google.com
rpi ~$ ping -c3 -I ppp0 google.com

It is no problem when all interfaces are up. The kernel will use the interface with the lowest metric first. But this has a great disadvantage. As you can see with ip -4 -brief addr each interface has it's own ip-address. If the kernel switches the interface because one is gone down it also uses its new source ip-address. This will break any established stateful TCP communication, e.g. ssh, streaming, login sessions and so on. You can use a new connection from the changed source ip address but the old connections are stuck. That isn't really what we want.

The solution of this problem is bonding. We create an interim interface bond0 that does not change its settings. First disable the discrete *.network files:

rpi ~$ sudo -Es
rpi ~# cd /etc/systemd/network/
rpi ~# mv 04-wired.network 04-wired.network~
rpi ~# mv 08-wifi.network 08-wifi.network~
rpi ~# mv 12-ppp.network 12-ppp.network~

Then setup bonding with these four files:

root@raspberrypi:~ # cat >/etc/systemd/network/02-bond0.netdev <<EOF
[NetDev]
# status: cat /proc/net/bonding/bond0
Name=bond
Kind=bond
[Bond]
Mode=active-backup
# primary slave is defined in *eth.network
MIIMonitorSec=500ms
MinLinks=1
EOF

root@raspberrypi:~ # cat >/etc/systemd/network/16-bond0-add-primary.network <<EOF
[Match]
Name=e*
[Network]
Bond=bond0
PrimarySlave=yes
EOF

root@raspberrypi:~ # cat >/etc/systemd/network/20-bond0-add-secondary.network <<EOF
[Match]
Name=wl* ppp*
[Network]
Bond=bond0
EOF

root@raspberrypi:~ # cat >/etc/systemd/network/24-bond0-up.network <<EOF
[Match]
Name=bond0
[Network]
# to use static IP (with your settings) toggle commenting the next 4 lines.
DHCP=yes
#Address=192.168.50.60/24
#Gateway=192.168.50.1
#DNS=84.200.69.80 1.1.1.1
EOF

But this is not the whole story. systemd-networkd checks if all interfaces are up before proceeding with startup depending services. With bonding we have slave interfaces (eth0, wlan0, ppp0) that never signal that they are up. Its only the bond interface that comes up if at least one of its slaves is connected. So the check will fail with errors and long waiting on bootup. To manage this you have to modify the systemd-networkd-wait-online.service. How to do it, please follow the instructions at

If finished that, it's time to reboot.

It is possible that the RasPi gets a new ip address so you may have to look at it for the next connection with ssh.

Then you can check the bonding status:

pi@raspberrypi:~ $ cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: eth0 (primary_reselect always)
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 500
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: dc:a6:32:4c:08:1b
Slave queue ID: 0

Slave Interface: wlan0
MII Status: up
Speed: Unknown
Duplex: Unknown
Link Failure Count: 0
Permanent HW addr: dc:a6:32:4c:08:1c
Slave queue ID: 0

Slave Interface: ppp0
MII Status: up
Speed: Unknown
Duplex: Unknown
Link Failure Count: 0
Permanent HW addr: dc:a6:32:4c:08:1d
Slave queue ID: 0

Test bonding: with the bonding status above you will see that the Currently Active Slave: will change and the MII Status: is down.

If your are headless, don't down all interfaces together ;-)

pi@raspberrypi:~ $ ip addr
pi@raspberrypi:~ $ sudo ip link set eth0 down
pi@raspberrypi:~ $ sudo ip link set eth0 up
pi@raspberrypi:~ $ sudo ip link set wlan0 down
pi@raspberrypi:~ $ sudo ip link set wlan0 up
pi@raspberrypi:~ $ sudo ip link set ppp0 down
pi@raspberrypi:~ $ sudo ip link set ppp0 up

Be patient after setting wlan0 up. I may take some time to reconnect to the router and manage bonding. This time ssh will not response.

Another example about bonding you can find at Howto migrate from networking to systemd-networkd with dynamic failover.


references:
[2] man systemd.netdev
[3] man systemd.network
[4] https://wiki.debian.org/Bonding
[5] https://www.kernel.org/doc/Documentation/networking/bonding.txt

Ingo
  • 40,606
  • 15
  • 76
  • 189