NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-mips/43882: On special condition,you get incorrect TCP checksum.
The following reply was made to PR port-mips/43882; it has been noted by GNATS.
From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: port-mips-maintainer%NetBSD.org@localhost, gnats-admin%NetBSD.org@localhost,
netbsd-bugs%NetBSD.org@localhost, tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: port-mips/43882: On special condition,you get incorrect TCP
checksum.
Date: Wed, 15 Sep 2010 19:14:43 +0900
> Apply following patch to sys/arch/mips/mips/in_cksum.c
BTW, human readable unified diff (by diff -u) is better in PRs.
> < if (n < 3){
> < /*
> < * This code is for following condition.
> < * (1)mbufs size is 2byte.
> < * (2)align is not 32-bit-align.
Your analysis looks correct, but I don't think we have to
handle unaligned two byte payload as a special case.
It's enough to fix handlings for leading/trailing unaligned words/bytes.
How about this one? (untested)
Index: in_cksum.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/in_cksum.c,v
retrieving revision 1.13
diff -u -p -r1.13 in_cksum.c
--- in_cksum.c 24 Jan 2007 13:08:11 -0000 1.13
+++ in_cksum.c 15 Sep 2010 10:02:18 -0000
@@ -56,11 +56,10 @@ __KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v
#include <machine/endian.h>
union memptr {
- unsigned int *i;
- unsigned long *l;
- unsigned long u;
- unsigned short *s;
- unsigned char *c;
+ uint32_t *l;
+ uintptr_t u;
+ uint16_t *s;
+ uint8_t *c;
};
static inline uint32_t fastsum(union memptr, int, unsigned int, int);
@@ -83,10 +82,6 @@ fastsum(union memptr buf, int n, unsigne
/* Align to 32 bits. */
if (buf.u & 0x3) {
- /* Skip to the end for very small mbufs */
- if (n < 3)
- goto verylittleleft;
-
/*
* 16-bit-align.
* If buf is odd-byte-aligned, add the byte and toggle
@@ -107,6 +102,9 @@ fastsum(union memptr buf, int n, unsigne
n -= 1;
odd_aligned = !odd_aligned;
}
+ /* Skip to the end for very small mbufs */
+ if (n <= 2)
+ goto postunaligned;
/* 32-bit-align */
if (buf.u & 0x2) {
@@ -198,7 +196,7 @@ fastsum(union memptr buf, int n, unsigne
notmuchleft:
high = hilo = 0;
- while (n >= 4) {
+ while (n >= sizeof(uint32_t)) {
w0 = *(buf.l++);
hilo += w0;
high += w0 >> 16;
@@ -208,19 +206,21 @@ fastsum(union memptr buf, int n, unsigne
sum += hilo;
sum += high;
- while (n > 1) {
- n -= sizeof(*buf.s);
+ postunaligned:
+ /* handle post 32bit unaligned payloads */
+ if (n >= sizeof(uint16_t)) {
sum += *(buf.s++);
+ n -= sizeof(uint16_t);
}
- verylittleleft:
- /* handle trailing byte and short (possibly) unaligned payloads */
- while (n-- > 0) {
+ /* handle a trailing odd byte */
+ if (n > 0) {
#if BYTE_ORDER == BIG_ENDIAN
sum += *(buf.c++) << 8;
#else
sum += *(buf.c++);
#endif
+ n = 0;
}
/*
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index