> Date: Thu, 13 Jan 2022 20:34:36 +0100 > From: Alexander Bluhm <alexander.bl...@gmx.net> > > On Wed, Jan 12, 2022 at 05:36:01PM +0100, Mark Kettenis wrote: > > > Date: Wed, 12 Jan 2022 17:02:03 +0100 > > > From: Jan Klemkow <j.klem...@wemelug.de> > > > > > > Hi, > > > > > > This diff enables TCP and UDP checksum offloading in ix(4) for IPv6. > > > > > > IPv6 extension headers aren't a problem in this case. > > > in6_proto_cksum_out() in netinet6/ip6_output.c disables checksum > > > offloading if ip6_nxt is not TCP or UDP. Thus, we can just use this > > > field. > > > > > > Tested with: > > > ix0 at pci5 dev 0 function 0 "Intel 82599" rev 0x01, msix, 8 queues, > > > address 00:1b:21:94:4c:48 > > > > > > OK? > > > > Isn't this the same disaster as the ixl(4) diff you sent earlier? We > > have sparc64 machines with onboard ix(4)... > > No, it is another case. The disaster was with TCP bit fields, here > we are talking about IPv6 header. > > - A few lines above ip->ip_p is used the same way, and that works. > - I have checked sparc64 assembler, it uses byte instruction. > 1bd0: c4 08 60 06 ldub [ %g1 + 6 ], %g2 > - struct ip6_hdr uses __packed. I think this is wrong, but that > is a different story. > - Even if I remove this __packed, gcc uses a byte instruction for > reading ip6_nxt. > - m_getptr() returns the correct mbuf and offset to the header. I > think we can assume that a single IPv6 header, that our stack has > created, is in contiguous memory. The IPv4 case just above makes > the same assumption.
So the crucial thing here is that this only accesses a single byte in the header. We did indeed establish that that is safe provided the header itself is indeed not fragmented. > OK bluhm@ > > > > Index: dev/pci/if_ix.c > > > =================================================================== > > > RCS file: /mount/openbsd/cvs/src/sys/dev/pci/if_ix.c,v > > > retrieving revision 1.180 > > > diff -u -p -r1.180 if_ix.c > > > --- dev/pci/if_ix.c 27 Jul 2021 01:44:55 -0000 1.180 > > > +++ dev/pci/if_ix.c 12 Jan 2022 14:53:14 -0000 > > > @@ -1879,7 +1879,8 @@ ixgbe_setup_interface(struct ix_softc *s > > > ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; > > > #endif > > > > > > - ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; > > > + ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4 > > > + | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; > > > > > > /* > > > * Specify the media types supported by this sc and register > > > @@ -2438,9 +2439,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, > > > struct ether_header *eh; > > > #endif > > > struct ip *ip; > > > -#ifdef notyet > > > struct ip6_hdr *ip6; > > > -#endif > > > struct mbuf *m; > > > int ipoff; > > > uint32_t vlan_macip_lens = 0, type_tucmd_mlhl = 0; > > > @@ -2521,19 +2520,16 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, > > > ipproto = ip->ip_p; > > > type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; > > > break; > > > -#ifdef notyet > > > case ETHERTYPE_IPV6: > > > if (mp->m_pkthdr.len < ehdrlen + sizeof(*ip6)) > > > return (-1); > > > m = m_getptr(mp, ehdrlen, &ipoff); > > > KASSERT(m != NULL && m->m_len - ipoff >= sizeof(*ip6)); > > > - ip6 = (struct ip6 *)(m->m_data + ipoff); > > > + ip6 = (struct ip6_hdr *)(m->m_data + ipoff); > > > ip_hlen = sizeof(*ip6); > > > - /* XXX-BZ this will go badly in case of ext hdrs. */ > > > ipproto = ip6->ip6_nxt; > > > type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; > > > break; > > > -#endif > > > default: > > > offload = FALSE; > > > break; > > > Index: dev/pci/ixgbe.h > > > =================================================================== > > > RCS file: /mount/openbsd/cvs/src/sys/dev/pci/ixgbe.h,v > > > retrieving revision 1.32 > > > diff -u -p -r1.32 ixgbe.h > > > --- dev/pci/ixgbe.h 18 Jul 2020 07:18:22 -0000 1.32 > > > +++ dev/pci/ixgbe.h 12 Jan 2022 14:57:13 -0000 > > > @@ -65,6 +65,7 @@ > > > #include <netinet/in.h> > > > #include <netinet/if_ether.h> > > > #include <netinet/ip.h> > > > +#include <netinet/ip6.h> > > > > > > #if NBPFILTER > 0 > > > #include <net/bpf.h> > > > > > > >