Turn on "hw-tc-offload" function etc. by script

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

Inquiry results

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

SetON results example

This script will require input and show before and after status changes accordingly.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.