? if_npflog.h
? npfklog.diff
? o
? stateful-ends
? x
Index: if_npflog.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/if_npflog.c,v
retrieving revision 1.4
diff -u -u -r1.4 if_npflog.c
--- if_npflog.c	26 Dec 2016 23:05:06 -0000	1.4
+++ if_npflog.c	29 Dec 2016 21:28:01 -0000
@@ -53,6 +53,7 @@
 #endif
 
 #include "npf_impl.h"
+#include "if_npflog.h"
 
 MODULE(MODULE_CLASS_DRIVER, if_npflog, NULL);
 
@@ -128,7 +129,7 @@
 	KERNEL_LOCK(1, NULL);
 	if_attach(ifp);
 	if_alloc_sadl(ifp);
-	bpf_attach(ifp, DLT_NULL, 0);
+	bpf_attach(ifp, DLT_NPFLOG, NPFLOG_HDRLEN);
 	LIST_INSERT_HEAD(&npflog_if_list, sc, sc_entry);
 	KERNEL_UNLOCK_ONE(NULL);
 
Index: npf.h
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf.h,v
retrieving revision 1.53
diff -u -u -r1.53 npf.h
--- npf.h	26 Dec 2016 23:39:18 -0000	1.53
+++ npf.h	29 Dec 2016 21:28:01 -0000
@@ -200,7 +200,7 @@
 	void *		ctx;
 	int		(*ctor)(npf_rproc_t *, prop_dictionary_t);
 	void		(*dtor)(npf_rproc_t *, void *);
-	bool		(*proc)(npf_cache_t *, void *, int *);
+	bool		(*proc)(npf_cache_t *, void *, int *, const void *);
 } npf_ext_ops_t;
 
 void *		npf_ext_register(npf_t *, const char *, const npf_ext_ops_t *);
Index: npf_conf.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_conf.c,v
retrieving revision 1.10
diff -u -u -r1.10 npf_conf.c
--- npf_conf.c	26 Dec 2016 23:05:06 -0000	1.10
+++ npf_conf.c	29 Dec 2016 21:28:02 -0000
@@ -83,8 +83,8 @@
 	/* Load the empty configuration. */
 	tset = npf_tableset_create(0);
 	rpset = npf_rprocset_create();
-	rlset = npf_ruleset_create(0);
-	nset = npf_ruleset_create(0);
+	rlset = npf_ruleset_create("rules", 0);
+	nset = npf_ruleset_create("nat-rules", 0);
 	npf_config_load(npf, rlset, tset, nset, rpset, NULL, true);
 	KASSERT(npf->config != NULL);
 }
Index: npf_ctl.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ctl.c,v
retrieving revision 1.45
diff -u -u -r1.45 npf_ctl.c
--- npf_ctl.c	26 Dec 2016 23:05:06 -0000	1.45
+++ npf_ctl.c	29 Dec 2016 21:28:02 -0000
@@ -545,7 +545,7 @@
 		goto fail;
 	}
 
-	nset = npf_ruleset_create(nitems);
+	nset = npf_ruleset_create("nat-rules", nitems);
 	error = npf_mk_natlist(npf, nset, natlist, errdict);
 	if (error) {
 		goto fail;
@@ -582,7 +582,7 @@
 		goto fail;
 	}
 
-	rlset = npf_ruleset_create(nitems);
+	rlset = npf_ruleset_create("rules", nitems);
 	error = npf_mk_rules(npf, rlset, rules, rpset, errdict);
 	if (error) {
 		goto fail;
Index: npf_ext_log.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ext_log.c,v
retrieving revision 1.10
diff -u -u -r1.10 npf_ext_log.c
--- npf_ext_log.c	26 Dec 2016 23:05:06 -0000	1.10
+++ npf_ext_log.c	29 Dec 2016 21:28:02 -0000
@@ -52,6 +52,7 @@
 #endif
 
 #include "npf_impl.h"
+#include "if_npflog.h"
 
 NPF_EXT_MODULE(npf_ext_log, "");
 
@@ -81,23 +82,53 @@
 }
 
 static bool
-npf_log(npf_cache_t *npc, void *meta, int *decision)
+npf_log(npf_cache_t *npc, void *meta, int *decision, const void *v)
 {
 	struct mbuf *m = nbuf_head_mbuf(npc->npc_nbuf);
 	const npf_ext_log_t *log = meta;
+	const npf_rproc_param_t *param = v;
 	struct psref psref;
 	ifnet_t *ifp;
-	int family;
+	struct npfloghdr hdr;
 
+	memset(&hdr, 0, sizeof(hdr));
 	/* Set the address family. */
 	if (npf_iscached(npc, NPC_IP4)) {
-		family = AF_INET;
+		hdr.af = AF_INET;
 	} else if (npf_iscached(npc, NPC_IP6)) {
-		family = AF_INET6;
+		hdr.af = AF_INET6;
 	} else {
-		family = AF_UNSPEC;
+		hdr.af = AF_UNSPEC;
 	}
 
+	hdr.length = NPFLOG_REAL_HDRLEN;
+	hdr.action = *decision == NPF_DECISION_PASS ?
+	    0 /* pass */ : 1 /* block */;
+	hdr.reason = 0;	/* match */
+	strlcpy(hdr.ifname, param->ifp->if_xname, sizeof(hdr.ifname));
+
+	hdr.rulenr = htonl((uint32_t)param->rid);
+	hdr.subrulenr = htonl((uint32_t)(param->rid >> 32));
+	strlcpy(hdr.ruleset, param->rsname, sizeof(hdr.ruleset));
+
+	hdr.uid = UID_MAX;
+	hdr.pid = (pid_t)-1;
+	hdr.rule_uid = UID_MAX;
+	hdr.rule_pid = (pid_t)-1;
+
+	switch (param->direction) {
+	default:
+	case PFIL_IN|PFIL_OUT:
+	    hdr.dir = 0;
+	    break;
+	case PFIL_IN:
+	    hdr.dir = 1;
+	    break;
+	case PFIL_OUT:
+	    hdr.dir = 2;
+	    break;
+	}
+	    
 	KERNEL_LOCK(1, NULL);
 
 	/* Find a pseudo-interface to log. */
@@ -111,7 +142,8 @@
 	/* Pass through BPF. */
 	ifp->if_opackets++;
 	ifp->if_obytes += m->m_pkthdr.len;
-	bpf_mtap_af(ifp, family, m);
+	if (ifp->if_bpf)
+		bpf_mtap2(ifp->if_bpf, &hdr, NPFLOG_HDRLEN, m);
 	if_put(ifp, &psref);
 
 	KERNEL_UNLOCK_ONE(NULL);
Index: npf_ext_normalize.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ext_normalize.c,v
retrieving revision 1.4
diff -u -u -r1.4 npf_ext_normalize.c
--- npf_ext_normalize.c	26 Dec 2016 23:05:06 -0000	1.4
+++ npf_ext_normalize.c	29 Dec 2016 21:28:02 -0000
@@ -143,7 +143,7 @@
  * npf_normalize: the main routine to normalize IPv4 and/or TCP headers.
  */
 static bool
-npf_normalize(npf_cache_t *npc, void *params, int *decision)
+npf_normalize(npf_cache_t *npc, void *params, int *decision, const void *v)
 {
 	npf_normalize_t *np = params;
 	struct tcphdr *th = npc->npc_l4.tcp;
Index: npf_ext_rndblock.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ext_rndblock.c,v
retrieving revision 1.6
diff -u -u -r1.6 npf_ext_rndblock.c
--- npf_ext_rndblock.c	26 Dec 2016 23:05:06 -0000	1.6
+++ npf_ext_rndblock.c	29 Dec 2016 21:28:02 -0000
@@ -99,7 +99,7 @@
  * npf_ext_rndblock: main routine implementing the extension functionality.
  */
 static bool
-npf_ext_rndblock(npf_cache_t *npc, void *meta, int *decision)
+npf_ext_rndblock(npf_cache_t *npc, void *meta, int *decision, const void *v)
 {
 	npf_ext_rndblock_t *rndblock = meta;
 	unsigned long c;
Index: npf_handler.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_handler.c,v
retrieving revision 1.35
diff -u -u -r1.35 npf_handler.c
--- npf_handler.c	26 Dec 2016 23:05:06 -0000	1.35
+++ npf_handler.c	29 Dec 2016 21:28:02 -0000
@@ -129,9 +129,9 @@
 	npf_conn_t *con;
 	npf_rule_t *rl;
 	npf_rproc_t *rp;
-	int error, retfl;
+	int error, retfl, decision;
 	uint32_t ntag;
-	int decision;
+	npf_rproc_param_t param;
 
 	/* QSBR checkpoint. */
 	pserialize_checkpoint(npf->qsbr);
@@ -146,6 +146,7 @@
 	npc.npc_nbuf = &nbuf;
 	npc.npc_info = 0;
 
+	param.ifp = ifp;
 	decision = NPF_DECISION_BLOCK;
 	error = 0;
 	retfl = 0;
@@ -191,11 +192,14 @@
 	/* Acquire the lock, inspect the ruleset using this packet. */
 	int slock = npf_config_read_enter();
 	npf_ruleset_t *rlset = npf_config_ruleset(npf);
+	// XXX: copy
+	param.rsname = npf_ruleset_getname(rlset);
 
 	rl = npf_ruleset_inspect(&npc, rlset, di, NPF_LAYER_3);
 	if (__predict_false(rl == NULL)) {
 		const bool pass = npf_default_pass(npf);
 		npf_config_read_exit(slock);
+		param.rid = 0;
 
 		if (pass) {
 			npf_stats_inc(npf, NPF_STAT_PASS_DEFAULT);
@@ -203,7 +207,8 @@
 		}
 		npf_stats_inc(npf, NPF_STAT_BLOCK_DEFAULT);
 		goto block;
-	}
+	} else
+		param.rid = npf_rule_getid(rl);
 
 	/*
 	 * Get the rule procedure (acquires a reference) for association
@@ -250,7 +255,7 @@
 	 * Execute the rule procedure, if any is associated.
 	 * It may reverse the decision from pass to block.
 	 */
-	if (rp && !npf_rproc_run(&npc, rp, &decision)) {
+	if (rp && !npf_rproc_run(&npc, rp, &decision, &param)) {
 		if (con) {
 			npf_conn_release(con);
 		}
Index: npf_impl.h
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_impl.h,v
retrieving revision 1.65
diff -u -u -r1.65 npf_impl.h
--- npf_impl.h	28 Dec 2016 21:55:04 -0000	1.65
+++ npf_impl.h	29 Dec 2016 21:28:02 -0000
@@ -200,6 +200,13 @@
 	percpu_t *		stats_percpu;
 };
 
+typedef struct {
+	int		direction;
+	const char *	rsname;
+	uint64_t	rid;
+	struct ifnet *	ifp;
+} npf_rproc_param_t;
+
 /*
  * INTERFACES.
  */
@@ -313,7 +320,7 @@
 int		npf_table_flush(npf_table_t *);
 
 /* Ruleset interface. */
-npf_ruleset_t *	npf_ruleset_create(size_t);
+npf_ruleset_t *	npf_ruleset_create(const char *name, size_t);
 void		npf_ruleset_destroy(npf_ruleset_t *);
 void		npf_ruleset_insert(npf_ruleset_t *, npf_rule_t *);
 void		npf_ruleset_reload(npf_t *, npf_ruleset_t *,
@@ -330,6 +337,7 @@
 prop_dictionary_t npf_ruleset_list(npf_t *, npf_ruleset_t *, const char *);
 int		npf_ruleset_flush(npf_ruleset_t *, const char *);
 void		npf_ruleset_gc(npf_ruleset_t *);
+const char *	npf_ruleset_getname(const npf_ruleset_t *);
 
 npf_rule_t *	npf_ruleset_inspect(npf_cache_t *, const npf_ruleset_t *,
 		    const int, const int);
@@ -360,7 +368,8 @@
 void		npf_rproc_acquire(npf_rproc_t *);
 void		npf_rproc_release(npf_rproc_t *);
 const char *	npf_rproc_getname(const npf_rproc_t *);
-bool		npf_rproc_run(npf_cache_t *, npf_rproc_t *, int *);
+bool		npf_rproc_run(npf_cache_t *, npf_rproc_t *, int *,
+    const npf_rproc_param_t *);
 
 /* State handling. */
 bool		npf_state_init(npf_cache_t *, npf_state_t *);
Index: npf_rproc.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_rproc.c,v
retrieving revision 1.15
diff -u -u -r1.15 npf_rproc.c
--- npf_rproc.c	28 Dec 2016 21:55:04 -0000	1.15
+++ npf_rproc.c	29 Dec 2016 21:28:02 -0000
@@ -358,7 +358,8 @@
  * => Reference on the rule procedure must be held.
  */
 bool
-npf_rproc_run(npf_cache_t *npc, npf_rproc_t *rp, int *decision)
+npf_rproc_run(npf_cache_t *npc, npf_rproc_t *rp, int *decision,
+    const npf_rproc_param_t *param)
 {
 	const unsigned extcount = rp->rp_ext_count;
 
@@ -370,7 +371,7 @@
 		const npf_ext_ops_t *extops = ext->ext_ops;
 
 		KASSERT(ext->ext_refcnt > 0);
-		if (!extops->proc(npc, rp->rp_ext_meta[i], decision)) {
+		if (!extops->proc(npc, rp->rp_ext_meta[i], decision, param)) {
 			return false;
 		}
 
Index: npf_ruleset.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ruleset.c,v
retrieving revision 1.44
diff -u -u -r1.44 npf_ruleset.c
--- npf_ruleset.c	28 Dec 2016 21:55:04 -0000	1.44
+++ npf_ruleset.c	29 Dec 2016 21:28:02 -0000
@@ -71,6 +71,7 @@
 	u_int			rs_slots;
 	u_int			rs_nitems;
 
+	char			rs_name[64];
 	/* Array of ordered rules. */
 	npf_rule_t *		rs_rules[];
 };
@@ -138,12 +139,13 @@
     (((attr) & NPF_DYNAMIC_GROUP) == NPF_RULE_DYNAMIC)
 
 npf_ruleset_t *
-npf_ruleset_create(size_t slots)
+npf_ruleset_create(const char *name, size_t slots)
 {
 	size_t len = offsetof(npf_ruleset_t, rs_rules[slots]);
 	npf_ruleset_t *rlset;
 
 	rlset = kmem_zalloc(len, KM_SLEEP);
+	strlcpy(rlset->rs_name, name, sizeof(rlset->rs_name));
 	LIST_INIT(&rlset->rs_dynamic);
 	LIST_INIT(&rlset->rs_all);
 	LIST_INIT(&rlset->rs_gc);
@@ -201,6 +203,7 @@
 
 	rlset->rs_rules[n] = rl;
 	rlset->rs_nitems++;
+	rl->r_id = ++rlset->rs_idcnt;
 
 	if (rl->r_skip_to < ++n) {
 		rl->r_skip_to = SKIPTO_ADJ_FLAG | n;
@@ -426,6 +429,7 @@
 		LIST_INSERT_HEAD(&rlset->rs_gc, rl, r_aentry);
 		rl = rl->r_next;
 	}
+	rlset->rs_idcnt = 0;
 	return 0;
 }
 
@@ -643,6 +647,12 @@
 	}
 }
 
+const char *
+npf_ruleset_getname(const npf_ruleset_t *rs)
+{
+	return rs->rs_name;
+}
+
 /*
  * npf_rule_alloc: allocate a rule and initialise it.
  */
--- /dev/null	2016-12-29 16:22:04.165985227 -0500
+++ if_npflog.h	2016-12-29 16:00:53.456278222 -0500
@@ -0,0 +1,61 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ */
+#ifndef _NET_NPF_IF_NPFLOG_H_
+#define _NET_NPF_IF_NPFLOG_H_
+
+#define NPFLOG_RULESET_NAME_SIZE	16
+
+/* Copied bit by bit from pflog, so we re-use the same code */
+
+struct npfloghdr {
+	u_int8_t	length;
+	sa_family_t	af;
+	u_int8_t	action;
+	u_int8_t	reason;
+	char		ifname[IFNAMSIZ];
+	char		ruleset[NPFLOG_RULESET_NAME_SIZE];
+	u_int32_t	rulenr;
+	u_int32_t	subrulenr;
+	uid_t		uid;
+	pid_t		pid;
+	uid_t		rule_uid;
+	pid_t		rule_pid;
+	u_int8_t	dir;
+	u_int8_t	pad[3];
+};
+
+#define DLT_NPFLOG	DLT_PFLOG
+
+#define NPFLOG_HDRLEN		sizeof(struct npfloghdr)
+/* minus pad, also used as a signature */
+#define NPFLOG_REAL_HDRLEN	offsetof(struct npfloghdr, pad)
+
+#endif /* _NET_NPF_IF_NPFLOG_H_ */