diff options
author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2012-05-28 09:30:13 +0000 |
---|---|---|
committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2012-05-28 09:30:13 +0000 |
commit | 356ab07e2dba0f8e7300f2ffc2cf1c175aad34a8 (patch) | |
tree | 5f5a5c87a324064ee224e0476ab7846e52c50a3d /sys/netinet6 | |
parent | 81174e787263a18dbd1fcc6b8cf211d314d170ae (diff) | |
download | src-356ab07e2dba0f8e7300f2ffc2cf1c175aad34a8.tar.gz src-356ab07e2dba0f8e7300f2ffc2cf1c175aad34a8.zip |
It turns out that too many drivers are not only parsing the L2/3/4
headers for TSO but also for generic checksum offloading. Ideally we
would only have one common function shared amongst all drivers, and
perhaps when updating them for IPv6 we should introduce that.
Eventually we should provide the meta information along with mbufs to
avoid (re-)parsing entirely.
To not break IPv6 (checksums and offload) and to be able to MFC the
changes without risking to hurt 3rd party drivers, duplicate the v4
framework, as other OSes have done as well.
Introduce interface capability flags for TX/RX checksum offload with
IPv6, to allow independent toggling (where possible). Add CSUM_*_IPV6
flags for UDP/TCP over IPv6, and reserve further for SCTP, and IPv6
fragmentation. Define CSUM_DELAY_DATA_IPV6 as we do for legacy IP and
add an alias for CSUM_DATA_VALID_IPV6.
This pretty much brings IPv6 handling in line with IPv4.
TSO is still handled in a different way and not via if_hwassist.
Update ifconfig to allow (un)setting of the new capability flags.
Update loopback to announce the new capabilities and if_hwassist flags.
Individual driver updates will have to follow, as will SCTP.
Reported by: gallatin, dim, ..
Reviewed by: gallatin (glanced at?)
MFC after: 3 days
X-MFC with: r235961,235959,235958
Notes
Notes:
svn path=/head/; revision=236170
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/ip6_forward.c | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_ipsec.c | 1 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 18 | ||||
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 4 |
4 files changed, 16 insertions, 15 deletions
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index dfecdc1a483a..93c7bf211237 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -581,9 +581,9 @@ skip_routing: m->m_flags |= M_FASTFWD_OURS; if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP @@ -601,9 +601,9 @@ skip_routing: if (m->m_flags & M_FASTFWD_OURS) { if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index e8689172dbb4..757f1cc7b528 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -291,6 +291,7 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, /* * Do delayed checksums now because we send before * this is done in the normal processing path. + * XXX-BZ CSUM_DELAY_DATA_IPV6? */ if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { ipseclog((LOG_DEBUG, diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index ec2d9bdcc839..fddb45b5276f 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -190,7 +190,7 @@ in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset) u_short csum; csum = in_cksum_skip(m, offset + plen, offset); - if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0) + if (m->m_pkthdr.csum_flags & CSUM_UDP_IPV6 && csum == 0) csum = 0xffff; offset += m->m_pkthdr.csum_data; /* checksum offset */ @@ -885,9 +885,9 @@ again: m->m_flags |= M_FASTFWD_OURS; if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP @@ -905,9 +905,9 @@ again: if (m->m_flags & M_FASTFWD_OURS) { if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP @@ -960,8 +960,8 @@ passout: * XXX-BZ Need a framework to know when the NIC can handle it, even * with ext. hdrs. */ - if (sw_csum & CSUM_DELAY_DATA) { - sw_csum &= ~CSUM_DELAY_DATA; + if (sw_csum & CSUM_DELAY_DATA_IPV6) { + sw_csum &= ~CSUM_DELAY_DATA_IPV6; in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr)); } #ifdef SCTP @@ -1076,9 +1076,9 @@ passout: * fragmented packets, then do it here. * XXX-BZ handle the hw offloading case. Need flags. */ - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { in6_delayed_cksum(m, plen, hlen); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; } #ifdef SCTP if (m->m_pkthdr.csum_flags & CSUM_SCTP) { diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 9d10dee90cdf..c43d958f0826 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -230,7 +230,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) goto badunlocked; } - if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { + if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) uh_sum = m->m_pkthdr.csum_data; else @@ -784,7 +784,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, ip6->ip6_dst = *faddr; udp6->uh_sum = in6_cksum_pseudo(ip6, plen, IPPROTO_UDP, 0); - m->m_pkthdr.csum_flags = CSUM_UDP; + m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); flags = 0; |