Module Name:    src
Committed By:   rmind
Date:           Sun Dec 10 00:07:36 UTC 2017

Modified Files:
        src/sys/net/npf: npf_alg_icmp.c npf_bpf.c npf_conn.c npf_conn.h
            npf_ext_normalize.c

Log Message:
- npf_cop_table: handle non-IP packets in the ether (fixes PR/52290).
- npfa_icmp_nat: do not recompute the checksum if no port translation.
- npf_normalize (MSS clamping): fix the checksum handling on PFIL_OUT.
- npflog: report the packet direction correctly.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/net/npf/npf_alg_icmp.c
cvs rdiff -u -r1.12 -r1.13 src/sys/net/npf/npf_bpf.c \
    src/sys/net/npf/npf_conn.h
cvs rdiff -u -r1.23 -r1.24 src/sys/net/npf/npf_conn.c
cvs rdiff -u -r1.5 -r1.6 src/sys/net/npf/npf_ext_normalize.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_alg_icmp.c
diff -u src/sys/net/npf/npf_alg_icmp.c:1.24 src/sys/net/npf/npf_alg_icmp.c:1.25
--- src/sys/net/npf/npf_alg_icmp.c:1.24	Mon Dec 26 23:05:06 2016
+++ src/sys/net/npf/npf_alg_icmp.c	Sun Dec 10 00:07:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_alg_icmp.c,v 1.24 2016/12/26 23:05:06 christos Exp $	*/
+/*	$NetBSD: npf_alg_icmp.c,v 1.25 2017/12/10 00:07:36 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.24 2016/12/26 23:05:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.25 2017/12/10 00:07:36 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/module.h>
@@ -336,31 +336,25 @@ npfa_icmp_nat(npf_cache_t *npc, npf_nat_
 	/*
 	 * Fetch the IP and port in the _embedded_ packet.  Also, fetch
 	 * the IPv4 and TCP/UDP checksums before they are rewritten.
-	 * Calculate the part of the ICMP checksum fixup.
 	 */
 	const int proto = enpc.npc_proto;
 	uint16_t ipcksum = 0, l4cksum = 0;
-	npf_addr_t *addr;
-	in_port_t port;
-
-	npf_nat_getorig(nt, &addr, &port);
+	in_port_t old_port = 0;
 
 	if (npf_iscached(&enpc, NPC_IP4)) {
 		const struct ip *eip = enpc.npc_ip.v4;
 		ipcksum = eip->ip_sum;
 	}
-	cksum = npf_addr_cksum(cksum, enpc.npc_alen, enpc.npc_ips[which], addr);
-
 	switch (proto) {
 	case IPPROTO_TCP: {
 		const struct tcphdr *th = enpc.npc_l4.tcp;
-		cksum = npf_fixup16_cksum(cksum, th->th_sport, port);
+		old_port = th->th_sport;
 		l4cksum = th->th_sum;
 		break;
 	}
 	case IPPROTO_UDP: {
 		const struct udphdr *uh = enpc.npc_l4.udp;
-		cksum = npf_fixup16_cksum(cksum, uh->uh_sport, port);
+		old_port = uh->uh_sport;
 		l4cksum = uh->uh_sum;
 		break;
 	}
@@ -372,6 +366,20 @@ npfa_icmp_nat(npf_cache_t *npc, npf_nat_
 	}
 
 	/*
+	 * Get the original IP address and port.
+	 * Calculate the part of the ICMP checksum fixup.
+	 */
+	npf_addr_t *addr;
+	in_port_t port;
+
+	npf_nat_getorig(nt, &addr, &port);
+
+	cksum = npf_addr_cksum(cksum, enpc.npc_alen, enpc.npc_ips[which], addr);
+	if (port) {
+		cksum = npf_fixup16_cksum(cksum, old_port, port);
+	}
+
+	/*
 	 * Translate the embedded packet.  The following changes will
 	 * be performed by npf_napt_rwr():
 	 *

Index: src/sys/net/npf/npf_bpf.c
diff -u src/sys/net/npf/npf_bpf.c:1.12 src/sys/net/npf/npf_bpf.c:1.13
--- src/sys/net/npf/npf_bpf.c:1.12	Mon Dec 26 23:05:06 2016
+++ src/sys/net/npf/npf_bpf.c	Sun Dec 10 00:07:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_bpf.c,v 1.12 2016/12/26 23:05:06 christos Exp $	*/
+/*	$NetBSD: npf_bpf.c,v 1.13 2017/12/10 00:07:36 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.12 2016/12/26 23:05:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.13 2017/12/10 00:07:36 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -181,9 +181,11 @@ npf_cop_table(const bpf_ctx_t *bc, bpf_a
 	const npf_addr_t *addr;
 	npf_table_t *t;
 
-	KASSERT(npf_iscached(npc, NPC_IP46));
-
-	if ((t = npf_tableset_getbyid(tblset, tid)) == NULL) {
+	if (!npf_iscached(npc, NPC_IP46)) {
+		return 0;
+	}
+	t = npf_tableset_getbyid(tblset, tid);
+	if (__predict_false(!t)) {
 		return 0;
 	}
 	addr = npc->npc_ips[(A & SRC_FLAG_BIT) ? NPF_SRC : NPF_DST];
Index: src/sys/net/npf/npf_conn.h
diff -u src/sys/net/npf/npf_conn.h:1.12 src/sys/net/npf/npf_conn.h:1.13
--- src/sys/net/npf/npf_conn.h:1.12	Sun Jan 29 00:15:54 2017
+++ src/sys/net/npf/npf_conn.h	Sun Dec 10 00:07:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.h,v 1.12 2017/01/29 00:15:54 christos Exp $	*/
+/*	$NetBSD: npf_conn.h,v 1.13 2017/12/10 00:07:36 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -88,7 +88,12 @@ struct npf_conn {
 	npf_state_t		c_state;
 	u_int			c_refcnt;
 	uint64_t		c_atime;
-	npf_match_info_t	c_mi;
+
+	/*
+	 * Save the matching rule ID and flags.
+	 */
+	uint64_t		c_rid;
+	u_int			c_retfl;
 };
 
 #endif

Index: src/sys/net/npf/npf_conn.c
diff -u src/sys/net/npf/npf_conn.c:1.23 src/sys/net/npf/npf_conn.c:1.24
--- src/sys/net/npf/npf_conn.c:1.23	Sun Jan 29 00:15:54 2017
+++ src/sys/net/npf/npf_conn.c	Sun Dec 10 00:07:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.c,v 1.23 2017/01/29 00:15:54 christos Exp $	*/
+/*	$NetBSD: npf_conn.c,v 1.24 2017/12/10 00:07:36 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2014-2015 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -100,7 +100,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.23 2017/01/29 00:15:54 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.24 2017/12/10 00:07:36 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -727,7 +727,8 @@ npf_conn_pass(const npf_conn_t *con, npf
 {
 	KASSERT(con->c_refcnt > 0);
 	if (__predict_true(con->c_flags & CONN_PASS)) {
-		*mi = con->c_mi;
+		mi->mi_rid = con->c_rid;
+		mi->mi_retfl = con->c_retfl;
 		*rp = con->c_rproc;
 		return true;
 	}
@@ -752,8 +753,10 @@ npf_conn_setpass(npf_conn_t *con, const 
 	 */
 	atomic_or_uint(&con->c_flags, CONN_PASS);
 	con->c_rproc = rp;
-	if (rp)
-		con->c_mi = *mi;
+	if (rp) {
+		con->c_rid = mi->mi_rid;
+		con->c_retfl = mi->mi_retfl;
+	}
 }
 
 /*

Index: src/sys/net/npf/npf_ext_normalize.c
diff -u src/sys/net/npf/npf_ext_normalize.c:1.5 src/sys/net/npf/npf_ext_normalize.c:1.6
--- src/sys/net/npf/npf_ext_normalize.c:1.5	Sun Jan 29 00:15:54 2017
+++ src/sys/net/npf/npf_ext_normalize.c	Sun Dec 10 00:07:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ext_normalize.c,v 1.5 2017/01/29 00:15:54 christos Exp $	*/
+/*	$NetBSD: npf_ext_normalize.c,v 1.6 2017/12/10 00:07:36 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.5 2017/01/29 00:15:54 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.6 2017/12/10 00:07:36 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/module.h>
@@ -147,8 +147,8 @@ npf_normalize(npf_cache_t *npc, void *pa
     int *decision)
 {
 	npf_normalize_t *np = params;
-	struct tcphdr *th = npc->npc_l4.tcp;
 	uint16_t cksum, mss, maxmss = np->n_maxmss;
+	struct tcphdr *th;
 	int wscale;
 
 	/* Skip, if already blocking. */
@@ -160,6 +160,7 @@ npf_normalize(npf_cache_t *npc, void *pa
 	if (npf_iscached(npc, NPC_IP4) && (np->n_random_id || np->n_minttl)) {
 		npf_normalize_ip4(npc, np);
 	}
+	th = npc->npc_l4.tcp;
 
 	/*
 	 * TCP Maximum Segment Size (MSS) "clamping".  Only if SYN packet.
@@ -180,8 +181,13 @@ npf_normalize(npf_cache_t *npc, void *pa
 	}
 	maxmss = htons(maxmss);
 
-	/* Store new MSS, calculate TCP checksum and update it. */
-	if (npf_fetch_tcpopts(npc, &maxmss, &wscale)) {
+	/*
+	 * Store new MSS, calculate TCP checksum and update it.
+	 * WARNING: must re-fetch the TCP header after the modification.
+	 */
+	if (npf_fetch_tcpopts(npc, &maxmss, &wscale) &&
+	    nbuf_cksum_barrier(npc->npc_nbuf, mi->mi_di)) {
+		th = npc->npc_l4.tcp;
 		cksum = npf_fixup16_cksum(th->th_sum, mss, maxmss);
 		th->th_sum = cksum;
 	}

Reply via email to