2020-02-09 改udev硬件配置策略,改ETHTOOL_OPTS 或改 `/etc/NetworkManager/dispatcher.d/20-ethtool`

Disabling Offloading on Ubuntu 18.04 with Netplan and/or systemd-networkd

原文: https://michael.mulqueen.me.uk/2018/08/disable-offloading-netplan-ubuntu/
发布于:21 Aug 2018

Why Disable Offloading?

Firstly, why not disable offloading? Offloading is a way for the operating system and your CPU to offload some of the work involved in transmitting packets (which can be significant, especially at higher speeds. The two main cases that I’ve come across for this are offloading the calculation of TCP checksums and handling fragmentation. Hardware offloading should be a good thing and it often is, I’ve only rarely found a need to disable it.

However, sometimes it just seems to break things and you can’t find a better work around. For example, I had a problem earlier where a particular host of a network was sending TCP segments and they were being routed to their destinations but then being discarded. I set up a packet capture on another remote host under our control and I was seeing a SYN arriving and then more SYNs as retransmission was attempted and no SYN-ACK was being sent back. This was isolated to this host, no other hosts on the sending network had this issue. I ruled out the other usual suspects - NAT, firewall rules etc.

Finally, I decided there was nothing left to try other than disable offloading and like that, the issue was gone! I had to disable checksum offloading, but you may have a slightly different issue.

Disabling Offloading Temporarily

This should work whatever you’re using to manage your network.

To do this, you’ll need to have ethtool installed:

sudo apt install ethtool

Once it’s installed, work out what interface is affected. For the sake of this post, we’ll say it’s eth0, but it could be something completely different (e.g. br1, vnet2, enp1s2)

My problem was caused by checksum offloading, which can be disabled by running this command:

sudo ethtool --offload eth0  rx off  tx off

rx off disables for things you’re receiving. tx off disables it for things you’re transmitting.

If the problem goes away, then you’ve found the cause. Great. Bear in mind though, when you next reboot, these settings will be reset to default and the problem will come back.

If this didn’t solve the problem, it may be worth looking at some of the features that can be enabled/disabled:

  • rx - receive (RX) checksumming
  • tx - transmit (TX) checksumming
  • sg - scatter-gather
  • tso - TCP segmentation offload
  • ufo - UDP fragmentation offload
  • gso - generic segmentation offload
  • gro - generic receive offload
  • lro - large receive offload
  • rxvlan - receive (RX) VLAN acceleration
  • txvlan - transmit (TX) VLAN acceleration
  • ntuple - receive (RX) ntuple filters and actions
  • rxhash - receive hashing offload

In general, it’s best to disable the minimum amount of features you need to resolve your issue rather than blanket disabling everything.

Netplan and systemd-networkd

Ubuntu 18.04 brought with it Canonical’s new answer to the problem of network configuration, netplan. I don’t particularly like netplan, but I also like to use the defaults wherever possible. On a server, the best choice is to use the systemd-networkd backend to netplan (the other choice is NetworkManager). You might argue that an even better choice is to cut netplan out of the loop and use systemd-networkd directly. In either case, I’m assuming in this post that you’re either using netplan and systemd-networkd together or systemd-networkd alone.

If you’ve used netplan, you’ll realise that for basic uses, it’s quite nice and neat, but for more advanced uses, you start to find the bugs and the missing features (though it is continuing to improve).

Disabling Offloading Permanently

Netplan doesn’t offer a way to turn off offloading within its configuration. Systemd-networkd does provide some options to disable offloading, although I wasn’t able to find options for all of the features available in ethtool, for this reason I’ve not investigated it further.

Luckily, Ubuntu 18.04 comes with the networkd-dispatcher package. You can use this to run scripts (like legacy ifup/ifdown scripts).

If you’re missing the package:

sudo apt install networkd-dispatcher

We need to create a script to run as the network comes up:

sudo nano /usr/lib/networkd-dispatcher/routable.d/10-disable-offloading

I put the following content in it:

#!/bin/sh
ethtool --offload eth0 rx off tx off

You’ll need to change this if you’ve used other options or a different network interface.

Finally, ensure that it’s executable:

sudo chmod +x /usr/lib/networkd-dispatcher/routable.d/10-disable-offloading

If everything has worked, you’ll now be able to boot without issue.

Please note, I’ve located this configuration file in /usr/lib/networkd-dispatcher due to LP #1765152, you may see /etc/networkd-dispatcher in other distributions or other documentation. The correct location in Ubuntu 18.04 is in /usr/lib/networkd-dispatcher, even if that seems a bit odd.

追加说明: LP #1765152BUG解决后, Scripts can be installed into these directories under /usr/lib/networkd-dispatcher for system packages, and /etc/networkd-dispatcher for local overrides


红帽Linux技术支持页面给出的解决方案

How to write a NetworkManager dispatcher script to apply ethtool commands?

SOLUTION

环境

  • Red Hat Enterprise Linux 8
  • Red Hat Enterprise Linux 7
  • NetworkManager used to manage network connections
  • Network interface supporting configurable offload via ethtool -K commands

问题
How to write a NetworkManager dispatcher script to apply ethtool commands?
Need to apply ethtool offloading to a network interface at boot or startup?
What is the correct syntax for a NM dispatcher script to enable or disable offloading like checksumming or large receive (GSO/LRO) or segmentation (GRO/LSO)?

决议
Create a unique executable file in the /etc/NetworkManager/dispatcher.d/ directory, for example:

sudo su
touch /etc/NetworkManager/dispatcher.d/30-ethtool
chmod +x /etc/NetworkManager/dispatcher.d/30-ethtool

For a standalone network interface:

#!/bin/bash

if [ "$1" == "eth0" ] && [ "$2" == "up" ]; then
    ethtool -K "$1" rx off gro off lro off
fi

For 2 standalone network interfaces:

#!/bin/bash

if [ "$1" == "eth0" -a "$2" == "up" ] || [ "$1" == "eth1" -a "$2" == "up" ] ; then
    ethtool -K "$1" rx off gro off lro off
fi

For a bonding or teaming network interface:

#!/bin/bash

if [ "$1" == "bond0" ] && [ "$2" == "up" ]; then
    for INTERFACE in bond0 eth0 eth1; do
        ethtool -K "$INTERFACE" rx off gro off lro off
    done
fi

Modify the list of interfaces as required, ensure the parent bond/team device and all slave devices have settings applied to them.


For RHEL7 in /etc/sysconfig/network-scripts/ifcfg-* you may have:

ETHTOOL_OPTS="-K ${DEVICE} gso off gro off tso off"

if more options then use like

ETHTOOL_OPTS="-K ${DEVICE} gso off;-K ${DEVICE} gro off;-K ${DEVICE} tso off"

you have to have naturally DEVICE defined in your ifcfg file.

No rc.local nor extra ifup scripts needed. Easy to you in generic deployment systems.

但如果你的Linux虚拟机是带图形界面的Desktop版本, 还需要手动创建一个Network Manager配置文件/etc/NetworkManager/dispatcher.d/20-ethtool

If you are on RHEL7 (or alike) and use Network Manager instead of /etc/init.d/network to control your interfaces the proposed answer will not work, since /sbin/ifup-local (as well as ifdown-pre-local and ifdown-local) will never get executed.

Instead put your scripts into /etc/NetworkManager/dispatcher.d/ and make sure the NetworkManager-dispatcher service is enabled

systemctl enable NetworkManager-dispatcher

Hint: The dispatcher will only kick in once NetworkManager makes changes to an interface, it doesn't need to be running or anything, so if the status reads

Active: inactive (dead)
that's completely fine!

Also make sure your script is:

  • executable (chmod +x)
  • owned by root (chown root:root)
  • writable by root only (chmod 755)

Now NetworkManager will pass two (2) variables to the dispatcher:

$1 being the interface (eno16777984, eth0, ppp0, etc...)
$2 holding the status (either up or down)

and it allows chaining the scripts (just like /etc/rc...) to have some control over the order in which the dispatcher will execute them:

10-first, 20-second and so on...

The order will be ascending on a connect

if [$2 = "up"] its 10-first followed by 20-second

and descending on a disconnect

if [$2 = "down"] you get 20-second followed by 10-first

and so on.

So to accomplish what OP was looking for you could put something like this:

#!/bin/bash
# 注意bash脚本中括号要写 [[ ]]否则逻辑错误
if [[ "$1" = "eth0" && "$2" = "up" ]]; then
  /sbin/ethtool --offload "$1" gro off
fi

in /etc/NetworkManager/dispatcher.d/20-ethtool


参考:

  • https://serverfault.com/questions/463111/how-to-persist-ethtool-settings-through-reboot

你可能感兴趣的:(2020-02-09 改udev硬件配置策略,改ETHTOOL_OPTS 或改 `/etc/NetworkManager/dispatcher.d/20-ethtool`)