Page MenuHomeFreeBSD

aq(4): expand and correct offloads, fix VLAN/multicast filtering
ClosedPublic

Authored by nick_spun.io on Fri, Jul 10, 5:06 AM.
Referenced Files
Unknown Object (File)
Sat, Aug 1, 7:47 AM
Unknown Object (File)
Sat, Aug 1, 5:57 AM
Unknown Object (File)
Sat, Aug 1, 4:15 AM
Unknown Object (File)
Fri, Jul 31, 10:38 AM
Unknown Object (File)
Fri, Jul 31, 4:15 AM
Unknown Object (File)
Fri, Jul 31, 3:51 AM
Unknown Object (File)
Fri, Jul 31, 12:58 AM
Unknown Object (File)
Thu, Jul 30, 8:18 PM
Subscribers

Details

Summary

Advertise the offloads the hardware already performs, correct the TX
descriptor's L3 family selection, and correct the VLAN and multicast
receive-filter paths.

Offloads: advertise IFCAP_HWCSUM_IPV6 (adding CSUM_IP6_TCP/UDP/TSO to
isc_tx_csum_flags) and IFCAP_VLAN_HWTSO, and enable the RX outer
(S-VLAN) tag parse mode in aq_hw_offload_set().

TX descriptor L3 family: aq_setup_offloads() derived tx_desc_cmd_ipv4
from CSUM_IP|CSUM_TSO, but CSUM_TSO is (CSUM_IP_TSO|CSUM_IP6_TSO) and
tcp_output() sets both bits without regard to address family, so an
IPv6 TSO frame matched on CSUM_IP_TSO and went out with the IPv4
header-checksum command set on a frame that carries no IPv4 header.
The checksum flags cannot distinguish the family; key the bit off
IPI_TX_IPV4 instead, which iflib derives from the parsed ethertype,
as the IPI_TX_INTR test below it already does. Plain IPv6 checksum
offload was unaffected, as CSUM_IP6_TCP alone never matched the mask.

RX VLAN tag stripping: ring init hardwired hardware tag stripping off
while the RX path still set M_VLANTAG and the writeback tag for every
tagged frame, so a tagged frame arrived with the tag in line while the
mbuf claimed it stripped and ether_demux() parsed four bytes short of
the payload. Program per-ring stripping from IFCAP_VLAN_HWTAGGING and
set M_VLANTAG only under the same capability, so the two states stay
coherent.

VLAN filter and promiscuous edge cases: filter only when 1..16 VLANs are
registered -- with none (or more than the 16 the table holds) fall back
to VLAN-promiscuous and pass all tags, rather than dropping every tagged
frame against an empty filter table; and keep VLAN-promiscuous set
whenever the interface is IFF_PROMISC, so adding or removing a VLAN under
promisc does not clear it and start dropping tagged frames.

Multicast reconcile: ifdi_multi_set is declarative, but aq_if_multi_set()
only added -- shrinking the list left accept-all-multicast latched or
stale exact slots enabled, defeating hardware multicast filtering until
a reinit. Clear the exact slots before reprogramming the current list,
and always drive accept-all-multicast from the current state so a shrink
clears it.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

(This is the base of the diff stack but got committed last because I copied the wrong commit hash when I was initially using git-arc)

(This is the base of the diff stack but got committed last because I copied the wrong commit hash when I was initially using git-arc)

You can adjust that, use the "Edit Related Revisions" option on this page.

(This is the base of the diff stack but got committed last because I copied the wrong commit hash when I was initially using git-arc)

You can adjust that, use the "Edit Related Revisions" option on this page.

Oh I set it as the parent revision already, I was just talking about the diff number being the highest 😆

adrian added a reviewer: drivers.
adrian added a subscriber: drivers.
This revision is now accepted and ready to land.Sat, Jul 11, 6:38 PM
This revision now requires review to proceed.Tue, Jul 14, 3:38 AM
This revision is now accepted and ready to land.Wed, Jul 15, 8:11 PM