Module Name:    src
Committed By:   rmind
Date:           Fri Mar 14 11:29:45 UTC 2014

Modified Files:
        src/sys/net/npf: npf.h npf_handler.c npf_impl.h npf_nat.c npf_session.c
        src/usr.sbin/npf/npfctl: npf_parse.y npf_scan.l npf_show.c

Log Message:
NPF: add support for "stateful-ends".


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/sys/net/npf/npf.h
cvs rdiff -u -r1.28 -r1.29 src/sys/net/npf/npf_handler.c
cvs rdiff -u -r1.49 -r1.50 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.26 -r1.27 src/sys/net/npf/npf_nat.c
cvs rdiff -u -r1.30 -r1.31 src/sys/net/npf/npf_session.c
cvs rdiff -u -r1.33 -r1.34 src/usr.sbin/npf/npfctl/npf_parse.y
cvs rdiff -u -r1.19 -r1.20 src/usr.sbin/npf/npfctl/npf_scan.l
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/npf/npfctl/npf_show.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.37 src/sys/net/npf/npf.h:1.38
--- src/sys/net/npf/npf.h:1.37	Thu Feb 13 03:34:40 2014
+++ src/sys/net/npf/npf.h	Fri Mar 14 11:29:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.37 2014/02/13 03:34:40 rmind Exp $	*/
+/*	$NetBSD: npf.h,v 1.38 2014/03/14 11:29:44 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -210,6 +210,7 @@ bool		npf_autounload_p(void);
 #define	NPF_RULE_RETRST			0x0010
 #define	NPF_RULE_RETICMP		0x0020
 #define	NPF_RULE_DYNAMIC		0x0040
+#define	NPF_RULE_MULTIENDS		0x0080
 
 #define	NPF_DYNAMIC_GROUP		(NPF_RULE_GROUP | NPF_RULE_DYNAMIC)
 

Index: src/sys/net/npf/npf_handler.c
diff -u src/sys/net/npf/npf_handler.c:1.28 src/sys/net/npf/npf_handler.c:1.29
--- src/sys/net/npf/npf_handler.c:1.28	Fri Nov  8 00:38:26 2013
+++ src/sys/net/npf/npf_handler.c	Fri Mar 14 11:29:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_handler.c,v 1.28 2013/11/08 00:38:26 rmind Exp $	*/
+/*	$NetBSD: npf_handler.c,v 1.29 2014/03/14 11:29:44 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.28 2013/11/08 00:38:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.29 2014/03/14 11:29:44 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -229,7 +229,8 @@ npf_packet_handler(void *arg, struct mbu
 	 * if session creation fails (e.g. due to unsupported protocol).
 	 */
 	if ((retfl & NPF_RULE_STATEFUL) != 0 && !se) {
-		se = npf_session_establish(&npc, &nbuf, di);
+		se = npf_session_establish(&npc, &nbuf, di,
+		    (retfl & NPF_RULE_MULTIENDS) == 0);
 		if (se) {
 			/*
 			 * Note: the reference on the rule procedure is

Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.49 src/sys/net/npf/npf_impl.h:1.50
--- src/sys/net/npf/npf_impl.h:1.49	Wed Feb 19 03:51:31 2014
+++ src/sys/net/npf/npf_impl.h	Fri Mar 14 11:29:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_impl.h,v 1.49 2014/02/19 03:51:31 rmind Exp $	*/
+/*	$NetBSD: npf_impl.h,v 1.50 2014/03/14 11:29:44 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -311,7 +311,7 @@ void		sess_htable_destroy(npf_sehash_t *
 npf_session_t *	npf_session_lookup(const npf_cache_t *, const nbuf_t *,
 		    const int, bool *);
 npf_session_t *	npf_session_inspect(npf_cache_t *, nbuf_t *, const int, int *);
-npf_session_t *	npf_session_establish(npf_cache_t *, nbuf_t *, const int);
+npf_session_t *	npf_session_establish(npf_cache_t *, nbuf_t *, int, bool);
 void		npf_session_release(npf_session_t *);
 void		npf_session_expire(npf_session_t *);
 bool		npf_session_pass(const npf_session_t *, npf_rproc_t **);

Index: src/sys/net/npf/npf_nat.c
diff -u src/sys/net/npf/npf_nat.c:1.26 src/sys/net/npf/npf_nat.c:1.27
--- src/sys/net/npf/npf_nat.c:1.26	Wed Feb 19 03:51:31 2014
+++ src/sys/net/npf/npf_nat.c	Fri Mar 14 11:29:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat.c,v 1.26 2014/02/19 03:51:31 rmind Exp $	*/
+/*	$NetBSD: npf_nat.c,v 1.27 2014/03/14 11:29:44 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.26 2014/02/19 03:51:31 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.27 2014/03/14 11:29:44 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -669,7 +669,7 @@ npf_do_nat(npf_cache_t *npc, npf_session
 	 * stream depends on other, stateless filtering rules.
 	 */
 	if (se == NULL) {
-		nse = npf_session_establish(npc, nbuf, di);
+		nse = npf_session_establish(npc, nbuf, di, true);
 		if (nse == NULL) {
 			atomic_dec_uint(&np->n_refcnt);
 			return ENOMEM;

Index: src/sys/net/npf/npf_session.c
diff -u src/sys/net/npf/npf_session.c:1.30 src/sys/net/npf/npf_session.c:1.31
--- src/sys/net/npf/npf_session.c:1.30	Fri Dec  6 01:33:37 2013
+++ src/sys/net/npf/npf_session.c	Fri Mar 14 11:29:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_session.c,v 1.30 2013/12/06 01:33:37 rmind Exp $	*/
+/*	$NetBSD: npf_session.c,v 1.31 2014/03/14 11:29:44 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@@ -92,7 +92,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.30 2013/12/06 01:33:37 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.31 2014/03/14 11:29:44 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -260,19 +260,12 @@ sess_rbtree_cmp_nodes(void *ctx, const v
 	const int sz = sen1->se_alen;
 	int ret;
 
-	/*
-	 * Ports are expected to vary most, therefore they are first.
-	 */
 	if (sen1->se_src_id != sen2->se_src_id) {
 		return (sen1->se_src_id < sen2->se_src_id) ? -1 : 1;
 	}
 	if (sen1->se_dst_id != sen2->se_dst_id) {
 		return (sen1->se_dst_id < sen2->se_dst_id) ? -1 : 1;
 	}
-
-	/*
-	 * Note that hash should minimise differentiation on addresses.
-	 */
 	if (sen1->se_alen != sen2->se_alen) {
 		return (sen1->se_alen < sen2->se_alen) ? -1 : 1;
 	}
@@ -285,7 +278,19 @@ sess_rbtree_cmp_nodes(void *ctx, const v
 
 	const npf_secomid_t *id1 = &sen1->se_backptr->s_common_id;
 	const npf_secomid_t *id2 = ctx ? ctx : &sen2->se_backptr->s_common_id;
-	return memcmp(id1, id2, sizeof(npf_secomid_t));
+
+	if (id1->proto != id2->proto) {
+		return (id1->proto < id2->proto) ? -1 : 1;
+	}
+
+	/*
+	 * Zero interface ID is a special case indicating a global state,
+	 * in which case we match straight away.
+	 */
+	if (id1->ifid && id1->ifid != id2->ifid) {
+		return (id1->ifid < id2->ifid) ? -1 : 1;
+	}
+	return 0;
 }
 
 static signed int
@@ -312,8 +317,7 @@ sess_hash_bucket(npf_sehash_t *stbl, con
 	const int sz = sen->se_alen;
 	uint32_t hash, mix[2];
 
-	mix[0] = (scid->proto ^ scid->ifid) << 16;
-	mix[0] |= sen->se_src_id ^ sen->se_dst_id;
+	mix[0] = (scid->proto << 16) | (sen->se_src_id ^ sen->se_dst_id);
 	mix[1] = npf_addr_mix(sz, &sen->se_src_addr, &sen->se_dst_addr);
 	hash = murmurhash2(mix, sizeof(mix), sess_hash_seed);
 
@@ -486,6 +490,7 @@ npf_session_lookup(const npf_cache_t *np
     const int di, bool *forw)
 {
 	const u_int proto = npc->npc_proto;
+	const u_int ifid = nbuf->nb_ifid;
 	npf_sentry_t senkey, *sen;
 	npf_session_t *se;
 	npf_sehash_t *sh;
@@ -505,9 +510,7 @@ npf_session_lookup(const npf_cache_t *np
 	 * Note: this is a special case where we use common ID pointer
 	 * to pass the structure for the key comparator.
 	 */
-	npf_secomid_t scid;
-	memset(&scid, 0, sizeof(npf_secomid_t));
-	scid = (npf_secomid_t){ .proto = proto, .ifid = nbuf->nb_ifid };
+	npf_secomid_t scid = { .proto = proto, .ifid = ifid };
 	senkey.se_common_id = &scid;
 
 	/*
@@ -528,7 +531,7 @@ npf_session_lookup(const npf_cache_t *np
 	}
 	se = sen->se_backptr;
 	KASSERT(se->s_common_id.proto == proto);
-	KASSERT(se->s_common_id.ifid == nbuf->nb_ifid);
+	KASSERT(se->s_common_id.ifid == 0 || se->s_common_id.ifid == ifid);
 	flags = se->s_flags;
 
 	/* Check if session is active and not expired. */
@@ -597,13 +600,13 @@ npf_session_inspect(npf_cache_t *npc, nb
 }
 
 /*
- * npf_establish_session: create a new session, insert into the global list.
+ * npf_session_establish: create a new session, insert into the global list.
  *
  * => Session is created with the reference held for the caller.
  * => Session will be activated on the first reference release.
  */
 npf_session_t *
-npf_session_establish(npf_cache_t *npc, nbuf_t *nbuf, const int di)
+npf_session_establish(npf_cache_t *npc, nbuf_t *nbuf, int di, bool per_if)
 {
 	npf_sentry_t *fw, *bk;
 	npf_sehash_t *sh;
@@ -612,6 +615,7 @@ npf_session_establish(npf_cache_t *npc, 
 	bool ok;
 
 	KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
+
 	if (!npf_session_trackable_p(npc)) {
 		return NULL;
 	}
@@ -644,9 +648,8 @@ npf_session_establish(npf_cache_t *npc, 
 	memcpy(&fw->se_dst_addr, npc->npc_ips[NPF_DST], alen);
 
 	/* Protocol and interface. */
-	memset(&se->s_common_id, 0, sizeof(npf_secomid_t));
 	se->s_common_id.proto = npc->npc_proto;
-	se->s_common_id.ifid = nbuf->nb_ifid;
+	se->s_common_id.ifid = per_if ? nbuf->nb_ifid : 0;
 
 	/* Setup "forwards" entry. */
 	if (!npf_session_fillent(npc, fw)) {

Index: src/usr.sbin/npf/npfctl/npf_parse.y
diff -u src/usr.sbin/npf/npfctl/npf_parse.y:1.33 src/usr.sbin/npf/npfctl/npf_parse.y:1.34
--- src/usr.sbin/npf/npfctl/npf_parse.y:1.33	Mon Feb 17 00:45:24 2014
+++ src/usr.sbin/npf/npfctl/npf_parse.y	Fri Mar 14 11:29:45 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_parse.y,v 1.33 2014/02/17 00:45:24 rmind Exp $	*/
+/*	$NetBSD: npf_parse.y,v 1.34 2014/03/14 11:29:45 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -136,6 +136,7 @@ yyerror(const char *fmt, ...)
 %token			SEPLINE
 %token			SLASH
 %token			STATEFUL
+%token			STATEFUL_ENDS
 %token			TABLE
 %token			TCP
 %token			TO
@@ -553,6 +554,7 @@ all_or_filt_opts
 
 opt_stateful
 	: STATEFUL	{ $$ = NPF_RULE_STATEFUL; }
+	| STATEFUL_ENDS	{ $$ = NPF_RULE_STATEFUL | NPF_RULE_MULTIENDS; }
 	|		{ $$ = 0; }
 	;
 

Index: src/usr.sbin/npf/npfctl/npf_scan.l
diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.19 src/usr.sbin/npf/npfctl/npf_scan.l:1.20
--- src/usr.sbin/npf/npfctl/npf_scan.l:1.19	Thu Feb 13 03:34:40 2014
+++ src/usr.sbin/npf/npfctl/npf_scan.l	Fri Mar 14 11:29:45 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_scan.l,v 1.19 2014/02/13 03:34:40 rmind Exp $	*/
+/*	$NetBSD: npf_scan.l,v 1.20 2014/03/14 11:29:45 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -118,6 +118,7 @@ block			return BLOCK;
 pass			return PASS;
 pcap-filter		return PCAP_FILTER;
 stateful		return STATEFUL;
+stateful-ends		return STATEFUL_ENDS;
 apply			return APPLY;
 final			return FINAL;
 quick			return FINAL;

Index: src/usr.sbin/npf/npfctl/npf_show.c
diff -u src/usr.sbin/npf/npfctl/npf_show.c:1.12 src/usr.sbin/npf/npfctl/npf_show.c:1.13
--- src/usr.sbin/npf/npfctl/npf_show.c:1.12	Wed Feb 19 01:43:16 2014
+++ src/usr.sbin/npf/npfctl/npf_show.c	Fri Mar 14 11:29:45 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_show.c,v 1.12 2014/02/19 01:43:16 rmind Exp $	*/
+/*	$NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_show.c,v 1.12 2014/02/19 01:43:16 rmind Exp $");
+__RCSID("$NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $");
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -218,6 +218,7 @@ print_portrange(npf_conf_info_t *ctx, co
  */
 
 #define	F(name)		__CONCAT(NPF_RULE_, name)
+#define	STATEFUL_ENDS	(NPF_RULE_STATEFUL | NPF_RULE_MULTIENDS)
 #define	NAME_AT		2
 
 static const struct attr_keyword_mapent {
@@ -232,7 +233,8 @@ static const struct attr_keyword_mapent 
 	{ F(RETRST)|F(RETICMP),	F(RETRST)|F(RETICMP),	"return"	},
 	{ F(RETRST)|F(RETICMP),	F(RETRST),		"return-rst"	},
 	{ F(RETRST)|F(RETICMP),	F(RETICMP),		"return-icmp"	},
-	{ F(STATEFUL),		F(STATEFUL),		"stateful"	},
+	{ STATEFUL_ENDS,	F(STATEFUL),		"stateful"	},
+	{ STATEFUL_ENDS,	STATEFUL_ENDS,		"stateful-ends"	},
 	{ F(DIMASK),		F(IN),			"in"		},
 	{ F(DIMASK),		F(OUT),			"out"		},
 	{ F(FINAL),		F(FINAL),		"final"		},

Reply via email to