Subject: kern/27079: ipf marks fastrouted packets for hw checksum offload incorrectly
To: None <gnats-bugs@gnats.netbsd.org>
From: None <bad@bsd.de>
List: netbsd-bugs
Date: 09/29/2004 16:42:49
>Number:         27079
>Category:       kern
>Synopsis:       ipf marks fastrouted packets for hw checksum offload incorrectly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 29 14:43:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Christoph Badura
>Release:        NetBSD 2.0_BETA
>Organization:
	
>Environment:
	
NetBSD ghost 2.0_BETA NetBSD 2.0_BETA (ghost) #1: Mon Sep 20 18:34:01 CEST 2004 sebastian@ghost:/usr/src/sys/arch/i386/compile/ghost i386

>Description:

netinet/ip_fil_netbsd.c:fr_fastroute() has the following code:

		if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
			m->m_pkthdr.csuminfo |= M_CSUM_IPv4;
		else if (ip->ip_sum == 0)
			ip->ip_sum = in_cksum(m, hlen);

That marks the fast-routed packet for checksum offload on the interface
regardless whether checksum offload has been enabled on that interface
or not.

The IPF 3.x code almost got this correct with the following code in
netinet/ip_fil.c:

		if (ifp->if_csum_flags_tx & IFCAP_CSUM_IPv4)
			m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
		else if (ip->ip_sum == 0)
			ip->ip_sum = in_cksum(m, hlen);

Except, of course, it should have checked for M_CSUM_IPv4 instead of
IFCAP_CSUM_IPv4.

>How-To-Repeat:
	code inspection
>Fix:
Apply the following patch to sys/netinet/ip_fil_netbsd.c.

--- ip_fil_netbsd.c,0	2004-09-11 13:25:43.000000000 +0200
+++ ip_fil_netbsd.c	2004-09-29 12:38:35.000000000 +0200
@@ -1159,8 +1159,13 @@
 		ip->ip_len = htons(ip->ip_len);
 		ip->ip_off = htons(ip->ip_off);
 #if defined(M_CSUM_IPv4)
+#  if (__NetBSD_Version__ >= 105009999)
+		if (ifp->if_csum_flags_tx & M_CSUM_IPv4)
+			m->m_pkthdr.csuminfo |= M_CSUM_IPv4;
+#  else
 		if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
 			m->m_pkthdr.csuminfo |= M_CSUM_IPv4;
+#  endif /* (__NetBSD_Version__ >= 105009999) */
 		else if (ip->ip_sum == 0)
 			ip->ip_sum = in_cksum(m, hlen);
 #else

>Release-Note:
>Audit-Trail:
>Unformatted: