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
--- 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;
--- 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_ */
--- 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_) */
--- 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