Make Network Manager restart after dropped connection?

Solution 1:

Here is an Upstart script you can place to /etc/init/reconnect.conf:

start on started network-manager
stop on runlevel [016]

script
  while true; do
    if ifconfig eth0 | grep -q "inet addr:"; then
       # echo "all ok!"
    else
       restart network-manager
    fi
    sleep 5
  done
end script

Upon losing an ip address for eth0 (configure to your interface if its different), it will restart network-manager job and restore connectivity.

Solution 2:

A quick and dirty workaround is to write a script that runs ping -i 5 google.com || service network-manager restart as root (you could write a /etc/init.d/-daemon for that, but since the solution is VERY dirty, I wouldn't do that)

That script would restart the network-manager every time Google is not found and checks once every fifth second.

Solution 3:

Try wicd instead of network-manager, it has been recommended for a similar case: https://bbs.archlinux.org/viewtopic.php?id=124443

I don't know if it will fix the problem nor if wicd supports pppoe.

  1. Backup the .deb files, just in case:

    sudo apt-get download network-manager network-manager-gnome
    
  2. Purge network manager and install wicd

    sudo apt-get purge network-manager network-manager-gnome
    sudo apt-get install wicd wicd-gtk
    
  3. Reboot. Try to connect using wicd.

If anything goes wrong, just purge wicd and reinstall network manager:

sudo apt-get purge wicd wicd-gtk
sudo dpkg -i network-manager*.deb

Solution 4:

Why I'm answering this question?

Ther are very good answers, but all is written using init or upstart. As from now we will be using systemd, I'm writing a better script and info. on how to do that.

But is there a way?

Is, there is a way. You just need to create a script that monitors your network state and restart Network Manager on demand. We will build this script and a systemd service that will be started with the system and will monitor your network status every 5 seconds to find if you are online or not.

What should I do?

First of all, we need to install the fping tool the make one of the connection tests (fping return "is alive" if a connection is possible and "address not found" if not):

$ sudo apt-get install fping -y

Now we will create the monitor script on our system. Create a file at /usr/local/bin/ called nm-watcher:

$ sudo touch /usr/local/bin/nm-watcher

And edit it using nano or your prefered text editor:

$ sudo nano /usr/local/bin/nm-watcher

Copy and paste this script inside the editor, save and close the file (if you are using nano, like in this tutorial, use "CTRL+X" "Y" and "ENTER" in sequence). Don't forget to change wlan0 to the interface that you want wm-watcher to monitor:

#!/bin/bash

while true; do #create a infinite loop to keep looking at your connection
        NET=$(ifconfig wlan0 | grep "inet inet addr:") # verify if the interface has an assigned IP
        ROUTE=$(fping google.com 2>&1 | grep "alive") # try to ping google.com and verify if we have any response
        WEB=$(wget --tries=10 --timeout=20 --spider http://google.com 2>&1 | grep "OK") # spiders google.com to verify if the page exists. returns error if a connections is not possible

        if [ ! "$NET" != "" ] || [ ! "$ROUTE" != "" ] || [ ! "$WEB" != "" ]; then # verify if any of the above conditions aren't OK
                service network-manager restart
        fi

        sleep 5
done

To run this script we need to make it executable:

$ sudo chmod 755 /usr/local/bin/nm-watcher

Now, we will create the SystemD service, for this, you should create and edit the nm-watcher.service file at /etc/systemd/system/:

$ sudo touch /etc/systemd/system/nm-watcher.service && sudo nano /etc/systemd/system/nm-watcher.service

And put this content inside the file:

[Unit]
Description=NetworkManager Watcher
Wants=NetworkManager.service
Before=NetworkManager.service

[Service]
ExecStart=/usr/local/bin/nm-watcher

[Install]
WantedBy=multi-user.target

This will create the service file that make SystemD call the script that we have created before at every boot, after we have estabished a connection using network-manager.service.

We should know enable this service to run using:

$ sudo systemctl enable nm-watcher.service

And start the service by typing:

$ sudo service nm-watcher start

To verify if the service is running type:

$ sudo service nm-watcher status

If you have any problems with the service, you can see the debug messages using:

$ sudo journalctl -u nm-watcher

Should I do any other things?

No, this is all what is needed to accomplish this task. This script has very low impact at the system performance, like you can see at this screenshot:

nm-watcher footprint