Automatically enable and disable WiFi based on Ethernet connection with NetworkManager

I use a laptop as my daily driver and am on WiFi most of the time. However, I also have a dock which has Ethernet. Thanks to NetworkManager dispatcher scripts, we can automatically disable WiFi when Ethernet is connected and then enable it again once Ethernet is disconnected.

NetworkManager will execute scripts in the /etc/NetworkManager/dispatcher.d directory in alphabetical order in response to network events. Each script should be (a) a regular file, (b) owned by root, (c) not writable by group or other, (d) not set-uid, (e) and executable by the owner. Each script receives two arguments, the first being the interface name of the device just activated, and second an action.

https://linux.die.net/man/8/networkmanager

Let’s create the script (this is not mine, it comes from the nmcli-examples man page).

cat << \EOF |sudo tee /etc/NetworkManager/dispatcher.d/70-wifi-wired-exclusive.sh
#!/bin/bash
export LC_ALL=C

enable_disable_wifi ()
{
    result=$(nmcli dev | grep "ethernet" | grep -w "connected")
    if [ -n "$result" ]; then
        nmcli radio wifi off
    else
        nmcli radio wifi on
    fi
}

if [ "$2" = "up" ]; then
    enable_disable_wifi
fi

if [ "$2" = "down" ]; then
    enable_disable_wifi
fi
EOF

Set the required permissions as outlined in the quote above from the man page.

sudo chown root:root /etc/NetworkManager/dispatcher.d/70-wifi-wired-exclusive.sh
sudo chmod 744 /etc/NetworkManager/dispatcher.d/70-wifi-wired-exclusive.sh

Restart NetworkManager to pick up the dispatcher script.

sudo systemctl restart NetworkManager

And finally, test by plugging an Ethernet cable in and out. You should see WiFi being enabled and disabled automatically.

7 thoughts on “Automatically enable and disable WiFi based on Ethernet connection with NetworkManager

  1. Hello Chris,

    i am trying to find your email to contact you.
    Im new to KVM and just trying to build a bunch ubuntu 20.04 kvm with ansible for ease of management.

    i have my nested virtualised enviroment and role clones and all that but not sure exactly how to get it working. I would happy to be a tester for you as well. If we could have a 30min zoom session.

    I would be grateful

  2. Hi Nick, if you have a look at my sample virt-infra-ansible Git repository it has a set of steps that should get you going. There is also an SVG demo here https://github.com/csmart/virt-infra-ansible/blob/master/demo.svg

    Here is the steps to get going to spin up a few CentOS 8 VMs.

    Download CentOS cloud image:
    curl -O https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2

    Move the image in place:
    sudo mkdir -p /var/lib/libvirt/images
    sudo mv -iv CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2 /var/lib/libvirt/images/

    Clone the paybook and role:
    git clone --recursive https://github.com/csmart/virt-infra-ansible.git
    cd virt-infra-ansible

    Spin up 3 simple CentOS VMs
    ./run.sh --limit kvmhost,simple

  3. Great , concise article.
    I’ve been looking for this solution for a while.
    Many Thanks

  4. make sure to set interfaces to Managed, else Network Manager won’t rigger t use the script. I’m using this on static IP configured system, and wanted WIFI to take over when ethernet was disabled.

    in `/etc/NetworkManager/NetworkManager.conf`
    “`
    [ifupdown]
    managed=true
    “`

Leave a Reply

Your email address will not be published. Required fields are marked *