I would like to automate these command instead of running it from putty.
ethtool -K eth0 tso off gso off gro off
ethtool -K br-lan tso off gso off gro off
ethtool -K ifb4br-lan tso off gso off gro off
I have tried applying these command in /etc/rc.local and also in /etc/init.d/sqm.
However, only eth0 changes are applied when I rebooted the router.
The changes for br-lan and ifb4br-lan are not applied automatically when the router starts up.
Can someone help please?
I have verified it by using ethtool -k and also tc -s qdisc.
br-lan is available after netifd sets it up
and ifb4br-lan may be available after the qos part ran
You could add a hotplug script.
I think it's under /etc/hotplug.d/iface (not sure if you need to make it executable).
Whenever an interface comes up, those scripts will run ( I am not sure atm which process runs them ; could be netifd )
When those scripts run, they have some env vars.
I think DEVICE should be available.
Check for ACTION as well.
I'd run the ethtool cmd on "ifup" action.
You could do ethtool $DEVICE
Thank you for the response.
I don't know how to do that.
However you gave me an idea.
I have set a sleep time in rc.local
This seems an OK solution though not the best I guess.
Ummm.
So that would be simple too.
cd /etc/hotplug.d/iface
vi 10-ethtool
in that file add
[ ifup = "$ACTION" ] || exit 0
[ -n "$DEVICE" ] || exit 0
if [ "$DEVICE" == eth0 ] || [ "$DEVICE" == br-lan ] || [ "$DEVICE" == ifb4br-lan ] ; then
ethtool -K "$DEVICE" tso off gso off gro off
fi
or maybe you don't want/need the check for
if [ "$DEVICE" == eth0 ] || [ "$DEVICE" == br-lan ] || [ "$DEVICE" == ifb4br-lan ] ; then
Did I do it wrong?
It seems to not have an effect on eth0 after reboot.
Code
[ ifup = "$ACTION" ] || exit 0
[ -n "$DEVICE" ] || exit 0
ethtool -K "$DEVICE" tso off gso off gro off
It should be fine.
Maybe eth0 is initialized before the event processing takes place.
You could also add ethtool -K eth0 tso off gso off gro off
explicitly there.
If you want to debug this, you could add some messages with logger
Something like
logger "Got event '$ACTION' for '$DEVICE'"
then you can check the logs with logread | grep "Got event"
Alright.
Thank you very much.
ssh into your router
install ethtool if you already haven't
cd /etc
nano disable_offloads.sh
( copy the script below and paste into disable_offloads.sh using nano )
#!/bin/bash
# Disable Offloads for all interfaces
for DEV in $(ls /sys/class/net) ; do
echo -n "$DEV "
ethtool -K ${DEV} tso off
ethtool -K ${DEV} ufo off
ethtool -K ${DEV} gso off
ethtool -K ${DEV} gro off
ethtool -K ${DEV} lro off
ethtool -K ${DEV} rxvlan off
ethtool -K ${DEV} txvlan off
echo "Offloads Disabled"
done
exit nano and save
chmod a+rx disable_offloads.sh ( this makes it writeable and readable for all)
nano edit /etc/rc.local
You mave have to adjust your sleep time to according to your estimated boot time
sleep 10 &&
sh /etc/disable_offloads.sh
exit 0
(exit nano and save)
reboot && exit
test using:
ethtool -k (insert your device) | grep offload
fixed means at the nic level it cannot be changed
Note: by adding the sleep action we can wait for virtual devices to be created
i use this as an init.d script
#!/bin/sh /etc/rc.common
#
START=99
start() {
local count=1
local eth
while true ; do
eth=`ls /sys/class/net | grep 'eth' | sed -n "$count"p`
if [ "$eth" == "" ]; then
break
fi
ethtool -K $eth tso off gso off gro off
if [ $? -eq 0 ]; then
logger -s "$eth offload turned off"
else
logger -s "[ERR] $eth offload turn off FAILED: '$?'"
fi
count=$((count+1))
done
}
Super helpful, thanks.
These instructions should be add to the wiki.
How to make the ethtool init.d follow the state of sqm scripts? Such as a script that when sqm is started or restart/reloaded that ethtool init.d will run again?
Here is what I came up with and works well
credit to shm0 for the ethtool script to start!
1.) /etc/init.d/ethtool
#!/bin/sh /etc/rc.common
#
START=99
start() {
local count=1
local eth
while true ; do
eth=`ls /sys/class/net | sed -n "$count"p`
if [ "$eth" == "" ]; then
break
fi
ethtool -K $eth gro off
if [ $? -eq 0 ]; then
logger -s "$eth offload turned off"
else
logger -s "[ERR] $eth offload turn off FAILED: '$?'"
fi
count=$((count+1))
done
}
stop() {
local count=1
local eth
while true ; do
eth=`ls /sys/class/net | sed -n "$count"p`
if [ "$eth" == "" ]; then
break
fi
ethtool -K $eth gro on
if [ $? -eq 0 ]; then
logger -s "$eth offload turned on"
else
logger -s "[ERR] $eth offload turn on FAILED: '$?'"
fi
count=$((count+1))
done
}
2.) Here we edit the existing /etc/init.d/sqm script ( make a backup of this file first)
#!/bin/sh /etc/rc.common
START=50
USE_PROCD=1
service_triggers()
{
procd_add_reload_trigger "sqm"
}
reload_service()
{
stop "$@"
start "$@"
}
start_service()
{
/usr/lib/sqm/run.sh start "$@"
/etc/init.d/ethtool start "$@"
}
stop_service()
{
/usr/lib/sqm/run.sh stop "$@"
/etc/init.d/ethtool stop "$@"
}
boot()
{
export SQM_VERBOSITY_MIN=5 # Silence errors
start "$@"
}
The second script is edited to disable offloads for sqm=on or enable offloads when sqm=off. One could choose to not edit the sqm script and just run the ethtool script by itself as a service also.
The script wasn't my work. i found it on this forum or some other forum.
i can't remember who wrote this. so please no credit here
i made this script some weeks ago.
which does disable everything.
#!/bin/sh
sleep 15
function log()
{
local status="$1"
local feature="$2"
local interface="$3"
if [ $status -eq 0 ]; then
logger "[ETHTOOL] $feature: Disabled on $interface"
fi
if [ $status -eq 1 ]; then
logger -s "[ETHTOOL] $feature: Failed to disable on $interface"
fi
if [ $status -gt 1 ]; then
logger "[ETHTOOL] $feature: Nothing changed on $interface"
fi
}
function disable_offloads()
{
local interface="$1"
local features
local cmd
# Check if we can change features
if ethtool -k $interface 1>/dev/null 2>/dev/null;then
# Filter whitespaces
# Get only enabled/not fixed features
# Filter features that are only changeable by global keyword
# Filter empty lines
# Cut to First colum
features=$(ethtool -k "$interface" | awk '{$1=$1;print}' \
| grep -E '^.+: on$' \
| grep -v -E '^tx-checksum-.+$' \
| grep -v -E '^tx-scatter-gather.+$' \
| grep -v -E '^tx-tcp.+segmentation.+$' \
| grep -v -E '^tx-udp-fragmentation$' \
| grep -v -E '^tx-generic-segmentation$' \
| grep -v -E '^rx-gro$' \
| grep -v -E '^rx-gro$' \
| grep -v -E '^$' \
| cut -d: -f1)
# Replace feature name by global key word
features=$(echo "$features" | sed -e s/rx-checksumming/rx/ \
-e s/tx-checksumming/tx/ \
-e s/scatter-gather/sg/ \
-e s/tcp-segmentation-offload/tso/ \
-e s/udp-fragmentation-offload/ufo/ \
-e s/generic-segmentation-offload/gso/ \
-e s/generic-receive-offload/gro/ \
-e s/large-receive-offload/lro/ \
-e s/rx-vlan-offload/rxvlan/ \
-e s/tx-vlan-offload/txvlan/ \
-e s/ntuple-filters/ntuple/ \
-e s/receive-hashing/rxhash/)
# Check if we can disable someting
if [ -z "$features" ]; then
logger "[ETHTOOL] Offloads: Nothing changed on $interface"
return 0
fi
# Construct ethtool command line
cmd="-K $interface"
for feature in $features; do
cmd="$cmd $feature off"
done
# Try to disable offloads
ethtool $cmd 1>/dev/null 2>/dev/null
log $? "Offloads" "$interface"
else
log $? "Offloads" "$interface"
fi
}
function disable_flow_control()
{
local interface="$1"
local features
local cmd
# Check if we can change settings
if ethtool -a $interface 1>/dev/null 2>/dev/null;then
# Construct ethtool command line
cmd="-A $interface autoneg off tx off rx off"
# Try to disable flow control
ethtool $cmd 1>/dev/null 2>/dev/null
log $? "Flow Control" "$interface"
else
log $? "Flow Control" "$interface"
fi
}
function disable_interrupt_moderation()
{
local interface="$1"
local features
local cmd
# Check if we can change settings
if ethtool -c $interface 1>/dev/null 2>/dev/null;then
# Construct ethtool command line
cmd="-C $interface adaptive-tx off adaptive-rx off"
# Try to disable adaptive interrupt moderation
ethtool $cmd 1>/dev/null 2>/dev/null
log $? "Adaptive Interrupt Moderation" "$interface"
features=$(ethtool -c $interface | awk '{$1=$1;print}' \
| grep -v -E '^.+: 0$|Adaptive|Coalesce' \
| grep -v -E '^$' \
| cut -d: -f1)
# Check if we can disable someting
if [ -z "$features" ]; then
logger "[ETHTOOL] Interrupt Moderation: Nothing changed on $interface"
return 0
fi
# Construct ethtool command line
cmd="-C $interface"
for feature in $features; do
cmd="$cmd $feature 0"
done
# Try to disable interrupt Moderation
ethtool $cmd 1>/dev/null 2>/dev/null
log $? "Interrupt Moderation" "$interface"
else
log $? "Interrupt Moderation" "$interface"
fi
}
function main()
{
for interface in /sys/class/net/*; do
interface=$(basename $interface)
# Skip Loopback
if [ $interface == lo ]; then
continue
fi
disable_offloads "$interface"
disable_flow_control "$interface"
disable_interrupt_moderation "$interface"
done
}
main
Disabling offloads globally through sysctl would be much better.
Some distros have a feature to disable offloads in the network config directly.
Works as expected and appeals to my OCD!
Do I put this script on firewall custom rules or where?
Hi I would all so like to know why would people want to disable these things?
Hi!
You can save it somewhere and then call through rc.local or periodically with cron. I also made a much simpler version that uses a hotplug.d approach. It can be found in David wrt* firmware builds thread. I will try to combine both scripts and post it here.
The positive is that packets are not waiting to be grouped together into "super-packets" to be sent out on the wire.
The negative is that cpu overhead is increased per packet and throughput appears slightly reduced because your pipe doesn't fill as fast.
I would only suggest disabling these if you your device has a 1Ghz processor or more AND you're speeds are not +300Mbit.
I forgot about /etc/hotplug.d/net and it's much simpler to just copy+paste and set a number before it such as 20-disable-offloads. no need to chmod either.