Module Name:    src
Committed By:   tls
Date:           Sun Aug 10 07:00:01 UTC 2014

Modified Files:
        src/usr.sbin/npf [tls-earlyentropy]: Makefile
        src/usr.sbin/npf/npfctl [tls-earlyentropy]: npf.conf.5 npf_bpf_comp.c
            npf_build.c npf_scan.l npf_show.c npfctl.8 npfctl.c npfctl.h
        src/usr.sbin/npf/npftest [tls-earlyentropy]: README
        src/usr.sbin/npf/npftest/libnpftest [tls-earlyentropy]: npf_bpf_test.c
            npf_nat_test.c npf_perf_test.c npf_rule_test.c npf_state_test.c
            npf_test_subr.c
Added Files:
        src/usr.sbin/npf [tls-earlyentropy]: npf.7

Log Message:
Rebase.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.4.6.1 src/usr.sbin/npf/Makefile
cvs rdiff -u -r0 -r1.1.2.2 src/usr.sbin/npf/npf.7
cvs rdiff -u -r1.39 -r1.39.2.1 src/usr.sbin/npf/npfctl/npf.conf.5
cvs rdiff -u -r1.4 -r1.4.2.1 src/usr.sbin/npf/npfctl/npf_bpf_comp.c
cvs rdiff -u -r1.36 -r1.36.2.1 src/usr.sbin/npf/npfctl/npf_build.c \
    src/usr.sbin/npf/npfctl/npfctl.h
cvs rdiff -u -r1.20 -r1.20.2.1 src/usr.sbin/npf/npfctl/npf_scan.l
cvs rdiff -u -r1.13 -r1.13.2.1 src/usr.sbin/npf/npfctl/npf_show.c
cvs rdiff -u -r1.15 -r1.15.2.1 src/usr.sbin/npf/npfctl/npfctl.8
cvs rdiff -u -r1.40 -r1.40.2.1 src/usr.sbin/npf/npfctl/npfctl.c
cvs rdiff -u -r1.4 -r1.4.6.1 src/usr.sbin/npf/npftest/README
cvs rdiff -u -r1.4 -r1.4.2.1 \
    src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c
cvs rdiff -u -r1.8 -r1.8.2.1 \
    src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c
cvs rdiff -u -r1.3 -r1.3.2.1 \
    src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c
cvs rdiff -u -r1.10 -r1.10.2.1 \
    src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c
cvs rdiff -u -r1.5 -r1.5.2.1 \
    src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c
cvs rdiff -u -r1.9.2.1 -r1.9.2.2 \
    src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c

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

Modified files:

Index: src/usr.sbin/npf/Makefile
diff -u src/usr.sbin/npf/Makefile:1.4 src/usr.sbin/npf/Makefile:1.4.6.1
--- src/usr.sbin/npf/Makefile:1.4	Thu Sep 13 21:02:50 2012
+++ src/usr.sbin/npf/Makefile	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2012/09/13 21:02:50 martin Exp $
+# $NetBSD: Makefile,v 1.4.6.1 2014/08/10 07:00:01 tls Exp $
 
 .include <bsd.own.mk>
 
@@ -8,4 +8,7 @@ SUBDIR=		npfctl
 SUBDIR+=	npftest
 .endif
 
+MAN=		npf.7
+
+.include <bsd.man.mk>
 .include <bsd.subdir.mk>

Index: src/usr.sbin/npf/npfctl/npf.conf.5
diff -u src/usr.sbin/npf/npfctl/npf.conf.5:1.39 src/usr.sbin/npf/npfctl/npf.conf.5:1.39.2.1
--- src/usr.sbin/npf/npfctl/npf.conf.5:1.39	Fri Feb 14 01:52:58 2014
+++ src/usr.sbin/npf/npfctl/npf.conf.5	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-.\"    $NetBSD: npf.conf.5,v 1.39 2014/02/14 01:52:58 rmind Exp $
+.\"    $NetBSD: npf.conf.5,v 1.39.2.1 2014/08/10 07:00:01 tls Exp $
 .\"
 .\" Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 14, 2014
+.Dd August 2, 2014
 .Dt NPF.CONF 5
 .Os
 .Sh NAME
@@ -155,6 +155,25 @@ block out final pcap-filter "tcp and dst
 .Pp
 Fragments are not selectable since NPF always reassembles packets
 before further processing.
+.Ss Stateful
+Stateful packet inspection is enabled using
+.Cd stateful
+or
+.Cd stateful-ends
+keywords.
+The former creates a state which is uniquely identified by a 5-tuple (source
+and destination IP addresses, port numbers and an interface identifier).
+The latter excludes the interface identifier and must be used with
+precaution.
+In both cases, a full TCP state tracking is performed for TCP connections
+and a limited tracking for message-based protocols (UDP and ICMP).
+.Pp
+By default, a stateful rule implies SYN-only flag check ("flags S/SAFR")
+for the TCP packets.
+It is not advisable to change this behavior; however,
+it can be overridden with the
+.Cd flags
+keyword.
 .Ss Map
 Network Address Translation (NAT) is expressed in a form of segment mapping.
 The translation may be dynamic (stateful) or static (stateless).
@@ -252,7 +271,8 @@ rule-list	= [ rule new-line ] rule-list
 
 npf-filter	= [ "family" family-opt ] [ "proto" protocol [ proto-opts ] ]
 		  ( "all" | filt-opts )
-static-rule	= ( "block" [ block-opts ] | "pass" ) [ "stateful" ]
+static-rule	= ( "block" [ block-opts ] | "pass" )
+		  [ "stateful" | "stateful-ends" ]
 		  [ "in" | out" ] [ "final" ] [ "on" interface ]
 		  ( npf-filter | "pcap-filter" pcap-filter-expr )
 		  [ "apply" proc-name ]
@@ -332,6 +352,7 @@ group default {
 .\" -----
 .Sh SEE ALSO
 .Xr bpf 4 ,
+.Xr npf 7 ,
 .Xr pcap-filter 7 ,
 .Xr npfctl 8
 .Sh HISTORY

Index: src/usr.sbin/npf/npfctl/npf_bpf_comp.c
diff -u src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.4 src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.4.2.1
--- src/usr.sbin/npf/npfctl/npf_bpf_comp.c:1.4	Sat Mar 15 08:46:01 2014
+++ src/usr.sbin/npf/npfctl/npf_bpf_comp.c	Sun Aug 10 07:00:01 2014
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_bpf_comp.c,v 1.4 2014/03/15 08:46:01 rmind Exp $	*/
+/*	$NetBSD: npf_bpf_comp.c,v 1.4.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
- * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_bpf_comp.c,v 1.4 2014/03/15 08:46:01 rmind Exp $");
+__RCSID("$NetBSD: npf_bpf_comp.c,v 1.4.2.1 2014/08/10 07:00:01 tls Exp $");
 
 #include <stdlib.h>
 #include <stdbool.h>
@@ -62,7 +62,8 @@ __RCSID("$NetBSD: npf_bpf_comp.c,v 1.4 2
  * something other than L4 header offset.  Generally, when BPF_LDX is used.
  */
 #define	FETCHED_L3		0x01
-#define	X_EQ_L4OFF		0x02
+#define	CHECKED_L4		0x02
+#define	X_EQ_L4OFF		0x04
 
 struct npf_bpf {
 	/*
@@ -283,8 +284,7 @@ fetch_l3(npf_bpf_t *ctx, sa_family_t af,
 	}
 
 	/*
-	 * Fetch L3 information.  The coprocessor populates the following
-	 * words in the scratch memory store:
+	 * The memory store is populated with:
 	 * - BPF_MW_IPVER: IP version (4 or 6).
 	 * - BPF_MW_L4OFF: L4 header offset.
 	 * - BPF_MW_L4PROTO: L4 protocol.
@@ -307,21 +307,12 @@ fetch_l3(npf_bpf_t *ctx, sa_family_t af,
 		 * A <- IP version; A == expected-version?
 		 * If no particular version specified, check for non-zero.
 		 */
-		if ((ctx->flags & FETCHED_L3) == 0) {
-			struct bpf_insn insns_l3[] = {
-				BPF_STMT(BPF_MISC+BPF_COP, NPF_COP_L3),
-				BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ver, jt, jf),
-			};
-			add_insns(ctx, insns_l3, __arraycount(insns_l3));
-			ctx->flags |= FETCHED_L3;
-		} else {
-			/* IP version is already fetched in BPF_MW_IPVER. */
-			struct bpf_insn insns_af[] = {
-				BPF_STMT(BPF_LD+BPF_W+BPF_MEM, BPF_MW_IPVER),
-				BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ver, jt, jf),
-			};
-			add_insns(ctx, insns_af, __arraycount(insns_af));
-		}
+		struct bpf_insn insns_af[] = {
+			BPF_STMT(BPF_LD+BPF_W+BPF_MEM, BPF_MW_IPVER),
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ver, jt, jf),
+		};
+		add_insns(ctx, insns_af, __arraycount(insns_af));
+		ctx->flags |= FETCHED_L3;
 		ctx->af = af;
 
 		if (af) {
@@ -369,6 +360,7 @@ npfctl_bpf_proto(npf_bpf_t *ctx, sa_fami
 
 	uint32_t mwords[] = { BM_PROTO, 1, proto };
 	done_block(ctx, mwords, sizeof(mwords));
+	ctx->flags |= CHECKED_L4;
 }
 
 /*
@@ -471,6 +463,7 @@ npfctl_bpf_ports(npf_bpf_t *ctx, u_int o
 	/* TCP and UDP port offsets are the same. */
 	assert(sport_off == offsetof(struct tcphdr, th_sport));
 	assert(dport_off == offsetof(struct tcphdr, th_dport));
+	assert(ctx->flags & CHECKED_L4);
 
 	assert(((opts & MATCH_SRC) != 0) ^ ((opts & MATCH_DST) != 0));
 	off = (opts & MATCH_SRC) ? sport_off : dport_off;
@@ -513,12 +506,26 @@ npfctl_bpf_ports(npf_bpf_t *ctx, u_int o
  * npfctl_bpf_tcpfl: code block to match TCP flags.
  */
 void
-npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask)
+npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask, bool checktcp)
 {
 	const u_int tcpfl_off = offsetof(struct tcphdr, th_flags);
+	const bool usingmask = tf_mask != tf;
 
 	/* X <- IP header length */
 	fetch_l3(ctx, AF_UNSPEC, X_EQ_L4OFF);
+	if (checktcp) {
+		const u_int jf = usingmask ? 3 : 2;
+		assert(ctx->ingroup == false);
+
+		/* A <- L4 protocol; A == TCP?  If not, jump out. */
+		struct bpf_insn insns_tcp[] = {
+			BPF_STMT(BPF_LD+BPF_W+BPF_MEM, BPF_MW_L4PROTO),
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, jf),
+		};
+		add_insns(ctx, insns_tcp, __arraycount(insns_tcp));
+	} else {
+		assert(ctx->flags & CHECKED_L4);
+	}
 
 	struct bpf_insn insns_tf[] = {
 		/* A <- TCP flags */
@@ -526,7 +533,7 @@ npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t
 	};
 	add_insns(ctx, insns_tf, __arraycount(insns_tf));
 
-	if (tf_mask != tf) {
+	if (usingmask) {
 		/* A <- (A & mask) */
 		struct bpf_insn insns_mask[] = {
 			BPF_STMT(BPF_ALU+BPF_AND+BPF_K, tf_mask),
@@ -540,8 +547,10 @@ npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t
 	};
 	add_insns(ctx, insns_cmp, __arraycount(insns_cmp));
 
-	uint32_t mwords[] = { BM_TCPFL, 2, tf, tf_mask};
-	done_block(ctx, mwords, sizeof(mwords));
+	if (!checktcp) {
+		uint32_t mwords[] = { BM_TCPFL, 2, tf, tf_mask};
+		done_block(ctx, mwords, sizeof(mwords));
+	}
 }
 
 /*
@@ -554,6 +563,7 @@ npfctl_bpf_icmp(npf_bpf_t *ctx, int type
 	const u_int type_off = offsetof(struct icmp, icmp_type);
 	const u_int code_off = offsetof(struct icmp, icmp_code);
 
+	assert(ctx->flags & CHECKED_L4);
 	assert(offsetof(struct icmp6_hdr, icmp6_type) == type_off);
 	assert(offsetof(struct icmp6_hdr, icmp6_code) == code_off);
 	assert(type != -1 || code != -1);

Index: src/usr.sbin/npf/npfctl/npf_build.c
diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.36 src/usr.sbin/npf/npfctl/npf_build.c:1.36.2.1
--- src/usr.sbin/npf/npfctl/npf_build.c:1.36	Thu Feb 13 03:34:40 2014
+++ src/usr.sbin/npf/npfctl/npf_build.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_build.c,v 1.36 2014/02/13 03:34:40 rmind Exp $	*/
+/*	$NetBSD: npf_build.c,v 1.36.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -34,11 +34,12 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.36 2014/02/13 03:34:40 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.36.2.1 2014/08/10 07:00:01 tls Exp $");
 
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
+#include <netinet/tcp.h>
 
 #include <stdlib.h>
 #include <inttypes.h>
@@ -267,7 +268,7 @@ npfctl_build_proto(npf_bpf_t *ctx, sa_fa
 			assert(npfvar_get_count(popts) == 2);
 			tf = npfvar_get_data(popts, NPFVAR_TCPFLAG, 0);
 			tf_mask = npfvar_get_data(popts, NPFVAR_TCPFLAG, 1);
-			npfctl_bpf_tcpfl(ctx, *tf, *tf_mask);
+			npfctl_bpf_tcpfl(ctx, *tf, *tf_mask, false);
 		}
 		break;
 	case IPPROTO_ICMP:
@@ -292,10 +293,10 @@ static bool
 npfctl_build_code(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op,
     const filt_opts_t *fopts)
 {
+	bool noproto, noaddrs, noports, need_tcpudp = false;
 	const addr_port_t *apfrom = &fopts->fo_from;
 	const addr_port_t *apto = &fopts->fo_to;
 	const int proto = op->op_proto;
-	bool noproto, noaddrs, noports;
 	npf_bpf_t *bc;
 	size_t len;
 
@@ -316,7 +317,9 @@ npfctl_build_code(nl_rule_t *rl, sa_fami
 		switch (proto) {
 		case IPPROTO_TCP:
 		case IPPROTO_UDP:
+			break;
 		case -1:
+			need_tcpudp = true;
 			break;
 		default:
 			yyerror("invalid filter options for protocol %d", proto);
@@ -328,11 +331,28 @@ npfctl_build_code(nl_rule_t *rl, sa_fami
 	/* Build layer 4 protocol blocks. */
 	npfctl_build_proto(bc, family, op);
 
+	/*
+	 * If this is a stateful rule and TCP flags are not specified,
+	 * then add "flags S/SAFR" filter for TCP protocol case.
+	 */
+	if ((npf_rule_getattr(rl) & NPF_RULE_STATEFUL) != 0 &&
+	    (proto == -1 || (proto == IPPROTO_TCP && !op->op_opts))) {
+		npfctl_bpf_tcpfl(bc, TH_SYN,
+		    TH_SYN | TH_ACK | TH_FIN | TH_RST, proto == -1);
+	}
+
 	/* Build IP address blocks. */
 	npfctl_build_vars(bc, family, apfrom->ap_netaddr, MATCH_SRC);
 	npfctl_build_vars(bc, family, apto->ap_netaddr, MATCH_DST);
 
 	/* Build port-range blocks. */
+	if (need_tcpudp) {
+		/* TCP/UDP check for the ports. */
+		npfctl_bpf_group(bc);
+		npfctl_bpf_proto(bc, AF_UNSPEC, IPPROTO_TCP);
+		npfctl_bpf_proto(bc, AF_UNSPEC, IPPROTO_UDP);
+		npfctl_bpf_endgroup(bc);
+	}
 	npfctl_build_vars(bc, family, apfrom->ap_portrange, MATCH_SRC);
 	npfctl_build_vars(bc, family, apto->ap_portrange, MATCH_DST);
 
Index: src/usr.sbin/npf/npfctl/npfctl.h
diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.36 src/usr.sbin/npf/npfctl/npfctl.h:1.36.2.1
--- src/usr.sbin/npf/npfctl/npfctl.h:1.36	Thu Feb 13 03:34:40 2014
+++ src/usr.sbin/npf/npfctl/npfctl.h	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.h,v 1.36 2014/02/13 03:34:40 rmind Exp $	*/
+/*	$NetBSD: npfctl.h,v 1.36.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
 
 #define	NPF_DEV_PATH	"/dev/npf"
 #define	NPF_CONF_PATH	"/etc/npf.conf"
-#define	NPF_SESSDB_PATH	"/var/db/npf_sessions.db"
+#define	NPF_DB_PATH	"/var/db/npf.db"
 
 typedef struct fam_addr_mask {
 	sa_family_t	fam_family;
@@ -166,7 +166,7 @@ void		npfctl_bpf_proto(npf_bpf_t *, sa_f
 void		npfctl_bpf_cidr(npf_bpf_t *, u_int, sa_family_t,
 		    const npf_addr_t *, const npf_netmask_t);
 void		npfctl_bpf_ports(npf_bpf_t *, u_int, in_port_t, in_port_t);
-void		npfctl_bpf_tcpfl(npf_bpf_t *, uint8_t, uint8_t);
+void		npfctl_bpf_tcpfl(npf_bpf_t *, uint8_t, uint8_t, bool);
 void		npfctl_bpf_icmp(npf_bpf_t *, int, int);
 void		npfctl_bpf_table(npf_bpf_t *, u_int, u_int);
 

Index: src/usr.sbin/npf/npfctl/npf_scan.l
diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.20 src/usr.sbin/npf/npfctl/npf_scan.l:1.20.2.1
--- src/usr.sbin/npf/npfctl/npf_scan.l:1.20	Fri Mar 14 11:29:45 2014
+++ src/usr.sbin/npf/npfctl/npf_scan.l	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_scan.l,v 1.20 2014/03/14 11:29:45 rmind Exp $	*/
+/*	$NetBSD: npf_scan.l,v 1.20.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -84,6 +84,7 @@ npfctl_parse_string(const char *str)
 ID	[a-zA-Z_][a-zA-Z_0-9]*
 DID	[a-zA-Z_][a-zA-Z_0-9-]*
 NUMBER	[0-9]+
+HEXDIG	[0-9a-fA-F]+
 
 %%
 alg			return ALG;
@@ -151,7 +152,7 @@ any			return ANY;
 ","			return COMMA;
 "="			return EQ;
 
-"0x"[0-9a-fA-F]+ {
+"0x"{HEXDIG} {
 			char *endp, *buf = ecalloc(1, yyleng + 1);
 			buf[yyleng] = 0;
 			yylval.num = strtoul(buf+2, &endp, 16);
@@ -166,7 +167,12 @@ any			return ANY;
 			return FPNUM;
 		}
 
-[0-9a-fA-F]+":"[0-9a-fA-F:]* {
+{HEXDIG}":"[0-9a-fA-F:]* {
+			yylval.str = estrndup(yytext, yyleng);
+			return IPV6ADDR;
+		}
+
+"::"{HEXDIG}[0-9a-fA-F:]* {
 			yylval.str = estrndup(yytext, yyleng);
 			return IPV6ADDR;
 		}

Index: src/usr.sbin/npf/npfctl/npf_show.c
diff -u src/usr.sbin/npf/npfctl/npf_show.c:1.13 src/usr.sbin/npf/npfctl/npf_show.c:1.13.2.1
--- src/usr.sbin/npf/npfctl/npf_show.c:1.13	Fri Mar 14 11:29:45 2014
+++ src/usr.sbin/npf/npfctl/npf_show.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $	*/
+/*	$NetBSD: npf_show.c,v 1.13.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $");
+__RCSID("$NetBSD: npf_show.c,v 1.13.2.1 2014/08/10 07:00:01 tls Exp $");
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -248,7 +248,7 @@ static const struct mark_keyword_mapent 
 	u_int		fwords;
 } mark_keyword_map[] = {
 	{ BM_IPVER,	"family %s",	NULL,		print_family,	1 },
-	{ BM_PROTO,	"proto %s",	NULL,		print_proto,	1 },
+	{ BM_PROTO,	"proto %s",	", ",		print_proto,	1 },
 	{ BM_TCPFL,	"flags %s",	NULL,		print_tcpflags,	2 },
 	{ BM_ICMP_TYPE,	"icmp-type %s",	NULL,		print_number,	1 },
 	{ BM_ICMP_CODE,	"code %s",	NULL,		print_number,	1 },
@@ -452,7 +452,7 @@ npfctl_config_show(int fd)
 		if (ncf == NULL) {
 			return errno;
 		}
-		fprintf(ctx->fp, "Filtering:\t%s\nConfiguration:\t%s\n",
+		fprintf(ctx->fp, "# filtering:\t%s\n# config:\t%s\n",
 		    active ? "active" : "inactive",
 		    loaded ? "loaded" : "empty");
 		print_linesep(ctx);

Index: src/usr.sbin/npf/npfctl/npfctl.8
diff -u src/usr.sbin/npf/npfctl/npfctl.8:1.15 src/usr.sbin/npf/npfctl/npfctl.8:1.15.2.1
--- src/usr.sbin/npf/npfctl/npfctl.8:1.15	Fri Sep 20 21:30:49 2013
+++ src/usr.sbin/npf/npfctl/npfctl.8	Sun Aug 10 07:00:01 2014
@@ -1,6 +1,6 @@
-.\"	$NetBSD: npfctl.8,v 1.15 2013/09/20 21:30:49 wiz Exp $
+.\"	$NetBSD: npfctl.8,v 1.15.2.1 2014/08/10 07:00:01 tls Exp $
 .\"
-.\" Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This material is based upon work partially supported by The
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd September 19, 2013
+.Dd August 2, 2014
 .Dt NPFCTL 8
 .Os
 .Sh NAME
@@ -53,26 +53,26 @@ Valid commands are:
 .It Ic start
 Enable packet inspection using the currently loaded configuration, if any.
 Note that this command does not load or reload the configuration,
-or affect existing sessions.
+or affect existing connections.
 .It Ic stop
 Disable packet inspection.
 This command does not change the currently loaded configuration,
-or affect existing sessions.
+or affect existing connections.
 .It Ic reload Op Ar path
 Load or reload configuration from file.
 The configuration file at
 .Pa /etc/npf.conf
 will be used unless a file is specified by
 .Ar path .
-All sessions will be preserved during the reload, except those which
+All connections will be preserved during the reload, except those which
 will lose NAT policy due to removal.
 NAT policy is determined by the translation type and address.
-Note that change of filter criteria will not expire associated sessions.
+Note that change of filter criteria will not expire associated connections.
 The reload operation (i.e., replacing the ruleset, NAT policies and tables)
 is atomic.
 .It Ic flush
 Flush configuration.
-That is, remove all rules, tables and expire all sessions.
+That is, remove all rules, tables and expire all connections.
 This command does not disable packet inspection.
 .It Ic show
 Show the current state and configuration.
@@ -137,20 +137,16 @@ List all entries in the currently loaded
 .Ar tid .
 This operation is expensive and should be used with caution.
 .\" ---
-.It Ic sess-save
-Save all active sessions.
+.It Ic save
+Save the active configuration and a spanshot of the current connections.
 The data will be stored in the
-.Pa /var/db/npf_sessions.db
+.Pa /var/db/npf.db
 file.
-Administrator may want to stop the packet inspection before the
-session saving.
-.It Ic sess-load
-Load saved sessions from the file.
-Note that original configuration should be loaded before the session loading.
-In a case of NAT policy changes, sessions which lose an associated policy
-will not be loaded.
-Any existing sessions during the load operation will be expired.
-Administrator may want to start packet inspection after the session loading.
+Administrator may want to stop the packet inspection before saving.
+.It Ic load
+Load the saved configuration file and the connections from the file.
+Note that any existing connections will be destroyed.
+Administrator may want to start packet inspection after the load.
 .It Ic stats
 Print various statistics.
 .It Ic debug
@@ -190,7 +186,8 @@ Addition and removal of entries in the t
 .\" -----
 .Sh SEE ALSO
 .Xr bpf 4 ,
-.Xr npf.conf 5
+.Xr npf.conf 5 ,
+.Xr npf 7
 .Sh HISTORY
 NPF first appeared in
 .Nx 6.0 .

Index: src/usr.sbin/npf/npfctl/npfctl.c
diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.40 src/usr.sbin/npf/npfctl/npfctl.c:1.40.2.1
--- src/usr.sbin/npf/npfctl/npfctl.c:1.40	Tue Nov 12 00:46:34 2013
+++ src/usr.sbin/npf/npfctl/npfctl.c	Sun Aug 10 07:00:01 2014
@@ -1,7 +1,7 @@
-/*	$NetBSD: npfctl.c,v 1.40 2013/11/12 00:46:34 rmind Exp $	*/
+/*	$NetBSD: npfctl.c,v 1.40.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfctl.c,v 1.40 2013/11/12 00:46:34 rmind Exp $");
+__RCSID("$NetBSD: npfctl.c,v 1.40.2.1 2014/08/10 07:00:01 tls Exp $");
 
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -60,8 +60,8 @@ enum {
 	NPFCTL_TABLE,
 	NPFCTL_RULE,
 	NPFCTL_STATS,
-	NPFCTL_SESSIONS_SAVE,
-	NPFCTL_SESSIONS_LOAD,
+	NPFCTL_SAVE,
+	NPFCTL_LOAD,
 };
 
 static const struct operations_s {
@@ -69,23 +69,23 @@ static const struct operations_s {
 	int			action;
 } operations[] = {
 	/* Start, stop, reload */
-	{	"start",		NPFCTL_START		},
-	{	"stop",			NPFCTL_STOP		},
-	{	"reload",		NPFCTL_RELOAD		},
-	{	"show",			NPFCTL_SHOWCONF,	},
-	{	"flush",		NPFCTL_FLUSH		},
-	{	"valid",		NPFCTL_VALIDATE		},
+	{	"start",	NPFCTL_START		},
+	{	"stop",		NPFCTL_STOP		},
+	{	"reload",	NPFCTL_RELOAD		},
+	{	"show",		NPFCTL_SHOWCONF,	},
+	{	"flush",	NPFCTL_FLUSH		},
+	{	"valid",	NPFCTL_VALIDATE		},
 	/* Table */
-	{	"table",		NPFCTL_TABLE		},
+	{	"table",	NPFCTL_TABLE		},
 	/* Rule */
-	{	"rule",			NPFCTL_RULE		},
+	{	"rule",		NPFCTL_RULE		},
 	/* Stats */
-	{	"stats",		NPFCTL_STATS		},
-	/* Sessions */
-	{	"sess-save",		NPFCTL_SESSIONS_SAVE	},
-	{	"sess-load",		NPFCTL_SESSIONS_LOAD	},
+	{	"stats",	NPFCTL_STATS		},
+	/* Full state save/load */
+	{	"save",		NPFCTL_SAVE		},
+	{	"load",		NPFCTL_LOAD		},
 	/* --- */
-	{	NULL,			0			}
+	{	NULL,		0			}
 };
 
 bool
@@ -137,7 +137,7 @@ usage(void)
 	    "\t%s table <tid> { list | flush }\n",
 	    progname);
 	fprintf(stderr,
-	    "\t%s sess-load | sess-save\n",
+	    "\t%s save | load\n",
 	    progname);
 	exit(EXIT_FAILURE);
 }
@@ -153,15 +153,15 @@ npfctl_print_stats(int fd)
 		{ -1, "Packets passed"					},
 		{ NPF_STAT_PASS_DEFAULT,	"default pass"		},
 		{ NPF_STAT_PASS_RULESET,	"ruleset pass"		},
-		{ NPF_STAT_PASS_SESSION,	"session pass"		},
+		{ NPF_STAT_PASS_CONN,		"state pass"		},
 
 		{ -1, "Packets blocked"					},
 		{ NPF_STAT_BLOCK_DEFAULT,	"default block"		},
 		{ NPF_STAT_BLOCK_RULESET,	"ruleset block"		},
 
-		{ -1, "Session and NAT entries"				},
-		{ NPF_STAT_SESSION_CREATE,	"session allocations"	},
-		{ NPF_STAT_SESSION_DESTROY,	"session destructions"	},
+		{ -1, "State and NAT entries"				},
+		{ NPF_STAT_CONN_CREATE,		"state allocations"},
+		{ NPF_STAT_CONN_DESTROY,	"state destructions"},
 		{ NPF_STAT_NAT_CREATE,		"NAT entry allocations"	},
 		{ NPF_STAT_NAT_DESTROY,		"NAT entry destructions"},
 
@@ -177,7 +177,7 @@ npfctl_print_stats(int fd)
 
 		{ -1, "Packet race cases"				},
 		{ NPF_STAT_RACE_NAT,		"NAT association race"	},
-		{ NPF_STAT_RACE_SESSION,	"duplicate session race"},
+		{ NPF_STAT_RACE_CONN,		"duplicate state race"	},
 
 		{ -1, "Fragmentation"					},
 		{ NPF_STAT_FRAGMENTS,		"fragments"		},
@@ -480,6 +480,37 @@ npfctl_rule(int fd, int argc, char **arg
 	exit(EXIT_SUCCESS);
 }
 
+static int
+npfctl_save(int fd)
+{
+	nl_config_t *ncf;
+	bool active, loaded;
+	int error;
+
+	ncf = npf_config_retrieve(fd, &active, &loaded);
+	if (ncf == NULL) {
+		return errno;
+	}
+	error = npf_config_export(ncf, NPF_DB_PATH);
+	npf_config_destroy(ncf);
+	return error;
+}
+
+static int
+npfctl_load(int fd)
+{
+	nl_config_t *ncf;
+	int error;
+
+	ncf = npf_config_import(NPF_DB_PATH);
+	if (ncf == NULL) {
+		return errno;
+	}
+	error = npf_config_submit(ncf, fd);
+	npf_config_destroy(ncf);
+	return error;
+}
+
 static void
 npfctl(int action, int argc, char **argv)
 {
@@ -544,22 +575,18 @@ npfctl(int action, int argc, char **argv
 		argv += 2;
 		npfctl_rule(fd, argc, argv);
 		break;
+	case NPFCTL_LOAD:
+		ret = npfctl_load(fd);
+		fun = "npfctl_config_load";
+		break;
+	case NPFCTL_SAVE:
+		fd = npfctl_save(fd);
+		fun = "npfctl_config_save";
+		break;
 	case NPFCTL_STATS:
 		ret = npfctl_print_stats(fd);
 		fun = "npfctl_print_stats";
 		break;
-	case NPFCTL_SESSIONS_SAVE:
-		if (npf_sessions_recv(fd, NPF_SESSDB_PATH) != 0) {
-			errx(EXIT_FAILURE, "could not save sessions to '%s'",
-			    NPF_SESSDB_PATH);
-		}
-		break;
-	case NPFCTL_SESSIONS_LOAD:
-		if (npf_sessions_send(fd, NPF_SESSDB_PATH) != 0) {
-			errx(EXIT_FAILURE, "no sessions loaded from '%s'",
-			    NPF_SESSDB_PATH);
-		}
-		break;
 	}
 	if (ret) {
 		err(EXIT_FAILURE, "%s", fun);

Index: src/usr.sbin/npf/npftest/README
diff -u src/usr.sbin/npf/npftest/README:1.4 src/usr.sbin/npf/npftest/README:1.4.6.1
--- src/usr.sbin/npf/npftest/README:1.4	Sat Feb  9 03:35:33 2013
+++ src/usr.sbin/npf/npftest/README	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-$NetBSD: README,v 1.4 2013/02/09 03:35:33 rmind Exp $
+$NetBSD: README,v 1.4.6.1 2014/08/10 07:00:01 tls Exp $
 
 npftest - a tool for regression testing and debugging NPF.
 It uses RUMP framework to run NPF kernel module in the userspace.
@@ -12,12 +12,16 @@ npftest -c /tmp/npf.plist -t
 
 Stream:
 
-tcpdump -w stream.pcap -i $INTERFACE "host $HOST and tcp"
-npfctl debug
-npftest -c /tmp/npf.plist -s stream.pcap -o stream_npf_data.txt
+tcpdump -w stream.pcap -i $interface "host $host and tcp"
+npfctl debug npftest.conf /tmp/npf.plist
+npftest -c /tmp/npf.plist -s stream.pcap > stream_npf_data.txt
 
 Preferably, use MALLOC_OPTIONS="AJ" and/or other facilities.
 
+Benchmark:
+
+npftest -b rule -c /tmp/npf.plist -p $ncpu
+
 ---
 
 Update RUMP libraries once the kernel side has been changed.  Hint:

Index: src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c:1.4 src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c:1.4.2.1
--- src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c:1.4	Sat Nov 23 19:40:11 2013
+++ src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_bpf_test.c,v 1.4 2013/11/23 19:40:11 rmind Exp $	*/
+/*	$NetBSD: npf_bpf_test.c,v 1.4.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -63,6 +63,7 @@ test_bpf_code(void *code, size_t size)
 {
 	ifnet_t *dummy_ifp = npf_test_addif(IFNAME_TEST, false, false);
 	npf_cache_t npc = { .npc_info = 0 };
+	uint32_t memstore[BPF_MEMWORDS];
 	bpf_args_t bc_args;
 	struct mbuf *m;
 	nbuf_t nbuf;
@@ -72,11 +73,13 @@ test_bpf_code(void *code, size_t size)
 	/* Layer 3 (IP + TCP). */
 	m = fill_packet(IPPROTO_TCP);
 	nbuf_init(&nbuf, m, dummy_ifp);
-	npf_cache_all(&npc, &nbuf);
+	npc.npc_nbuf = &nbuf;
+	npf_cache_all(&npc);
 
-	memset(&bc_args, 0, sizeof(bpf_args_t));
-	bc_args.pkt = m;
-	bc_args.wirelen = m_length(m);
+	bc_args.pkt = (const uint8_t *)m;
+	bc_args.buflen = m_length(m);
+	bc_args.wirelen = bc_args.buflen;
+	bc_args.mem = memstore;
 	bc_args.arg = &npc;
 
 	ret = npf_bpf_filter(&bc_args, code, NULL);

Index: src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c:1.8 src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c:1.8.2.1
--- src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c:1.8	Thu Feb 13 03:34:40 2014
+++ src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_nat_test.c,v 1.8 2014/02/13 03:34:40 rmind Exp $	*/
+/*	$NetBSD: npf_nat_test.c,v 1.8.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*
  * NPF NAT test.
@@ -166,7 +166,8 @@ checkresult(bool verbose, unsigned i, st
 	}
 
 	nbuf_init(&nbuf, m, ifp);
-	if (!npf_cache_all(&npc, &nbuf)) {
+	npc.npc_nbuf = &nbuf;
+	if (!npf_cache_all(&npc)) {
 		printf("error: could not fetch the packet data");
 		return false;
 	}

Index: src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c:1.3 src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c:1.3.2.1
--- src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c:1.3	Tue Sep 24 22:52:14 2013
+++ src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_perf_test.c,v 1.3 2013/09/24 22:52:14 joerg Exp $	*/
+/*	$NetBSD: npf_perf_test.c,v 1.3.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*
  * NPF benchmarking.
@@ -99,5 +99,5 @@ npf_test_conc(bool st, unsigned nthreads
 	kmem_free(npackets, sizeof(uint64_t) * nthreads);
 	kmem_free(l, sizeof(lwp_t *) * nthreads);
 
-	printf("%u\t%" PRIu64 "\n", nthreads, total);
+	printf("%u\t%" PRIu64 "\n", nthreads, total / NSECS);
 }

Index: src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.10 src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.10.2.1
--- src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.10	Tue Sep 24 02:04:21 2013
+++ src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_rule_test.c,v 1.10 2013/09/24 02:04:21 rmind Exp $	*/
+/*	$NetBSD: npf_rule_test.c,v 1.10.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*
  * NPF ruleset test.
@@ -80,10 +80,11 @@ npf_rule_raw_test(bool verbose, struct m
 	int retfl, error;
 
 	nbuf_init(&nbuf, m, ifp);
-	npf_cache_all(&npc, &nbuf);
+	npc.npc_nbuf = &nbuf;
+	npf_cache_all(&npc);
 
 	int slock = npf_config_read_enter();
-	rl = npf_ruleset_inspect(&npc, &nbuf, npf_config_ruleset(),
+	rl = npf_ruleset_inspect(&npc, npf_config_ruleset(),
 	    di, NPF_LAYER_3);
 	if (rl) {
 		error = npf_rule_conclude(rl, &retfl);

Index: src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c:1.5 src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c:1.5.2.1
--- src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c:1.5	Fri Nov  8 00:38:27 2013
+++ src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_state_test.c,v 1.5 2013/11/08 00:38:27 rmind Exp $	*/
+/*	$NetBSD: npf_state_test.c,v 1.5.2.1 2014/08/10 07:00:01 tls Exp $	*/
 
 /*
  * NPF state tracking test.
@@ -146,15 +146,16 @@ process_packet(const int i, npf_state_t 
 	}
 
 	nbuf_init(&nbuf, construct_packet(p), dummy_ifp);
-	ret = npf_cache_all(&npc, &nbuf);
+	npc.npc_nbuf = &nbuf;
+	ret = npf_cache_all(&npc);
 	KASSERT((ret & NPC_IPFRAG) == 0);
 
 	if (*snew) {
-		ret = npf_state_init(&npc, &nbuf, nst);
+		ret = npf_state_init(&npc, nst);
 		KASSERT(ret == true);
 		*snew = false;
 	}
-	ret = npf_state_inspect(&npc, &nbuf, nst, p->flags == OUT);
+	ret = npf_state_inspect(&npc, nst, p->flags == OUT);
 	m_freem(nbuf.nb_mbuf);
 
 	return ret ? true : (p->flags & ERR) != 0;

Index: src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.9.2.1 src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.9.2.2
--- src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.9.2.1	Sat Aug  9 06:19:50 2014
+++ src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c	Sun Aug 10 07:00:01 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_test_subr.c,v 1.9.2.1 2014/08/09 06:19:50 tls Exp $	*/
+/*	$NetBSD: npf_test_subr.c,v 1.9.2.2 2014/08/10 07:00:01 tls Exp $	*/
 
 /*
  * NPF initialisation and handler routines.
@@ -40,7 +40,7 @@ int
 npf_test_load(const void *xml)
 {
 	prop_dictionary_t npf_dict = prop_dictionary_internalize(xml);
-	return npfctl_reload(0, npf_dict);
+	return npfctl_load(0, npf_dict);
 }
 
 ifnet_t *

Added files:

Index: src/usr.sbin/npf/npf.7
diff -u /dev/null src/usr.sbin/npf/npf.7:1.1.2.2
--- /dev/null	Sun Aug 10 07:00:01 2014
+++ src/usr.sbin/npf/npf.7	Sun Aug 10 07:00:01 2014
@@ -0,0 +1,91 @@
+.\"	$NetBSD: npf.7,v 1.1.2.2 2014/08/10 07:00:01 tls Exp $
+.\"
+.\" Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This material is based upon work partially supported by The
+.\" NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd August 2, 2014
+.Dt NPF 7
+.Os
+.Sh NAME
+.Nm NPF
+.Nd NetBSD packet filter
+.\" -----
+.Sh DESCRIPTION
+NPF is a layer 3 packet filter, supporting IPv4 and IPv6 as well as
+layer 4 protocols such as TCP, UDP, and ICMP.
+It was designed with a focus on high performance, scalability, and
+modularity.
+.Pp
+NPF was written from scratch in 2009 and is distributed under the
+2-clause BSD license.
+.\" -----
+.Sh FEATURES
+NPF offers the traditional set of features provided by packet filters.
+Some key features are:
+.Bl -bullet -offset indent
+.It
+Stateful inspection (connection tracking).
+.It
+Network address translation (NAT).
+This includes static (stateless) and dynamic (stateful) translation,
+port translation, bi-directional NAT, etc.
+.It
+IPv6-to-IPv6 network prefix translation (NPTv6).
+.It
+Tables for efficient IP sets.
+.It
+Application Level Gateways (e.g., to support traceroute).
+.It
+NPF uses BPF with just-in-time (JIT) compilation.
+.It
+Rule procedures and a framework for NPF extensions.
+.It
+Traffic normalization (extension).
+.It
+Packet logging (extension).
+.El
+.Pp
+For a full set features and their description, see the NPF
+documentation and other manual pages.
+.\" -----
+.Sh SEE ALSO
+.Xr libnpf 3 ,
+.Xr bpf 4 ,
+.Xr bpfjit 4 ,
+.Xr npf.conf 5 ,
+.Xr pcap-filter 7 ,
+.Xr npfctl 8
+.Pp
+.Lk http://www.netbsd.org/~rmind/npf/ "NPF documentation"
+.Sh HISTORY
+.Nm
+first appeared in
+.Nx 7.0 .
+.Sh AUTHORS
+.Nm
+was designed and implemented by
+.An Mindaugas Rasiukevicius .

Reply via email to