diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c --- a/sys/dev/usb/net/if_ure.c +++ b/sys/dev/usb/net/if_ure.c @@ -47,6 +47,7 @@ /* needed for checksum offload */ #include #include +#include #include #include @@ -2168,10 +2169,15 @@ static int ure_txcsum(struct mbuf *m, int caps, uint32_t *regout) { - struct ip ip; + union { + struct ip v4; +#ifdef INET6 + struct ip6_hdr v6; +#endif + } ip; + struct ether_header *eh; int flags; - uint32_t data; uint32_t reg; int l3off, l4off; uint16_t type; @@ -2206,10 +2212,9 @@ if (flags & CSUM_IP) reg |= URE_TXPKT_IPV4_CS; - data = m->m_pkthdr.csum_data; if (flags & (CSUM_IP_TCP | CSUM_IP_UDP)) { - m_copydata(m, l3off, sizeof ip, (caddr_t)&ip); - l4off = l3off + (ip.ip_hl << 2) + data; + m_copydata(m, l3off, sizeof ip.v4, (caddr_t)&ip.v4); + l4off = l3off + (ip.v4.ip_hl << 2); if (__predict_false(l4off > URE_L4_OFFSET_MAX)) return (1); @@ -2222,7 +2227,13 @@ } #ifdef INET6 else if (flags & (CSUM_IP6_TCP | CSUM_IP6_UDP)) { - l4off = l3off + data; + m_copydata(m, l3off, sizeof ip.v6, (caddr_t)&ip.v6); + + if (ip.v6.ip6_nxt != IPPROTO_TCP && + ip.v6.ip6_nxt != IPPROTO_UDP) + return (1); + + l4off = l3off + sizeof(ip.v6); if (__predict_false(l4off > URE_L4_OFFSET_MAX)) return (1);