Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Mar 2001 12:31:56 +0200
From:      Ruslan Ermilov <ru@FreeBSD.ORG>
To:        Jonathan Lemon <jlemon@flugsvamp.com>
Cc:        Jonathan Lemon <jlemon@FreeBSD.ORG>, net@FreeBSD.ORG
Subject:   Re: Delayed checksums commit broke UDP checksum calculation
Message-ID:  <20010307123156.A19829@sunbay.com>
In-Reply-To: <20001116091954.A19895@prism.flugsvamp.com>; from jlemon@flugsvamp.com on Thu, Nov 16, 2000 at 09:19:54AM -0600
References:  <20001116120936.A45755@sunbay.com> <20001116091954.A19895@prism.flugsvamp.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Nov 16, 2000 at 09:19:54AM -0600, Jonathan Lemon wrote:
> On Thu, Nov 16, 2000 at 12:09:36PM +0200, Ruslan Ermilov wrote:
> > Hi!
> > 
> > RFC768> If the computed checksum is zero, it is transmitted as all ones
> > RFC768> (the equivalent in one's complement arithmetic).  An all zero
> > RFC768> transmitted checksum value means that the transmitter generated
> > RFC768> no checksum.
> > 
> > This (0x0000 -> 0xFFFF) apparently got broken in udp_usrreq.c,v 1.65.
> 
> Actually, it got broken in a different fashion; I had originally moved
> the above logic within in_cksum itself, and when that got taken out,
> the UDP case wasn't updated.
> 
Actually, the "logic move" was implemented wrong, and then got wiped
out in revision 1.21 of sys/i386/i386/in_cksum.c.

Also, you MFC'ed this fix for i386, but did not for alpha.
(sys/alpha/alpha/in_cksum.c,v 1.5).

> > Index: ip_output.c
> > ===================================================================
> > RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
> > retrieving revision 1.116
> > diff -u -p -r1.116 ip_output.c
> > --- ip_output.c	2000/11/01 01:59:28	1.116
> > +++ ip_output.c	2000/11/16 10:05:06
> > @@ -974,6 +974,8 @@ in_delayed_cksum(struct mbuf *m)
> >  	ip = mtod(m, struct ip *);
> >  	offset = IP_VHL_HL(ip->ip_vhl) << 2 ;
> >  	csum = in_cksum_skip(m, ip->ip_len, offset);
> > +	if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0)
> > +		csum = 0xffff;			/* per RFC768 */
> >  	offset += m->m_pkthdr.csum_data;	/* checksum offset */
> >  
> >  	if (offset + sizeof(u_short) > m->m_len) {
> 
> 
> This would work.  Alternatively, you could change it to:
> 
> 	if (csum == 0)
> 		csum = 0xffff;
> 
> So that the same logic applies to TCP packets as well.  Currently, we
> can send a TCP packet with a checksum of 0, which is legal.  Of possible
> interest is that Linux doesn't do this; they alwyas send a non-zero
> checksum in the TCP case, if a checksum was computed.
> 
Hmm, but why would we do this for TCP?  This violates RFC 793.
AFAIK, only UDP checksums are special.


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010307123156.A19829>