Page MenuHomeFreeBSD

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

Authored by nick_spun.io on Fri, Jul 10, 5:06 AM.

Details

Reviewers
adrian
Group Reviewers
drivers
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 Skipped
Unit
Tests Skipped
Build Status
Buildable 74691
Build 71574: arc lint + arc unit

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