NPF: add support for table naming and remove NPF_TABLE_SLOTS (there is

just an arbitrary sanity limit of NPF_MAX_TABLES currently set to 128).

Few misc fixes.  Bump NPF_VERSION.
This commit is contained in:
rmind 2013-11-12 00:46:34 +00:00
parent 80f3dc5a69
commit 1e7342c150
15 changed files with 341 additions and 230 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: npf.3,v 1.11 2013/11/08 13:17:45 wiz Exp $
.\" $NetBSD: npf.3,v 1.12 2013/11/12 00:46:34 rmind Exp $
.\"
.\" Copyright (c) 2011-2013 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 November 7, 2013
.Dd November 12, 2013
.Dt NPF 3
.Os
.Sh NAME
@ -78,7 +78,7 @@
.Fn npf_nat_insert "nl_config_t *ncf" "nl_nat_t *nt" "pri_t pri"
.\" ---
.Ft nl_table_t *
.Fn npf_table_create "u_int id" "int type"
.Fn npf_table_create "const char *name", "u_int id" "int type"
.Ft int
.Fn npf_table_add_entry "nl_table_t *tl" "int af" \
"in_addr_t addr" "in_addr_t mask"
@ -261,7 +261,7 @@ Insert NAT policy, its rule, into the specified configuration.
.\" -----
.Ss Table interface
.Bl -tag -width 4n
.It Fn npf_table_create "index" "type"
.It Fn npf_table_create "name" "index" "type"
Create NPF table of specified type.
The following types are supported:
.Bl -tag -width "NPF_TABLE_TREE "
@ -269,7 +269,9 @@ The following types are supported:
Indicates to use hash table for storage.
.It Dv NPF_TABLE_TREE
Indicates to use red-black tree for storage.
Table is identified by
Table is identified by the
.Fa name
and
.Fa index ,
which should be in the range between 1 and
.Dv NPF_MAX_TABLE_ID .

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf.c,v 1.22 2013/11/08 00:38:27 rmind Exp $ */
/* $NetBSD: npf.c,v 1.23 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.22 2013/11/08 00:38:27 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.23 2013/11/12 00:46:34 rmind Exp $");
#include <sys/types.h>
#include <netinet/in_systm.h>
@ -892,7 +892,7 @@ npf_nat_getmap(nl_nat_t *nt, npf_addr_t *addr, size_t *alen, in_port_t *port)
*/
nl_table_t *
npf_table_create(u_int id, int type)
npf_table_create(const char *name, u_int id, int type)
{
prop_dictionary_t tldict;
prop_array_t tblents;
@ -907,6 +907,7 @@ npf_table_create(u_int id, int type)
free(tl);
return NULL;
}
prop_dictionary_set_cstring(tldict, "name", name);
prop_dictionary_set_uint32(tldict, "id", id);
prop_dictionary_set_int32(tldict, "type", type);
@ -1014,12 +1015,22 @@ unsigned
npf_table_getid(nl_table_t *tl)
{
prop_dictionary_t tldict = tl->ntl_dict;
u_int id = 0;
unsigned id = (unsigned)-1;
prop_dictionary_get_uint32(tldict, "id", &id);
return id;
}
const char *
npf_table_getname(nl_table_t *tl)
{
prop_dictionary_t tldict = tl->ntl_dict;
const char *tname = NULL;
prop_dictionary_get_cstring_nocopy(tldict, "name", &tname);
return tname;
}
int
npf_table_gettype(nl_table_t *tl)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf.h,v 1.19 2013/11/08 00:38:27 rmind Exp $ */
/* $NetBSD: npf.h,v 1.20 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
@ -108,7 +108,7 @@ nl_nat_t * npf_nat_create(int, u_int, const char *,
npf_addr_t *, int, in_port_t);
int npf_nat_insert(nl_config_t *, nl_nat_t *, pri_t);
nl_table_t * npf_table_create(u_int, int);
nl_table_t * npf_table_create(const char *, u_int, int);
int npf_table_add_entry(nl_table_t *, int,
const npf_addr_t *, const npf_netmask_t);
bool npf_table_exists_p(nl_config_t *, u_int);
@ -130,6 +130,7 @@ const void * npf_rule_getinfo(nl_rule_t *, size_t *);
const char * npf_rule_getproc(nl_rule_t *);
nl_table_t * npf_table_iterate(nl_config_t *);
const char * npf_table_getname(nl_table_t *);
unsigned npf_table_getid(nl_table_t *);
int npf_table_gettype(nl_table_t *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf.h,v 1.32 2013/11/08 00:38:26 rmind Exp $ */
/* $NetBSD: npf.h,v 1.33 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@ -45,7 +45,7 @@
#include <netinet/in_systm.h>
#include <netinet/in.h>
#define NPF_VERSION 11
#define NPF_VERSION 12
/*
* Public declarations and definitions.
@ -231,6 +231,8 @@ bool npf_autounload_p(void);
#define NPF_TABLE_HASH 1
#define NPF_TABLE_TREE 2
#define NPF_TABLE_MAXNAMELEN 32
/* Layers. */
#define NPF_LAYER_2 2
#define NPF_LAYER_3 3
@ -272,7 +274,7 @@ typedef struct npf_ioctl_buf {
typedef struct npf_ioctl_table {
int nct_cmd;
u_int nct_tid;
const char * nct_name;
union {
npf_ioctl_ent_t ent;
npf_ioctl_buf_t buf;

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_bpf.c,v 1.1 2013/09/19 01:04:46 rmind Exp $ */
/* $NetBSD: npf_bpf.c,v 1.2 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.1 2013/09/19 01:04:46 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.2 2013/11/12 00:46:34 rmind Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -145,11 +145,15 @@ npf_cop_table(const struct mbuf *pkt, void *arg, uint32_t A, uint32_t *M)
npf_tableset_t *tblset = npf_config_tableset();
const uint32_t tid = A & (SRC_FLAG_BIT - 1);
const npf_addr_t *addr;
npf_table_t *t;
KASSERT(npc != NULL);
KASSERT(npf_iscached(npc, NPC_IP46));
memset(M, 0, sizeof(uint32_t) * BPF_MEMWORDS);
if ((t = npf_tableset_getbyid(tblset, tid)) == NULL) {
return 0;
}
addr = (A & SRC_FLAG_BIT) ? npc->npc_srcip : npc->npc_dstip;
return npf_table_lookup(tblset, tid, npc->npc_alen, addr) == 0;
return npf_table_lookup(t, npc->npc_alen, addr) == 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_conf.c,v 1.3 2013/11/08 00:38:26 rmind Exp $ */
/* $NetBSD: npf_conf.c,v 1.4 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.3 2013/11/08 00:38:26 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.4 2013/11/12 00:46:34 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -86,7 +86,7 @@ npf_config_init(void)
/* Load the empty configuration. */
dict = prop_dictionary_create();
tset = npf_tableset_create();
tset = npf_tableset_create(0);
rpset = npf_rprocset_create();
rlset = npf_ruleset_create(0);
nset = npf_ruleset_create(0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_ctl.c,v 1.31 2013/11/08 00:38:26 rmind Exp $ */
/* $NetBSD: npf_ctl.c,v 1.32 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.31 2013/11/08 00:38:26 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.32 2013/11/12 00:46:34 rmind Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@ -95,6 +95,7 @@ npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables,
prop_dictionary_t ent;
prop_object_iterator_t eit;
prop_array_t entries;
const char *name;
npf_table_t *t;
u_int tid;
int type;
@ -106,17 +107,22 @@ npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables,
break;
}
/* Table ID and type. */
/* Table name, ID and type. Validate them. */
if (!prop_dictionary_get_cstring_nocopy(tbldict, "name", &name)) {
NPF_ERR_DEBUG(errdict);
error = EINVAL;
break;
}
prop_dictionary_get_uint32(tbldict, "id", &tid);
prop_dictionary_get_int32(tbldict, "type", &type);
/* Validate them, check for duplicate IDs. */
error = npf_table_check(tblset, tid, type);
if (error)
error = npf_table_check(tblset, name, tid, type);
if (error) {
NPF_ERR_DEBUG(errdict);
break;
}
/* Create and insert the table. */
t = npf_table_create(tid, type, 1024); /* XXX */
t = npf_table_create(name, tid, type, 1024); /* XXX */
if (t == NULL) {
NPF_ERR_DEBUG(errdict);
error = ENOMEM;
@ -144,7 +150,7 @@ npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables,
prop_dictionary_get_uint8(ent, "mask", &mask);
alen = prop_data_size(obj);
error = npf_table_insert(tblset, tid, alen, addr, mask);
error = npf_table_insert(t, alen, addr, mask);
if (error)
break;
}
@ -478,16 +484,22 @@ npfctl_reload(u_long cmd, void *data)
}
/* Tables. */
tblset = npf_tableset_create();
tables = prop_dictionary_get(npf_dict, "tables");
if ((nitems = prop_array_count(tables)) > NPF_MAX_TABLES) {
goto fail;
}
tblset = npf_tableset_create(nitems);
error = npf_mk_tables(tblset, tables, errdict);
if (error) {
goto fail;
}
/* Rule procedures. */
rpset = npf_rprocset_create();
rprocs = prop_dictionary_get(npf_dict, "rprocs");
if ((nitems = prop_array_count(rprocs)) > NPF_MAX_RPROCS) {
goto fail;
}
rpset = npf_rprocset_create();
error = npf_mk_rprocs(rpset, rprocs, errdict);
if (error) {
goto fail;
@ -778,39 +790,48 @@ int
npfctl_table(void *data)
{
const npf_ioctl_table_t *nct = data;
npf_tableset_t *tblset;
int error;
char tname[NPF_TABLE_MAXNAMELEN];
npf_tableset_t *ts;
npf_table_t *t;
int s, error;
//npf_config_ref();
tblset = npf_config_tableset();
error = copyinstr(nct->nct_name, tname, sizeof(tname), NULL);
if (error) {
return error;
}
s = npf_config_read_enter(); /* XXX */
ts = npf_config_tableset();
if ((t = npf_tableset_getbyname(ts, tname)) == NULL) {
npf_config_read_exit(s);
return EINVAL;
}
switch (nct->nct_cmd) {
case NPF_CMD_TABLE_LOOKUP:
error = npf_table_lookup(tblset, nct->nct_tid,
nct->nct_data.ent.alen, &nct->nct_data.ent.addr);
error = npf_table_lookup(t, nct->nct_data.ent.alen,
&nct->nct_data.ent.addr);
break;
case NPF_CMD_TABLE_ADD:
error = npf_table_insert(tblset, nct->nct_tid,
nct->nct_data.ent.alen, &nct->nct_data.ent.addr,
nct->nct_data.ent.mask);
error = npf_table_insert(t, nct->nct_data.ent.alen,
&nct->nct_data.ent.addr, nct->nct_data.ent.mask);
break;
case NPF_CMD_TABLE_REMOVE:
error = npf_table_remove(tblset, nct->nct_tid,
nct->nct_data.ent.alen, &nct->nct_data.ent.addr,
nct->nct_data.ent.mask);
error = npf_table_remove(t, nct->nct_data.ent.alen,
&nct->nct_data.ent.addr, nct->nct_data.ent.mask);
break;
case NPF_CMD_TABLE_LIST:
error = npf_table_list(tblset, nct->nct_tid,
nct->nct_data.buf.buf, nct->nct_data.buf.len);
error = npf_table_list(t, nct->nct_data.buf.buf,
nct->nct_data.buf.len);
break;
case NPF_CMD_TABLE_FLUSH:
error = npf_table_flush(tblset, nct->nct_tid);
error = npf_table_flush(t);
break;
default:
error = EINVAL;
break;
}
//npf_config_unref();
npf_config_read_exit(s);
return error;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_impl.h,v 1.37 2013/11/08 00:38:26 rmind Exp $ */
/* $NetBSD: npf_impl.h,v 1.38 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@ -86,11 +86,11 @@ typedef struct npf_session npf_session_t;
struct npf_sehash;
struct npf_table;
struct npf_tableset;
typedef struct npf_sehash npf_sehash_t;
typedef struct npf_table npf_table_t;
typedef npf_table_t * npf_tableset_t;
typedef struct npf_tableset npf_tableset_t;
/*
* DEFINITIONS.
@ -101,8 +101,9 @@ typedef npf_session_t *(*npf_alg_sfunc_t)(npf_cache_t *, nbuf_t *, int);
typedef void (*npf_workfunc_t)(void);
/* Some artificial limits. */
#define NPF_TABLE_SLOTS 32
#define NPF_MAX_RULES (1024 * 1024)
#define NPF_MAX_TABLES 128
#define NPF_MAX_RPROCS 128
#define NPF_MAX_IFMAP 64
/*
@ -216,23 +217,24 @@ void npf_tableset_sysfini(void);
extern const pt_tree_ops_t npf_table_ptree_ops;
npf_tableset_t *npf_tableset_create(void);
npf_tableset_t *npf_tableset_create(u_int);
void npf_tableset_destroy(npf_tableset_t *);
int npf_tableset_insert(npf_tableset_t *, npf_table_t *);
npf_table_t * npf_tableset_getbyname(npf_tableset_t *, const char *);
npf_table_t * npf_tableset_getbyid(npf_tableset_t *, u_int);
void npf_tableset_reload(npf_tableset_t *, npf_tableset_t *);
npf_table_t * npf_table_create(u_int, int, size_t);
npf_table_t * npf_table_create(const char *, u_int, int, size_t);
void npf_table_destroy(npf_table_t *);
int npf_table_check(const npf_tableset_t *, u_int, int);
int npf_table_insert(npf_tableset_t *, u_int,
const int, const npf_addr_t *, const npf_netmask_t);
int npf_table_remove(npf_tableset_t *, u_int,
const int, const npf_addr_t *, const npf_netmask_t);
int npf_table_lookup(npf_tableset_t *, u_int,
const int, const npf_addr_t *);
int npf_table_list(npf_tableset_t *, u_int, void *, size_t);
int npf_table_flush(npf_tableset_t *, u_int);
int npf_table_check(npf_tableset_t *, const char *, u_int, int);
int npf_table_insert(npf_table_t *, const int,
const npf_addr_t *, const npf_netmask_t);
int npf_table_remove(npf_table_t *, const int,
const npf_addr_t *, const npf_netmask_t);
int npf_table_lookup(npf_table_t *, const int, const npf_addr_t *);
int npf_table_list(npf_table_t *, void *, size_t);
int npf_table_flush(npf_table_t *);
/* Ruleset interface. */
npf_ruleset_t * npf_ruleset_create(size_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_tableset.c,v 1.18 2013/05/19 20:45:34 rmind Exp $ */
/* $NetBSD: npf_tableset.c,v 1.19 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.18 2013/05/19 20:45:34 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.19 2013/11/12 00:46:34 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -57,10 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.18 2013/05/19 20:45:34 rmind Exp
#include "npf_impl.h"
/*
* Table structures.
*/
typedef struct npf_tblent {
union {
LIST_ENTRY(npf_tblent) hashq;
@ -73,22 +69,36 @@ typedef struct npf_tblent {
LIST_HEAD(npf_hashl, npf_tblent);
struct npf_table {
char t_name[16];
/* Lock and reference count. */
krwlock_t t_lock;
u_int t_refcnt;
/* Total number of items. */
u_int t_nitems;
/* Table ID. */
u_int t_id;
/* The storage type can be: a) hash b) tree. */
int t_type;
/*
* The storage type can be: a) hash b) tree.
* There are separate trees for IPv4 and IPv6.
*/
struct npf_hashl * t_hashl;
u_long t_hashmask;
/* Separate trees for IPv4 and IPv6. */
pt_tree_t t_tree[2];
/*
* Table ID, type and lock. The ID may change during the
* config reload, it is protected by the npf_config_lock.
*/
int t_type;
u_int t_id;
krwlock_t t_lock;
/* The number of items, reference count and table name. */
u_int t_nitems;
u_int t_refcnt;
char t_name[NPF_TABLE_MAXNAMELEN];
};
struct npf_tableset {
u_int ts_nitems;
npf_table_t * ts_map[];
};
#define NPF_TABLESET_SIZE(n) \
(offsetof(npf_tableset_t, ts_map[n]) * sizeof(npf_table_t *))
#define NPF_ADDRLEN2TREE(alen) ((alen) >> 4)
static pool_cache_t tblent_cache __read_mostly;
@ -99,7 +109,6 @@ static pool_cache_t tblent_cache __read_mostly;
void
npf_tableset_sysinit(void)
{
tblent_cache = pool_cache_init(sizeof(npf_tblent_t), coherency_unit,
0, 0, "npftblpl", NULL, IPL_NONE, NULL, NULL, NULL);
}
@ -107,36 +116,32 @@ npf_tableset_sysinit(void)
void
npf_tableset_sysfini(void)
{
pool_cache_destroy(tblent_cache);
}
npf_tableset_t *
npf_tableset_create(void)
npf_tableset_create(u_int nitems)
{
const size_t sz = NPF_TABLE_SLOTS * sizeof(npf_table_t *);
return kmem_zalloc(sz, KM_SLEEP);
npf_tableset_t *ts = kmem_zalloc(NPF_TABLESET_SIZE(nitems), KM_SLEEP);
ts->ts_nitems = nitems;
return ts;
}
void
npf_tableset_destroy(npf_tableset_t *tblset)
npf_tableset_destroy(npf_tableset_t *ts)
{
const size_t sz = NPF_TABLE_SLOTS * sizeof(npf_table_t *);
npf_table_t *t;
u_int tid;
/*
* Destroy all tables (no references should be held, as ruleset
* should be destroyed before).
* Destroy all tables (no references should be held, since the
* ruleset should be destroyed before).
*/
for (tid = 0; tid < NPF_TABLE_SLOTS; tid++) {
t = tblset[tid];
for (u_int tid = 0; tid < ts->ts_nitems; tid++) {
npf_table_t *t = ts->ts_map[tid];
if (t && atomic_dec_uint_nv(&t->t_refcnt) == 0) {
npf_table_destroy(t);
}
}
kmem_free(tblset, sz);
kmem_free(ts, NPF_TABLESET_SIZE(ts->ts_nitems));
}
/*
@ -145,16 +150,16 @@ npf_tableset_destroy(npf_tableset_t *tblset)
* => Returns 0 on success. Fails and returns error if ID is already used.
*/
int
npf_tableset_insert(npf_tableset_t *tblset, npf_table_t *t)
npf_tableset_insert(npf_tableset_t *ts, npf_table_t *t)
{
const u_int tid = t->t_id;
int error;
KASSERT((u_int)tid < NPF_TABLE_SLOTS);
KASSERT((u_int)tid < ts->ts_nitems);
if (tblset[tid] == NULL) {
if (ts->ts_map[tid] == NULL) {
atomic_inc_uint(&t->t_refcnt);
tblset[tid] = t;
ts->ts_map[tid] = t;
error = 0;
} else {
error = EEXIST;
@ -162,6 +167,32 @@ npf_tableset_insert(npf_tableset_t *tblset, npf_table_t *t)
return error;
}
/*
* npf_tableset_getbyname: look for a table in the set given the name.
*/
npf_table_t *
npf_tableset_getbyname(npf_tableset_t *ts, const char *name)
{
npf_table_t *t;
for (u_int tid = 0; tid < ts->ts_nitems; tid++) {
if ((t = ts->ts_map[tid]) == NULL)
continue;
if (strcmp(name, t->t_name) == 0)
return t;
}
return NULL;
}
npf_table_t *
npf_tableset_getbyid(npf_tableset_t *ts, u_int tid)
{
if (__predict_true(tid < ts->ts_nitems)) {
return ts->ts_map[tid];
}
return NULL;
}
/*
* npf_tableset_reload: iterate all tables and if the new table is of the
* same type and has no items, then we preserve the old one and its entries.
@ -169,26 +200,44 @@ npf_tableset_insert(npf_tableset_t *tblset, npf_table_t *t)
* => The caller is responsible for providing synchronisation.
*/
void
npf_tableset_reload(npf_tableset_t *ntset, npf_tableset_t *otset)
npf_tableset_reload(npf_tableset_t *nts, npf_tableset_t *ots)
{
for (int i = 0; i < NPF_TABLE_SLOTS; i++) {
npf_table_t *t = ntset[i], *ot = otset[i];
for (u_int tid = 0; tid < nts->ts_nitems; tid++) {
npf_table_t *t, *ot;
if (t == NULL || ot == NULL) {
if ((t = nts->ts_map[tid]) == NULL) {
continue;
}
if (t->t_nitems || t->t_type != ot->t_type) {
/* If our table has entries, just load it. */
if (t->t_nitems) {
continue;
}
/* Look for a currently existing table with such name. */
ot = npf_tableset_getbyname(ots, t->t_name);
if (ot == NULL) {
/* Not found: we have a new table. */
continue;
}
/* Found. Did the type change? */
if (t->t_type != ot->t_type) {
/* Yes, load the new. */
continue;
}
/*
* Acquire a reference since the table has to be kept
* in the old tableset.
* Preserve the current table. Acquire a reference since
* we are keeping it in the old table set. Update its ID.
*/
atomic_inc_uint(&ot->t_refcnt);
ntset[i] = ot;
nts->ts_map[tid] = ot;
/* Only reference, never been visible. */
KASSERT(npf_config_locked_p());
ot->t_id = tid;
/* Destroy the new table (we hold only reference). */
t->t_refcnt--;
npf_table_destroy(t);
}
@ -250,13 +299,13 @@ table_tree_destroy(pt_tree_t *tree)
* npf_table_create: create table with a specified ID.
*/
npf_table_t *
npf_table_create(u_int tid, int type, size_t hsize)
npf_table_create(const char *name, u_int tid, int type, size_t hsize)
{
npf_table_t *t;
KASSERT((u_int)tid < NPF_TABLE_SLOTS);
t = kmem_zalloc(sizeof(npf_table_t), KM_SLEEP);
strlcpy(t->t_name, name, NPF_TABLE_MAXNAMELEN);
switch (type) {
case NPF_TABLE_TREE:
ptree_init(&t->t_tree[0], &npf_table_ptree_ops,
@ -310,21 +359,26 @@ npf_table_destroy(npf_table_t *t)
}
/*
* npf_table_check: validate ID and type.
* npf_table_check: validate the name, ID and type.
*/
int
npf_table_check(const npf_tableset_t *tset, u_int tid, int type)
npf_table_check(npf_tableset_t *ts, const char *name, u_int tid, int type)
{
if ((u_int)tid >= NPF_TABLE_SLOTS) {
if ((u_int)tid >= ts->ts_nitems) {
return EINVAL;
}
if (tset[tid] != NULL) {
if (ts->ts_map[tid] != NULL) {
return EEXIST;
}
if (type != NPF_TABLE_TREE && type != NPF_TABLE_HASH) {
return EINVAL;
}
if (strlen(name) >= NPF_TABLE_MAXNAMELEN) {
return ENAMETOOLONG;
}
if (npf_tableset_getbyname(ts, name)) {
return EINVAL;
}
return 0;
}
@ -332,11 +386,10 @@ static int
table_cidr_check(const u_int aidx, const npf_addr_t *addr,
const npf_netmask_t mask)
{
if (mask > NPF_MAX_NETMASK && mask != NPF_NO_NETMASK) {
if (aidx > 1) {
return EINVAL;
}
if (aidx > 1) {
if (mask > NPF_MAX_NETMASK && mask != NPF_NO_NETMASK) {
return EINVAL;
}
@ -354,18 +407,13 @@ table_cidr_check(const u_int aidx, const npf_addr_t *addr,
* npf_table_insert: add an IP CIDR entry into the table.
*/
int
npf_table_insert(npf_tableset_t *tset, u_int tid, const int alen,
npf_table_insert(npf_table_t *t, const int alen,
const npf_addr_t *addr, const npf_netmask_t mask)
{
const u_int aidx = NPF_ADDRLEN2TREE(alen);
npf_tblent_t *ent;
npf_table_t *t;
int error;
if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
return EINVAL;
}
error = table_cidr_check(aidx, addr, mask);
if (error) {
return error;
@ -430,12 +478,11 @@ npf_table_insert(npf_tableset_t *tset, u_int tid, const int alen,
* npf_table_remove: remove the IP CIDR entry from the table.
*/
int
npf_table_remove(npf_tableset_t *tset, u_int tid, const int alen,
npf_table_remove(npf_table_t *t, const int alen,
const npf_addr_t *addr, const npf_netmask_t mask)
{
const u_int aidx = NPF_ADDRLEN2TREE(alen);
npf_tblent_t *ent;
npf_table_t *t;
int error;
error = table_cidr_check(aidx, addr, mask);
@ -443,10 +490,6 @@ npf_table_remove(npf_tableset_t *tset, u_int tid, const int alen,
return error;
}
if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
return EINVAL;
}
rw_enter(&t->t_lock, RW_WRITER);
switch (t->t_type) {
case NPF_TABLE_HASH: {
@ -487,21 +530,15 @@ npf_table_remove(npf_tableset_t *tset, u_int tid, const int alen,
* the contents with the specified IP address.
*/
int
npf_table_lookup(npf_tableset_t *tset, u_int tid,
const int alen, const npf_addr_t *addr)
npf_table_lookup(npf_table_t *t, const int alen, const npf_addr_t *addr)
{
const u_int aidx = NPF_ADDRLEN2TREE(alen);
npf_tblent_t *ent;
npf_table_t *t;
if (__predict_false(aidx > 1)) {
return EINVAL;
}
if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
return EINVAL;
}
rw_enter(&t->t_lock, RW_READER);
switch (t->t_type) {
case NPF_TABLE_HASH: {
@ -563,16 +600,11 @@ table_tree_list(pt_tree_t *tree, npf_netmask_t maxmask, void *ubuf,
* npf_table_list: copy a list of all table entries into a userspace buffer.
*/
int
npf_table_list(npf_tableset_t *tset, u_int tid, void *ubuf, size_t len)
npf_table_list(npf_table_t *t, void *ubuf, size_t len)
{
npf_table_t *t;
size_t off = 0;
int error = 0;
if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
return EINVAL;
}
rw_enter(&t->t_lock, RW_READER);
switch (t->t_type) {
case NPF_TABLE_HASH:
@ -603,14 +635,8 @@ npf_table_list(npf_tableset_t *tset, u_int tid, void *ubuf, size_t len)
* npf_table_flush: remove all table entries.
*/
int
npf_table_flush(npf_tableset_t *tset, u_int tid)
npf_table_flush(npf_table_t *t)
{
npf_table_t *t;
if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
return EINVAL;
}
rw_enter(&t->t_lock, RW_WRITER);
switch (t->t_type) {
case NPF_TABLE_HASH:
@ -626,6 +652,5 @@ npf_table_flush(npf_tableset_t *tset, u_int tid)
KASSERT(false);
}
rw_exit(&t->t_lock);
return 0;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: npf.conf.5,v 1.32 2013/11/05 13:09:12 kefren Exp $
.\" $NetBSD: npf.conf.5,v 1.33 2013/11/12 00:46:34 rmind Exp $
.\"
.\" Copyright (c) 2009-2013 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 November 5, 2013
.Dd November 10, 2013
.Dt NPF.CONF 5
.Os
.Sh NAME
@ -78,12 +78,11 @@ $var2 = { 10.0.0.1, 10.0.0.2 }
Common variable definitions are for IP addresses, networks, ports,
and interfaces.
.Ss Tables
Tables are specified using a number between angle brackets
Tables are specified using a name between angle brackets
\*[Lt] and \*[Gt].
The number used to specify a table should be between 0 and 15.
The following is an example of table definition:
.Bd -literal
table <1> type hash dynamic
table <black> type hash dynamic
.Pp
.Ed
Currently, tables support two storage types: "hash" or "tree".
@ -115,7 +114,7 @@ Groups may have the following options: name, interface, and direction.
They are defined in the following form:
.Pp
.Bd -literal
group "my_group_name" in on wm0 {
group "my-name" in on wm0 {
# List of rules
}
.Ed
@ -146,6 +145,13 @@ specification at present is limited to protocol TCP understanding flags,
TCP and UDP understanding source and destination ports, and ICMP and
IPv6-ICMP understanding icmp-type.
.Pp
Alternatively, NPF supports
.Xr pcap-filter 7
syntax, for example:
.Bd -literal
block out final pcap-filter "tcp and dst 10.1.1.252"
.Ed
.Pp
Fragments are not selectable since NPF always reassembles packets
before further processing.
.Ss Map
@ -216,7 +222,7 @@ var-def = var "=" ( var-value | "{" value *[ "," value ] "}" )
; Table definition. Table ID shall be numeric. Path is in the double quotes.
table-id = \*[Lt]tid\*[Gt]
table-id = \*[Lt]table-name\*[Gt]
table-def = "table" table-id "type" ( "hash" | "tree" )
( "dynamic" | "file" path )
@ -242,10 +248,13 @@ group = "group" ( "default" | group-opts ) "{" rule-list "}"
group-opts = name-string [ "in" | "out" ] [ "on" interface ]
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" ]
[ "in" | out" ] [ "final" ] [ "on" interface ]
[ "family" family-opt ] [ "proto" protocol [ proto-opts ] ]
( "all" | filt-opts ) [ "apply" proc-name ]
( npf-filter | "pcap-filter" pcap-filter-expr )
[ "apply" proc-name ]
dynamic-ruleset = "ruleset" group-opts
rule = static-rule | dynamic-ruleset
@ -275,8 +284,8 @@ directory containing further examples
$ext_if = ifnet(wm0)
$int_if = ifnet(wm1)
table <1> type hash file "/etc/npf_blacklist"
table <2> type tree dynamic
table <black> type hash file "/etc/npf_blacklist"
table <limited> type tree dynamic
$services_tcp = { http, https, smtp, domain, 6000, 9022 }
$services_udp = { domain, ntp, 6000 }
@ -296,7 +305,7 @@ procedure "log" {
group "external" on $ext_if {
pass stateful out final all
block in final from \*[Lt]1\*[Gt]
block in final from \*[Lt]black\*[Gt]
pass stateful in final family inet proto tcp to $ext_if port ssh apply "log"
pass stateful in final proto tcp to $ext_if port $services_tcp
pass stateful in final proto udp to $ext_if port $services_udp
@ -306,7 +315,7 @@ group "external" on $ext_if {
group "internal" on $int_if {
block in all
block in final from \*[Lt]2\*[Gt]
block in final from \*[Lt]limited\*[Gt]
# Ingress filtering as per RFC 2827.
pass in final from $localnet
@ -321,6 +330,7 @@ group default {
.\" -----
.Sh SEE ALSO
.Xr bpf 4 ,
.Xr pcap-filter 7 ,
.Xr npfctl 8
.Sh HISTORY
NPF first appeared in

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_build.c,v 1.28 2013/11/08 00:38:26 rmind Exp $ */
/* $NetBSD: npf_build.c,v 1.29 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_build.c,v 1.28 2013/11/08 00:38:26 rmind Exp $");
__RCSID("$NetBSD: npf_build.c,v 1.29 2013/11/12 00:46:34 rmind Exp $");
#include <sys/types.h>
#include <sys/ioctl.h>
@ -42,6 +42,7 @@ __RCSID("$NetBSD: npf_build.c,v 1.28 2013/11/08 00:38:26 rmind Exp $");
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <err.h>
@ -658,17 +659,16 @@ npfctl_fill_table(nl_table_t *tl, u_int type, const char *fname)
* if required, fill with contents from a file.
*/
void
npfctl_build_table(const char *tid, u_int type, const char *fname)
npfctl_build_table(const char *tname, u_int type, const char *fname)
{
static unsigned tid = 0;
nl_table_t *tl;
u_int id;
id = atoi(tid);
tl = npf_table_create(id, type);
tl = npf_table_create(tname, tid++, type);
assert(tl != NULL);
if (npf_table_insert(npf_conf, tl)) {
errx(EXIT_FAILURE, "table '%d' is already defined\n", id);
yyerror("table '%s' is already defined", tname);
}
if (fname) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_scan.l,v 1.13 2013/09/20 03:03:52 rmind Exp $ */
/* $NetBSD: npf_scan.l,v 1.14 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@ -82,7 +82,7 @@ npfctl_parse_string(const char *str)
%option noyywrap nounput noinput
ID [a-zA-Z_][a-zA-Z_0-9]*
NID [a-zA-Z_0-9]+
DID [a-zA-Z_][a-zA-Z_0-9-]*
NUMBER [0-9]+
%%
@ -181,12 +181,12 @@ any return ANY;
return NUM;
}
"<"{NID}">" {
"<"{DID}">" {
yylval.str = estrndup(yytext + 1, yyleng - 2);
return TABLE_ID;
}
"$"{NID} {
"$"{ID} {
yylval.str = estrndup(yytext + 1, yyleng - 1);
return VAR_ID;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_show.c,v 1.3 2013/11/08 00:38:26 rmind Exp $ */
/* $NetBSD: npf_show.c,v 1.4 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_show.c,v 1.3 2013/11/08 00:38:26 rmind Exp $");
__RCSID("$NetBSD: npf_show.c,v 1.4 2013/11/12 00:46:34 rmind Exp $");
#include <sys/socket.h>
#include <netinet/in.h>
@ -54,6 +54,7 @@ __RCSID("$NetBSD: npf_show.c,v 1.3 2013/11/08 00:38:26 rmind Exp $");
#include "npfctl.h"
typedef struct {
nl_config_t * conf;
FILE * fp;
long fpos;
} npf_conf_info_t;
@ -104,7 +105,7 @@ tcpflags2string(char *buf, u_int tfl)
}
static char *
print_family(const uint32_t *words)
print_family(npf_conf_info_t *ctx, const uint32_t *words)
{
const int af = words[0];
@ -120,7 +121,7 @@ print_family(const uint32_t *words)
}
static char *
print_address(const uint32_t *words)
print_address(npf_conf_info_t *ctx, const uint32_t *words)
{
const int af = *words++;
const u_int mask = *words++;
@ -142,7 +143,7 @@ print_address(const uint32_t *words)
}
static char *
print_number(const uint32_t *words)
print_number(npf_conf_info_t *ctx, const uint32_t *words)
{
char *p;
easprintf(&p, "%u", words[0]);
@ -150,7 +151,22 @@ print_number(const uint32_t *words)
}
static char *
print_proto(const uint32_t *words)
print_table(npf_conf_info_t *ctx, const uint32_t *words)
{
unsigned tid = words[0];
nl_table_t *tl;
char *p;
while ((tl = npf_table_iterate(ctx->conf)) != NULL) {
if (npf_table_getid(tl) == tid)
break;
}
easprintf(&p, "%s", npf_table_getname(tl));
return p;
}
static char *
print_proto(npf_conf_info_t *ctx, const uint32_t *words)
{
switch (words[0]) {
case IPPROTO_TCP:
@ -162,11 +178,11 @@ print_proto(const uint32_t *words)
case IPPROTO_ICMPV6:
return estrdup("ipv6-icmp");
}
return print_number(words);
return print_number(ctx, words);
}
static char *
print_tcpflags(const uint32_t *words)
print_tcpflags(npf_conf_info_t *ctx, const uint32_t *words)
{
const u_int tf = words[0], tf_mask = words[1];
char buf[16];
@ -180,7 +196,7 @@ print_tcpflags(const uint32_t *words)
}
static char *
print_portrange(const uint32_t *words)
print_portrange(npf_conf_info_t *ctx, const uint32_t *words)
{
u_int fport = words[0], tport = words[1];
char *p;
@ -224,7 +240,7 @@ static const struct mark_keyword_mapent {
u_int mark;
const char * token;
const char * sep;
char * (*printfn)(const uint32_t *);
char * (*printfn)(npf_conf_info_t *, const uint32_t *);
u_int fwords;
} mark_keyword_map[] = {
{ BM_IPVER, "family %s", NULL, print_family, 1 },
@ -234,11 +250,11 @@ static const struct mark_keyword_mapent {
{ BM_ICMP_CODE, "code %s", NULL, print_number, 1 },
{ BM_SRC_CIDR, "from %s", ", ", print_address, 6 },
{ BM_SRC_TABLE, "from <%s>", NULL, print_number, 1 },
{ BM_SRC_TABLE, "from <%s>", NULL, print_table, 1 },
{ BM_SRC_PORTS, "port %s", ", ", print_portrange,2 },
{ BM_DST_CIDR, "to %s", ", ", print_address, 6 },
{ BM_DST_TABLE, "to <%s>", NULL, print_number, 1 },
{ BM_DST_TABLE, "to <%s>", NULL, print_table, 1 },
{ BM_DST_PORTS, "port %s", ", ", print_portrange,2 },
};
@ -267,7 +283,7 @@ scan_marks(npf_conf_info_t *ctx, const struct mark_keyword_mapent *mk,
if (m == mk->mark) {
/* Value is processed by the print function. */
assert(mk->fwords == nwords);
vals[nvals++] = mk->printfn(marks);
vals[nvals++] = mk->printfn(ctx, marks);
}
marks += nwords;
mlen -= nwords;
@ -401,10 +417,10 @@ npfctl_print_nat(npf_conf_info_t *ctx, nl_nat_t *nt)
static void
npfctl_print_table(npf_conf_info_t *ctx, nl_table_t *tl)
{
const u_int id = npf_table_getid(tl);
const char *name = npf_table_getname(tl);
const int type = npf_table_gettype(tl);
fprintf(ctx->fp, "table <%u> type %s\n", id,
fprintf(ctx->fp, "table <%s> type %s\n", name,
(type == NPF_TABLE_HASH) ? "hash" :
(type == NPF_TABLE_TREE) ? "tree" :
"unknown");
@ -431,6 +447,7 @@ npfctl_config_show(int fd)
ncf = npfctl_config_ref();
loaded = true;
}
ctx->conf = ncf;
if (loaded) {
nl_rule_t *rl;
@ -475,6 +492,8 @@ npfctl_ruleset_show(int fd, const char *ruleset_name)
int error;
ncf = npf_config_create();
ctx->conf = ncf;
if ((error = _npf_ruleset_list(fd, ruleset_name, ncf)) != 0) {
return error;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npfctl.c,v 1.39 2013/09/19 12:05:11 rmind Exp $ */
/* $NetBSD: npfctl.c,v 1.40 2013/11/12 00:46:34 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npfctl.c,v 1.39 2013/09/19 12:05:11 rmind Exp $");
__RCSID("$NetBSD: npfctl.c,v 1.40 2013/11/12 00:46:34 rmind Exp $");
#include <sys/ioctl.h>
#include <sys/stat.h>
@ -274,12 +274,12 @@ npfctl_table(int fd, int argc, char **argv)
npf_ioctl_table_t nct;
fam_addr_mask_t fam;
size_t buflen = 512;
char *cmd, *arg = NULL; /* XXX gcc */
char *cmd, *arg;
int n, alen;
/* Default action is list. */
memset(&nct, 0, sizeof(npf_ioctl_table_t));
nct.nct_tid = atoi(argv[0]);
nct.nct_name = argv[0];
cmd = argv[1];
for (n = 0; tblops[n].cmd != NULL; n++) {
@ -296,6 +296,7 @@ npfctl_table(int fd, int argc, char **argv)
switch (nct.nct_cmd) {
case NPF_CMD_TABLE_LIST:
case NPF_CMD_TABLE_FLUSH:
arg = NULL;
break;
default:
if (argc < 3) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_table_test.c,v 1.6 2012/10/29 02:27:11 rmind Exp $ */
/* $NetBSD: npf_table_test.c,v 1.7 2013/11/12 00:46:34 rmind Exp $ */
/*
* NPF tableset test.
@ -41,8 +41,8 @@ static const uint16_t ip6_list[][8] = {
}
};
#define HASH_TID 1
#define TREE_TID 2
#define HASH_TID "hash-table"
#define TREE_TID "tree-table"
static bool
npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
@ -53,18 +53,21 @@ npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
/* Fill both tables with IP addresses. */
for (unsigned i = 0; i < __arraycount(ip_list); i++) {
npf_table_t *t;
int error;
addr->s6_addr32[0] = inet_addr(ip_list[i]);
error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, HASH_TID);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error == 0);
error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error != 0);
error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, TREE_TID);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error == 0);
error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error != 0);
}
return fail;
@ -76,16 +79,16 @@ npf_table_test(bool verbose)
npf_addr_t addr_storage, *addr = &addr_storage;
const int nm = NPF_NO_NETMASK;
npf_tableset_t *tblset;
npf_table_t *t1, *t2;
npf_table_t *t, *t1, *t2;
int error, alen;
bool fail = false;
u_int i;
tblset = npf_tableset_create();
tblset = npf_tableset_create(2);
fail |= !(tblset != NULL);
/* Table ID 1, using hash table with 256 lists. */
t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256);
t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, 256);
fail |= !(t1 != NULL);
error = npf_tableset_insert(tblset, t1);
fail |= !(error == 0);
@ -94,8 +97,8 @@ npf_table_test(bool verbose)
error = npf_tableset_insert(tblset, t1);
fail |= !(error != 0);
/* Table ID 2, using RB-tree. */
t2 = npf_table_create(TREE_TID, NPF_TABLE_TREE, 0);
/* Table ID 2, using a prefix tree. */
t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, 0);
fail |= !(t2 != NULL);
error = npf_tableset_insert(tblset, t2);
fail |= !(error == 0);
@ -104,10 +107,12 @@ npf_table_test(bool verbose)
addr->s6_addr32[0] = inet_addr(ip_list[0]);
alen = sizeof(struct in_addr);
error = npf_table_lookup(tblset, HASH_TID, alen, addr);
t = npf_tableset_getbyname(tblset, HASH_TID);
error = npf_table_lookup(t, alen, addr);
fail |= !(error != 0);
error = npf_table_lookup(tblset, TREE_TID, alen, addr);
t = npf_tableset_getbyname(tblset, TREE_TID);
error = npf_table_lookup(t, alen, addr);
fail |= !(error != 0);
/* Fill both tables with IP addresses. */
@ -117,20 +122,24 @@ npf_table_test(bool verbose)
addr->s6_addr32[0] = inet_addr(ip_list[0]);
alen = sizeof(struct in_addr);
error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, HASH_TID);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error != 0);
error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, TREE_TID);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error != 0);
/* Match (validate) each IP entry. */
for (i = 0; i < __arraycount(ip_list); i++) {
addr->s6_addr32[0] = inet_addr(ip_list[i]);
error = npf_table_lookup(tblset, HASH_TID, alen, addr);
t = npf_tableset_getbyname(tblset, HASH_TID);
error = npf_table_lookup(t, alen, addr);
fail |= !(error == 0);
error = npf_table_lookup(tblset, TREE_TID, alen, addr);
t = npf_tableset_getbyname(tblset, TREE_TID);
error = npf_table_lookup(t, alen, addr);
fail |= !(error == 0);
}
@ -138,18 +147,20 @@ npf_table_test(bool verbose)
memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
alen = sizeof(struct in6_addr);
error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, HASH_TID);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error == 0);
error = npf_table_lookup(tblset, HASH_TID, alen, addr);
error = npf_table_lookup(t, alen, addr);
fail |= !(error == 0);
error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
error = npf_table_remove(t, alen, addr, nm);
fail |= !(error == 0);
error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, TREE_TID);
error = npf_table_insert(t, alen, addr, nm);
fail |= !(error == 0);
error = npf_table_lookup(tblset, TREE_TID, alen, addr);
error = npf_table_lookup(t, alen, addr);
fail |= !(error == 0);
error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
error = npf_table_remove(t, alen, addr, nm);
fail |= !(error == 0);
/*
@ -157,41 +168,41 @@ npf_table_test(bool verbose)
*/
memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
error = npf_table_insert(tblset, TREE_TID, alen, addr, 96);
error = npf_table_insert(t, alen, addr, 96);
fail |= !(error == 0);
memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
error = npf_table_lookup(tblset, TREE_TID, alen, addr);
error = npf_table_lookup(t, alen, addr);
fail |= !(error == 0);
memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
error = npf_table_remove(tblset, TREE_TID, alen, addr, 96);
error = npf_table_remove(t, alen, addr, 96);
fail |= !(error == 0);
memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
error = npf_table_insert(tblset, TREE_TID, alen, addr, 32);
error = npf_table_insert(t, alen, addr, 32);
fail |= !(error == 0);
memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
error = npf_table_lookup(tblset, TREE_TID, alen, addr);
error = npf_table_lookup(t, alen, addr);
fail |= !(error == 0);
memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
error = npf_table_remove(tblset, TREE_TID, alen, addr, 32);
error = npf_table_remove(t, alen, addr, 32);
fail |= !(error == 0);
memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
error = npf_table_insert(tblset, TREE_TID, alen, addr, 126);
error = npf_table_insert(t, alen, addr, 126);
fail |= !(error == 0);
memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
error = npf_table_lookup(tblset, TREE_TID, alen, addr);
error = npf_table_lookup(t, alen, addr);
fail |= !(error != 0);
memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
error = npf_table_remove(tblset, TREE_TID, alen, addr, 126);
error = npf_table_remove(t, alen, addr, 126);
fail |= !(error == 0);
@ -201,10 +212,12 @@ npf_table_test(bool verbose)
for (i = 0; i < __arraycount(ip_list); i++) {
addr->s6_addr32[0] = inet_addr(ip_list[i]);
error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, HASH_TID);
error = npf_table_remove(t, alen, addr, nm);
fail |= !(error == 0);
error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
t = npf_tableset_getbyname(tblset, TREE_TID);
error = npf_table_remove(t, alen, addr, nm);
fail |= !(error == 0);
}