Hi there
I want to share two shell scripts for offloading function settings that are easier than “set interface ethernet …” one by one. The configure commands of the combination of functions and ethernet ports are kind of painful to me.
It’s imperfect but works as I expected.
Meanwhile, I know there is a bug to turn on Hw-tc-offload related to netfilter.
https://bugzilla.netfilter.org/show_bug.cgi?id=1776
Let’s wait and see when/what will be fixed.
eth_offload_inquiry.sh
#!/bin/bash
get_interfaces() {
ip link show | awk -F: '/^[0-9]+: [^lo]/ {print $2}' | grep -v '@' | tr -d ' '
}
print_table() {
local interfaces=($(get_interfaces))
if [ ${#interfaces[@]} -eq 0 ]; then
echo "No network interfaces found."
return
fi
echo "Interfaces found: ${interfaces[@]}"
local offload_keys=(
"rx-checksumming" "tx-checksumming" "tx-checksum-ip-generic" "tx-checksum-sctp"
"scatter-gather" "tx-scatter-gather" "tcp-segmentation-offload" "tx-tcp-segmentation"
"tx-tcp-ecn-segmentation" "tx-tcp-mangleid-segmentation" "tx-tcp6-segmentation"
"generic-segmentation-offload" "generic-receive-offload" "rx-vlan-offload"
"tx-vlan-offload" "ntuple-filters" "receive-hashing" "highdma" "tx-gre-segmentation"
"tx-gre-csum-segmentation" "tx-ipxip4-segmentation" "tx-ipxip6-segmentation"
"tx-udp_tnl-segmentation" "tx-udp_tnl-csum-segmentation" "tx-gso-partial"
"tx-udp-segmentation" "tx-nocache-copy" "loopback" "l2-fwd-offload" "hw-tc-offload"
"rx-udp_tunnel-port-offload" "rx-gro-list" "rx-udp-gro-forwarding"
)
# Print header with sufficient width for the longest key
local key_width=35 # Adjust this value if necessary for longer keys
printf "%-${key_width}s" "Offload Setting"
for iface in "${interfaces[@]}"; do
printf "| %-4s " "$iface"
done
echo
printf '%0.s-' {1..80}
echo
# Print offload settings for each interface
for key in "${offload_keys[@]}"; do
printf "%-${key_width}s" "$key"
for iface in "${interfaces[@]}"; do
local status=$(ethtool --show-features "$iface" | grep -w "$key" | awk 'NR==1 {print $2}')
if [ -z "$status" ]; then
status="N/A"
fi
if [ "$status" == "off" ]; then
printf "| \033[91m%-4s\033[0m " "$status"
else
printf "| %-4s " "$status"
fi
done
echo
done
}
print_table
eth_offload_setON.sh
#!/bin/bash
get_interfaces() {
ip link show | awk -F: '/^[0-9]+: [^lo]/ {print $2}' | grep -v '@' | tr -d ' '
}
set_offload_on() {
local interface=$1
local features=(
"hw-tc-offload"
"generic-receive-offload"
"generic-segmentation-offload"
"scatter-gather"
"tcp-segmentation-offload"
)
for feature in "${features[@]}"; do
ethtool -K "$interface" "$feature" on 2>/dev/null
if [ $? -ne 0 ]; then
echo -e "\e[31mFailed to set $feature on $interface\e[0m"
else
echo -e "\e[32mSuccessfully set $feature on $interface\e[0m"
fi
done
}
print_table() {
local interfaces=($(get_interfaces))
if [ ${#interfaces[@]} -eq 0 ]; then
echo "No network interfaces found."
return
fi
echo -e "\nInterfaces found: ${interfaces[@]}\n"
local offload_keys=(
"hw-tc-offload" "generic-receive-offload" "generic-segmentation-offload"
"scatter-gather" "tcp-segmentation-offload"
)
# Calculate the maximum key width for alignment
local max_key_length=0
for key in "${offload_keys[@]}"; do
if [ ${#key} -gt $max_key_length ]; then
max_key_length=${#key}
fi
done
# Print header
printf "%-${max_key_length}s " "Offload Setting"
for iface in "${interfaces[@]}"; do
printf "| %-4s" "$iface"
done
echo
printf '%0.s-' {1..80}
echo
# Print offload settings for each interface
for key in "${offload_keys[@]}"; do
printf "%-${max_key_length}s " "$key"
for iface in "${interfaces[@]}"; do
local status=$(ethtool --show-offload "$iface" 2>/dev/null | grep -w "$key" | awk 'NR==1 {print $2}')
if [ -z "$status" ]; then
status="N/A"
fi
if [[ "$status" == "off" ]]; then
printf "| \e[31m%-4s\e[0m" "$status"
else
printf "| %-4s" "$status"
fi
done
echo
done
}
print_table
# Prompt for user input with cursor at the same line
echo -e "\n\e[31mYou must Enter a specific interface name to set offload features or Enter \"\e[31mall\e[0m\e[31m\" for all interfaces:\e[0m "
read -p "" user_iface
if [ -z "$user_iface" ]; then
echo -e "\e[31mNo interface specified. Skipping offload settings change.\e[0m\n"
else
if [ "$user_iface" == "all" ]; then
interfaces=$(get_interfaces)
else
interfaces=($user_iface)
fi
for iface in ${interfaces[@]}; do
set_offload_on "$iface"
done
fi
print_table