Skip to content

Instantly share code, notes, and snippets.

@lzlrd
Last active December 15, 2025 06:51
Show Gist options
  • Select an option

  • Save lzlrd/22c655e5f05533eb61d4a63e40aadf22 to your computer and use it in GitHub Desktop.

Select an option

Save lzlrd/22c655e5f05533eb61d4a63e40aadf22 to your computer and use it in GitHub Desktop.
#! /usr/bin/env bash
# For OpenWrt hotplug.d Scripts
if [ -n "$ACTION" ]; then
if [ "$ACTION" = "add" ] || [ "$ACTION" = "ifup" ]; then
:
else
exit 0
fi
fi
# Configuration
# Disable LRO and HW-GRO on Routers/Gateways to fix bridge/forwarding issues.
lroDisable=true
rxGroHwDisable=true
# Disable RX-GRO-LIST to improve QUIC/UDP throughput (fixes packet reordering/latency).
rxGroListDisable=true
# Disable TX-NOCACHE-COPY to bypass local cache for direct memory access.
txNocacheCopyDisable=true
# Interface Detection Logic
if [ -n "$DEVICE" ]; then
TARGET_INTERFACES="$DEVICE"
echo "[ethtool-offload] Hotplug event detected for: $DEVICE"
elif [ -n "$DEVICENAME" ]; then
TARGET_INTERFACES="$DEVICENAME"
echo "[ethtool-offload] Hotplug event detected for: $DEVICENAME"
else
echo "[ethtool-offload] Manual run mode. Scanning all interfaces..."
TARGET_INTERFACES="$(ip -o link show | awk -F': ' '{print $2}' | grep -v "lo" | sed 's/@.*$//')"
fi
for i in $TARGET_INTERFACES; do
# Physical Check
# We check if the interface has a symlink to a hardware device in sysfs.
if [ ! -e "/sys/class/net/$i/device" ]; then
echo "[ethtool-offload] Skipping $i (Virtual Interface)"
continue
fi
# Double check it isn't a virtual device masquerading.
if readlink -f "/sys/class/net/$i/device" | grep -q "/virtual/"; then
echo "[ethtool-offload] Skipping $i (Virtual Device Path)"
continue
fi
echo "[ethtool-offload] Applying settings to Physical Interface: $i..."
# Base Offloads
ethtool --offload "$i" rx on tx on sg on tso on gso on gro on highdma on rxvlan on txvlan on ntuple on rxhash on rx-udp-gro-forwarding on tx-tcp6-segmentation on tx-gre-segmentation on tx-ipip-segmentation on tx-sit-segmentation on tx-udp_tnl-segmentation on tx-sctp-segmentation on tx-checksum-sctp on esp-hw-offload on esp-tx-csum-hw-offload on tls-hw-tx-offload on tls-hw-rx-offload on l2-fwd-offload on 2>/dev/null
# Bridge Member Check
# Detect if interface is part of a bridge (directly or via a bond).
IS_BRIDGE_MEMBER=false
MASTER_IF=$(basename $(readlink /sys/class/net/$i/master) 2>/dev/null)
if [ -n "$MASTER_IF" ]; then
# Check if a member of a bridge.
if [ -d "/sys/class/net/$MASTER_IF/bridge" ]; then
IS_BRIDGE_MEMBER=true
# Check if a bond slave of a bond which is a member of a bridge.
elif [ -d "/sys/class/net/$MASTER_IF/bonding" ]; then
BOND_MASTER=$(basename $(readlink /sys/class/net/$MASTER_IF/master) 2>/dev/null)
if [ -n "$BOND_MASTER" ] && [ -d "/sys/class/net/$BOND_MASTER/bridge" ]; then
IS_BRIDGE_MEMBER=true
fi
fi
fi
# Disable RX-VLAN-Filter dynamically based on bridge status.
if [ "$IS_BRIDGE_MEMBER" = true ]; then
echo "[ethtool-offload] Interface $i is a bridge member. Disabling RX-VLAN-Filter..."
ethtool -K "$i" rx-vlan-filter off 2>/dev/null
else
ethtool -K "$i" rx-vlan-filter on 2>/dev/null
fi
# Bond Slave Check
if [ -e "/sys/class/net/$i/master" ] && [ -d "/sys/class/net/$(basename $(readlink /sys/class/net/$i/master))/bonding" ]; then
echo "[ethtool-offload] Interface $i is a bond slave. Disabling Fraglist, GSO-Partial, and VLAN-Stag offloads..."
ethtool -K "$i" tx-scatter-gather-fraglist off 2>/dev/null
ethtool -K "$i" tx-gso-partial off 2>/dev/null
# Disable VLAN-Stag offloads on bond slaves to prevent conflicts with LACP.
ethtool -K "$i" tx-vlan-stag-hw-insert off rx-vlan-stag-hw-parse off 2>/dev/null
else
ethtool -K "$i" tx-scatter-gather-fraglist on 2>/dev/null
ethtool -K "$i" tx-gso-partial on 2>/dev/null
ethtool -K "$i" tx-vlan-stag-hw-insert on rx-vlan-stag-hw-parse on 2>/dev/null
fi
if [ "$lroDisable" = true ]; then
echo "[ethtool-offload] Disabling LRO on $i..."
echo "[ethtool-offload] See https://serverfault.com/a/806454 for more information."
ethtool -K "$i" lro off 2>/dev/null
else
ethtool -K "$i" lro on 2>/dev/null
fi
if [ "$rxGroHwDisable" = true ]; then
echo "[ethtool-offload] Disabling HW-GRO on $i..."
ethtool -K "$i" rx-gro-hw off 2>/dev/null
else
ethtool -K "$i" rx-gro-hw on 2>/dev/null
fi
if [ "$rxGroListDisable" = true ]; then
echo "[ethtool-offload] Disabling RX-GRO-List on $i..."
echo "[ethtool-offload] See https://tailscale.com/blog/quic-udp-throughput for more information."
ethtool -K "$i" rx-gro-list off 2>/dev/null
else
ethtool -K "$i" rx-gro-list on 2>/dev/null
fi
if [ "$txNocacheCopyDisable" = true ]; then
echo "[ethtool-offload] Disabling TX-NoCache-Copy on $i..."
echo "[ethtool-offload] See https://enterprise-support.nvidia.com/s/article/how-to-bypass-local-cache--disable-tx-nocache-copy-x for more information."
ethtool -K "$i" tx-nocache-copy off 2>/dev/null
else
ethtool -K "$i" tx-nocache-copy on 2>/dev/null
fi
done
exit 0
ACTION=="add|bind", SUBSYSTEM=="net", RUN+="/usr/local/sbin/ethtool-offload %k"
ACTION=="change", SUBSYSTEM=="net", ATTR{operstate}=="up", RUN+="/usr/local/sbin/ethtool-offload %k"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment