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:
parent
80f3dc5a69
commit
1e7342c150
@ -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 .
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user