Skip to content

Commit df43101

Browse files
authored
Intel NIC offload Fix by @rcastley (#5155)
* Create nic-offloading-fix.sh * Update nic-offloading-fix.json
1 parent 3044a77 commit df43101

File tree

2 files changed

+228
-1
lines changed

2 files changed

+228
-1
lines changed

frontend/public/json/nic-offloading-fix.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"categories": [
55
1
66
],
7-
"date_created": "2025-06-15",
7+
"date_created": "2025-05-25",
88
"type": "pve",
99
"updateable": false,
1010
"privileged": false,

tools/pve/nic-offloading-fix.sh

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#!/usr/bin/env bash
2+
3+
# Creates a systemd service to disable NIC offloading features for Intel e1000e interfaces
4+
# Author: rcastley
5+
# License: MIT
6+
7+
YW=$(echo "\033[33m")
8+
YWB=$'\e[93m'
9+
BL=$(echo "\033[36m")
10+
RD=$(echo "\033[01;31m")
11+
BGN=$(echo "\033[4;92m")
12+
GN=$(echo "\033[1;92m")
13+
DGN=$(echo "\033[32m")
14+
CL=$(echo "\033[m")
15+
TAB=" "
16+
CM="${TAB}✔️${TAB}"
17+
CROSS="${TAB}✖️${TAB}"
18+
INFO="${TAB}ℹ️${TAB}${CL}"
19+
WARN="${TAB}⚠️${TAB}${CL}"
20+
21+
function header_info {
22+
clear
23+
cat <<"EOF"
24+
25+
_ ____________ ____ __________ ___ ____ _ __ __
26+
/ | / / _/ ____/ / __ \/ __/ __/ /___ ____ _____/ (_)___ ____ _ / __ \(_)________ _/ /_ / /__ _____
27+
/ |/ // // / / / / / /_/ /_/ / __ \/ __ `/ __ / / __ \/ __ `/ / / / / / ___/ __ `/ __ \/ / _ \/ ___/
28+
/ /| // // /___ / /_/ / __/ __/ / /_/ / /_/ / /_/ / / / / / /_/ / / /_/ / (__ ) /_/ / /_/ / / __/ /
29+
/_/ |_/___/\____/ \____/_/ /_/ /_/\____/\__,_/\__,_/_/_/ /_/\__, / /_____/_/____/\__,_/_.___/_/\___/_/
30+
/____/
31+
32+
EOF
33+
}
34+
35+
header_info
36+
37+
function msg_info() { echo -e "${INFO} ${YW}${1}...${CL}"; }
38+
function msg_ok() { echo -e "${CM} ${GN}${1}${CL}"; }
39+
function msg_error() { echo -e "${CROSS} ${RD}${1}${CL}"; }
40+
function msg_warn() { echo -e "${WARN} ${YWB}${1}"; }
41+
42+
# Check for root privileges
43+
if [ "$(id -u)" -ne 0 ]; then
44+
msg_error "Error: This script must be run as root."
45+
exit 1
46+
fi
47+
48+
if ! command -v ethtool >/dev/null 2>&1; then
49+
msg_info "Installing ethtool"
50+
apt-get update &>/dev/null
51+
apt-get install -y ethtool &>/dev/null || { msg_error "Failed to install ethtool. Exiting."; exit 1; }
52+
msg_ok "ethtool installed successfully"
53+
fi
54+
55+
# Get list of network interfaces using Intel e1000e driver
56+
INTERFACES=()
57+
COUNT=0
58+
59+
msg_info "Searching for Intel e1000e interfaces"
60+
61+
for device in /sys/class/net/*; do
62+
interface="$(basename "$device")" # or adjust the rest of the usages below, as mostly you'll use the path anyway
63+
# Skip loopback interface and virtual interfaces
64+
if [[ "$interface" != "lo" ]] && [[ ! "$interface" =~ ^(tap|fwbr|veth|vmbr|bonding_masters) ]]; then
65+
# Check if the interface uses the e1000e driver
66+
driver=$(basename $(readlink -f /sys/class/net/$interface/device/driver 2>/dev/null) 2>/dev/null)
67+
68+
if [[ "$driver" == "e1000e" ]]; then
69+
# Get MAC address for additional identification
70+
mac=$(cat /sys/class/net/$interface/address 2>/dev/null)
71+
INTERFACES+=("$interface" "Intel e1000e NIC ($mac)")
72+
((COUNT++))
73+
fi
74+
fi
75+
done
76+
77+
# Check if any Intel e1000e interfaces were found
78+
if [ ${#INTERFACES[@]} -eq 0 ]; then
79+
whiptail --title "Error" --msgbox "No Intel e1000e network interfaces found!" 10 60
80+
msg_error "No Intel e1000e network interfaces found! Exiting."
81+
exit 1
82+
fi
83+
84+
msg_ok "Found ${BL}$COUNT${GN} Intel e1000e interfaces"
85+
86+
# Create a checklist for interface selection with all interfaces initially checked
87+
INTERFACES_CHECKLIST=()
88+
for ((i=0; i<${#INTERFACES[@]}; i+=2)); do
89+
INTERFACES_CHECKLIST+=("${INTERFACES[i]}" "${INTERFACES[i+1]}" "ON")
90+
done
91+
92+
# Show interface selection checklist
93+
SELECTED_INTERFACES=$(whiptail --backtitle "Intel e1000e NIC Offloading Disabler" --title "Network Interfaces" \
94+
--separate-output --checklist "Select Intel e1000e network interfaces\n(Space to toggle, Enter to confirm):" 15 80 6 \
95+
"${INTERFACES_CHECKLIST[@]}" 3>&1 1>&2 2>&3)
96+
97+
exitstatus=$?
98+
if [ $exitstatus != 0 ]; then
99+
msg_info "User canceled. Exiting."
100+
exit 0
101+
fi
102+
103+
# Check if any interfaces were selected
104+
if [ -z "$SELECTED_INTERFACES" ]; then
105+
msg_error "No interfaces selected. Exiting."
106+
exit 0
107+
fi
108+
109+
# Convert the selected interfaces into an array
110+
readarray -t INTERFACE_ARRAY <<< "$SELECTED_INTERFACES"
111+
112+
# Show the number of selected interfaces
113+
INTERFACE_COUNT=${#INTERFACE_ARRAY[@]}
114+
115+
# Print selected interfaces
116+
for iface in "${INTERFACE_ARRAY[@]}"; do
117+
msg_ok "Selected interface: ${BL}$iface${CL}"
118+
done
119+
120+
# Ask for confirmation with the list of selected interfaces
121+
CONFIRMATION_MSG="You have selected the following interface(s):\n\n"
122+
for iface in "${INTERFACE_ARRAY[@]}"; do
123+
SPEED=$(cat /sys/class/net/$iface/speed 2>/dev/null)
124+
MAC=$(cat /sys/class/net/$iface/address 2>/dev/null)
125+
CONFIRMATION_MSG+="- $iface (MAC: $MAC, Speed: ${SPEED}Mbps)\n"
126+
done
127+
CONFIRMATION_MSG+="\nThis will create systemd service(s) to disable offloading features.\n\nProceed?"
128+
129+
if ! whiptail --backtitle "Intel e1000e NIC Offloading Disabler" --title "Confirmation" \
130+
--yesno "$CONFIRMATION_MSG" 20 80; then
131+
msg_info "User canceled. Exiting."
132+
exit 0
133+
fi
134+
135+
# Loop through all selected interfaces and create services for each
136+
for SELECTED_INTERFACE in "${INTERFACE_ARRAY[@]}"; do
137+
# Create service name for this interface
138+
SERVICE_NAME="disable-nic-offload-$SELECTED_INTERFACE.service"
139+
SERVICE_PATH="/etc/systemd/system/$SERVICE_NAME"
140+
141+
# Create the service file with e1000e specific optimizations
142+
msg_info "Creating systemd service for interface: ${BL}$SELECTED_INTERFACE${YW}"
143+
144+
# Start with the common part of the service file
145+
cat > "$SERVICE_PATH" << EOF
146+
[Unit]
147+
Description=Disable NIC offloading for Intel e1000e interface $SELECTED_INTERFACE
148+
After=network.target
149+
150+
[Service]
151+
Type=oneshot
152+
# Disable all offloading features for Intel e1000e
153+
ExecStart=/sbin/ethtool -K $SELECTED_INTERFACE gso off gro off tso off tx off rx off rxvlan off txvlan off sg off
154+
RemainAfterExit=true
155+
156+
[Install]
157+
WantedBy=multi-user.target
158+
EOF
159+
160+
# Check if service file was created successfully
161+
if [ ! -f "$SERVICE_PATH" ]; then
162+
whiptail --title "Error" --msgbox "Failed to create service file for $SELECTED_INTERFACE!" 10 50
163+
msg_error "Failed to create service file for $SELECTED_INTERFACE! Skipping to next interface."
164+
continue
165+
fi
166+
167+
# Configure this service
168+
{
169+
echo "25"; sleep 0.2
170+
# Reload systemd to recognize the new service
171+
systemctl daemon-reload
172+
echo "50"; sleep 0.2
173+
# Start the service
174+
systemctl start "$SERVICE_NAME"
175+
echo "75"; sleep 0.2
176+
# Enable the service to start on boot
177+
systemctl enable "$SERVICE_NAME"
178+
echo "100"; sleep 0.2
179+
} | whiptail --backtitle "Intel e1000e NIC Offloading Disabler" --gauge "Configuring service for $SELECTED_INTERFACE..." 10 80 0
180+
181+
# Individual service status
182+
if systemctl is-active --quiet "$SERVICE_NAME"; then
183+
SERVICE_STATUS="Active"
184+
else
185+
SERVICE_STATUS="Inactive"
186+
fi
187+
188+
if systemctl is-enabled --quiet "$SERVICE_NAME"; then
189+
BOOT_STATUS="Enabled"
190+
else
191+
BOOT_STATUS="Disabled"
192+
fi
193+
194+
# Show individual service results
195+
msg_ok "Service for ${BL}$SELECTED_INTERFACE${GN} created and enabled!"
196+
msg_info "${TAB}Service: ${BL}$SERVICE_NAME${YW}"
197+
msg_info "${TAB}Status: ${BL}$SERVICE_STATUS${YW}"
198+
msg_info "${TAB}Start on boot: ${BL}$BOOT_STATUS${YW}"
199+
done
200+
201+
# Prepare summary of all interfaces
202+
SUMMARY_MSG="Services created successfully!\n\n"
203+
SUMMARY_MSG+="Configured Interfaces:\n"
204+
205+
for iface in "${INTERFACE_ARRAY[@]}"; do
206+
SERVICE_NAME="disable-nic-offload-$iface.service"
207+
if systemctl is-active --quiet "$SERVICE_NAME"; then
208+
SVC_STATUS="Active"
209+
else
210+
SVC_STATUS="Inactive"
211+
fi
212+
213+
if systemctl is-enabled --quiet "$SERVICE_NAME"; then
214+
BOOT_SVC_STATUS="Enabled"
215+
else
216+
BOOT_SVC_STATUS="Disabled"
217+
fi
218+
219+
SUMMARY_MSG+="- $iface: $SVC_STATUS, Boot: $BOOT_SVC_STATUS\n"
220+
done
221+
222+
# Show summary results
223+
whiptail --backtitle "Intel e1000e NIC Offloading Disabler" --title "Success" --msgbox "$SUMMARY_MSG" 20 80
224+
225+
msg_ok "Intel e1000e optimization complete for ${#INTERFACE_ARRAY[@]} interface(s)!"
226+
227+
exit 0

0 commit comments

Comments
 (0)