Mon Apr 25 22:20:59 2011 UTC ()
undefer csum in looutput.
looutput is used by various code (ether_output, mcast) to loopback packets.


(yamt)
diff -r1.72 -r1.73 src/sys/net/if_loop.c
diff -r1.7 -r1.8 src/sys/netinet/in_offload.h
diff -r1.6 -r1.7 src/sys/netinet6/in6_offload.h
diff -r1.139 -r1.140 src/sys/netinet6/ip6_output.c

cvs diff -r1.72 -r1.73 src/sys/net/if_loop.c (expand / switch to context diff)
--- src/sys/net/if_loop.c 2010/04/05 07:22:23 1.72
+++ src/sys/net/if_loop.c 2011/04/25 22:20:59 1.73
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_loop.c,v 1.72 2010/04/05 07:22:23 joerg Exp $	*/
+/*	$NetBSD: if_loop.c,v 1.73 2011/04/25 22:20:59 yamt Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.72 2010/04/05 07:22:23 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.73 2011/04/25 22:20:59 yamt Exp $");
 
 #include "opt_inet.h"
 #include "opt_atalk.h"
@@ -94,6 +94,7 @@
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
+#include <netinet/in_offload.h>
 #include <netinet/ip.h>
 #endif
 
@@ -102,10 +103,10 @@
 #include <netinet/in.h>
 #endif
 #include <netinet6/in6_var.h>
+#include <netinet6/in6_offload.h>
 #include <netinet/ip6.h>
 #endif
 
-
 #ifdef IPX
 #include <netipx/ipx.h>
 #include <netipx/ipx_if.h>
@@ -212,6 +213,7 @@
 {
 	int s, isr;
 	struct ifqueue *ifq = NULL;
+	int csum_flags;
 
 	MCLAIM(m, ifp->if_mowner);
 	if ((m->m_flags & M_PKTHDR) == 0)
@@ -264,12 +266,25 @@
 
 #ifdef INET
 	case AF_INET:
+		csum_flags = m->m_pkthdr.csum_flags;
+		KASSERT((csum_flags & ~(M_CSUM_IPv4|M_CSUM_UDPv4)) == 0);
+		if (csum_flags != 0 && IN_LOOPBACK_NEED_CHECKSUM(csum_flags)) {
+			ip_undefer_csum(m, 0, csum_flags);
+		}
+		m->m_pkthdr.csum_flags = 0;
 		ifq = &ipintrq;
 		isr = NETISR_IP;
 		break;
 #endif
 #ifdef INET6
 	case AF_INET6:
+		csum_flags = m->m_pkthdr.csum_flags;
+		KASSERT((csum_flags & ~M_CSUM_UDPv6) == 0);
+		if (csum_flags != 0 &&
+		    IN6_LOOPBACK_NEED_CHECKSUM(csum_flags)) {
+			ip6_undefer_csum(m, 0, csum_flags);
+		}
+		m->m_pkthdr.csum_flags = 0;
 		m->m_flags |= M_LOOP;
 		ifq = &ip6intrq;
 		isr = NETISR_IPV6;

cvs diff -r1.7 -r1.8 src/sys/netinet/in_offload.h (expand / switch to context diff)
--- src/sys/netinet/in_offload.h 2010/12/11 22:37:46 1.7
+++ src/sys/netinet/in_offload.h 2011/04/25 22:20:59 1.8
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_offload.h,v 1.7 2010/12/11 22:37:46 matt Exp $	*/
+/*	$NetBSD: in_offload.h,v 1.8 2011/04/25 22:20:59 yamt Exp $	*/
 
 /*-
  * Copyright (c)2005, 2006 YAMAMOTO Takashi,
@@ -48,10 +48,13 @@
 extern int tcp_do_loopback_cksum; /* do TCP checksum on loopback? */
 extern int udp_do_loopback_cksum; /* do UDP checksum on loopback? */
 
+#define	IN_LOOPBACK_NEED_CHECKSUM(csum_flags) \
+	((((csum_flags) & M_CSUM_UDPv4) != 0 && udp_do_loopback_cksum) || \
+	(((csum_flags) & M_CSUM_TCPv4) != 0 && tcp_do_loopback_cksum) || \
+	(((csum_flags) & M_CSUM_IPv4) != 0 && ip_do_loopback_cksum))
+
 #define	IN_NEED_CHECKSUM(ifp, csum_flags) \
 	(__predict_true(((ifp)->if_flags & IFF_LOOPBACK) == 0 || \
-	(((csum_flags) & M_CSUM_UDPv4) != 0 && udp_do_loopback_cksum) || \
-	(((csum_flags) & M_CSUM_TCPv4) != 0 && tcp_do_loopback_cksum) || \
-	(((csum_flags) & M_CSUM_IPv4) != 0 && ip_do_loopback_cksum)))
+	IN_LOOPBACK_NEED_CHECKSUM(csum_flags)))
 
 #endif /* !_NETINET_IN_OFFLOAD_H_ */

cvs diff -r1.6 -r1.7 src/sys/netinet6/in6_offload.h (expand / switch to context diff)
--- src/sys/netinet6/in6_offload.h 2010/12/11 22:37:47 1.6
+++ src/sys/netinet6/in6_offload.h 2011/04/25 22:20:59 1.7
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_offload.h,v 1.6 2010/12/11 22:37:47 matt Exp $	*/
+/*	$NetBSD: in6_offload.h,v 1.7 2011/04/25 22:20:59 yamt Exp $	*/
 
 /*-
  * Copyright (c)2005, 2006 YAMAMOTO Takashi,
@@ -37,5 +37,16 @@
 int ip6_tso_output(struct ifnet *, struct ifnet *, struct mbuf *,
     const struct sockaddr_in6 *, struct rtentry *);
 void ip6_undefer_csum(struct mbuf *, size_t, int);
+
+extern int tcp_do_loopback_cksum; /* do TCP checksum on loopback? */
+extern int udp_do_loopback_cksum; /* do UDP checksum on loopback? */
+
+#define	IN6_LOOPBACK_NEED_CHECKSUM(csum_flags) \
+	((((csum_flags) & M_CSUM_UDPv6) != 0 && udp_do_loopback_cksum) || \
+	(((csum_flags) & M_CSUM_TCPv6) != 0 && tcp_do_loopback_cksum))
+
+#define	IN6_NEED_CHECKSUM(ifp, csum_flags) \
+	(__predict_true(((ifp)->if_flags & IFF_LOOPBACK) == 0 || \
+	IN6_LOOPBACK_NEED_CHECKSUM(csum_flags)))
 
 #endif /* !defined(_NETINET6_IN6_OFFLOAD_H_) */

cvs diff -r1.139 -r1.140 src/sys/netinet6/ip6_output.c (expand / switch to context diff)
--- src/sys/netinet6/ip6_output.c 2009/05/07 21:51:47 1.139
+++ src/sys/netinet6/ip6_output.c 2011/04/25 22:20:59 1.140
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_output.c,v 1.139 2009/05/07 21:51:47 elad Exp $	*/
+/*	$NetBSD: ip6_output.c,v 1.140 2011/04/25 22:20:59 yamt Exp $	*/
 /*	$KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.139 2009/05/07 21:51:47 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.140 2011/04/25 22:20:59 yamt Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -146,11 +146,6 @@
 #ifdef RFC2292
 static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *);
 #endif
-
-#define	IN6_NEED_CHECKSUM(ifp, csum_flags) \
-	(__predict_true(((ifp)->if_flags & IFF_LOOPBACK) == 0 || \
-	(((csum_flags) & M_CSUM_UDPv6) != 0 && udp_do_loopback_cksum) || \
-	(((csum_flags) & M_CSUM_TCPv6) != 0 && tcp_do_loopback_cksum)))
 
 /*
  * IP6 output. The packet in mbuf chain m contains a skeletal IP6