0

I've got a device that is connected to one network via ethernet and a different network via wifi. I use netctl to manage the interfaces. When both netctl profiles are active, the configuration looks like this:

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether b8:27:eb:eb:ab:dc brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.200/21 brd 192.168.7.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:feeb:abdc/64 scope link 
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether b8:27:eb:be:fe:89 brd ff:ff:ff:ff:ff:ff
    inet 10.10.0.89/23 brd 10.10.1.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:febe:fe89/64 scope link 
       valid_lft forever preferred_lft forever

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth0
0.0.0.0         10.10.0.1       0.0.0.0         UG    303    0        0 wlan0
10.10.0.0       0.0.0.0         255.255.254.0   U     303    0        0 wlan0
192.168.0.0     0.0.0.0         255.255.248.0   U     0      0        0 eth0

What I have noticed is that, when both netctl profiles are active, I can successfully ping a host (google.com) when I specify the ethernet interface, but pings fail when I specify the wifi interface:

$ ping -c4 -Ieth0 google.com
PING google.com (74.125.136.100) from 192.168.1.200 eth0: 56(84) bytes of data.
64 bytes from 74.125.136.100 (74.125.136.100): icmp_seq=1 ttl=44 time=21.4 ms
64 bytes from 74.125.136.100 (74.125.136.100): icmp_seq=2 ttl=44 time=21.3 ms
64 bytes from 74.125.136.100 (74.125.136.100): icmp_seq=3 ttl=44 time=21.10 ms
64 bytes from 74.125.136.100 (74.125.136.100): icmp_seq=4 ttl=44 time=37.1 ms

--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 7ms
rtt min/avg/max/mdev = 21.317/25.440/37.086/6.729 ms

$ ping -c4 -Iwlan0 google.com
PING google.com (74.125.136.138) from 10.10.0.89 wlan0: 56(84) bytes of data.

--- google.com ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 154ms

When I saw this behavior, I tried pulling out the ethernet cable, after which I still couldn't ping using wlan0, and I noticed that eth0 kept its IP address, gateway, etc. The only thing that changed was that it reported state DOWN rather than state UP.

I then ran netctl stop my-ethernet-profile to actually stop the profile for real, after which I could successfully ping from wlan0. So, ICMP isn't blocked on wlan0... everything seems fine when eth0's profile is actually stopped, just not when it's running (regardless of whether the interface is UP or DOWN).

So, I'm trying to understand a couple things:

  1. Why would the wifi ping fail when both devices are connected (or, more accurately, when both netctl profiles are active)?
  2. Why does the ethernet interface keep its configuration even if the system recognizes that it is not connected?
  3. Is there a way to configure netctl to stop the profile if the interface goes down?
  4. Is there a way to run an arbitrary script when the state transitions from UP to DOWN? For example, if I need to run netctl stop my-ethernet-profile when the cable becomes disconnected?

As a final note, I know that there are ways to do a bonded interface or wifi failover, but this is for a very purpose-built situation. It may sound like I'm reinventing the wheel here, but there is a good reason.

0

I am not that familiar with netctl but your basic issue is related to the fact that your kernel routing table has two default gateways specified.

Why would the wifi ping fail when both devices are connected (or, more accurately, when both netctl profiles are active)?

The problem here is due to the fact that your routing table contains two default gateways:

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth0
0.0.0.0         10.10.0.1       0.0.0.0         UG    303    0        0 wlan0

When routes conflict (as these two do) the kernel picks the one with the lowest 'metric' (in this case eth0 with a value of '0') or the one that was added first I believe.

The reason pings to remote hosts fail when you specify the wireless interface in your example, ping -Iwlan0, is most likely that the kernel does not how to route to that remote host using your specified interface since the default gateway (with the lowest metric) is technically reached via another interface. These pings are most likely going into the bitbucket.

Redundancy

If you are looking for redundant internet in case of an outage on one side or the other, you will probably need to roll your own shell script that can do the following:

  1. Detect when traffic is not flowing on the primary gateway interface
  2. Change the kernel routing table to use a new interface for the default GW
  3. Monitor the primary interface for traffic (UP and can reach remote hosts)
  4. Reconfigure the routing table to go back to the primary interface.

Note: The netctl settings for wired-to-wireless failover may be of some use if you want to ensure basic layer1 connectivity (cable unplugged or wifi AP goes down), but usually the two interfaces will need to be on the same network and will basically be getting internet from the same gateway.

Is there a way to configure netctl to stop the profile if the interface goes down?

You can do this with the preup and predown directives I believe.

ExecUpPost='ifconfig wlan0 down|| true'
ExecDownPre='ifconfig wlan0 up|| true'

Take a look at the /etc/netctl/hooks/ in the documentation.

  • I tried implementing a hook already, but it seemed to only execute when I started/stopped the profile, not when the interface came up/down. I might need to dig into that a bit more, but a first pass didn't do the job. – maldata Apr 10 at 18:54
  • Yeah, it seems like these hooks only execute when a profile starts or stops. I'm looking for something that will execute when the state of the interface changes from UP to DOWN or vice versa. – maldata Apr 15 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.