From owner-freebsd-net Thu Nov 16 7:20: 0 2000 Delivered-To: freebsd-net@freebsd.org Received: from prism.flugsvamp.com (cb58709-a.mdsn1.wi.home.com [24.17.241.9]) by hub.freebsd.org (Postfix) with ESMTP id EE5A337B479; Thu, 16 Nov 2000 07:19:56 -0800 (PST) Received: (from jlemon@localhost) by prism.flugsvamp.com (8.11.0/8.11.0) id eAGFJs762592; Thu, 16 Nov 2000 09:19:54 -0600 (CST) (envelope-from jlemon) Date: Thu, 16 Nov 2000 09:19:54 -0600 From: Jonathan Lemon To: Jonathan Lemon , net@FreeBSD.org Subject: Re: Delayed checksums commit broke UDP checksum calculation Message-ID: <20001116091954.A19895@prism.flugsvamp.com> References: <20001116120936.A45755@sunbay.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0pre2i In-Reply-To: <20001116120936.A45755@sunbay.com> Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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. > 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. -- Jonathan To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message