summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_ix.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2023-01-26 07:32:41 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2023-01-26 07:32:41 +0000
commit79b330f605e3fa47910da94e95decb9164f91d7b (patch)
tree2b07f5af82f8e4a5fbbf947f1953496ce4f4f2b2 /sys/dev/pci/if_ix.c
parent4a7e84638cc8707c6a8d913ee8b21c22eb89d028 (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.c47
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;