Using ethernet + WLAN interfaces (not at the same time) in v6.30

I wanted to use my raspberry 4 connected with ethernet and sometimes bring it to the tv where there is no ethernet cable and i have to use WLAN. In order to do it reliably and automatically, emulating what you get in desktop computers like a laptop, which disconnects to wifi when connected to ethernet and connects to wifi when there is no ethernet connected, i used ifplugd. Also, using this method you can have both interfaces with the same static ip, which may or may not work but it is up to your router (if you connect with one interface, and then disconnect it and connect with the second one, the router will probably reject the second connection or static ip assignation, as the first one, with the same ip, has been connected too recently and the router would probably think it is still connected. You would have to wait longer until connecting with the second one, or just reboot the router and connect with the second interface).

Note: this setup works reliably to change between one interface and the another, but i haven’t tested the autoconnect wifi system of dietpi, and so right now i have been using this setup without autoconnect, and for several days it has been connected without any interruption but theoretically, right now, if for some reason my raspberry got any wifi interruption or whatever, it should stay disconnected to the wlan. This hasn’t happened yet, but theoretically this setup doesn’t have a WLAN autoreconnection system running.

Okay so steps from a clean flash (modify as you want to apply it to a running system):

Clean flash, and as I know two active interfaces have been problematic to me, I went throught the initial setup only with ethernet

Then I installed ifplugd:

apt-get install ifplugd

to have it already installed in case internet connection doesnt work at some point throught the process, then i just set the internet using the dietpi-config for both ethernet, with static ip (you can use dynamic if you want), and then a reboot, and then the wifi with static (same, dynamic if wished) and both ssid, the country, the inboard wifi (in my case), and then a reboot, and then proceed to edit the config files of wpa_supplicant (it doesnt have to be modified, dietpi-config does it right, but i check it just in case, to see everything is set correctly; this file is where every wlan connection is configured, this is, the ssid and the passphrase, basically), /etc/network/interface (this file is where you write what kind of ip you want to get in each interface; for this setup, you must comment the hotplugging of eth0, and checking that both interfaces has correct static ips if you want static, or dynamic in any of those interfaces you want)
My /etc/network/interfaces file:

# Location: /etc/network/interfaces
# Please modify network settings via: dietpi-config
# Or create your own drop-ins in: /etc/network/interfaces.d/

# Drop-in configs
source interfaces.d/*

# Local
auto lo
iface lo inet loopback

# Ethernet
#allow-hotplug eth0
iface eth0 inet static
address 192.168.1.10
netmask 255.255.255.0
gateway 192.168.1.1
#dns-nameservers 1.1.1.1 1.0.0.1

# WiFi
allow-hotplug wlan0
iface wlan0 inet static
address 192.168.1.10
netmask 255.255.255.0
gateway 192.168.1.1
#dns-nameservers 1.1.1.1 1.0.0.1
wireless-power off
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Check that /etc/default/crda has REGDOMAIN=ES (for Spain, for other countries you have to check http://www.summitdata.com/Documents/Regulatory_Domains.pdf ), and finally edit /etc/ifplugd/ifplugd.action to contain:

#!/bin/sh
set -e
if [ -z "$1" ] || [ -z "$2" ] ; then
       echo "Wrong arguments" > /dev/stderr
       exit 1
fi
if [ "$1" != "eth0" ]; then
       echo "Wrong interface!" > /dev/stderr
       exit 1
fi
if [ "$2" = "up" ] ; then
       echo "bring down WiFi"
       /sbin/ifdown wlan0 --force
       /sbin/ifup eth0 --force
       exit 0
elif [ "$2" = "down" ] ; then
       echo "bring up WiFi"
       /sbin/ifdown eth0 --force
       /sbin/ifup wlan0 --force
       exit 0
fi
exit 1

and /etc/default/ifplugd

INTERFACES="eth0"
HOTPLUG_INTERFACES="auto"
ARGS="-q -f -u0 -d5 -w -I"
SUSPEND_ACTION="stop"

finally,
systemctl enable ifplugd.service
systemctl start ifplugd.service
reboot
and voilá, it is working

some more explanation on the settings done within the config files

https://dietpi.com/forum/t/how-to-purge-all-network-related-config/4224/12

Okay so how to add autoreconnect wlan feature? easy, we add two lines that just enables or disables the dietpi-wifi-monitor.service when ethernet is plugged or unplugged, in the /etc/ifplugd/ifplugd.action file, so replace the content of that file with

set -e
if [ -z "$1" ] || [ -z "$2" ] ; then
       echo "Wrong arguments" > /dev/stderr
       exit 1
fi
if [ "$1" != "eth0" ]; then
       echo "Wrong interface!" > /dev/stderr
       exit 1
fi
if [ "$2" = "up" ] ; then
       echo "bring down WiFi"
       /sbin/ifdown wlan0 --force
       /sbin/ifup eth0 --force
       /bin/systemctl disable --now dietpi-wifi-monitor.service
       exit 0
elif [ "$2" = "down" ] ; then
       echo "bring up WiFi"
       /sbin/ifdown eth0 --force
       /sbin/ifup wlan0 --force
       /bin/systemctl enable --now dietpi-wifi-monitor.service
       exit 0
fi
exit 1

(or just add the 2 systemctl lines in the correct places)
And reboot.

ohhh

Sharing my few cents – I managed to get Ethernet seamlessly falling back to WiFi in the same LAN when unplugging the cable without ifplugd. It’s not available in modern Debian repos (had no installation candidates for aarch64 on my system) and building it from source seemed unwarranted.

TL;DR of What Worked for Me (c)

A small bash script installed as a systemd service that reads /sys/class/net/eth0/carrier every 3 seconds (can’t subscribe to any events, so polling similarly to dietpi-wifi-monitor) and calls ifup/ifdown on eth0 to fix conflicting routing rules, which otherwise ruined connectivity over wlan0 if it’s the same LAN on both interfaces.

Use Case

Retain connectivity with Pi over WiFi in the same LAN while unplugged from a usual Ethernet-enabled spot. Useful when temporarily moving the Pi around the house for whatever reason: R&D, hardware tinkering, etc.

Approaches That Didn’t Work

  • ifplugd is not available on arm64 in Debian 13
  • udev rules for ACTION=="change", ATTR{carrier} never fire — the RTL8125B Ethernet driver on OrangePi 5 Ultra does not emit kernel UEVENTs for carrier changes (confirmed with udevadm monitor). It sends RTNETLINK messages (visible via ip monitor), but udev only listens to UEVENTs.
  • metrics alone (metric 100/metric 200 in /etc/network/interfaces) are insufficient: ifdown eth0 is never called on cable unplug, so the dynamic eth0 subnet route (192.168.x.0/24 dev eth0 metric 0) stays in the routing table and causes ECMP routing that breaks wlan0 traffic even when Ethernet has no carrier (given eth0 and wlan0 share the same LAN subnet).

Keeping only one interface up at any given moment seems like the cleanest solution here.

The Polling Daemon

  • On carrier loss: calls ifdown eth0 --force then ip link set eth0 up (keeping the NIC in admin state UP so carrier can be re-detected when cable is plugged back)
  • On carrier restore: calls ifup eth0 --force

/usr/local/sbin/eth0-monitor.sh:

#!/bin/bash

ip link set eth0 up || echo "failed to bring eth0 up after boot"

LAST_CARRIER=""
while true; do
    sleep 3
    CARRIER=$(cat /sys/class/net/eth0/carrier 2>/dev/null) || continue
    [ "$CARRIER" = "$LAST_CARRIER" ] && continue
    LAST_CARRIER="$CARRIER"
    if [ "$CARRIER" = "0" ]; then
        logger "eth0-monitor: carrier lost, running ifdown eth0"
        /sbin/ifdown eth0 --force 2>/dev/null || true
        ip link set eth0 up 2>/dev/null || true
        # ^ keep admin link state UP to detect re-insertion
    else
        logger "eth0-monitor: carrier up, running ifup eth0"
        /sbin/ifup eth0 --force 2>/dev/null || true
    fi
done

/etc/systemd/system/eth0-monitor.service:

[Unit]
Description=ETH0 Carrier Monitor
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/sbin/eth0-monitor.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Activation

sudo chmod +x /usr/local/sbin/eth0-monitor.sh
sudo systemctl daemon-reload
sudo systemctl enable --now eth0-monitor

/etc/network/interfaces changes

  1. Comment out allow-hotplug eth0 — the daemon owns eth0 now

And this – not 100% sure if it’s needed, but probably good to have:

  1. Add metric 100 to eth0 (lower metric makes it preferred)
  2. Add metric 200 to wlan0

Notes

  • Power overhead: effectively zero — sleep 3 loop with a sysfs read is even lighter than dietpi-wifi-monitor’s periodic ping.
  • Tested on OrangePi 5 Ultra (RK3588), Debian 13.3, DietPi 10.1, kernel 6.1.115-vendor-rk35xx.
  • My understanding is that there are plans to make dietpi-wifi-monitor support this out of the box. That’s great!

UPD1: added bringing eth0 link admin state UP after boot as it didn’t happen automatically