mirror of
https://github.com/qosmio/nss-packages.git
synced 2025-12-16 08:12:53 +00:00
The way ECM uci config is handled is pretty ugly due to it not specifying a
named section for 'general'.
Current:
```
➤ uci show ecm
ecm.global=ecm
ecm.global.acceleration_engine='nss'
ecm.@general[0]=general
ecm.@general[0].enable_bridge_filtering='0'
ecm.@general[0].disable_offloads='0'
ecm.@general[0].disable_flow_control='0'
ecm.@general[0].disable_interrupt_moderation='0'
ecm.@general[0].disable_gro='0'
```
None of the options require the use of unnamed sections
(like /etc/config/dhcp does when defining configs for multiple hosts)
With this change the config would produce:
```
ecm.global=ecm
ecm.global.acceleration_engine='nss'
ecm.general=ecm
ecm.general.enable_bridge_filtering='0'
ecm.general.disable_offloads='0'
ecm.general.disable_flow_control='0'
ecm.general.disable_interrupt_moderation='0'
ecm.general.disable_gro='0'
```
Which is a lot easier to read, and access programmatically.
We can also merge `global` and `general` into a single section as it
doesn't really make sense why we need global/general when it's
technically "ALL" globally applied.
For now, to ease users on the change, let's just stick to 2 sections.
**PLEASE NOTE: For users building their own images, and storing their**
**configs in 'files/etc/config/ecm' you will need to manually update the**
**config before compiling.**
For users using **sysupgrade** or installing without custom config at build
time 'files/etc/config/ecm' should be OK.
The following can be run manually on the config file 'ecm'
```sh
conf=/etc/config/ecm
uci -q show ecm.general || {
echo "Converting 'ECM' config to new format."
sed -i "s/config.*general.*/config ecm 'general'/g" "$conf"
}
```
Signed-off-by: Sean Khan <datapronix@protonmail.com>
211 lines
5.2 KiB
Bash
Executable File
211 lines
5.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# shellcheck disable=3014,3043,2086,1091,2154
|
|
#
|
|
# Helper script which uses ethtool to disable (most)
|
|
# interface offloads, if possible.
|
|
#
|
|
# Reference:
|
|
# https://forum.openwrt.org/t/how-to-make-ethtool-setting-persistent-on-br-lan/6433/14
|
|
#
|
|
. /lib/functions.sh
|
|
|
|
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: no changes performed on $interface"
|
|
fi
|
|
}
|
|
|
|
interface_is_virtual() {
|
|
local interface="$1"
|
|
[ -d /sys/devices/virtual/net/"$interface"/ ] || return 1
|
|
return 0
|
|
}
|
|
|
|
get_base_interface() {
|
|
local interface="$1"
|
|
echo "$interface" | grep -Eo '^[a-z]*[0-9]*' 2> /dev/null || return 1
|
|
return 0
|
|
}
|
|
|
|
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 column
|
|
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 '^$' \
|
|
| cut -d: -f1)
|
|
|
|
# Replace feature name by global keyword
|
|
echo $features
|
|
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 anything
|
|
if [ -z "$features" ]; then
|
|
logger "[ethtool] Offloads : no changes performed 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
|
|
}
|
|
|
|
disable_gro() {
|
|
local interface="$1"
|
|
local cmd
|
|
|
|
# Construct ethtool command line
|
|
cmd="-K $interface gro off"
|
|
|
|
# Try to disable flow control
|
|
ethtool $cmd 1> /dev/null 2> /dev/null
|
|
log $? "Generic Receive Offload" "$interface"
|
|
}
|
|
|
|
disable_flow_control() {
|
|
local interface="$1"
|
|
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
|
|
}
|
|
|
|
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 anything
|
|
if [ -z "$features" ]; then
|
|
logger "[ethtool] Interrupt Moderation: no changes performed 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
|
|
}
|
|
|
|
disable_offload() {
|
|
config_load ecm
|
|
|
|
config_get_bool enable_bridge_filtering ecm enable_bridge_filtering 0
|
|
config_get_bool disable_offloads ecm disable_offloads 0
|
|
config_get_bool disable_flow_control ecm disable_flow_control 0
|
|
config_get_bool disable_interrupt_moderation ecm disable_interrupt_moderation 0
|
|
config_get_bool disable_gro ecm disable_gro 0
|
|
|
|
[ -z $1 ] && interface=$(echo /sys/class/net/*) || interface=$*
|
|
|
|
for i in $interface; do
|
|
i=${i##*/}
|
|
|
|
# Skip Loopback
|
|
if [ $i == lo ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "$disable_gro" -eq 1 ]; then
|
|
disable_gro "$i"
|
|
fi
|
|
|
|
if [ "$disable_offloads" -eq 1 ]; then
|
|
disable_offloads "$i"
|
|
fi
|
|
|
|
if [ "$disable_flow_control" -eq 1 ]; then
|
|
disable_flow_control "$i"
|
|
fi
|
|
|
|
if [ "$disable_interrupt_moderation" -eq 1 ]; then
|
|
disable_interrupt_moderation "$i"
|
|
fi
|
|
done
|
|
}
|