From 1966e5b5a1c43050be44cf863defcccefad7c752 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Fri, 12 Mar 2010 22:58:52 +0000 Subject: [PATCH] The proper fix for the delayed SCTP checksum is to have the delayed function take an argument as to the offset to the SCTP header. This allows it to work for V4 and V6. This of course means changing all callers of the function to either pass the header len, if they have it, or create it (ip_hl << 2 or sizeof(ip6_hdr)). PR: 144529 MFC after: 2 weeks --- sys/dev/xen/netback/netback.c | 2 +- sys/netinet/ip_divert.c | 2 +- sys/netinet/ip_ipsec.c | 2 +- sys/netinet/ip_output.c | 4 ++-- sys/netinet/sctp_crc32.c | 4 +--- sys/netinet/sctp_crc32.h | 2 +- sys/netinet6/ip6_output.c | 2 +- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index a6111e265f58..3088ecbdd120 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -302,7 +302,7 @@ fixup_checksum(struct mbuf *m) m->m_pkthdr.csum_flags &= ~CSUM_TCP; #ifdef SCTP } else if (sw_csum & CSUM_SCTP) { - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, iphlen); sw_csum &= ~CSUM_SCTP; #endif } else { diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 7fd20f84527c..22e52bafbf2b 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -227,7 +227,7 @@ divert_packet(struct mbuf *m, int incoming) #ifdef SCTP if (m->m_pkthdr.csum_flags & CSUM_SCTP) { ip->ip_len = ntohs(ip->ip_len); - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); m->m_pkthdr.csum_flags &= ~CSUM_SCTP; ip->ip_len = htons(ip->ip_len); } diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index b49b620f3976..3465d4b5f5b5 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -342,7 +342,7 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error) } #ifdef SCTP if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) { - sctp_delayed_cksum(*m); + sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2)); (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP; } #endif diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index ca5de12384f3..dc26705bd217 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -583,7 +583,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, } #ifdef SCTP if (sw_csum & CSUM_SCTP) { - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); sw_csum &= ~CSUM_SCTP; } #endif @@ -725,7 +725,7 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, #ifdef SCTP if (m0->m_pkthdr.csum_flags & CSUM_SCTP && (if_hwassist_flags & CSUM_IP_FRAGS) == 0) { - sctp_delayed_cksum(m0); + sctp_delayed_cksum(m0, hlen); m0->m_pkthdr.csum_flags &= ~CSUM_SCTP; } #endif diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c index aeb97153855c..d9ae238835f1 100644 --- a/sys/netinet/sctp_crc32.c +++ b/sys/netinet/sctp_crc32.c @@ -127,14 +127,12 @@ sctp_calculate_cksum(struct mbuf *m, uint32_t offset) void -sctp_delayed_cksum(struct mbuf *m) +sctp_delayed_cksum(struct mbuf *m, uint32_t offset) { struct ip *ip; uint32_t checksum; - uint32_t offset; ip = mtod(m, struct ip *); - offset = ip->ip_hl << 2; checksum = sctp_calculate_cksum(m, offset); SCTP_STAT_DECR(sctps_sendhwcrc); SCTP_STAT_INCR(sctps_sendswcrc); diff --git a/sys/netinet/sctp_crc32.h b/sys/netinet/sctp_crc32.h index 44196b16abec..e66815ee5172 100644 --- a/sys/netinet/sctp_crc32.h +++ b/sys/netinet/sctp_crc32.h @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$"); #if defined(_KERNEL) || defined(__Userspace__) uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t); -void sctp_delayed_cksum(struct mbuf *); +void sctp_delayed_cksum(struct mbuf *, uint32_t offset); #endif /* _KERNEL */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index aadb51fd760a..a878aacf79ff 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -872,7 +872,7 @@ skip_ipsec2:; #ifdef SCTP sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist; if (sw_csum & CSUM_SCTP) { - sctp_delayed_cksum(m); + sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); sw_csum &= ~CSUM_SCTP; } #endif