Mon Apr 25 22:11:32 2011 UTC ()
ip_undefer_csum:
- don't forget ntohs.
- don't add hdrlen twice for l4 header offset.
- use M_CSUM_DATA_IPv4_IPHL instead of extracting it from ip header.
- simplify code.
- KNF.


(yamt)
diff -r1.4 -r1.5 src/sys/netinet/in_offload.c

cvs diff -r1.4 -r1.5 src/sys/netinet/in_offload.c (expand / switch to unified diff)

--- src/sys/netinet/in_offload.c 2011/04/14 15:53:36 1.4
+++ src/sys/netinet/in_offload.c 2011/04/25 22:11:31 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: in_offload.c,v 1.4 2011/04/14 15:53:36 yamt Exp $ */ 1/* $NetBSD: in_offload.c,v 1.5 2011/04/25 22:11:31 yamt Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c)2005, 2006 YAMAMOTO Takashi, 4 * Copyright (c)2005, 2006 YAMAMOTO Takashi,
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: in_offload.c,v 1.4 2011/04/14 15:53:36 yamt Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: in_offload.c,v 1.5 2011/04/25 22:11:31 yamt Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/mbuf.h> 33#include <sys/mbuf.h>
34 34
35#include <net/if.h> 35#include <net/if.h>
36 36
37#include <netinet/in.h> 37#include <netinet/in.h>
38#include <netinet/in_systm.h> 38#include <netinet/in_systm.h>
39#include <netinet/ip.h> 39#include <netinet/ip.h>
40#include <netinet/tcp.h> 40#include <netinet/tcp.h>
41#include <netinet/in_offload.h> 41#include <netinet/in_offload.h>
42 42
43struct ip_tso_output_args { 43struct ip_tso_output_args {
@@ -193,62 +193,64 @@ quit: @@ -193,62 +193,64 @@ quit:
193 if (hdr != NULL) { 193 if (hdr != NULL) {
194 m_freem(hdr); 194 m_freem(hdr);
195 } 195 }
196 if (m != NULL) { 196 if (m != NULL) {
197 m_freem(m); 197 m_freem(m);
198 } 198 }
199 199
200 return error; 200 return error;
201} 201}
202 202
203void 203void
204ip_undefer_csum(struct mbuf *m, size_t hdrlen, int csum_flags) 204ip_undefer_csum(struct mbuf *m, size_t hdrlen, int csum_flags)
205{ 205{
206 KASSERT(m->m_flags & M_PKTHDR); 206 const size_t iphdrlen = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
207 KASSERT((m->m_pkthdr.csum_flags & csum_flags) == csum_flags); 
208 uint16_t csum; 207 uint16_t csum;
209 uint16_t ip_len; 208 uint16_t ip_len;
210 uint16_t *csump; 209 uint16_t *csump;
211 size_t iphdrlen; 210
 211 KASSERT(m->m_flags & M_PKTHDR);
 212 KASSERT((m->m_pkthdr.csum_flags & csum_flags) == csum_flags);
212 213
213 if (__predict_true(hdrlen + sizeof(struct ip) <= m->m_len)) { 214 if (__predict_true(hdrlen + sizeof(struct ip) <= m->m_len)) {
214 struct ip *ip = (struct ip *)(mtod(m, uint8_t *) + hdrlen); 215 struct ip *ip = (struct ip *)(mtod(m, uint8_t *) + hdrlen);
 216
215 ip_len = ip->ip_len; 217 ip_len = ip->ip_len;
216 iphdrlen = ip->ip_hl << 2; 
217 csump = &ip->ip_sum; 218 csump = &ip->ip_sum;
218 } else { 219 } else {
219 uint8_t ip_vhl; 220 const size_t ip_len_offset =
220 const size_t ip_len_offset = hdrlen + offsetof(struct ip, ip_len); 221 hdrlen + offsetof(struct ip, ip_len);
221 m_copydata(m, hdrlen, sizeof(ip_vhl), &ip_vhl); 222
222 m_copydata(m, ip_len_offset, sizeof(ip_len), &ip_len); 223 m_copydata(m, ip_len_offset, sizeof(ip_len), &ip_len);
223 iphdrlen = (ip_vhl & 0x0f) << 2; 
224 csump = NULL; 224 csump = NULL;
225 } 225 }
 226 ip_len = ntohs(ip_len);
226 227
227 if (csum_flags & M_CSUM_IPv4) { 228 if (csum_flags & M_CSUM_IPv4) {
228 const size_t offset = hdrlen + offsetof(struct ip, ip_sum); 
229 csum = in4_cksum(m, 0, hdrlen, iphdrlen); 229 csum = in4_cksum(m, 0, hdrlen, iphdrlen);
230 if (csump != NULL) { 230 if (csump != NULL) {
231 *csump = csum; 231 *csump = csum;
232 } else { 232 } else {
 233 const size_t offset = hdrlen +
 234 offsetof(struct ip, ip_sum);
 235
233 m_copyback(m, offset, sizeof(uint16_t), &csum); 236 m_copyback(m, offset, sizeof(uint16_t), &csum);
234 } 237 }
235 } 238 }
236 239
237 if (csum_flags & (M_CSUM_UDPv4|M_CSUM_TCPv4)) { 240 if (csum_flags & (M_CSUM_UDPv4|M_CSUM_TCPv4)) {
238 size_t l4offset = hdrlen 241 size_t l4offset = hdrlen + iphdrlen;
239 + M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data); 
240 242
241 csum = in4_cksum(m, 0, hdrlen + l4offset, ip_len - l4offset); 243 csum = in4_cksum(m, 0, l4offset, ip_len - l4offset - hdrlen);
242 if (csum == 0 && (csum_flags & M_CSUM_UDPv4) != 0) 244 if (csum == 0 && (csum_flags & M_CSUM_UDPv4) != 0)
243 csum = 0xffff; 245 csum = 0xffff;
244 246
245 l4offset += M_CSUM_DATA_IPv4_OFFSET(m->m_pkthdr.csum_data); 247 l4offset += M_CSUM_DATA_IPv4_OFFSET(m->m_pkthdr.csum_data);
246 248
247 if (__predict_true(l4offset + sizeof(uint16_t) <= m->m_len)) { 249 if (__predict_true(l4offset + sizeof(uint16_t) <= m->m_len)) {
248 *(uint16_t *)(mtod(m, char *) + l4offset) = csum; 250 *(uint16_t *)(mtod(m, char *) + l4offset) = csum;
249 } else { 251 } else {
250 m_copyback(m, l4offset, sizeof(csum), (void *) &csum); 252 m_copyback(m, l4offset, sizeof(csum), (void *) &csum);
251 } 253 }
252 } 254 }
253 255
254 m->m_pkthdr.csum_flags ^= csum_flags; 256 m->m_pkthdr.csum_flags ^= csum_flags;