? 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, ¶m)) { 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_ */