Mon Mar 16 12:02:00 2009 UTC ()
Fix a bug in calculation of checksum deduction:
- To get 16 bit one's complement value from uint32_t variable,
  higher 16 bits should be ignored.
- RFC 1624 describes methods to recalculate checksum field in headers,
  i.e. one's complement of one's complement sum that could be 0x0000,
  but we don't have to use the strategy to deduct one's complement sum
  itself which won't be zero but should be 0xffff.

Found on debugging mec(4) on sgimips O2.


(tsutsui)
diff -r1.82 -r1.83 src/sys/dev/ic/gem.c
diff -r1.72 -r1.73 src/sys/dev/ic/hme.c

cvs diff -r1.82 -r1.83 src/sys/dev/ic/gem.c (expand / switch to context diff)
--- src/sys/dev/ic/gem.c 2009/03/14 21:04:19 1.82
+++ src/sys/dev/ic/gem.c 2009/03/16 12:02:00 1.83
@@ -1,4 +1,4 @@
-/*	$NetBSD: gem.c,v 1.82 2009/03/14 21:04:19 dsl Exp $ */
+/*	$NetBSD: gem.c,v 1.83 2009/03/16 12:02:00 tsutsui Exp $ */
 
 /*
  *
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.82 2009/03/14 21:04:19 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.83 2009/03/16 12:02:00 tsutsui Exp $");
 
 #include "opt_inet.h"
 #include "bpfilter.h"
@@ -1844,9 +1844,8 @@
 					optsum = (optsum >> 16) +
 						 (optsum & 0xffff);
 
-				/* Deduct ip opts sum from hwsum (rfc 1624). */
-				m->m_pkthdr.csum_data =
-					~((~m->m_pkthdr.csum_data) - ~optsum);
+				/* Deduct ip opts sum from hwsum. */
+				m->m_pkthdr.csum_data += (uint16_t)~optsum;
 
 				while (m->m_pkthdr.csum_data >> 16)
 					m->m_pkthdr.csum_data =

cvs diff -r1.72 -r1.73 src/sys/dev/ic/hme.c (expand / switch to context diff)
--- src/sys/dev/ic/hme.c 2009/03/14 21:04:20 1.72
+++ src/sys/dev/ic/hme.c 2009/03/16 12:02:00 1.73
@@ -1,4 +1,4 @@
-/*	$NetBSD: hme.c,v 1.72 2009/03/14 21:04:20 dsl Exp $	*/
+/*	$NetBSD: hme.c,v 1.73 2009/03/16 12:02:00 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.72 2009/03/14 21:04:20 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.73 2009/03/16 12:02:00 tsutsui Exp $");
 
 /* #define HMEDEBUG */
 
@@ -797,9 +797,8 @@
 			while (optsum >> 16)
 				optsum = (optsum >> 16) + (optsum & 0xffff);
 
-			/* Deduct the ip opts sum from the hwsum (rfc 1624). */
-			m0->m_pkthdr.csum_data = ~((~m0->m_pkthdr.csum_data) -
-						   ~optsum);
+			/* Deduct the ip opts sum from the hwsum. */
+			m0->m_pkthdr.csum_data += (uint16_t)~optsum;
 
 			while (m0->m_pkthdr.csum_data >> 16)
 				m0->m_pkthdr.csum_data =