Module Name:    src
Committed By:   riz
Date:           Sun Dec 16 18:19:53 UTC 2012

Modified Files:
        src/sys/net/npf [netbsd-6]: npf.h npf_inet.c npf_mbuf.c

Log Message:
Pull up following revision(s) (requested by rmind in ticket #746):
        sys/net/npf/npf_inet.c: revision 1.18
        sys/net/npf/npf_mbuf.c: revision 1.8
        sys/net/npf/npf.h: revision 1.23
npf_rwrcksum: handle delayed checksums in the network stack; also fix
non-NPF_NAT_PORTS case and add some comments.  PR/47235.


To generate a diff of this commit:
cvs rdiff -u -r1.14.2.8 -r1.14.2.9 src/sys/net/npf/npf.h
cvs rdiff -u -r1.10.4.6 -r1.10.4.7 src/sys/net/npf/npf_inet.c
cvs rdiff -u -r1.6.14.1 -r1.6.14.2 src/sys/net/npf/npf_mbuf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/npf/npf.h
diff -u src/sys/net/npf/npf.h:1.14.2.8 src/sys/net/npf/npf.h:1.14.2.9
--- src/sys/net/npf/npf.h:1.14.2.8	Sat Nov 24 04:34:42 2012
+++ src/sys/net/npf/npf.h	Sun Dec 16 18:19:52 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.14.2.8 2012/11/24 04:34:42 riz Exp $	*/
+/*	$NetBSD: npf.h,v 1.14.2.9 2012/12/16 18:19:52 riz Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -146,6 +146,7 @@ int		nbuf_advstore(nbuf_t **, void **, u
 int		nbuf_fetch_datum(nbuf_t *, void *, size_t, void *);
 int		nbuf_store_datum(nbuf_t *, void *, size_t, void *);
 
+void		nbuf_cksum_barrier(nbuf_t *);
 int		nbuf_add_tag(nbuf_t *, uint32_t, uint32_t);
 int		nbuf_find_tag(nbuf_t *, uint32_t, void **);
 

Index: src/sys/net/npf/npf_inet.c
diff -u src/sys/net/npf/npf_inet.c:1.10.4.6 src/sys/net/npf/npf_inet.c:1.10.4.7
--- src/sys/net/npf/npf_inet.c:1.10.4.6	Sun Nov 18 22:38:25 2012
+++ src/sys/net/npf/npf_inet.c	Sun Dec 16 18:19:52 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_inet.c,v 1.10.4.6 2012/11/18 22:38:25 riz Exp $	*/
+/*	$NetBSD: npf_inet.c,v 1.10.4.7 2012/12/16 18:19:52 riz Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.10.4.6 2012/11/18 22:38:25 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.10.4.7 2012/12/16 18:19:52 riz Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -597,65 +597,80 @@ npf_rwrcksum(npf_cache_t *npc, nbuf_t *n
 {
 	const int proto = npf_cache_ipproto(npc);
 	npf_addr_t *oaddr;
-	in_port_t *oport;
-	uint16_t *cksum;
+	uint16_t *ocksum;
+	in_port_t oport;
 	u_int offby;
 
-	/* Checksum update for IPv4 header. */
+	/* XXX: NetBSD - process delayed checksums. */
+	if (di == PFIL_OUT && proto != IPPROTO_ICMP) {
+		nbuf_cksum_barrier(nbuf);
+		npc->npc_info &= ~(NPC_LAYER4 | NPC_TCP | NPC_UDP);
+		if (!npf_cache_all(npc, nbuf)) {
+			return false;
+		}
+	}
+
+	oaddr = (di == PFIL_OUT) ? npc->npc_srcip : npc->npc_dstip;
+
 	if (npf_iscached(npc, NPC_IP4)) {
 		struct ip *ip = &npc->npc_ip.v4;
 		uint16_t ipsum;
 
-		oaddr = (di == PFIL_OUT) ? npc->npc_srcip : npc->npc_dstip;
+		/* Recalculate IPv4 checksum, advance to it and rewrite. */
 		ipsum = npf_addr_cksum(ip->ip_sum, npc->npc_alen, oaddr, addr);
-
-		/* Advance to the IPv4 checksum and rewrite it. */
 		offby = offsetof(struct ip, ip_sum);
 		if (nbuf_advstore(&nbuf, &n_ptr, offby, sizeof(ipsum), &ipsum))
 			return false;
-
 		ip->ip_sum = ipsum;
-		offby = npf_cache_hlen(npc) - offby;
 	} else {
 		/* No checksum for IPv6. */
 		KASSERT(npf_iscached(npc, NPC_IP6));
-		oaddr = NULL;
 		offby = 0;
-		return false;	/* XXX: Not yet supported. */
 	}
 
-	/* Determine whether TCP/UDP checksum update is needed. */
-	if (proto == IPPROTO_ICMP || port == 0) {
+	/* Nothing else to do for ICMP. */
+	if (proto == IPPROTO_ICMP) {
 		return true;
 	}
 	KASSERT(npf_iscached(npc, NPC_TCP) || npf_iscached(npc, NPC_UDP));
+	offby = npf_cache_hlen(npc) - offby;
 
-	/* Calculate TCP/UDP checksum. */
+	/*
+	 * Calculate TCP/UDP checksum:
+	 * - Skip if UDP and the current checksum is zero.
+	 * - Fixup the IP address change.
+	 * - Fixup the port change, if required (non-zero).
+	 */
 	if (proto == IPPROTO_TCP) {
 		struct tcphdr *th = &npc->npc_l4.tcp;
 
-		cksum = &th->th_sum;
+		ocksum = &th->th_sum;
 		offby += offsetof(struct tcphdr, th_sum);
-		oport = (di == PFIL_OUT) ? &th->th_sport : &th->th_dport;
+		oport = (di == PFIL_OUT) ? th->th_sport : th->th_dport;
 	} else {
 		struct udphdr *uh = &npc->npc_l4.udp;
 
 		KASSERT(proto == IPPROTO_UDP);
-		cksum = &uh->uh_sum;
-		if (*cksum == 0) {
+		ocksum = &uh->uh_sum;
+		if (*ocksum == 0) {
 			/* No need to update. */
 			return true;
 		}
 		offby += offsetof(struct udphdr, uh_sum);
-		oport = (di == PFIL_OUT) ? &uh->uh_sport : &uh->uh_dport;
+		oport = (di == PFIL_OUT) ? uh->uh_sport : uh->uh_dport;
+	}
+
+	uint16_t cksum = *ocksum;
+	cksum = npf_addr_cksum(cksum, npc->npc_alen, oaddr, addr);
+	if (port) {
+		cksum = npf_fixup16_cksum(cksum, oport, port);
 	}
-	*cksum = npf_addr_cksum(*cksum, npc->npc_alen, oaddr, addr);
-	*cksum = npf_fixup16_cksum(*cksum, *oport, port);
 
 	/* Advance to TCP/UDP checksum and rewrite it. */
-	if (nbuf_advstore(&nbuf, &n_ptr, offby, sizeof(uint16_t), cksum)) {
+	if (nbuf_advstore(&nbuf, &n_ptr, offby, sizeof(cksum), &cksum)) {
 		return false;
 	}
+	*ocksum = cksum;
 	return true;
 }
 

Index: src/sys/net/npf/npf_mbuf.c
diff -u src/sys/net/npf/npf_mbuf.c:1.6.14.1 src/sys/net/npf/npf_mbuf.c:1.6.14.2
--- src/sys/net/npf/npf_mbuf.c:1.6.14.1	Tue Jun 26 00:07:16 2012
+++ src/sys/net/npf/npf_mbuf.c	Sun Dec 16 18:19:52 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_mbuf.c,v 1.6.14.1 2012/06/26 00:07:16 riz Exp $	*/
+/*	$NetBSD: npf_mbuf.c,v 1.6.14.2 2012/12/16 18:19:52 riz Exp $	*/
 
 /*-
  * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.6.14.1 2012/06/26 00:07:16 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.6.14.2 2012/12/16 18:19:52 riz Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -233,6 +233,17 @@ nbuf_advstore(nbuf_t **nbuf, void **n_pt
 	return error;
 }
 
+void
+nbuf_cksum_barrier(nbuf_t *nbuf)
+{
+	struct mbuf *m = nbuf;
+
+	if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
+		in_delayed_cksum(m);
+		m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4 | M_CSUM_UDPv4);
+	}
+}
+
 /*
  * nbuf_add_tag: add a tag to specified network buffer.
  *

Reply via email to