From: jan Date: Thu, 27 Jul 2023 20:21:25 +0000 (+0000) Subject: Fix inline vlan-tag handling of forwarded LRO packets from ix(4) X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=d1dd674394e26782b4b514c396291cce34071e5c;p=openbsd Fix inline vlan-tag handling of forwarded LRO packets from ix(4) Implement vlan-tag parsing ether_extract_header() to use this information to adjust the MSS calculation of LRO packets. pointed out by mbuhl and bluhm with tweaks from bluhm ok bluhm@ --- diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 3610ed92a26..80df360e06e 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.200 2023/07/18 16:01:20 bluhm Exp $ */ +/* $OpenBSD: if_ix.c,v 1.201 2023/07/27 20:21:25 jan Exp $ */ /****************************************************************************** @@ -3275,6 +3275,10 @@ ixgbe_rxeof(struct rx_ring *rxr) /* Calculate header size. */ ether_extract_headers(sendmp, &ext); hdrlen = sizeof(*ext.eh); +#if NVLAN > 0 + if (ext.evh) + hdrlen += ETHER_VLAN_ENCAP_LEN; +#endif if (ext.ip4) hdrlen += ext.ip4->ip_hl << 2; if (ext.ip6) diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 20f7a9aee2e..a77a0d6543c 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.290 2023/07/06 19:46:53 kn Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.291 2023/07/27 20:21:25 jan Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -1040,6 +1040,7 @@ ether_extract_headers(struct mbuf *mp, struct ether_extracted *ext) uint64_t hlen; int hoff; uint8_t ipproto; + uint16_t ether_type; /* Return NULL if header was not recognized. */ memset(ext, 0, sizeof(*ext)); @@ -1048,9 +1049,20 @@ ether_extract_headers(struct mbuf *mp, struct ether_extracted *ext) return; ext->eh = mtod(mp, struct ether_header *); - switch (ntohs(ext->eh->ether_type)) { + ether_type = ntohs(ext->eh->ether_type); + hlen = sizeof(*ext->eh); + +#if NVLAN > 0 + if (ether_type == ETHERTYPE_VLAN) { + ext->evh = mtod(mp, struct ether_vlan_header *); + ether_type = ntohs(ext->evh->evl_proto); + hlen = sizeof(*ext->evh); + } +#endif + + switch (ether_type) { case ETHERTYPE_IP: - m = m_getptr(mp, sizeof(*ext->eh), &hoff); + m = m_getptr(mp, hlen, &hoff); if (m == NULL || m->m_len - hoff < sizeof(*ext->ip4)) return; ext->ip4 = (struct ip *)(mtod(m, caddr_t) + hoff); @@ -1064,7 +1076,7 @@ ether_extract_headers(struct mbuf *mp, struct ether_extracted *ext) break; #ifdef INET6 case ETHERTYPE_IPV6: - m = m_getptr(mp, sizeof(*ext->eh), &hoff); + m = m_getptr(mp, hlen, &hoff); if (m == NULL || m->m_len - hoff < sizeof(*ext->ip6)) return; ext->ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff); diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h index 9ff5baeaed1..ed28944e721 100644 --- a/sys/netinet/if_ether.h +++ b/sys/netinet/if_ether.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.h,v 1.89 2023/07/06 19:46:53 kn Exp $ */ +/* $OpenBSD: if_ether.h,v 1.90 2023/07/27 20:21:25 jan Exp $ */ /* $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $ */ /* @@ -301,11 +301,12 @@ uint64_t ether_addr_to_e64(const struct ether_addr *); void ether_e64_to_addr(struct ether_addr *, uint64_t); struct ether_extracted { - struct ether_header *eh; - struct ip *ip4; - struct ip6_hdr *ip6; - struct tcphdr *tcp; - struct udphdr *udp; + struct ether_header *eh; + struct ether_vlan_header *evh; + struct ip *ip4; + struct ip6_hdr *ip6; + struct tcphdr *tcp; + struct udphdr *udp; }; void ether_extract_headers(struct mbuf *, struct ether_extracted *);