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.
This commit is contained in:
tsutsui 2009-03-16 12:02:00 +00:00
parent b8c79d033f
commit 24a0836984
2 changed files with 8 additions and 10 deletions

View File

@ -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 @@ gem_rint(struct gem_softc *sc)
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 =

View File

@ -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 @@ hme_get(struct hme_softc *sc, int ri, u_int32_t flags)
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 =