Fix receiving VLAN packets if LRO is enabled on ix(4).
authorbluhm <bluhm@openbsd.org>
Mon, 21 Aug 2023 21:45:18 +0000 (21:45 +0000)
committerbluhm <bluhm@openbsd.org>
Mon, 21 Aug 2023 21:45:18 +0000 (21:45 +0000)
The vlan packet bit is only valid for the last descriptor's receive
status.  When receiving just one buffer per packet, it makes no
difference, but with LRO there are multiple descriptors.  Checking
only the first one resulted in VLAN headers being stripped and large
packets appear as regular on ix interface.  Move the code setting
vlan tag from first to last descriptor.

bug reported and fix tested by Hrvoje Popovski
OK jan@

sys/dev/pci/if_ix.c

index 7cae7f7..a832a9a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ix.c,v 1.203 2023/08/03 18:56:32 jan Exp $ */
+/*     $OpenBSD: if_ix.c,v 1.204 2023/08/21 21:45:18 bluhm Exp $       */
 
 /******************************************************************************
 
@@ -3230,12 +3230,6 @@ ixgbe_rxeof(struct rx_ring *rxr)
                        sendmp = mp;
                        sendmp->m_pkthdr.len = 0;
                        sendmp->m_pkthdr.ph_mss = 0;
-#if NVLAN > 0
-                       if (staterr & IXGBE_RXD_STAT_VP) {
-                               sendmp->m_pkthdr.ether_vtag = vtag;
-                               SET(sendmp->m_flags, M_VLANTAG);
-                       }
-#endif
                }
                sendmp->m_pkthdr.len += mp->m_len;
                /*
@@ -3256,7 +3250,12 @@ ixgbe_rxeof(struct rx_ring *rxr)
                        uint16_t pkts;
 
                        ixgbe_rx_checksum(staterr, sendmp);
-
+#if NVLAN > 0
+                       if (staterr & IXGBE_RXD_STAT_VP) {
+                               sendmp->m_pkthdr.ether_vtag = vtag;
+                               SET(sendmp->m_flags, M_VLANTAG);
+                       }
+#endif
                        if (hashtype != IXGBE_RXDADV_RSSTYPE_NONE) {
                                sendmp->m_pkthdr.ph_flowid = hash;
                                SET(sendmp->m_pkthdr.csum_flags, M_FLOWID);