Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
8.9 kB · 220 lines
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221.. SPDX-License-Identifier: GPL-2.0
=====================================================Netdev features mess and how to get out from it alive=====================================================
Author: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Part I: Feature sets====================
Long gone are the days when a network card would just take and give packetsverbatim. Today's devices add multiple features and bugs (read: offloads)that relieve an OS of various tasks like generating and checking checksums,splitting packets, classifying them. Those capabilities and their stateare commonly referred to as netdev features in Linux kernel world.
There are currently three main sets of features on each netdevice,first and second are initialized by the driver:
1. netdev->hw_features set contains features whose state may possibly be changed (enabled or disabled) for a particular device by user's request. Drivers normally initialize this set before registration or in the ndo_init callback. Changes after registration should be made very carefully as other parts of the code may assume hw_features are static. At the very least changes must be made under rtnl_lock and the netdev instance lock, and followed by netdev_update_features().
2. netdev->features set contains features which are currently enabled for a device. This should be changed only by network core or in error paths of ndo_set_features callback.
3. netdev->wanted_features set contains feature set requested by user. This set is filtered by ndo_fix_features callback whenever it or some device-specific conditions change. This set is internal to networking core and should not be referenced in drivers.
On top of those three main sets, each netdev has:
1. Sets which control features inherited by child devices (VLAN, MPLS, hw_enc for L3/L4 tunnels). These sets allow the driver to limit which netdev->features are propagated, in case HW cannot perform the offloads with the extra headers present.
2. netdev->mangleid_features, TSO features which are supported only when IP ID field can be mangled (constant instead of incrementing) during TSO.
3. netdev->gso_partial_features, additional TSO features which HW can support via NETIF_F_GSO_PARTIAL.
Part II: Controlling enabled features=====================================
When current feature set (netdev->features) is to be changed, new setis calculated and filtered by calling ndo_fix_features callbackand netdev_fix_features(). If the resulting set differs from currentset, it is passed to ndo_set_features callback and (if the callbackreturns success) replaces value stored in netdev->features.NETDEV_FEAT_CHANGE notification is issued after that whenever currentset might have changed.
The following events trigger recalculation: 1. device's registration, after ndo_init returned success 2. user requested changes in features state 3. netdev_update_features() is called
ndo_*_features callbacks are called with rtnl_lock held. Missing callbacksare treated as always returning success.
A driver that wants to trigger recalculation must do so by callingnetdev_update_features() while holding rtnl_lock. If the device uses thenetdev instance lock, that lock must be held as well. This should not bedone from ndo_*_features callbacks. netdev->features should not be modifiedby driver except by means of ndo_fix_features callback.
For "ops locked" drivers (see Documentation/networking/netdevices.rst),ethtool callbacks that may end up invoking netdev_update_features() mustopt back into rtnl_lock by setting the matching ETHTOOL_OP_NEEDS_RTNL_*bit in ``ethtool_ops::op_needs_rtnl``. The ethtool core then keepsrtnl_lock held across those SET callbacks so the contract above stillholds.
ndo_features_check is called for each skb before that skb is passed tondo_start_xmit. Driver may perform any non-trivial checks (e.g. exactheader geometry / length) and withdraw features like HW_CSUM or TSO,requesting the networking stack to fall back to the software implementation.
Part III: Implementation hints==============================
* ndo_fix_features:
All dependencies between features should be resolved here. The resultingset can be reduced further by networking core imposed limitations (as codedin netdev_fix_features()). For this reason it is safer to disable a featurewhen its dependencies are not met instead of forcing the dependency on.
This callback should not modify hardware nor driver state (should bestateless). It can be called multiple times between successivendo_set_features calls.
Callback must not alter features contained in NETIF_F_SOFT_FEATURES orNETIF_F_NEVER_CHANGE, except that NETIF_F_VLAN_CHALLENGED may be changed.Care must be taken as changes to NETIF_F_VLAN_CHALLENGED won't affect alreadyconfigured VLANs.
* ndo_set_features:
Hardware should be reconfigured to match passed feature set. The setshould not be altered unless some error condition happens that can'tbe reliably detected in ndo_fix_features. In this case, the callbackshould update netdev->features to match resulting hardware state.Errors returned are not (and cannot be) propagated anywhere except dmesg.(Note: successful return is zero, >0 means silent error.)
Part IV: Features=================
For current list of features, see include/linux/netdev_features.h.This section describes semantics of some of them.
* Transmit checksumming
For complete description, see comments near the top of include/linux/skbuff.h.
Note: NETIF_F_HW_CSUM is a superset of NETIF_F_IP_CSUM + NETIF_F_IPV6_CSUM.It means that device can fill TCP/UDP-like checksum anywhere in the packetswhatever headers there might be.
* Transmit TCP segmentation offload
NETIF_F_TSO_ECN means that hardware can properly split packets with CWR bitset, be it TCPv4 (when NETIF_F_TSO is enabled) or TCPv6 (NETIF_F_TSO6).
* Transmit UDP segmentation offload
NETIF_F_GSO_UDP_L4 accepts a single UDP header with a payload that exceedsgso_size. On segmentation, it segments the payload on gso_size boundaries andreplicates the network and UDP headers (fixing up the last one if less thangso_size).
* Transmit DMA from high memory
On platforms where this is relevant, NETIF_F_HIGHDMA signals thatndo_start_xmit can handle skbs with frags in high memory.
* Transmit scatter-gather
Those features say that ndo_start_xmit can handle fragmented skbs:NETIF_F_SG --- paged skbs (skb_shinfo()->frags), NETIF_F_FRAGLIST ---chained skbs (skb->next/prev list).
* Software features
Features contained in NETIF_F_SOFT_FEATURES are features of networkingstack. Driver should not change behaviour based on them.
* VLAN challenged
NETIF_F_VLAN_CHALLENGED should be set for devices which can't cope with VLANheaders. Some drivers set this because the cards can't handle the bigger MTU.[FIXME: Those cases could be fixed in VLAN code by allowing only reduced-MTUVLANs. This may be not useful, though.]
* rx-fcs
This requests that the NIC append the Ethernet Frame Checksum (FCS)to the end of the skb data. This allows sniffers and other tools toread the CRC recorded by the NIC on receipt of the packet.
* rx-all
This requests that the NIC receive all possible frames, including erroredframes (such as bad FCS, etc). This can be helpful when sniffing a link withbad packets on it. Some NICs may receive more packets if also put into normalPROMISC mode.
* rx-gro-hw
This requests that the NIC enables Hardware GRO (generic receive offload).Hardware GRO is basically the exact reverse of TSO, and is generallystricter than Hardware LRO. A packet stream merged by Hardware GRO mustbe re-segmentable by GSO or TSO back to the exact original packet stream.Hardware GRO is dependent on RXCSUM since every packet successfully mergedby hardware must also have the checksum verified by hardware.
* hsr-tag-ins-offload
This should be set for devices which insert an HSR (High-availability SeamlessRedundancy) or PRP (Parallel Redundancy Protocol) tag automatically.
* hsr-tag-rm-offload
This should be set for devices which remove HSR (High-availability SeamlessRedundancy) or PRP (Parallel Redundancy Protocol) tags automatically.
* hsr-fwd-offload
This should be set for devices which forward HSR (High-availability SeamlessRedundancy) frames from one port to another in hardware.
* hsr-dup-offload
This should be set for devices which duplicate outgoing HSR (High-availabilitySeamless Redundancy) or PRP (Parallel Redundancy Protocol) framesautomatically in hardware.
Part V: Related device flags============================
* netdev->netmem_tx
This is not a netdev feature bit. Drivers support netmem TX by settingnetdev->netmem_tx to one of the values in enum netmem_tx_mode.See Documentation/networking/netmem.rst.