The NetworkManager support in Digi Embedded Yocto includes network failover and recovery functionality. This means that when the primary network interface loses the connection, NetworkManager replaces the current network interface with the next-available network interface that has connectivity, while attempting a recovery of the primary connection. Whenever the primary connection is recovered, connectivity through that connection resumes. This happens without user intervention.

See the NetworkManager documentation for more detailed information about NetworkManager options.

The network failover works at different levels:

To establish the priorities between the different network interfaces, see Set interface priorities and metrics.

NetworkManager brings a network interface down when it detects the loss of its physical link.

For example, a system with Ethernet, Wi-Fi, and cellular interfaces using DHCP has a routing table similar to the following:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.101  0.0.0.0         UG    100    0        0 eth0
0.0.0.0         192.168.11.101  0.0.0.0         UG    600    0        0 wlan0
0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

If the physical Ethernet link is lost, NetworkManager brings the interface down and removes its entries from the routing table:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.101  0.0.0.0         UG    600    0        0 wlan0
0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

This allows the system to reach the Internet over the interfaces that have connectivity.

Check upstream connectivity

NetworkManager allows you to perform a connectivity check by sending an HTTP request to a given URI and waiting for the specified response.

This support not enabled by default. To enable, see Enable upstream connectivity check.

When enabled, NetworkManager performs upstream connectivity checks over each interface in the routing table. When the check fails for one interface, NetworkManager penalizes the metric of that interface in the routing table so it is no longer the default that the system uses to reach the Internet.

NetworkManager continues to perform connectivity checks over all the interfaces. As soon as the connectivity is restored over a previously failing interface, the metric is also restored to the original value and the routing table goes back to the original state.

You can use Busybox’s httpd server as an endpoint for connectivity checks.

Enable upstream connectivity check

  1. Open the NetworkManager configuration file located at /etc/NetworkManager/NetworkManager.conf.

  2. Edit the configuration file and add the connectivity section. This section controls NetworkManager’s optional connectivity checking functionality. This allows NetworkManager to detect whether the system can actually access the Internet or whether it is behind a captive portal.

    /etc/NetworkManager/NetworkManager.conf
    [connectivity]
    uri=http://network-test.debian.org/nm
    interval=...
    response=...
    • uri: The URI of a web page to periodically request when connectivity is being checked. This page should return the header X-NetworkManager-Status with a value of online, or its body content should be set to NetworkManager is online. Use the response option to control the body content check. If this option is blank or missing, connectivity checking is disabled.

      # curl -v http://network-test.debian.org/nm
      * Hostname was NOT found in DNS cache
      *   Trying 128.31.0.62...
      * Connected to network-test.debian.org (128.31.0.62) port 80 (#0)
      > GET /nm HTTP/1.1
      > User-Agent: curl/7.35.0
      > Host: network-test.debian.org
      > Accept: */*
      >
      < HTTP/1.1 200 OK
      < Date: Thu, 05 Oct 2017 15:28:49 GMT
      * Server Apache is not blacklisted
      < Server: Apache
      < X-Content-Type-Options: nosniff
      < X-Frame-Options: sameorigin
      < Referrer-Policy: no-referrer
      < X-Xss-Protection: 1
      < Last-Modified: Sat, 16 Nov 2013 16:28:43 GMT
      < ETag: "19-4eb4dcee584c0"
      < Accept-Ranges: bytes
      < Content-Length: 25
      < X-Clacks-Overhead: GNU Terry Pratchett
      < Surrogate-Key: mirror-csail
      < X-NetworkManager-Status: online
      < Cache-Control: must-revalidate, max-age=0
      <
      NetworkManager is online
      * Connection #0 to host network-test.debian.org left intact
    • interval (in seconds): Controls how often connectivity is checked when a network connection exists. If set to 0, connectivity checking is disabled. If missing, the default is 300 seconds.

      The minimum value for the interval option is 60 seconds. If you set a lower time, the connectivity check may not work.
    • response: Controls what body content NetworkManager checks for when requesting the URI for connectivity checking. If missing, defaults to "NetworkManager is online".

  3. Save the changes in your file.

    Issue the sync command after editing the /etc/NetworkManager/NetworkManager.conf file.
  4. To apply all your changes, restart NetworkManager.

    # /etc/init.d/networkmanager restart
For information on how to include your NetworkManager.conf in your Digi Embedded Yocto images, see Set NetworkManager configuration.

For example, for the same configuration shown above with Ethernet, Wi-Fi, and cellular:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.101  0.0.0.0         UG    100    0        0 eth0
0.0.0.0         192.168.11.101  0.0.0.0         UG    600    0        0 wlan0
0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

If at any time the connectivity check fails over the Ethernet interface, NetworkManager changes the metrics so the new routing table looks like this:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.101  0.0.0.0         UG    600    0        0 wlan0
0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
0.0.0.0         192.168.11.101  0.0.0.0         UG    20100  0        0 eth0
77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

Note how the Ethernet interface has been penalized and the new primary interface is Wi-Fi.

If, later, the Wi-Fi interface also loses connectivity to the configured URI, the routing table would change:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
0.0.0.0         192.168.11.101  0.0.0.0         UG    20100  0        0 eth0
0.0.0.0         192.168.11.101  0.0.0.0         UG    20600  0        0 wlan0
77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

Note that the cellular interface is now the default.

Set interface priorities and metrics

The priority of the network interfaces is specified by their metric: the lower the metric, the higher the priority. By default, NetworkManager uses default metric values for each interface type where Ethernet has the highest priority (lowest metric) and cellular the lowest (highest metric).

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.101  0.0.0.0         UG    100    0        0 eth0
0.0.0.0         192.168.11.101  0.0.0.0         UG    600    0        0 wlan0
0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

To set the metric of any interface:

  1. Configure the new value:

    • From the NetworkManager configuration file.
      For example, to change the wlan0 metric to be 50, modify the nm.wlan0 file adding the route-metric parameter in the ipv4 section:

      [connection]
      id=wlan0
      type=wifi
      interface-name=wlan0
      
      [wifi]
      ssid=""
      
      [ipv4]
      method=auto
      route-metric=50
      
      [ipv6]
      method=ignore
    • From the NetworkManager command line interface (nmcli). For example, to change the wlan0 metric to 50 as in the previous example, execute:

      # nmcli con modify wlan0 ipv4.route-metric 50
  2. Bring the connection down and then back up for the changes to take effect. For example:

    # nmcli con down wlan0
    # nmcli con up wlan0
  3. To verify the changes have been applied, use the route command to print the routing table:

    # route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.11.101  0.0.0.0         UG    50     0        0 wlan0
    0.0.0.0         192.168.11.101  0.0.0.0         UG    100    0        0 eth0
    0.0.0.0         77.210.151.17   0.0.0.0         UG    700    0        0 ppp0
    77.210.151.17   0.0.0.0         255.255.255.255 UH    700    0        0 ppp0
    192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 wlan0
    192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
    192.168.0.0     0.0.0.0         255.255.0.0     U     100    0        0 eth0
    192.168.0.0     0.0.0.0         255.255.0.0     U     600    0        0 wlan0

Connection recovery

When NetworkManager detects a change of connectivity state, it executes in order the scripts located at /etc/NetworkManager/dispatcher.d/<event-type>.d.

The following event types have been added to the NetworkManager defaults:

  • up: A network connection has come up.

  • down: A network connection has come down.

  • device-connectivity-change: The network connectivity state for a network device has changed from full, indicating a loss of conectivity for the specific interface. The system connectivity might still be full if connectivity has fallen back to the next-available device. The interface that lost connectivity is passed with the event to the handler script.

  • connectivity-change: The network connectivity state for the system has changed from full. This means that connectivity is now not available through any network interface.

By default, the ifdownup script is executed when the device-connectivity-change is detected. This will attempt to bring a connection down and up.