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 7 Jan 2017 15:30:25 -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 7 Jan 2017 15:30:25 -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_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 7 Jan 2017 15:30:25 -0000 @@ -52,6 +52,7 @@ #endif #include "npf_impl.h" +#include "if_npflog.h" NPF_EXT_MODULE(npf_ext_log, ""); @@ -81,23 +82,56 @@ } 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 *pm = 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 */ + const char *ifname = pm->pm_ifid ? + npf_ifmap_getname(npc->npc_ctx, pm->pm_ifid) : "???"; + + strlcpy(hdr.ifname, ifname, sizeof(hdr.ifname)); + + hdr.rulenr = htonl((uint32_t)pm->pm_rid); + hdr.subrulenr = htonl((uint32_t)(pm->pm_rid >> 32)); + strlcpy(hdr.ruleset, "rules", sizeof(hdr.ruleset)); + + hdr.uid = UID_MAX; + hdr.pid = (pid_t)-1; + hdr.rule_uid = UID_MAX; + hdr.rule_pid = (pid_t)-1; + + switch (pm->pm_di) { + 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 +145,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 7 Jan 2017 15:30:25 -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 7 Jan 2017 15:30:25 -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 7 Jan 2017 15:30:25 -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 pm; /* QSBR checkpoint. */ pserialize_checkpoint(npf->qsbr); @@ -167,6 +167,9 @@ } } + pm.pm_ifid = npf_ifmap_getid(npf, ifp); + pm.pm_di = di; + /* Just pass-through if specially tagged. */ if (nbuf_find_tag(&nbuf, &ntag) == 0 && (ntag & NPF_NTAG_PASS) != 0) { con = NULL; @@ -196,6 +199,7 @@ if (__predict_false(rl == NULL)) { const bool pass = npf_default_pass(npf); npf_config_read_exit(slock); + pm.pm_rid = 0; if (pass) { npf_stats_inc(npf, NPF_STAT_PASS_DEFAULT); @@ -203,6 +207,8 @@ } npf_stats_inc(npf, NPF_STAT_BLOCK_DEFAULT); goto block; + } else { + pm.pm_rid = npf_rule_getid(rl); } /* @@ -250,7 +256,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, &pm)) { if (con) { npf_conn_release(con); } Index: npf_impl.h =================================================================== RCS file: /cvsroot/src/sys/net/npf/npf_impl.h,v retrieving revision 1.67 diff -u -u -r1.67 npf_impl.h --- npf_impl.h 3 Jan 2017 00:58:05 -0000 1.67 +++ npf_impl.h 7 Jan 2017 15:30:25 -0000 @@ -200,6 +200,12 @@ percpu_t * stats_percpu; }; +typedef struct { + uint64_t pm_rid; + u_int pm_ifid; + u_int pm_di; +} npf_rproc_param_t; + /* * INTERFACES. */ @@ -366,7 +372,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 7 Jan 2017 15:30:25 -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 7 Jan 2017 15:30:25 -0000 @@ -201,6 +201,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 +427,7 @@ LIST_INSERT_HEAD(&rlset->rs_gc, rl, r_aentry); rl = rl->r_next; } + rlset->rs_idcnt = 0; return 0; }