diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2023-01-26 07:32:41 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2023-01-26 07:32:41 +0000 |
commit | 79b330f605e3fa47910da94e95decb9164f91d7b (patch) | |
tree | 2b07f5af82f8e4a5fbbf947f1953496ce4f4f2b2 /sys/dev/pci/if_ix.c | |
parent | 4a7e84638cc8707c6a8d913ee8b21c22eb89d028 (diff) |
backing "consolidate mbuf header parsing on device driver layer"
easily repeatable ASSERT happens seconds after starting compiles over nfs.
Diffstat (limited to 'sys/dev/pci/if_ix.c')
-rw-r--r-- | sys/dev/pci/if_ix.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 21d48208954..32e0c601eb5 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.190 2023/01/24 22:35:46 jan Exp $ */ +/* $OpenBSD: if_ix.c,v 1.191 2023/01/26 07:32:39 deraadt Exp $ */ /****************************************************************************** @@ -2477,16 +2477,25 @@ static inline int ixgbe_csum_offload(struct mbuf *mp, uint32_t *vlan_macip_lens, uint32_t *type_tucmd_mlhl, uint32_t *olinfo_status) { - struct ether_extracted ext; + struct ether_header *eh = mtod(mp, struct ether_header *); + struct mbuf *m; + int hoff; int offload = 0; uint32_t iphlen; + uint8_t ipproto; - ether_extract_headers(mp, &ext); + *vlan_macip_lens |= (sizeof(*eh) << IXGBE_ADVTXD_MACLEN_SHIFT); - *vlan_macip_lens |= (sizeof(*ext.eh) << IXGBE_ADVTXD_MACLEN_SHIFT); + switch (ntohs(eh->ether_type)) { + case ETHERTYPE_IP: { + struct ip *ip; - if (ext.ip4) { - iphlen = ext.ip4->ip_hl << 2; + m = m_getptr(mp, sizeof(*eh), &hoff); + KASSERT(m != NULL && m->m_len - hoff >= sizeof(*ip)); + ip = (struct ip *)(mtod(m, caddr_t) + hoff); + + iphlen = ip->ip_hl << 2; + ipproto = ip->ip_p; if (ISSET(mp->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT)) { *olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8; @@ -2494,30 +2503,46 @@ ixgbe_csum_offload(struct mbuf *mp, uint32_t *vlan_macip_lens, } *type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; + break; + } + #ifdef INET6 - } else if (ext.ip6) { - iphlen = sizeof(*ext.ip6); + case ETHERTYPE_IPV6: { + struct ip6_hdr *ip6; + + m = m_getptr(mp, sizeof(*eh), &hoff); + KASSERT(m != NULL && m->m_len - hoff >= sizeof(*ip6)); + ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff); + + iphlen = sizeof(*ip6); + ipproto = ip6->ip6_nxt; *type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; + break; + } #endif - } else { + + default: return offload; } *vlan_macip_lens |= iphlen; - if (ext.tcp) { + switch (ipproto) { + case IPPROTO_TCP: *type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; if (ISSET(mp->m_pkthdr.csum_flags, M_TCP_CSUM_OUT)) { *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; offload = 1; } - } else if (ext.udp) { + break; + case IPPROTO_UDP: *type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP; if (ISSET(mp->m_pkthdr.csum_flags, M_UDP_CSUM_OUT)) { *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; offload = 1; } + break; } return offload; |