? npftest.diff ? libnpftest/npf_stand.h Index: npfstream.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/npfstream.c,v retrieving revision 1.6 diff -u -u -r1.6 npfstream.c --- npfstream.c 8 Nov 2013 00:38:26 -0000 1.6 +++ npfstream.c 26 Dec 2016 22:23:48 -0000 @@ -16,6 +16,7 @@ #include +#if !defined(_NPF_STANDALONE) #include #include #include @@ -25,6 +26,7 @@ #include #include +#endif #include "npftest.h" Index: npftest.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/npftest.c,v retrieving revision 1.19 diff -u -u -r1.19 npftest.c --- npftest.c 25 Jan 2016 12:24:41 -0000 1.19 +++ npftest.c 26 Dec 2016 22:23:48 -0000 @@ -16,6 +16,8 @@ #include #include +#include +#if !defined(_NPF_STANDALONE) #include #include #include @@ -24,6 +26,7 @@ #include #include +#endif #include @@ -32,7 +35,7 @@ static bool verbose, quiet; __dead static void -usage(void) +usage(const char *progname) { printf("usage:\n" " %s [ -q | -v ] [ -c ] " @@ -49,7 +52,7 @@ "\t-L: list testnames and description for -T\n" "\t-q: quiet mode\n" "\t-v: verbose mode\n", - getprogname(), getprogname(), getprogname()); + progname, progname, progname); exit(EXIT_FAILURE); } @@ -117,7 +120,7 @@ /* Pass the XML configuration for NPF kernel component to load. */ error = rumpns_npf_test_load(xml); if (error) { - errx(EXIT_FAILURE, "npf_test_load: %s", strerror(error)); + errx(EXIT_FAILURE, "npf_test_load: %s\n", strerror(error)); } free(xml); @@ -171,6 +174,27 @@ return cdb; } +static void +npf_kern_init(void) +{ +#if !defined(_NPF_STANDALONE) + /* XXX rn_init */ + extern int rumpns_max_keylen; + rumpns_max_keylen = 1; + + rump_init(); + rump_schedule(); +#endif +} + +static void +npf_kern_fini(void) +{ +#if !defined(_NPF_STANDALONE) + rump_unschedule(); +#endif +} + int main(int argc, char **argv) { @@ -226,14 +250,13 @@ /* Note: RUMP_NCPU must be high enough. */ if ((nthreads = atoi(optarg)) > 0 && getenv("RUMP_NCPU") == NULL) { - char *val; - asprintf(&val, "%u", nthreads + 1); - setenv("RUMP_NCPU", val, 1); - free(val); + static char nthr[64]; + sprintf(nthr, "%u", nthreads + 1); + setenv("RUMP_NCPU", nthr, 1); } break; default: - usage(); + usage(argv[0]); } } @@ -243,20 +266,17 @@ * config should be loaded. */ if ((benchmark != NULL) == test && (stream && !interface)) { - usage(); + usage(argv[0]); } if (benchmark && (!config || !nthreads)) { errx(EXIT_FAILURE, "missing config for the benchmark or " "invalid thread count"); } - /* XXX rn_init */ - extern int rumpns_max_keylen; - rumpns_max_keylen = 1; - - rump_init(); - rump_schedule(); - + /* + * Initialise the NPF kernel component. + */ + npf_kern_init(); rumpns_npf_test_init(inet_pton, inet_ntop, random); if (config) { @@ -308,6 +328,7 @@ } if (!testname || strcmp("nat", testname) == 0) { + srandom(1); ok = rumpns_npf_nat_test(verbose); fail |= result("nat", ok); tname_matched = true; @@ -327,7 +348,10 @@ } } - rump_unschedule(); + npf_kern_fini(); +#if 0 + npf_test_fini(); +#endif if (testname && !tname_matched) errx(EXIT_FAILURE, "test \"%s\" unknown", testname); Index: npftest.h =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/npftest.h,v retrieving revision 1.13 diff -u -u -r1.13 npftest.h --- npftest.h 13 Feb 2014 03:34:40 -0000 1.13 +++ npftest.h 26 Dec 2016 22:23:48 -0000 @@ -10,11 +10,30 @@ #include #include +#if !defined(_NPF_STANDALONE) #include +#else +#define rumpns_npf_test_addif npf_test_addif +#define rumpns_npf_test_load npf_test_load +#define rumpns_npf_test_init npf_test_init +#define rumpns_npf_test_fini npf_test_fini +#define rumpns_npf_test_getif npf_test_getif +#define rumpns_npf_nbuf_test npf_nbuf_test +#define rumpns_npf_bpf_test npf_bpf_test +#define rumpns_npf_table_test npf_table_test +#define rumpns_npf_state_test npf_state_test +#define rumpns_npf_rule_test npf_rule_test +#define rumpns_npf_nat_test npf_nat_test +#define rumpns_npf_test_conc npf_test_conc +#define rumpns_npf_test_statetrack npf_test_statetrack +#endif + +#include "npf.h" void rumpns_npf_test_init(int (*)(int, const char *, void *), const char *(*)(int, const void *, char *, socklen_t), long (*)(void)); +void rumpns_npf_test_fini(void); int rumpns_npf_test_load(const void *); ifnet_t * rumpns_npf_test_addif(const char *, bool, bool); ifnet_t * rumpns_npf_test_getif(const char *); Index: libnpftest/npf_bpf_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c,v retrieving revision 1.7 diff -u -u -r1.7 npf_bpf_test.c --- libnpftest/npf_bpf_test.c 20 Jul 2014 00:37:41 -0000 1.7 +++ libnpftest/npf_bpf_test.c 26 Dec 2016 22:23:48 -0000 @@ -33,8 +33,10 @@ * NPF test of BPF coprocessor. */ +#ifdef _KERNEL #include #include +#endif #define NPF_BPFCOP #include "npf_impl.h" @@ -62,7 +64,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 }; + npf_cache_t npc = { .npc_info = 0, .npc_ctx = npf_getkernctx() }; uint32_t memstore[BPF_MEMWORDS]; bpf_args_t bc_args; struct mbuf *m; @@ -72,11 +74,14 @@ /* Layer 3 (IP + TCP). */ m = fill_packet(IPPROTO_TCP); - nbuf_init(&nbuf, m, dummy_ifp); + nbuf_init(npf_getkernctx(), &nbuf, m, dummy_ifp); npc.npc_nbuf = &nbuf; npf_cache_all(&npc); - +#ifdef _NPF_STANDALONE + bc_args.pkt = (const uint8_t *)nbuf_dataptr(&nbuf); +#else bc_args.pkt = (const uint8_t *)m; +#endif bc_args.buflen = m_length(m); bc_args.wirelen = bc_args.buflen; bc_args.mem = memstore; Index: libnpftest/npf_mbuf_subr.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c,v retrieving revision 1.5 diff -u -u -r1.5 npf_mbuf_subr.c --- libnpftest/npf_mbuf_subr.c 13 Feb 2014 03:34:40 -0000 1.5 +++ libnpftest/npf_mbuf_subr.c 26 Dec 2016 22:23:48 -0000 @@ -6,12 +6,108 @@ * Public Domain. */ +#ifdef _KERNEL #include #include +#endif #include "npf_impl.h" #include "npf_test.h" + +#if defined(_NPF_STANDALONE) +struct mbuf * +npfkern_m_get(int flags, int space) +{ + unsigned mlen = offsetof(struct mbuf, m_data0[space]); + struct mbuf *m; + + m = calloc(1, sizeof(struct mbuf)); + if (m) { + m->m_type = 1; + m->m_flags = flags; + m->m_data = m->m_data0; + } + return m; +} +#else +struct mbuf * +npfkern_m_get(int flags, int space) +{ + return m_get(flags, space); +} +#endif + +static void * +npfkern_m_getdata(const struct mbuf *m) +{ + return m->m_data; +} + +static struct mbuf * +npfkern_m_next(struct mbuf *m) +{ + return m->m_next; +} + +static size_t +npfkern_m_buflen(const struct mbuf *m) +{ + return m->m_len; +} + +size_t +npfkern_m_length(const struct mbuf *m) +{ + const struct mbuf *m0; + unsigned pktlen = 0; + + if ((m->m_flags & M_PKTHDR) != 0) + return m->m_pkthdr.len; + for (m0 = m; m0 != NULL; m0 = m0->m_next) + pktlen += m0->m_len; + return pktlen; +} + +void +npfkern_m_freem(struct mbuf *m) +{ +#ifdef _NPF_STANDALONE + struct mbuf *n; + + do { + n = m->m_next; + m->m_type = MT_FREE; + free(m); + m = n; + } while (m); +#else + m_freem(m); +#endif +} + +static bool +npfkern_m_ensure_contig(struct mbuf **m0, size_t len) +{ + struct mbuf *m1; + unsigned tlen; + char *dptr; + + tlen = npfkern_m_length(*m0); + if ((m1 = npfkern_m_get(M_PKTHDR, tlen)) == NULL) { + return false; + } + m1->m_pkthdr.len = m1->m_len = tlen; + dptr = m1->m_data; + for (struct mbuf *m = *m0; m != NULL; m = m->m_next) { + memcpy(dptr, m->m_data, m->m_len); + dptr += m->m_len; + } + *m0 = m1; + return true; +} + + struct mbuf * mbuf_getwithdata(const void *data, size_t len) { @@ -159,3 +255,14 @@ m->m_len += addlen; m_freem(m_orig); } + +const npf_mbufops_t npftest_mbufops = { + .alloc = npfkern_m_get, + .free = npfkern_m_freem, + .getdata = npfkern_m_getdata, + .getnext = npfkern_m_next, + .getlen = npfkern_m_buflen, + .getchainlen = npfkern_m_length, + .ensure_contig = npfkern_m_ensure_contig, + .ensure_writable = NULL, +}; Index: libnpftest/npf_nat_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c,v retrieving revision 1.9 diff -u -u -r1.9 npf_nat_test.c --- libnpftest/npf_nat_test.c 20 Jul 2014 00:37:41 -0000 1.9 +++ libnpftest/npf_nat_test.c 26 Dec 2016 22:23:48 -0000 @@ -6,7 +6,9 @@ * Public Domain. */ +#ifdef _KERNEL #include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -154,7 +156,7 @@ checkresult(bool verbose, unsigned i, struct mbuf *m, ifnet_t *ifp, int error) { const struct test_case *t = &test_cases[i]; - npf_cache_t npc = { .npc_info = 0 }; + npf_cache_t npc = { .npc_info = 0, .npc_ctx = npf_getkernctx() }; const int af = t->af; nbuf_t nbuf; @@ -165,7 +167,7 @@ return error == t->ret; } - nbuf_init(&nbuf, m, ifp); + nbuf_init(npf_getkernctx(), &nbuf, m, ifp); npc.npc_nbuf = &nbuf; if (!npf_cache_all(&npc)) { printf("error: could not fetch the packet data"); @@ -234,9 +236,11 @@ bool npf_nat_test(bool verbose) { + npf_t *npf = npf_getkernctx(); + for (unsigned i = 0; i < __arraycount(test_cases); i++) { const struct test_case *t = &test_cases[i]; - ifnet_t *ifp = ifunit(t->ifname); + ifnet_t *ifp = npf_test_getif(t->ifname); struct mbuf *m = fill_packet(t); int error; bool ret; @@ -245,7 +249,7 @@ printf("Interface %s is not configured.\n", t->ifname); return false; } - error = npf_packet_handler(NULL, &m, ifp, t->di); + error = npf_packet_handler(npf, &m, ifp, t->di); ret = checkresult(verbose, i, m, ifp, error); if (m) { m_freem(m); Index: libnpftest/npf_nbuf_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_nbuf_test.c,v retrieving revision 1.5 diff -u -u -r1.5 npf_nbuf_test.c --- libnpftest/npf_nbuf_test.c 8 Nov 2013 00:38:27 -0000 1.5 +++ libnpftest/npf_nbuf_test.c 26 Dec 2016 22:23:48 -0000 @@ -6,8 +6,10 @@ * Public Domain. */ +#ifdef _KERNEL #include #include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -36,7 +38,7 @@ void *nptr; int n; - nbuf_init(&nbuf, m, dummy_ifp); + nbuf_init(npf_getkernctx(), &nbuf, m, dummy_ifp); nptr = nbuf_advance(&nbuf, (random() % 16) + 1, (random() % 16) + 1); mbuf_consistency_check(&nbuf); Index: libnpftest/npf_perf_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c,v retrieving revision 1.4 diff -u -u -r1.4 npf_perf_test.c --- libnpftest/npf_perf_test.c 25 Jun 2014 00:21:42 -0000 1.4 +++ libnpftest/npf_perf_test.c 26 Dec 2016 22:23:48 -0000 @@ -6,12 +6,14 @@ * Public Domain. */ +#ifdef _KERNEL #include #include #include #include #include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -46,7 +48,8 @@ __dead static void worker(void *arg) { - ifnet_t *ifp = ifunit(IFNAME_INT); + npf_t *npf = npf_getkernctx(); + ifnet_t *ifp = npf_test_getif(IFNAME_INT); unsigned int i = (uintptr_t)arg; struct mbuf *m = fill_packet(i); uint64_t n = 0; @@ -56,7 +59,7 @@ while (!done) { int error; - error = npf_packet_handler(NULL, &m, ifp, PFIL_OUT); + error = npf_packet_handler(npf, &m, ifp, PFIL_OUT); KASSERT(error == 0); n++; } @@ -80,15 +83,15 @@ l = kmem_zalloc(sizeof(lwp_t *) * nthreads, KM_SLEEP); for (unsigned i = 0; i < nthreads; i++) { - const int flags = KTHREAD_MUSTJOIN | KTHREAD_MPSAFE; - error = kthread_create(PRI_NONE, flags, NULL, - worker, (void *)(uintptr_t)i, &l[i], "npfperf"); + error = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | + KTHREAD_MPSAFE, NULL, worker, (void *)(uintptr_t)i, + &l[i], "npfperf"); KASSERT(error == 0); } /* Let them spin! */ run = true; - kpause("perf", false, NSECS * hz, NULL); + kpause("perf", false, mstohz(NSECS * 1000), NULL); done = true; /* Wait until all threads exit and sum the counts. */ Index: libnpftest/npf_rule_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c,v retrieving revision 1.12 diff -u -u -r1.12 npf_rule_test.c --- libnpftest/npf_rule_test.c 10 Aug 2014 19:09:43 -0000 1.12 +++ libnpftest/npf_rule_test.c 26 Dec 2016 22:23:48 -0000 @@ -6,7 +6,9 @@ * Public Domain. */ +#ifdef _KERNEL #include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -74,17 +76,18 @@ static int npf_rule_raw_test(bool verbose, struct mbuf *m, ifnet_t *ifp, int di) { - npf_cache_t npc = { .npc_info = 0 }; + npf_t *npf = npf_getkernctx(); + npf_cache_t npc = { .npc_info = 0, .npc_ctx = npf }; nbuf_t nbuf; npf_rule_t *rl; int retfl, error; - nbuf_init(&nbuf, m, ifp); + nbuf_init(npf, &nbuf, m, ifp); npc.npc_nbuf = &nbuf; npf_cache_all(&npc); int slock = npf_config_read_enter(); - rl = npf_ruleset_inspect(&npc, npf_config_ruleset(), + rl = npf_ruleset_inspect(&npc, npf_config_ruleset(npf), di, NPF_LAYER_3); if (rl) { error = npf_rule_conclude(rl, &retfl); @@ -99,7 +102,7 @@ npf_test_case(u_int i, bool verbose) { const struct test_case *t = &test_cases[i]; - ifnet_t *ifp = ifunit(t->ifname); + ifnet_t *ifp = npf_test_getif(t->ifname); int error; struct mbuf *m = fill_packet(t); @@ -111,17 +114,19 @@ static npf_rule_t * npf_blockall_rule(void) { + npf_t *npf = npf_getkernctx(); prop_dictionary_t rldict; rldict = prop_dictionary_create(); prop_dictionary_set_uint32(rldict, "attr", NPF_RULE_IN | NPF_RULE_OUT | NPF_RULE_DYNAMIC); - return npf_rule_alloc(rldict); + return npf_rule_alloc(npf, rldict); } bool npf_rule_test(bool verbose) { + npf_t *npf = npf_getkernctx(); npf_ruleset_t *rlset; npf_rule_t *rl; bool fail = false; @@ -130,7 +135,7 @@ for (unsigned i = 0; i < __arraycount(test_cases); i++) { const struct test_case *t = &test_cases[i]; - ifnet_t *ifp = ifunit(t->ifname); + ifnet_t *ifp = npf_test_getif(t->ifname); int serror; if (ifp == NULL) { @@ -140,7 +145,7 @@ struct mbuf *m = fill_packet(t); error = npf_rule_raw_test(verbose, m, ifp, t->di); - serror = npf_packet_handler(NULL, &m, ifp, t->di); + serror = npf_packet_handler(npf, &m, ifp, t->di); if (m) { m_freem(m); @@ -161,8 +166,8 @@ error = npf_test_case(0, verbose); assert(error == RESULT_PASS); - npf_config_enter(); - rlset = npf_config_ruleset(); + npf_config_enter(npf); + rlset = npf_config_ruleset(npf); rl = npf_blockall_rule(); error = npf_ruleset_add(rlset, "test-rules", rl); @@ -175,7 +180,7 @@ error = npf_ruleset_remove(rlset, "test-rules", id); fail |= error != 0; - npf_config_exit(); + npf_config_exit(npf); error = npf_test_case(0, verbose); fail |= (error != RESULT_PASS); Index: libnpftest/npf_state_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_state_test.c,v retrieving revision 1.6 diff -u -u -r1.6 npf_state_test.c --- libnpftest/npf_state_test.c 20 Jul 2014 00:37:41 -0000 1.6 +++ libnpftest/npf_state_test.c 26 Dec 2016 22:23:48 -0000 @@ -6,8 +6,10 @@ * Public Domain. */ +#ifdef _KERNEL #include #include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -135,7 +137,7 @@ { ifnet_t *dummy_ifp = npf_test_addif(IFNAME_TEST, false, false); const tcp_meta_t *p = &packet_sequence[i]; - npf_cache_t npc = { .npc_info = 0 }; + npf_cache_t npc = { .npc_info = 0, .npc_ctx = npf_getkernctx() }; nbuf_t nbuf; int ret; @@ -145,7 +147,7 @@ return true; } - nbuf_init(&nbuf, construct_packet(p), dummy_ifp); + nbuf_init(npf_getkernctx(), &nbuf, construct_packet(p), dummy_ifp); npc.npc_nbuf = &nbuf; ret = npf_cache_all(&npc); KASSERT((ret & NPC_IPFRAG) == 0); Index: libnpftest/npf_table_test.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c,v retrieving revision 1.8 diff -u -u -r1.8 npf_table_test.c --- libnpftest/npf_table_test.c 6 Feb 2014 02:51:28 -0000 1.8 +++ libnpftest/npf_table_test.c 26 Dec 2016 22:23:48 -0000 @@ -6,8 +6,16 @@ * Public Domain. */ +#ifdef _KERNEL #include -#include +#include +#endif + +#ifdef __linux__ +#include +#else +#include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -23,25 +31,36 @@ "10.0.0.2", }; +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define U16_TO_LE(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#else +#define U16_TO_LE(x) (x) +#endif + static const uint16_t ip6_list[][8] = { { - htons(0xfe80), 0x0, 0x0, 0x0, - htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1234) + U16_TO_LE(0xfe80), 0x0, 0x0, 0x0, + U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff), + U16_TO_LE(0xfe10), U16_TO_LE(0x1234) }, { - htons(0xfe80), 0x0, 0x0, 0x0, - htons(0x2a0), htons(0xc0ff), 0x00, 0x0 + U16_TO_LE(0xfe80), 0x0, 0x0, 0x0, + U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff), 0x00, 0x0 }, { - htons(0xfe80), 0x0, 0x0, 0x0, + U16_TO_LE(0xfe80), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, { - htons(0xfe80), 0x0, 0x0, 0x0, - htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1230) + U16_TO_LE(0xfe80), 0x0, 0x0, 0x0, + U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff), + U16_TO_LE(0xfe10), U16_TO_LE(0x1230) } }; +#define check_ok(x) \ + ((x) ? true : (printf("fail at line %d\n", __LINE__), false)) + #define HASH_TID "hash-table" #define TREE_TID "tree-table" #define CDB_TID "cdb-table" @@ -58,19 +77,19 @@ npf_table_t *t; int error; - addr->s6_addr32[0] = inet_addr(ip_list[i]); + addr->word32[0] = inet_addr(ip_list[i]); t = npf_tableset_getbyname(tblset, HASH_TID); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error != 0); + fail |= !check_ok(error != 0); t = npf_tableset_getbyname(tblset, TREE_TID); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error != 0); + fail |= !check_ok(error != 0); } return fail; } @@ -88,71 +107,71 @@ u_int i; tblset = npf_tableset_create(3); - fail |= !(tblset != NULL); + fail |= !check_ok(tblset != NULL); /* Table ID 1, using hash table with 256 lists. */ t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, NULL, 256); - fail |= !(t1 != NULL); + fail |= !check_ok(t1 != NULL); error = npf_tableset_insert(tblset, t1); - fail |= !(error == 0); + fail |= !check_ok(error == 0); /* Check for double-insert. */ error = npf_tableset_insert(tblset, t1); - fail |= !(error != 0); + fail |= !check_ok(error != 0); /* Table ID 2, using a prefix tree. */ t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, NULL, 0); fail |= !(t2 != NULL); error = npf_tableset_insert(tblset, t2); - fail |= !(error == 0); + fail |= !check_ok(error == 0); /* Table ID 3, using a CDB. */ - cdb = malloc(size, M_TEMP, M_WAITOK); + cdb = kmem_alloc(size, KM_SLEEP); memcpy(cdb, blob, size); t3 = npf_table_create(CDB_TID, 2, NPF_TABLE_CDB, cdb, size); fail |= !(t3 != NULL); error = npf_tableset_insert(tblset, t3); - fail |= !(error == 0); + fail |= !check_ok(error == 0); /* Attempt to match non-existing entries - should fail. */ - addr->s6_addr32[0] = inet_addr(ip_list[0]); + addr->word32[0] = inet_addr(ip_list[0]); alen = sizeof(struct in_addr); t = npf_tableset_getbyname(tblset, HASH_TID); error = npf_table_lookup(t, alen, addr); - fail |= !(error != 0); + fail |= !check_ok(error != 0); t = npf_tableset_getbyname(tblset, TREE_TID); error = npf_table_lookup(t, alen, addr); - fail |= !(error != 0); + fail |= !check_ok(error != 0); /* Fill both tables with IP addresses. */ fail |= npf_table_test_fill4(tblset, addr); /* Attempt to add duplicates - should fail. */ - addr->s6_addr32[0] = inet_addr(ip_list[0]); + addr->word32[0] = inet_addr(ip_list[0]); alen = sizeof(struct in_addr); t = npf_tableset_getbyname(tblset, HASH_TID); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error != 0); + fail |= !check_ok(error != 0); t = npf_tableset_getbyname(tblset, TREE_TID); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error != 0); + fail |= !check_ok(error != 0); /* Match (validate) each IP entry. */ for (i = 0; i < __arraycount(ip_list); i++) { - addr->s6_addr32[0] = inet_addr(ip_list[i]); + addr->word32[0] = inet_addr(ip_list[i]); t = npf_tableset_getbyname(tblset, HASH_TID); error = npf_table_lookup(t, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); t = npf_tableset_getbyname(tblset, TREE_TID); error = npf_table_lookup(t, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); } /* IPv6 addresses. */ @@ -161,19 +180,19 @@ t = npf_tableset_getbyname(tblset, HASH_TID); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); error = npf_table_lookup(t, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); error = npf_table_remove(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); t = npf_tableset_getbyname(tblset, TREE_TID); error = npf_table_insert(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); error = npf_table_lookup(t, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); error = npf_table_remove(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); /* * Masking: 96, 32, 127. @@ -181,69 +200,69 @@ memcpy(addr, ip6_list[1], sizeof(ip6_list[1])); error = npf_table_insert(t, alen, addr, 96); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); error = npf_table_lookup(t, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[1], sizeof(ip6_list[1])); error = npf_table_remove(t, alen, addr, 96); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[2], sizeof(ip6_list[2])); error = npf_table_insert(t, alen, addr, 32); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); error = npf_table_lookup(t, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[2], sizeof(ip6_list[2])); error = npf_table_remove(t, alen, addr, 32); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[3], sizeof(ip6_list[3])); error = npf_table_insert(t, alen, addr, 126); - fail |= !(error == 0); + fail |= !check_ok(error == 0); memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); error = npf_table_lookup(t, alen, addr); - fail |= !(error != 0); + fail |= !check_ok(error != 0); memcpy(addr, ip6_list[3], sizeof(ip6_list[3])); error = npf_table_remove(t, alen, addr, 126); - fail |= !(error == 0); + fail |= !check_ok(error == 0); alen = sizeof(struct in_addr); /* Remove all IPv4 entries. */ for (i = 0; i < __arraycount(ip_list); i++) { - addr->s6_addr32[0] = inet_addr(ip_list[i]); + addr->word32[0] = inet_addr(ip_list[i]); t = npf_tableset_getbyname(tblset, HASH_TID); error = npf_table_remove(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); t = npf_tableset_getbyname(tblset, TREE_TID); error = npf_table_remove(t, alen, addr, nm); - fail |= !(error == 0); + fail |= !check_ok(error == 0); } /* Test CDB. */ - addr->s6_addr32[0] = inet_addr(ip_list[0]); + addr->word32[0] = inet_addr(ip_list[0]); alen = sizeof(struct in_addr); error = npf_table_lookup(t3, alen, addr); - fail |= !(error == 0); + fail |= !check_ok(error == 0); for (i = 1; i < __arraycount(ip_list) - 1; i++) { - addr->s6_addr32[0] = inet_addr(ip_list[i]); + addr->word32[0] = inet_addr(ip_list[i]); alen = sizeof(struct in_addr); error = npf_table_lookup(t3, alen, addr); - fail |= !(error != 0); + fail |= !check_ok(error != 0); } npf_tableset_destroy(tblset); Index: libnpftest/npf_test.h =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_test.h,v retrieving revision 1.15 diff -u -u -r1.15 npf_test.h --- libnpftest/npf_test.h 13 Feb 2014 03:34:40 -0000 1.15 +++ libnpftest/npf_test.h 26 Dec 2016 22:23:48 -0000 @@ -7,6 +7,7 @@ #ifndef _LIB_NPF_TEST_H_ #define _LIB_NPF_TEST_H_ +#ifdef _KERNEL #include #include @@ -23,6 +24,7 @@ #include #include #include +#endif /* Test interfaces and IP addresses. */ #define IFNAME_EXT "npftest0" @@ -46,9 +48,46 @@ #define REMOTE_IP6 "2001:db8:fefe::1010" #define EXPECTED_IP6 "2001:db8:1:d550::1234" +#if defined(_NPF_STANDALONE) + +#define MLEN 512 + +struct mbuf { + unsigned m_flags; + int m_type; + unsigned m_len; + void * m_next; + struct { + int len; + } m_pkthdr; + char * m_data; + char m_data0[MLEN]; +}; + + +#define MT_FREE 0 +#define M_UNWRITABLE(m, l) false +#define M_NOWAIT 0x00001 +#define M_PKTHDR 0x00002 + +#define m_get(x, y) npfkern_m_get(0, MLEN) +#define m_gethdr(x, y) npfkern_m_get(M_PKTHDR, MLEN) +#define m_length(m) npfkern_m_length(m) +#define m_freem(m) npfkern_m_freem(m) +#define mtod(m, t) ((t)((m)->m_data)) + +#endif + +const npf_mbufops_t npftest_mbufops; + +struct mbuf * npfkern_m_get(int, int); +size_t npfkern_m_length(const struct mbuf *); +void npfkern_m_freem(struct mbuf *); + void npf_test_init(int (*)(int, const char *, void *), const char *(*)(int, const void *, char *, socklen_t), long (*)(void)); +void npf_test_fini(void); int npf_test_load(const void *); ifnet_t * npf_test_addif(const char *, bool, bool); ifnet_t * npf_test_getif(const char *); Index: libnpftest/npf_test_subr.c =================================================================== RCS file: /cvsroot/src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c,v retrieving revision 1.11 diff -u -u -r1.11 npf_test_subr.c --- libnpftest/npf_test_subr.c 10 Aug 2014 16:44:37 -0000 1.11 +++ libnpftest/npf_test_subr.c 26 Dec 2016 22:23:48 -0000 @@ -6,10 +6,12 @@ * Public Domain. */ +#ifdef _KERNEL #include #include #include #include +#endif #include "npf_impl.h" #include "npf_test.h" @@ -25,28 +27,71 @@ static void npf_state_sample(npf_state_t *, bool); +#ifndef __NetBSD__ +/* + * Standalone NPF: we define the same struct ifnet members + * to reduce the npf_ifops_t implementation differences. + */ +struct ifnet { + char if_xname[32]; + void * if_softc; + TAILQ_ENTRY(ifnet) if_list; +}; +#endif + +static TAILQ_HEAD(, ifnet) npftest_ifnet_list; + +static const char * npftest_ifop_getname(ifnet_t *); +static void npftest_ifop_flush(void *); +static void * npftest_ifop_getmeta(const ifnet_t *); +static void npftest_ifop_setmeta(ifnet_t *, void *); + +static const npf_ifops_t npftest_ifops = { + .getname = npftest_ifop_getname, + .lookup = npf_test_getif, + .flush = npftest_ifop_flush, + .getmeta = npftest_ifop_getmeta, + .setmeta = npftest_ifop_setmeta, +}; + void npf_test_init(int (*pton_func)(int, const char *, void *), const char *(*ntop_func)(int, const void *, char *, socklen_t), long (*rndfunc)(void)) { + npf_t *npf; + + npf_sysinit(1); + npf = npf_create(0, &npftest_mbufops, &npftest_ifops); + npf_thread_register(npf); + npf_setkernctx(npf); + npf_state_setsampler(npf_state_sample); _pton_func = pton_func; _ntop_func = ntop_func; _random_func = rndfunc; } +void +npf_test_fini(void) +{ + npf_t *npf = npf_getkernctx(); + npf_destroy(npf); + npf_sysfini(); +} + int npf_test_load(const void *xml) { prop_dictionary_t npf_dict = prop_dictionary_internalize(xml); - return npfctl_load(0, npf_dict); + return npfctl_load(npf_getkernctx(), 0, npf_dict); } ifnet_t * npf_test_addif(const char *ifname, bool reg, bool verbose) { - ifnet_t *ifp = if_alloc(IFT_OTHER); + npf_t *npf = npf_getkernctx(); + ifnet_t *ifp = malloc(sizeof(*ifp), M_TEST, M_WAITOK|M_ZERO); /* * This is a "fake" interface with explicitly set index. @@ -54,14 +99,11 @@ * may not trigger npf_ifmap_attach(), so we call it manually. */ strlcpy(ifp->if_xname, ifname, sizeof(ifp->if_xname)); - ifp->if_dlt = DLT_NULL; - ifp->if_index = 0; - if_attach(ifp); - if_alloc_sadl(ifp); + TAILQ_INSERT_TAIL(&npftest_ifnet_list, ifp, if_list); - npf_ifmap_attach(ifp); + npf_ifmap_attach(npf, ifp); if (reg) { - npf_ifmap_register(ifname); + npf_ifmap_register(npf, ifname); } if (verbose) { @@ -70,10 +112,43 @@ return ifp; } +static const char * +npftest_ifop_getname(ifnet_t *ifp) +{ + return ifp->if_xname; +} + ifnet_t * npf_test_getif(const char *ifname) { - return ifunit(ifname); + ifnet_t *ifp; + + TAILQ_FOREACH(ifp, &npftest_ifnet_list, if_list) { + if (!strcmp(ifp->if_xname, ifname)) + return ifp; + } + return NULL; +} + +static void +npftest_ifop_flush(void *arg) +{ + ifnet_t *ifp; + + TAILQ_FOREACH(ifp, &npftest_ifnet_list, if_list) + ifp->if_softc = arg; +} + +static void * +npftest_ifop_getmeta(const ifnet_t *ifp) +{ + return ifp->if_softc; +} + +static void +npftest_ifop_setmeta(ifnet_t *ifp, void *arg) +{ + ifp->if_softc = arg; } /* @@ -92,11 +167,12 @@ npf_test_statetrack(const void *data, size_t len, ifnet_t *ifp, bool forw, int64_t *result) { + npf_t *npf = npf_getkernctx(); struct mbuf *m; int i = 0, error; m = mbuf_getwithdata(data, len); - error = npf_packet_handler(NULL, &m, ifp, forw ? PFIL_OUT : PFIL_IN); + error = npf_packet_handler(npf, &m, ifp, forw ? PFIL_OUT : PFIL_IN); if (error) { assert(m == NULL); return error; @@ -137,6 +213,7 @@ return _ntop_func(af, src, dst, size); } +#ifdef _KERNEL /* * Need to override cprng_fast32() -- we need deterministic PRNG. */ @@ -145,3 +222,4 @@ { return (uint32_t)(_random_func ? _random_func() : random()); } +#endif