Index | Thread | Search

From:
Richard von Seck <richard_von_seck@genua.de>
Subject:
Enable ix(4) softLRO for IPv6 traffic
To:
"tech@openbsd.org" <tech@openbsd.org>
Date:
Mon, 8 Jun 2026 13:40:32 +0000

Download raw body.

Thread
Hi,

this patch enables software large receive offload (LRO) for ix(4)
devices on IPv6 traffic. IPv6 traffic is identified and then forwarded
to the existing TCP softLRO implementation as e.g., already used in
ixl(4).

rvs

diff --git sys/dev/pci/if_ix.c sys/dev/pci/if_ix.c
index 0ef30ea6355..5a41f8cc455 100644
--- sys/dev/pci/if_ix.c
+++ sys/dev/pci/if_ix.c
@@ -3279,14 +3279,15 @@ ixgbe_rxeof(struct ix_rxring *rxr)
 	struct ix_softc 	*sc = rxr->sc;
 	struct ifnet   		*ifp = &sc->arpcom.ac_if;
 	struct mbuf_list	ml = MBUF_LIST_INITIALIZER();
+	struct mbuf_list	mltcp6 = MBUF_LIST_INITIALIZER();
 	struct mbuf    		*mp, *sendmp;
 	uint8_t		   	eop = 0;
-	uint16_t		len, vtag;
+	uint16_t		len, vtag, ptype;
 	uint32_t		staterr = 0;
 	struct ixgbe_rx_buf	*rxbuf, *nxbuf;
 	union ixgbe_adv_rx_desc	*rxdesc;
 	size_t			dsize = sizeof(union ixgbe_adv_rx_desc);
-	int			i, nextp, rsccnt;
+	int			i, nextp, rsccnt, livelocked;
 
 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
 		return FALSE;
@@ -3322,9 +3323,15 @@ ixgbe_rxeof(struct ix_rxring *rxr)
 		vtag = letoh16(rxdesc->wb.upper.vlan);
 		eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0);
 		hash = lemtoh32(&rxdesc->wb.lower.hi_dword.rss);
-		hashtype =
-		   lemtoh16(&rxdesc->wb.lower.lo_dword.hs_rss.pkt_info) &
-		   IXGBE_RXDADV_RSSTYPE_MASK;
+		hashtype = ptype =
+		   lemtoh16(&rxdesc->wb.lower.lo_dword.hs_rss.pkt_info);
+		hashtype &= IXGBE_RXDADV_RSSTYPE_MASK;
+		ptype &= IXGBE_RXDADV_PKTTYPE_MASK;
+
+		/*
+		* since the NIC doesn't support RSC for IPv6 packets, rsccnt
+		* should be read as zero for incoming IPv6 traffic
+		*/
 		rsccnt = lemtoh32(&rxdesc->wb.lower.lo_dword.data) &
 		   IXGBE_RXDADV_RSCCNT_MASK;
 		rsccnt >>= IXGBE_RXDADV_RSCCNT_SHIFT;
@@ -3408,7 +3415,11 @@ ixgbe_rxeof(struct ix_rxring *rxr)
 				SET(sendmp->m_pkthdr.csum_flags, M_FLOWID);
 			}
 
-			ml_enqueue(&ml, sendmp);
+			if (ISSET(ifp->if_xflags, IFXF_LRO) &&
+			   ISSET(ptype, IXGBE_RXDADV_PKTTYPE_IPV6))
+				tcp_softlro_glue(&mltcp6, sendmp, ifp);
+			else
+				ml_enqueue(&ml, sendmp);
 		}
 next_desc:
 		if_rxr_put(&rxr->rx_ring, 1);
@@ -3422,7 +3433,12 @@ next_desc:
 	}
 	rxr->next_to_check = i;
 
+	livelocked = 0;
+	if (ifiq_input(rxr->ifiq, &mltcp6))
+		livelocked = 1;
 	if (ifiq_input(rxr->ifiq, &ml))
+		livelocked = 1;
+	if (livelocked)
 		if_rxr_livelocked(&rxr->rx_ring);
 
 	if (!(staterr & IXGBE_RXD_STAT_DD))