NPF: Major rework -- migrate NPF to the libnv library.

- This conversion significantly simplifies the code and moves NPF to
  a binary serialisation format (replacing the XML-like format).
- Fix some memory/reference leaks and possibly use-after-free bugs.
- Bump NPF_VERSION as this change makes libnpf incompatible with the
  previous versions.  Also, different serialisation format means NPF
  connection/config saving and loading is not compatible with the
  previous versions either.

Thanks to christos@ for extra testing.
This commit is contained in:
rmind 2018-09-29 14:41:35 +00:00
parent ce57e938bd
commit 39013e66c1
81 changed files with 1570 additions and 2045 deletions

View File

@ -1,9 +1,11 @@
# $NetBSD: Makefile,v 1.6 2016/01/05 13:07:47 christos Exp $
.include <bsd.own.mk>
# $NetBSD: Makefile,v 1.7 2018/09/29 14:41:36 rmind Exp $
USE_SHLIBDIR= yes
NOLINT= # disabled deliberately
.include <bsd.own.mk>
LIB= npf
MAN= libnpf.3
@ -12,9 +14,8 @@ SRCS= npf.c
INCS= npf.h
INCSDIR= /usr/include
LIBDPLIBS+= prop ${.CURDIR}/../libprop
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
WARNS= 5
NOLINT= # disabled deliberately
.include <bsd.lib.mk>

View File

@ -1,4 +1,4 @@
.\" $NetBSD: libnpf.3,v 1.5 2017/12/07 00:22:06 rmind Exp $
.\" $NetBSD: libnpf.3,v 1.6 2018/09/29 14:41:36 rmind Exp $
.\"
.\" Copyright (c) 2011-2017 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 December 7, 2017
.Dd June 10, 2018
.Dt LIBNPF 3
.Os
.Sh NAME
@ -256,6 +256,7 @@ If the value of
is
.Dv NULL ,
then insert into the main ruleset.
The rule must not be referenced after insertion.
.\" ---
.It Fn npf_rule_export "rl" "length"
Serialize the rule (including the byte-code), return a binary object
@ -276,6 +277,7 @@ Create a rule procedure with a given
Thr name must be unique for each procedure.
.It Fn npf_rproc_insert "ncf" "rp"
Insert the rule procedure into the specified configuration object.
The rule procedure must not be referenced after insertion.
.El
.\" -----
.Ss Translation interface
@ -331,6 +333,7 @@ algorithm is supported for NPTv6 (RFC 6296).
.\" ---
.It Fn npf_nat_insert "ncf" "nt" "pri"
Insert NAT policy, its rule, into the specified configuration.
The NAT rule must not be referenced after insertion.
.El
.\" -----
.Ss Table interface
@ -342,7 +345,7 @@ The table is identified by the
and
.Fa index ,
which should be in the range between 1 and
.Dv NPF_MAX_TABLE_ID .
.Dv NPF_MAX_TABLES .
.Pp
The following types are supported:
.Bl -tag -width "NPF_TABLE_HASH"
@ -353,12 +356,9 @@ Indicates to use a tree for storage, supporting the longest
prefix match.
.It Dv NPF_TABLE_CDB
Indicates to use constant database for storage, typically using
a perfect hash table.
In such case, the database produced by
.Xr cdbw 3
should be set using the
.Fn npf_table_setdata
function.
a perfect hash table, which will be generated on table insertion
into the configuration.
Such table will be immutable.
.El
.\" ---
.It Fn npf_table_add_entry "tl" "af" "addr" "mask"
@ -378,6 +378,7 @@ for IPv6 address.
.It Fn npf_table_insert "ncf" "tl"
Add the table to the configuration object.
This routine performs a check for duplicate table IDs.
The table must not be referenced after insertion.
.\" ---
.It Fn npf_table_destroy "tl"
Destroy the specified table.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf.h,v 1.33 2016/12/27 20:32:58 rmind Exp $ */
/*-
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -63,8 +61,6 @@ typedef void (*nl_table_callback_t)(unsigned, int);
#endif
#define NPF_MAX_TABLE_ID (16)
nl_config_t * npf_config_create(void);
void npf_config_destroy(nl_config_t *);
int npf_config_submit(nl_config_t *, int, npf_error_t *);
@ -102,15 +98,14 @@ int npf_rproc_extcall(nl_rproc_t *, nl_ext_t *);
bool npf_rproc_exists_p(nl_config_t *, const char *);
int npf_rproc_insert(nl_config_t *, nl_rproc_t *);
nl_nat_t * npf_nat_create(int, u_int, const char *,
nl_nat_t * npf_nat_create(int, unsigned, const char *,
int, npf_addr_t *, npf_netmask_t, in_port_t);
int npf_nat_insert(nl_config_t *, nl_nat_t *, int);
int npf_nat_lookup(int, int, npf_addr_t *[2], in_port_t [2], int, int);
nl_table_t * npf_table_create(const char *, u_int, int);
nl_table_t * npf_table_create(const char *, unsigned, int);
int npf_table_add_entry(nl_table_t *, int,
const npf_addr_t *, const npf_netmask_t);
int npf_table_setdata(nl_table_t *, const void *, size_t);
int npf_table_insert(nl_config_t *, nl_table_t *);
void npf_table_destroy(nl_table_t *);
@ -137,7 +132,7 @@ int npf_nat_gettype(nl_nat_t *);
unsigned npf_nat_getflags(nl_nat_t *);
void npf_nat_getmap(nl_nat_t *, npf_addr_t *, size_t *, in_port_t *);
int npf_nat_setalgo(nl_nat_t *, u_int);
int npf_nat_setalgo(nl_nat_t *, unsigned);
int npf_nat_setnpt66(nl_nat_t *, uint16_t);
nl_rproc_t * npf_rproc_iterate(nl_config_t *);
@ -145,9 +140,10 @@ const char * npf_rproc_getname(nl_rproc_t *);
int _npf_ruleset_list(int, const char *, nl_config_t *);
void _npf_debug_addif(nl_config_t *, const char *);
void _npf_config_dump(nl_config_t *, int);
/* The ALG interface is experimental */
int _npf_alg_load(nl_config_t *, const char *);
int _npf_alg_load(nl_config_t *, const char *);
int _npf_alg_unload(nl_config_t *, const char *);
typedef int (*npf_conn_func_t)(unsigned, const npf_addr_t *,

View File

@ -1,4 +1,4 @@
/* $NetBSD: npfext_log.c,v 1.4 2013/03/11 00:29:09 christos Exp $ */
/* $NetBSD: npfext_log.c,v 1.5 2018/09/29 14:41:37 rmind Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npfext_log.c,v 1.4 2013/03/11 00:29:09 christos Exp $");
__RCSID("$NetBSD: npfext_log.c,v 1.5 2018/09/29 14:41:37 rmind Exp $");
#include <sys/types.h>
#include <sys/socket.h>
@ -38,6 +38,7 @@ __RCSID("$NetBSD: npfext_log.c,v 1.4 2013/03/11 00:29:09 christos Exp $");
#include <net/if.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: npfext_normalize.c,v 1.1 2013/03/10 21:49:26 christos Exp $ */
/* $NetBSD: npfext_normalize.c,v 1.2 2018/09/29 14:41:37 rmind Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@ -27,9 +27,10 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npfext_normalize.c,v 1.1 2013/03/10 21:49:26 christos Exp $");
__RCSID("$NetBSD: npfext_normalize.c,v 1.2 2018/09/29 14:41:37 rmind Exp $");
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: npfext_rndblock.c,v 1.1 2012/12/10 00:32:24 rmind Exp $ */
/* $NetBSD: npfext_rndblock.c,v 1.2 2018/09/29 14:41:37 rmind Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@ -27,9 +27,10 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npfext_rndblock.c,v 1.1 2012/12/10 00:32:24 rmind Exp $");
__RCSID("$NetBSD: npfext_rndblock.c,v 1.2 2018/09/29 14:41:37 rmind Exp $");
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

View File

@ -1,4 +1,4 @@
# $NetBSD: mod.mk,v 1.6 2013/09/11 23:04:11 joerg Exp $
# $NetBSD: mod.mk,v 1.7 2018/09/29 14:41:36 rmind Exp $
.include <bsd.own.mk>
@ -26,6 +26,7 @@ SHLIBINSTALLDIR=${LIBROOTDIR}/npf
LIB= ${MOD}
SRCS= npf${MOD}.c
LIBDPLIBS+= npf ${NETBSDSRCDIR}/lib/libnpf
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
LIBDPLIBS+= npf ${NETBSDSRCDIR}/lib/libnpf
.include <bsd.lib.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.16 2018/02/04 09:03:23 mrg Exp $
# $NetBSD: Makefile,v 1.17 2018/09/29 14:41:37 rmind Exp $
.include <bsd.own.mk>
@ -22,8 +22,12 @@ CPPFLAGS+=-DWITH_PF
.if (${MKNPF} != "no")
SRCS+= npf.c
CPPFLAGS+=-DWITH_NPF
LDADD+=-lnpf -lprop
DPADD+=${LIBNPF} ${LIBPROP}
PROGDPLIBS+= nv ${NETBSDSRCDIR}/external/bsd/libnv/lib
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
LDADD+=-lnpf
DPADD+=${LIBNPF}
.endif
# XXX

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_ioctl.c,v 1.95 2018/09/24 21:15:39 jdolecek Exp $ */
/* $NetBSD: netbsd32_ioctl.c,v 1.96 2018/09/29 14:41:35 rmind Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.95 2018/09/24 21:15:39 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.96 2018/09/29 14:41:35 rmind Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ntp.h"
@ -73,8 +73,6 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.95 2018/09/24 21:15:39 jdolecek
#include <net/if_pppoe.h>
#include <net/if_sppp.h>
#include <net/npf/npf.h>
#include <net/bpf.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
@ -490,28 +488,6 @@ netbsd32_to_ksyms_gvalue(
p->kv_name = NETBSD32PTR64(s32p->kv_name);
}
static inline void
netbsd32_to_npf_ioctl_table(
const struct netbsd32_npf_ioctl_table *s32p,
struct npf_ioctl_table *p,
u_long cmd)
{
p->nct_cmd = s32p->nct_cmd;
p->nct_name = NETBSD32PTR64(s32p->nct_name);
switch (s32p->nct_cmd) {
case NPF_CMD_TABLE_LOOKUP:
case NPF_CMD_TABLE_ADD:
case NPF_CMD_TABLE_REMOVE:
p->nct_data.ent = s32p->nct_data.ent;
break;
case NPF_CMD_TABLE_LIST:
p->nct_data.buf.buf = NETBSD32PTR64(s32p->nct_data.buf.buf);
p->nct_data.buf.len = s32p->nct_data.buf.len;
break;
}
}
static inline void
netbsd32_to_devlistargs(
const struct netbsd32_devlistargs *s32p,
@ -955,28 +931,6 @@ netbsd32_from_ksyms_gvalue(
s32p->kv_value = p->kv_value;
}
static inline void
netbsd32_from_npf_ioctl_table(
const struct npf_ioctl_table *p,
struct netbsd32_npf_ioctl_table *s32p,
u_long cmd)
{
s32p->nct_cmd = p->nct_cmd;
NETBSD32PTR32(s32p->nct_name, p->nct_name);
switch (p->nct_cmd) {
case NPF_CMD_TABLE_LOOKUP:
case NPF_CMD_TABLE_ADD:
case NPF_CMD_TABLE_REMOVE:
s32p->nct_data.ent = p->nct_data.ent;
break;
case NPF_CMD_TABLE_LIST:
NETBSD32PTR32(s32p->nct_data.buf.buf, p->nct_data.buf.buf);
s32p->nct_data.buf.len = p->nct_data.buf.len;
break;
}
}
static inline void
netbsd32_from_devlistargs(
const struct devlistargs *p,
@ -1459,17 +1413,6 @@ netbsd32_ioctl(struct lwp *l, const struct netbsd32_ioctl_args *uap, register_t
case KIOCGVALUE32:
IOCTL_STRUCT_CONV_TO(KIOCGVALUE, ksyms_gvalue);
case IOC_NPF_LOAD32:
IOCTL_STRUCT_CONV_TO(IOC_NPF_LOAD, plistref);
case IOC_NPF_TABLE32:
IOCTL_STRUCT_CONV_TO(IOC_NPF_TABLE, npf_ioctl_table);
case IOC_NPF_STATS32:
IOCTL_CONV_TO(IOC_NPF_STATS, voidp);
case IOC_NPF_SAVE32:
IOCTL_STRUCT_CONV_TO(IOC_NPF_SAVE, plistref);
case IOC_NPF_RULE32:
IOCTL_STRUCT_CONV_TO(IOC_NPF_RULE, plistref);
case DRVRESCANBUS32:
IOCTL_STRUCT_CONV_TO(DRVRESCANBUS, devrescanargs);
case DRVLISTDEV32:

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_ioctl.h,v 1.63 2018/09/24 21:15:39 jdolecek Exp $ */
/* $NetBSD: netbsd32_ioctl.h,v 1.64 2018/09/29 14:41:35 rmind Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@ -560,28 +560,6 @@ struct netbsd32_ksyms_gvalue {
#define KIOCGSYMBOL32 _IOWR('l', 5, struct netbsd32_ksyms_gsymbol)
#endif /* KIOCGSYMBOL */
#include <net/npf/npf.h>
typedef struct netbsd32_npf_ioctl_buf {
netbsd32_voidp buf;
netbsd32_size_t len;
} netbsd32_npf_ioctl_buf_t;
typedef struct netbsd32_npf_ioctl_table {
int nct_cmd;
netbsd32_charp nct_name;
union {
npf_ioctl_ent_t ent;
netbsd32_npf_ioctl_buf_t buf;
} nct_data;
} netbsd32_npf_ioctl_table_t;
#define IOC_NPF_LOAD32 _IOWR('N', 102, struct netbsd32_plistref)
#define IOC_NPF_TABLE32 _IOW('N', 103, struct netbsd32_npf_ioctl_table)
#define IOC_NPF_STATS32 _IOW('N', 104, netbsd32_voidp)
#define IOC_NPF_SAVE32 _IOR('N', 105, struct netbsd32_plistref)
#define IOC_NPF_RULE32 _IOWR('N', 107, struct netbsd32_plistref)
/* From sys/drvctlio.h */
struct netbsd32_devlistargs {
char l_devname[16];

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.1 2013/03/10 20:54:14 christos Exp $
# $NetBSD: Makefile,v 1.2 2018/09/29 14:41:35 rmind Exp $
.include "../Makefile.inc"
@ -8,4 +8,6 @@ KMOD= if_npflog
SRCS= if_npflog.c
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.include <bsd.kmodule.mk>

View File

@ -1,11 +1,11 @@
# $NetBSD: Makefile,v 1.21 2017/01/02 21:49:51 rmind Exp $
# $NetBSD: Makefile,v 1.22 2018/09/29 14:41:35 rmind Exp $
#
# Public Domain.
#
.include "../Makefile.inc"
.PATH: ${S}/net/npf
.PATH: ${S}/net/npf ${S}/external/bsd/libnv/dist/
KMOD= npf
IOCONF= npf.ioconf
@ -14,7 +14,9 @@ SRCS+= npf_bpf.c npf_if.c npf_inet.c npf_mbuf.c npf_nat.c
SRCS+= npf_ruleset.c npf_conn.c npf_conndb.c npf_rproc.c
SRCS+= npf_state.c npf_state_tcp.c npf_tableset.c
SRCS+= lpm.c npf_sendpkt.c npf_worker.c npf_ifaddr.c npf_os.c
SRCS+= nvlist.c nvpair.c nv_kern_netbsd.c dnvlist.c
CPPFLAGS+= -DINET6
CPPFLAGS+= -I${S}/external/bsd/libnv/dist
.include <bsd.kmodule.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.1 2011/11/06 13:26:54 tron Exp $
# $NetBSD: Makefile,v 1.2 2018/09/29 14:41:35 rmind Exp $
.include "../Makefile.inc"
@ -9,5 +9,6 @@ KMOD= npf_alg_icmp
SRCS= npf_alg_icmp.c
CPPFLAGS+= -DINET6
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.include <bsd.kmodule.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.1 2012/09/16 13:47:42 rmind Exp $
# $NetBSD: Makefile,v 1.2 2018/09/29 14:41:35 rmind Exp $
.include "../Makefile.inc"
@ -8,4 +8,6 @@ KMOD= npf_ext_log
SRCS= npf_ext_log.c
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.include <bsd.kmodule.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.1 2013/03/12 20:49:22 christos Exp $
# $NetBSD: Makefile,v 1.2 2018/09/29 14:41:35 rmind Exp $
.include "../Makefile.inc"
@ -8,4 +8,6 @@ KMOD= npf_ext_normalize
SRCS= npf_ext_normalize.c
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.include <bsd.kmodule.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.1 2012/12/10 00:32:25 rmind Exp $
# $NetBSD: Makefile,v 1.2 2018/09/29 14:41:35 rmind Exp $
.include "../Makefile.inc"
@ -8,4 +8,6 @@ KMOD= npf_ext_rndblock
SRCS= npf_ext_rndblock.c
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.include <bsd.kmodule.mk>

2
sys/net/npf/README Normal file
View File

@ -0,0 +1,2 @@
The NPF project upstream repository: https://github.com/rmind/npf/
Please submit the pull requests to the upstream when possible.

View File

@ -1,4 +1,4 @@
# $NetBSD: files.npf,v 1.20 2017/01/02 21:49:51 rmind Exp $
# $NetBSD: files.npf,v 1.21 2018/09/29 14:41:36 rmind Exp $
#
# Public Domain.
#
@ -7,7 +7,7 @@
# NPF pseudo device and modules.
#
defpseudo npf: ifnet
defpseudo npf: ifnet, libnv
# Core
file net/npf/npf.c npf

View File

@ -1,5 +1,3 @@
/* $NetBSD: if_npflog.c,v 1.5 2017/01/29 00:15:54 christos Exp $ */
/*-
* Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_npflog.c,v 1.5 2017/01/29 00:15:54 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_npflog.c,v 1.6 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/module.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: if_npflog.h,v 1.1 2017/01/29 00:15:54 christos Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
* All rights reserved.

View File

@ -25,13 +25,20 @@
*/
/*
* TODO: Simple linear scan for now (works just well with a few prefixes).
* TBD on a better algorithm.
* Longest Prefix Match (LPM) library supporting IPv4 and IPv6.
*
* Algorithm:
*
* Each prefix gets its own hash map and all added prefixes are saved
* in a bitmap. On a lookup, we perform a linear scan of hash maps,
* iterating through the added prefixes only. Usually, there are only
* a few unique prefixes used and such simple algorithm is very efficient.
* With many IPv6 prefixes, the linear scan might become a bottleneck.
*/
#if defined(_KERNEL)
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lpm.c,v 1.4 2017/06/01 02:45:14 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: lpm.c,v 1.5 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -60,11 +67,12 @@ __KERNEL_RCSID(0, "$NetBSD: lpm.c,v 1.4 2017/06/01 02:45:14 chs Exp $");
#define LPM_MAX_WORDS (LPM_MAX_PREFIX >> 5)
#define LPM_TO_WORDS(x) ((x) >> 2)
#define LPM_HASH_STEP (8)
#define LPM_LEN_IDX(len) ((len) >> 4)
#ifdef DEBUG
#define ASSERT assert
#define ASSERT assert
#else
#define ASSERT
#define ASSERT(x)
#endif
typedef struct lpm_ent {
@ -75,17 +83,19 @@ typedef struct lpm_ent {
} lpm_ent_t;
typedef struct {
uint32_t hashsize;
uint32_t nitems;
lpm_ent_t **bucket;
unsigned hashsize;
unsigned nitems;
lpm_ent_t ** bucket;
} lpm_hmap_t;
struct lpm {
uint32_t bitmask[LPM_MAX_WORDS];
void * defval;
void * defvals[2];
lpm_hmap_t prefix[LPM_MAX_PREFIX + 1];
};
static const uint32_t zero_address[LPM_MAX_WORDS];
lpm_t *
lpm_create(void)
{
@ -122,8 +132,12 @@ lpm_clear(lpm_t *lpm, lpm_dtor_t dtor, void *arg)
hmap->hashsize = 0;
hmap->nitems = 0;
}
if (dtor) {
dtor(arg, zero_address, 4, lpm->defvals[0]);
dtor(arg, zero_address, 16, lpm->defvals[1]);
}
memset(lpm->bitmask, 0, sizeof(lpm->bitmask));
lpm->defval = NULL;
memset(lpm->defvals, 0, sizeof(lpm->defvals));
}
void
@ -150,10 +164,10 @@ fnv1a_hash(const void *buf, size_t len)
}
static bool
hashmap_rehash(lpm_hmap_t *hmap, uint32_t size)
hashmap_rehash(lpm_hmap_t *hmap, unsigned size)
{
lpm_ent_t **bucket;
uint32_t hashsize;
unsigned hashsize;
for (hashsize = 1; hashsize < size; hashsize <<= 1) {
continue;
@ -165,7 +179,7 @@ hashmap_rehash(lpm_hmap_t *hmap, uint32_t size)
while (list) {
lpm_ent_t *entry = list;
uint32_t hash = fnv1a_hash(entry->key, entry->len);
const size_t i = hash & (hashsize - 1);
const unsigned i = hash & (hashsize - 1);
list = entry->next;
entry->next = bucket[i];
@ -182,7 +196,7 @@ hashmap_rehash(lpm_hmap_t *hmap, uint32_t size)
static lpm_ent_t *
hashmap_insert(lpm_hmap_t *hmap, const void *key, size_t len)
{
const uint32_t target = hmap->nitems + LPM_HASH_STEP;
const unsigned target = hmap->nitems + LPM_HASH_STEP;
const size_t entlen = offsetof(lpm_ent_t, key[len]);
uint32_t hash, i;
lpm_ent_t *entry;
@ -201,13 +215,14 @@ hashmap_insert(lpm_hmap_t *hmap, const void *key, size_t len)
entry = entry->next;
}
entry = kmem_alloc(entlen, KM_SLEEP);
memcpy(entry->key, key, len);
entry->next = hmap->bucket[i];
entry->len = len;
if ((entry = kmem_alloc(entlen, KM_SLEEP)) != NULL) {
memcpy(entry->key, key, len);
entry->next = hmap->bucket[i];
entry->len = len;
hmap->bucket[i] = entry;
hmap->nitems++;
hmap->bucket[i] = entry;
hmap->nitems++;
}
return entry;
}
@ -215,8 +230,13 @@ static lpm_ent_t *
hashmap_lookup(lpm_hmap_t *hmap, const void *key, size_t len)
{
const uint32_t hash = fnv1a_hash(key, len);
const uint32_t i = hash & (hmap->hashsize - 1);
lpm_ent_t *entry = hmap->bucket[i];
const unsigned i = hash & (hmap->hashsize - 1);
lpm_ent_t *entry;
if (hmap->hashsize == 0) {
return NULL;
}
entry = hmap->bucket[i];
while (entry) {
if (entry->len == len && memcmp(entry->key, key, len) == 0) {
@ -231,8 +251,13 @@ static int
hashmap_remove(lpm_hmap_t *hmap, const void *key, size_t len)
{
const uint32_t hash = fnv1a_hash(key, len);
const uint32_t i = hash & (hmap->hashsize - 1);
lpm_ent_t *prev = NULL, *entry = hmap->bucket[i];
const unsigned i = hash & (hmap->hashsize - 1);
lpm_ent_t *prev = NULL, *entry;
if (hmap->hashsize == 0) {
return -1;
}
entry = hmap->bucket[i];
while (entry) {
if (entry->len == len && memcmp(entry->key, key, len) == 0) {
@ -293,10 +318,11 @@ lpm_insert(lpm_t *lpm, const void *addr,
const unsigned nwords = LPM_TO_WORDS(len);
uint32_t prefix[LPM_MAX_WORDS];
lpm_ent_t *entry;
KASSERT(len == 4 || len == 16);
if (preflen == 0) {
/* Default is a special case. */
lpm->defval = val;
/* 0-length prefix is a special case. */
lpm->defvals[LPM_LEN_IDX(len)] = val;
return 0;
}
compute_prefix(nwords, addr, preflen, prefix);
@ -318,9 +344,10 @@ lpm_remove(lpm_t *lpm, const void *addr, size_t len, unsigned preflen)
{
const unsigned nwords = LPM_TO_WORDS(len);
uint32_t prefix[LPM_MAX_WORDS];
KASSERT(len == 4 || len == 16);
if (preflen == 0) {
lpm->defval = NULL;
lpm->defvals[LPM_LEN_IDX(len)] = NULL;
return 0;
}
compute_prefix(nwords, addr, preflen, prefix);
@ -355,7 +382,31 @@ lpm_lookup(lpm_t *lpm, const void *addr, size_t len)
bitmask &= ~(1U << i);
}
}
return lpm->defval;
return lpm->defvals[LPM_LEN_IDX(len)];
}
/*
* lpm_lookup_prefix: return the value associated with a prefix
*
* => Returns the associated value on success or NULL on failure.
*/
void *
lpm_lookup_prefix(lpm_t *lpm, const void *addr, size_t len, unsigned preflen)
{
const unsigned nwords = LPM_TO_WORDS(len);
uint32_t prefix[LPM_MAX_WORDS];
lpm_ent_t *entry;
KASSERT(len == 4 || len == 16);
if (preflen == 0) {
return lpm->defvals[LPM_LEN_IDX(len)];
}
compute_prefix(nwords, addr, preflen, prefix);
entry = hashmap_lookup(&lpm->prefix[preflen], prefix, len);
if (entry) {
return entry->val;
}
return NULL;
}
#if !defined(_KERNEL)

View File

@ -39,6 +39,7 @@ void lpm_clear(lpm_t *, lpm_dtor_t, void *);
int lpm_insert(lpm_t *, const void *, size_t, unsigned, void *);
int lpm_remove(lpm_t *, const void *, size_t, unsigned);
void * lpm_lookup(lpm_t *, const void *, size_t);
void * lpm_lookup_prefix(lpm_t *, const void *, size_t, unsigned);
int lpm_strtobin(const char *, void *, size_t *, unsigned *);
__END_DECLS

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf.c,v 1.35 2018/09/12 21:58:38 christos Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.35 2018/09/12 21:58:38 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.36 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -48,7 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.35 2018/09/12 21:58:38 christos Exp $");
#include "npf_impl.h"
#include "npf_conn.h"
__read_mostly static npf_t * npf_kernel_ctx = NULL;
static __read_mostly npf_t * npf_kernel_ctx = NULL;
__dso_public int
npf_sysinit(unsigned nworkers)
@ -111,9 +109,9 @@ npf_destroy(npf_t *npf)
}
__dso_public int
npf_load(npf_t *npf, void *ref, npf_error_t *err)
npf_load(npf_t *npf, void *config_ref, npf_error_t *err)
{
return npfctl_load(npf, 0, ref);
return npfctl_load(npf, 0, config_ref);
}
__dso_public void
@ -128,6 +126,13 @@ npf_thread_register(npf_t *npf)
pserialize_register(npf->qsbr);
}
__dso_public void
npf_thread_unregister(npf_t *npf)
{
pserialize_perform(npf->qsbr);
pserialize_unregister(npf->qsbr);
}
void
npf_setkernctx(npf_t *npf)
{

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf.h,v 1.57 2018/04/19 21:50:09 christos Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -39,13 +37,12 @@
#include <sys/param.h>
#include <sys/types.h>
#define NPF_VERSION 19
#define NPF_VERSION 20
#if defined(_NPF_STANDALONE)
#include "npf_stand.h"
#else
#include <sys/ioctl.h>
#include <prop/proplib.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#endif
@ -180,7 +177,7 @@ typedef struct {
} npc_l4;
} npf_cache_t;
static __inline bool
static inline bool
npf_iscached(const npf_cache_t *npc, const int inf)
{
KASSERT(npc->npc_nbuf != NULL);
@ -190,32 +187,6 @@ npf_iscached(const npf_cache_t *npc, const int inf)
#define NPF_SRC 0
#define NPF_DST 1
/*
* NPF extensions and rule procedure interface.
*/
struct npf_rproc;
typedef struct npf_rproc npf_rproc_t;
typedef struct {
uint64_t mi_rid;
u_int mi_retfl;
u_int mi_di;
} npf_match_info_t;
typedef struct {
unsigned int version;
void * ctx;
int (*ctor)(npf_rproc_t *, prop_dictionary_t);
void (*dtor)(npf_rproc_t *, void *);
bool (*proc)(npf_cache_t *, void *, const npf_match_info_t *,
int *);
} npf_ext_ops_t;
void * npf_ext_register(npf_t *, const char *, const npf_ext_ops_t *);
int npf_ext_unregister(npf_t *, void *);
void npf_rproc_assign(npf_rproc_t *, void *);
/*
* Misc.
*/
@ -327,12 +298,12 @@ typedef struct npf_ioctl_table {
#define IOC_NPF_VERSION _IOR('N', 100, int)
#define IOC_NPF_SWITCH _IOW('N', 101, int)
#define IOC_NPF_LOAD _IOWR('N', 102, struct plistref)
#define IOC_NPF_LOAD _IOWR('N', 102, nvlist_ref_t)
#define IOC_NPF_TABLE _IOW('N', 103, struct npf_ioctl_table)
#define IOC_NPF_STATS _IOW('N', 104, void *)
#define IOC_NPF_SAVE _IOR('N', 105, struct plistref)
#define IOC_NPF_RULE _IOWR('N', 107, struct plistref)
#define IOC_NPF_CONN_LOOKUP _IOWR('N', 108, struct plistref)
#define IOC_NPF_SAVE _IOR('N', 105, nvlist_ref_t)
#define IOC_NPF_RULE _IOWR('N', 107, nvlist_ref_t)
#define IOC_NPF_CONN_LOOKUP _IOWR('N', 108, nvlist_ref_t)
/*
* NPF error report.

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_alg.c,v 1.17 2018/09/12 21:58:38 christos Exp $ */
/*-
* Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.17 2018/09/12 21:58:38 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.18 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -135,6 +133,7 @@ npf_alg_construct(npf_t *npf, const char *name)
npf_config_enter(npf);
if ((alg = npf_alg_lookup(npf, name)) == NULL) {
char modname[NPF_EXT_PREFLEN + 64];
snprintf(modname, sizeof(modname), "%s%s", alg_prefix, name);
npf_config_exit(npf);
@ -295,24 +294,24 @@ npf_alg_conn(npf_cache_t *npc, int di)
return con;
}
prop_array_t
npf_alg_export(npf_t *npf)
int
npf_alg_export(npf_t *npf, nvlist_t *npf_dict)
{
prop_array_t alglist = prop_array_create();
npf_algset_t *aset = npf->algset;
KASSERT(npf_config_locked_p(npf));
for (u_int i = 0; i < aset->alg_count; i++) {
const npf_alg_t *alg = &aset->alg_list[i];
nvlist_t *algdict;
if (alg->na_name == NULL) {
continue;
}
prop_dictionary_t algdict = prop_dictionary_create();
prop_dictionary_set_cstring(algdict, "name", alg->na_name);
prop_array_add(alglist, algdict);
prop_object_release(algdict);
algdict = nvlist_create(0);
nvlist_add_string(algdict, "name", alg->na_name);
nvlist_append_nvlist_array(npf_dict, "algs", algdict);
nvlist_destroy(algdict);
}
return alglist;
return 0;
}

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_alg_icmp.c,v 1.30 2018/03/23 08:34:57 maxv Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.30 2018/03/23 08:34:57 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.31 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/module.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_bpf.c,v 1.13 2017/12/10 00:07:36 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.13 2017/12/10 00:07:36 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.14 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/param.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_conf.c,v 1.11 2017/01/03 00:58:05 rmind Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -49,7 +47,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.11 2017/01/03 00:58:05 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.12 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_conn.c,v 1.24 2017/12/10 00:07:36 rmind Exp $ */
/*-
* Copyright (c) 2014-2015 Mindaugas Rasiukevicius <rmind at netbsd org>
* Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
@ -100,7 +98,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.24 2017/12/10 00:07:36 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.25 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -135,6 +133,7 @@ CTASSERT(PFIL_ALL == (0x001 | 0x002));
enum { CONN_TRACKING_OFF, CONN_TRACKING_ON };
static void npf_conn_destroy(npf_t *, npf_conn_t *);
static nvlist_t *npf_conn_export(npf_t *, const npf_conn_t *);
/*
* npf_conn_sys{init,fini}: initialise/destroy connection tracking.
@ -913,7 +912,7 @@ npf_conn_worker(npf_t *npf)
* Note: this is expected to be an expensive operation.
*/
int
npf_conndb_export(npf_t *npf, prop_array_t conlist)
npf_conndb_export(npf_t *npf, nvlist_t *npf_dict)
{
npf_conn_t *con, *prev;
@ -930,11 +929,11 @@ npf_conndb_export(npf_t *npf, prop_array_t conlist)
con = npf_conndb_getlist(npf->conn_db);
while (con) {
npf_conn_t *next = con->c_next;
prop_dictionary_t cdict;
nvlist_t *cdict;
if ((cdict = npf_conn_export(npf, con)) != NULL) {
prop_array_add(conlist, cdict);
prop_object_release(cdict);
nvlist_append_nvlist_array(npf_dict, "conn-list", cdict);
nvlist_destroy(cdict);
}
prev = con;
con = next;
@ -944,59 +943,48 @@ npf_conndb_export(npf_t *npf, prop_array_t conlist)
return 0;
}
static prop_dictionary_t
static nvlist_t *
npf_connkey_export(const npf_connkey_t *key)
{
uint16_t id[2], alen, proto;
prop_dictionary_t kdict;
npf_addr_t ips[2];
prop_data_t d;
nvlist_t *kdict;
kdict = prop_dictionary_create();
kdict = nvlist_create(0);
connkey_getkey(key, &proto, ips, id, &alen);
prop_dictionary_set_uint16(kdict, "proto", proto);
prop_dictionary_set_uint16(kdict, "sport", id[NPF_SRC]);
prop_dictionary_set_uint16(kdict, "dport", id[NPF_DST]);
d = prop_data_create_data(&ips[NPF_SRC], alen);
prop_dictionary_set_and_rel(kdict, "saddr", d);
d = prop_data_create_data(&ips[NPF_DST], alen);
prop_dictionary_set_and_rel(kdict, "daddr", d);
nvlist_add_number(kdict, "proto", proto);
nvlist_add_number(kdict, "sport", id[NPF_SRC]);
nvlist_add_number(kdict, "dport", id[NPF_DST]);
nvlist_add_binary(kdict, "saddr", &ips[NPF_SRC], alen);
nvlist_add_binary(kdict, "daddr", &ips[NPF_DST], alen);
return kdict;
}
/*
* npf_conn_export: serialise a single connection.
*/
prop_dictionary_t
static nvlist_t *
npf_conn_export(npf_t *npf, const npf_conn_t *con)
{
prop_dictionary_t cdict, kdict;
prop_data_t d;
nvlist_t *cdict, *kdict;
if ((con->c_flags & (CONN_ACTIVE|CONN_EXPIRE)) != CONN_ACTIVE) {
return NULL;
}
cdict = prop_dictionary_create();
prop_dictionary_set_uint32(cdict, "flags", con->c_flags);
prop_dictionary_set_uint32(cdict, "proto", con->c_proto);
cdict = nvlist_create(0);
nvlist_add_number(cdict, "flags", con->c_flags);
nvlist_add_number(cdict, "proto", con->c_proto);
if (con->c_ifid) {
const char *ifname = npf_ifmap_getname(npf, con->c_ifid);
prop_dictionary_set_cstring(cdict, "ifname", ifname);
nvlist_add_string(cdict, "ifname", ifname);
}
d = prop_data_create_data(&con->c_state, sizeof(npf_state_t));
prop_dictionary_set_and_rel(cdict, "state", d);
nvlist_add_binary(cdict, "state", &con->c_state, sizeof(npf_state_t));
kdict = npf_connkey_export(&con->c_forw_entry);
prop_dictionary_set_and_rel(cdict, "forw-key", kdict);
nvlist_move_nvlist(cdict, "forw-key", kdict);
kdict = npf_connkey_export(&con->c_back_entry);
prop_dictionary_set_and_rel(cdict, "back-key", kdict);
nvlist_move_nvlist(cdict, "back-key", kdict);
if (con->c_nat) {
npf_nat_export(cdict, con->c_nat);
@ -1005,49 +993,37 @@ npf_conn_export(npf_t *npf, const npf_conn_t *con)
}
static uint32_t
npf_connkey_import(prop_dictionary_t kdict, npf_connkey_t *key)
npf_connkey_import(const nvlist_t *kdict, npf_connkey_t *key)
{
prop_object_t sobj, dobj;
npf_addr_t const * ips[2];
uint16_t alen, proto, id[2];
uint16_t proto, id[2];
size_t alen1, alen2;
if (!prop_dictionary_get_uint16(kdict, "proto", &proto))
proto = dnvlist_get_number(kdict, "proto", 0);
id[NPF_SRC] = dnvlist_get_number(kdict, "sport", 0);
id[NPF_DST] = dnvlist_get_number(kdict, "dport", 0);
ips[NPF_SRC] = dnvlist_get_binary(kdict, "saddr", &alen1, NULL, 0);
ips[NPF_DST] = dnvlist_get_binary(kdict, "daddr", &alen2, NULL, 0);
if (__predict_false(alen1 == 0 || alen1 != alen2)) {
return 0;
if (!prop_dictionary_get_uint16(kdict, "sport", &id[NPF_SRC]))
return 0;
if (!prop_dictionary_get_uint16(kdict, "dport", &id[NPF_DST]))
return 0;
sobj = prop_dictionary_get(kdict, "saddr");
if ((ips[NPF_SRC] = prop_data_data_nocopy(sobj)) == NULL)
return 0;
dobj = prop_dictionary_get(kdict, "daddr");
if ((ips[NPF_DST] = prop_data_data_nocopy(dobj)) == NULL)
return 0;
alen = prop_data_size(sobj);
if (alen != prop_data_size(dobj))
return 0;
return connkey_setkey(key, proto, ips, id, alen, true);
}
return connkey_setkey(key, proto, ips, id, alen1, true);
}
/*
* npf_conn_import: fully reconstruct a single connection from a
* directory and insert into the given database.
* nvlist and insert into the given database.
*/
int
npf_conn_import(npf_t *npf, npf_conndb_t *cd, prop_dictionary_t cdict,
npf_conn_import(npf_t *npf, npf_conndb_t *cd, const nvlist_t *cdict,
npf_ruleset_t *natlist)
{
npf_conn_t *con;
npf_connkey_t *fw, *bk;
prop_object_t obj;
const nvlist_t *nat, *conkey;
const char *ifname;
const void *d;
const void *state;
size_t len;
/* Allocate a connection and initialise it (clear first). */
con = pool_cache_get(npf->conn_cache, PR_WAITOK);
@ -1055,44 +1031,41 @@ npf_conn_import(npf_t *npf, npf_conndb_t *cd, prop_dictionary_t cdict,
mutex_init(&con->c_lock, MUTEX_DEFAULT, IPL_SOFTNET);
npf_stats_inc(npf, NPF_STAT_CONN_CREATE);
prop_dictionary_get_uint32(cdict, "proto", &con->c_proto);
prop_dictionary_get_uint32(cdict, "flags", &con->c_flags);
con->c_proto = dnvlist_get_number(cdict, "proto", 0);
con->c_flags = dnvlist_get_number(cdict, "flags", 0);
con->c_flags &= PFIL_ALL | CONN_ACTIVE | CONN_PASS;
conn_update_atime(con);
if (prop_dictionary_get_cstring_nocopy(cdict, "ifname", &ifname) &&
(con->c_ifid = npf_ifmap_register(npf, ifname)) == 0) {
ifname = dnvlist_get_string(cdict, "ifname", NULL);
if (ifname && (con->c_ifid = npf_ifmap_register(npf, ifname)) == 0) {
goto err;
}
obj = prop_dictionary_get(cdict, "state");
if ((d = prop_data_data_nocopy(obj)) == NULL ||
prop_data_size(obj) != sizeof(npf_state_t)) {
state = dnvlist_get_binary(cdict, "state", &len, NULL, 0);
if (!state || len != sizeof(npf_state_t)) {
goto err;
}
memcpy(&con->c_state, d, sizeof(npf_state_t));
memcpy(&con->c_state, state, sizeof(npf_state_t));
/* Reconstruct NAT association, if any. */
if ((obj = prop_dictionary_get(cdict, "nat")) != NULL &&
(con->c_nat = npf_nat_import(npf, obj, natlist, con)) == NULL) {
if ((nat = dnvlist_get_nvlist(cdict, "nat", NULL)) != NULL &&
(con->c_nat = npf_nat_import(npf, nat, natlist, con)) == NULL) {
goto err;
}
/*
* Fetch and copy the keys for each direction.
*/
obj = prop_dictionary_get(cdict, "forw-key");
conkey = dnvlist_get_nvlist(cdict, "forw-key", NULL);
fw = &con->c_forw_entry;
if (obj == NULL || !npf_connkey_import(obj, fw)) {
if (conkey == NULL || !npf_connkey_import(conkey, fw)) {
goto err;
}
obj = prop_dictionary_get(cdict, "back-key");
conkey = dnvlist_get_nvlist(cdict, "back-key", NULL);
bk = &con->c_back_entry;
if (obj == NULL || !npf_connkey_import(obj, bk)) {
if (conkey == NULL || !npf_connkey_import(conkey, bk)) {
goto err;
}
fw->ck_backptr = bk->ck_backptr = con;
/* Insert the entries and the connection itself. */
@ -1113,41 +1086,30 @@ err:
}
int
npf_conn_find(npf_t *npf, prop_dictionary_t idict, prop_dictionary_t *odict)
npf_conn_find(npf_t *npf, const nvlist_t *idict, nvlist_t **odict)
{
prop_dictionary_t kdict;
const nvlist_t *kdict;
npf_connkey_t key;
npf_conn_t *con;
uint16_t dir;
bool forw;
if ((kdict = prop_dictionary_get(idict, "key")) == NULL)
kdict = dnvlist_get_nvlist(idict, "key", NULL);
if (!kdict || !npf_connkey_import(kdict, &key)) {
return EINVAL;
if (!npf_connkey_import(kdict, &key))
return EINVAL;
if (!prop_dictionary_get_uint16(idict, "direction", &dir))
return EINVAL;
}
dir = dnvlist_get_number(idict, "direction", 0);
con = npf_conndb_lookup(npf->conn_db, &key, &forw);
if (con == NULL) {
return ESRCH;
}
if (!npf_conn_ok(con, dir, true)) {
atomic_dec_uint(&con->c_refcnt);
return ESRCH;
}
*odict = npf_conn_export(npf, con);
if (*odict == NULL) {
atomic_dec_uint(&con->c_refcnt);
return ENOSPC;
}
atomic_dec_uint(&con->c_refcnt);
return 0;
return *odict ? 0 : ENOSPC;
}
#if defined(DDB) || defined(_NPF_TESTING)

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_conn.h,v 1.13 2017/12/10 00:07:36 rmind Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -121,10 +119,9 @@ int npf_conn_setnat(const npf_cache_t *, npf_conn_t *,
npf_nat_t * npf_conn_getnat(npf_conn_t *, const int, bool *);
void npf_conn_gc(npf_t *, npf_conndb_t *, bool, bool);
void npf_conn_worker(npf_t *);
int npf_conn_import(npf_t *, npf_conndb_t *, prop_dictionary_t,
int npf_conn_import(npf_t *, npf_conndb_t *, const nvlist_t *,
npf_ruleset_t *);
int npf_conn_find(npf_t *, prop_dictionary_t, prop_dictionary_t *);
prop_dictionary_t npf_conn_export(npf_t *, const npf_conn_t *);
int npf_conn_find(npf_t *, const nvlist_t *, nvlist_t **);
void npf_conn_print(const npf_conn_t *);
/*
@ -144,6 +141,6 @@ void npf_conndb_dequeue(npf_conndb_t *, npf_conn_t *,
npf_conn_t *);
npf_conn_t * npf_conndb_getlist(npf_conndb_t *);
void npf_conndb_settail(npf_conndb_t *, npf_conn_t *);
int npf_conndb_export(npf_t *, prop_array_t);
int npf_conndb_export(npf_t *, nvlist_t *);
#endif /* _NPF_CONN_H_ */

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_conndb.c,v 1.3 2016/12/26 23:05:06 christos Exp $ */
/*-
* Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_conndb.c,v 1.3 2016/12/26 23:05:06 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_conndb.c,v 1.4 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -141,10 +139,6 @@ npf_conndb_destroy(npf_conndb_t *cd)
KASSERT(!rb_tree_iterate(&hb->hb_tree, NULL, RB_DIR_LEFT));
rw_destroy(&hb->hb_lock);
}
#ifdef USE_JUDY
Word_t bytes;
JHSFA(bytes, cd->cd_tree);
#endif
kmem_free(cd, len);
}
@ -186,15 +180,6 @@ npf_conndb_lookup(npf_conndb_t *cd, const npf_connkey_t *key, bool *forw)
bool
npf_conndb_insert(npf_conndb_t *cd, npf_connkey_t *key, npf_conn_t *con)
{
#ifdef USE_JUDY
PWord_t pval;
JHSI(pval, cd->cd_tree, key, NPF_CONN_KEYLEN(key));
if (pval == PJERR || *pval != 0)
return false;
*pval = (uintptr_t)key;
return true;
#else
npf_hashbucket_t *hb = conndb_hash_bucket(cd, key);
bool ok;
@ -203,7 +188,6 @@ npf_conndb_insert(npf_conndb_t *cd, npf_connkey_t *key, npf_conn_t *con)
hb->hb_count += (u_int)ok;
rw_exit(&hb->hb_lock);
return ok;
#endif
}
/*
@ -213,12 +197,6 @@ npf_conndb_insert(npf_conndb_t *cd, npf_connkey_t *key, npf_conn_t *con)
npf_conn_t *
npf_conndb_remove(npf_conndb_t *cd, npf_connkey_t *key)
{
#ifdef USE_JUDY
PWord_t rc;
JHSD(rc, cd->cd_tree, key, NPF_CONN_KEYLEN(key));
return rc ? key->ck_backptr : NULL;
#else
npf_hashbucket_t *hb = conndb_hash_bucket(cd, key);
npf_connkey_t *foundkey;
npf_conn_t *con;
@ -233,7 +211,6 @@ npf_conndb_remove(npf_conndb_t *cd, npf_connkey_t *key)
}
rw_exit(&hb->hb_lock);
return con;
#endif
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_ext_log.c,v 1.14 2018/06/26 06:48:02 msaitoh Exp $ */
/*-
* Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_ext_log.c,v 1.14 2018/06/26 06:48:02 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_ext_log.c,v 1.15 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/module.h>
@ -65,12 +63,12 @@ typedef struct {
} npf_ext_log_t;
static int
npf_log_ctor(npf_rproc_t *rp, prop_dictionary_t params)
npf_log_ctor(npf_rproc_t *rp, const nvlist_t *params)
{
npf_ext_log_t *meta;
meta = kmem_zalloc(sizeof(npf_ext_log_t), KM_SLEEP);
prop_dictionary_get_uint32(params, "log-interface", &meta->if_idx);
meta->if_idx = dnvlist_get_number(params, "log-interface", 0);
npf_rproc_assign(rp, meta);
return 0;
}
@ -144,8 +142,9 @@ npf_log(npf_cache_t *npc, void *meta, const npf_match_info_t *mi, int *decision)
/* Pass through BPF. */
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
if (ifp->if_bpf)
if (ifp->if_bpf) {
bpf_mtap2(ifp->if_bpf, &hdr, NPFLOG_HDRLEN, m, BPF_D_OUT);
}
if_put(ifp, &psref);
KERNEL_UNLOCK_ONE(NULL);

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_ext_normalize.c,v 1.8 2018/08/31 14:16:06 maxv Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -28,7 +26,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.8 2018/08/31 14:16:06 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.9 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/module.h>
@ -67,7 +65,7 @@ typedef struct {
* with the given parameters.
*/
static int
npf_normalize_ctor(npf_rproc_t *rp, prop_dictionary_t params)
npf_normalize_ctor(npf_rproc_t *rp, const nvlist_t *params)
{
npf_normalize_t *np;
@ -75,12 +73,12 @@ npf_normalize_ctor(npf_rproc_t *rp, prop_dictionary_t params)
np = kmem_zalloc(sizeof(npf_normalize_t), KM_SLEEP);
/* IP ID randomisation and IP_DF flag cleansing. */
prop_dictionary_get_bool(params, "random-id", &np->n_random_id);
prop_dictionary_get_bool(params, "no-df", &np->n_no_df);
np->n_random_id = dnvlist_get_bool(params, "random-id", false);
np->n_no_df = dnvlist_get_bool(params, "no-df", false);
/* Minimum IP TTL and maximum TCP MSS. */
prop_dictionary_get_uint32(params, "min-ttl", &np->n_minttl);
prop_dictionary_get_uint32(params, "max-mss", &np->n_maxmss);
np->n_minttl = dnvlist_get_number(params, "min-ttl", 0);
np->n_maxmss = dnvlist_get_number(params, "max-mss", 0);
/* Assign the parameters for this rule procedure. */
npf_rproc_assign(rp, np);

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_ext_rndblock.c,v 1.7 2017/01/29 00:15:54 christos Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -33,7 +31,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_ext_rndblock.c,v 1.7 2017/01/29 00:15:54 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_ext_rndblock.c,v 1.8 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/cprng.h>
@ -69,7 +67,7 @@ typedef struct {
* associated with a rule procedure, which is being newly created.
*/
static int
npf_ext_rndblock_ctor(npf_rproc_t *rp, prop_dictionary_t params)
npf_ext_rndblock_ctor(npf_rproc_t *rp, const nvlist_t *params)
{
npf_ext_rndblock_t *meta;
@ -78,8 +76,8 @@ npf_ext_rndblock_ctor(npf_rproc_t *rp, prop_dictionary_t params)
* and our meta-data.
*/
meta = kmem_zalloc(sizeof(npf_ext_rndblock_t), KM_SLEEP);
prop_dictionary_get_uint32(params, "mod", &meta->mod);
prop_dictionary_get_uint32(params, "percentage", &meta->percentage);
meta->mod = dnvlist_get_number(params, "mod", 0);
meta->percentage = dnvlist_get_number(params, "percentage", 0);
npf_rproc_assign(rp, meta);
return 0;

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_handler.c,v 1.44 2018/07/10 16:49:09 maxv Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -37,7 +35,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.44 2018/07/10 16:49:09 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.45 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/param.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_if.c,v 1.8 2017/02/18 23:27:32 christos Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -46,7 +44,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_if.c,v 1.8 2017/02/18 23:27:32 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_if.c,v 1.9 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_ifaddr.c,v 1.3 2017/12/11 03:25:46 ozaki-r Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -33,8 +31,9 @@
* NPF network interface handling module.
*/
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_ifaddr.c,v 1.3 2017/12/11 03:25:46 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_ifaddr.c,v 1.4 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -43,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf_ifaddr.c,v 1.3 2017/12/11 03:25:46 ozaki-r Exp $
#include <net/if.h>
#include <netinet/in.h>
#include <netinet6/in6_var.h>
#endif
#include "npf_impl.h"
@ -177,5 +177,3 @@ npf_ifaddr_syncall(npf_t *npf)
IFNET_GLOBAL_UNLOCK();
KERNEL_UNLOCK_ONE(NULL);
}

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_impl.h,v 1.72 2018/09/12 21:58:38 christos Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -56,6 +54,8 @@
#include <net/bpfjit.h>
#include <net/if.h>
#endif
#include <dnv.h>
#include <nv.h>
#include "npf.h"
#include "npfkern.h"
@ -103,6 +103,12 @@ typedef struct npf_algset npf_algset_t;
typedef void (*npf_workfunc_t)(npf_t *);
typedef struct {
uint64_t mi_rid;
unsigned mi_retfl;
unsigned mi_di;
} npf_match_info_t;
/*
* Some artificial limits.
* Note: very unlikely to have many ALGs.
@ -200,6 +206,26 @@ struct npf {
percpu_t * stats_percpu;
};
/*
* NPF extensions and rule procedure interface.
*/
struct npf_rproc;
typedef struct npf_rproc npf_rproc_t;
typedef struct {
u_int version;
void * ctx;
int (*ctor)(npf_rproc_t *, const nvlist_t *);
void (*dtor)(npf_rproc_t *, void *);
bool (*proc)(npf_cache_t *, void *, const npf_match_info_t *, int *);
} npf_ext_ops_t;
void * npf_ext_register(npf_t *, const char *, const npf_ext_ops_t *);
int npf_ext_unregister(npf_t *, void *);
void npf_rproc_assign(npf_rproc_t *, void *);
/*
* INTERFACES.
*/
@ -306,13 +332,13 @@ npf_table_t * npf_tableset_getbyname(npf_tableset_t *, const char *);
npf_table_t * npf_tableset_getbyid(npf_tableset_t *, u_int);
npf_table_t * npf_tableset_swap(npf_tableset_t *, npf_table_t *);
void npf_tableset_reload(npf_t *, npf_tableset_t *, npf_tableset_t *);
int npf_tableset_export(npf_t *, const npf_tableset_t *, prop_array_t);
int npf_tableset_export(npf_t *, const npf_tableset_t *, nvlist_t *);
npf_table_t * npf_table_create(const char *, u_int, int, void *, size_t);
npf_table_t * npf_table_create(const char *, u_int, int, const void *, size_t);
void npf_table_destroy(npf_table_t *);
u_int npf_table_getid(npf_table_t *);
int npf_table_check(npf_tableset_t *, const char *, u_int, int);
int npf_table_check(npf_tableset_t *, const char *, uint64_t, uint64_t);
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,
@ -330,14 +356,15 @@ void npf_ruleset_reload(npf_t *, npf_ruleset_t *,
npf_rule_t * npf_ruleset_sharepm(npf_ruleset_t *, npf_natpolicy_t *);
npf_natpolicy_t *npf_ruleset_findnat(npf_ruleset_t *, uint64_t);
void npf_ruleset_freealg(npf_ruleset_t *, npf_alg_t *);
int npf_ruleset_export(npf_t *, const npf_ruleset_t *, prop_array_t);
int npf_ruleset_export(npf_t *, const npf_ruleset_t *,
const char *, nvlist_t *);
npf_rule_t * npf_ruleset_lookup(npf_ruleset_t *, const char *);
int npf_ruleset_add(npf_ruleset_t *, const char *, npf_rule_t *);
int npf_ruleset_remove(npf_ruleset_t *, const char *, uint64_t);
int npf_ruleset_remkey(npf_ruleset_t *, const char *,
const void *, size_t);
prop_dictionary_t npf_ruleset_list(npf_t *, npf_ruleset_t *, const char *);
nvlist_t * npf_ruleset_list(npf_t *, npf_ruleset_t *, const char *);
int npf_ruleset_flush(npf_ruleset_t *, const char *);
void npf_ruleset_gc(npf_ruleset_t *);
@ -346,7 +373,7 @@ npf_rule_t * npf_ruleset_inspect(npf_cache_t *, const npf_ruleset_t *,
int npf_rule_conclude(const npf_rule_t *, npf_match_info_t *);
/* Rule interface. */
npf_rule_t * npf_rule_alloc(npf_t *, prop_dictionary_t);
npf_rule_t * npf_rule_alloc(npf_t *, const nvlist_t *);
void npf_rule_setcode(npf_rule_t *, int, void *, size_t);
void npf_rule_setrproc(npf_rule_t *, npf_rproc_t *);
void npf_rule_free(npf_rule_t *);
@ -358,15 +385,15 @@ npf_rproc_t * npf_rule_getrproc(const npf_rule_t *);
void npf_ext_init(npf_t *);
void npf_ext_fini(npf_t *);
int npf_ext_construct(npf_t *, const char *,
npf_rproc_t *, prop_dictionary_t);
npf_rproc_t *, const nvlist_t *);
npf_rprocset_t *npf_rprocset_create(void);
void npf_rprocset_destroy(npf_rprocset_t *);
npf_rproc_t * npf_rprocset_lookup(npf_rprocset_t *, const char *);
void npf_rprocset_insert(npf_rprocset_t *, npf_rproc_t *);
int npf_rprocset_export(const npf_rprocset_t *, prop_array_t);
int npf_rprocset_export(const npf_rprocset_t *, nvlist_t *);
npf_rproc_t * npf_rproc_create(prop_dictionary_t);
npf_rproc_t * npf_rproc_create(const nvlist_t *);
void npf_rproc_acquire(npf_rproc_t *);
void npf_rproc_release(npf_rproc_t *);
const char * npf_rproc_getname(const npf_rproc_t *);
@ -385,8 +412,8 @@ int npf_state_tcp_timeout(const npf_state_t *);
/* NAT. */
void npf_nat_sysinit(void);
void npf_nat_sysfini(void);
npf_natpolicy_t *npf_nat_newpolicy(npf_t *, prop_dictionary_t, npf_ruleset_t *);
int npf_nat_policyexport(const npf_natpolicy_t *, prop_dictionary_t);
npf_natpolicy_t *npf_nat_newpolicy(npf_t *, const nvlist_t *, npf_ruleset_t *);
int npf_nat_policyexport(const npf_natpolicy_t *, nvlist_t *);
void npf_nat_freepolicy(npf_natpolicy_t *);
bool npf_nat_cmppolicy(npf_natpolicy_t *, npf_natpolicy_t *);
bool npf_nat_sharepm(npf_natpolicy_t *, npf_natpolicy_t *);
@ -400,8 +427,8 @@ void npf_nat_getorig(npf_nat_t *, npf_addr_t **, in_port_t *);
void npf_nat_gettrans(npf_nat_t *, npf_addr_t **, in_port_t *);
void npf_nat_setalg(npf_nat_t *, npf_alg_t *, uintptr_t);
void npf_nat_export(prop_dictionary_t, npf_nat_t *);
npf_nat_t * npf_nat_import(npf_t *, prop_dictionary_t, npf_ruleset_t *,
void npf_nat_export(nvlist_t *, npf_nat_t *);
npf_nat_t * npf_nat_import(npf_t *, const nvlist_t *, npf_ruleset_t *,
npf_conn_t *);
/* ALG interface. */
@ -415,7 +442,7 @@ npf_alg_t * npf_alg_construct(npf_t *, const char *);
bool npf_alg_match(npf_cache_t *, npf_nat_t *, int);
void npf_alg_exec(npf_cache_t *, npf_nat_t *, bool);
npf_conn_t * npf_alg_conn(npf_cache_t *, int);
prop_array_t npf_alg_export(npf_t *);
int npf_alg_export(npf_t *, nvlist_t *);
/* Debugging routines. */
const char * npf_addr_dump(const npf_addr_t *, int);
@ -431,6 +458,7 @@ npf_t * npf_getkernctx(void);
#ifdef __NetBSD__
#define pserialize_register(x)
#define pserialize_checkpoint(x)
#define pserialize_unregister(x)
#endif
#endif /* _NPF_IMPL_H_ */

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_inet.c,v 1.51 2018/08/31 14:16:06 maxv Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -40,7 +38,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.51 2018/08/31 14:16:06 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.52 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_mbuf.c,v 1.20 2018/08/10 06:46:09 maxv Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -38,7 +36,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.20 2018/08/10 06:46:09 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.21 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/mbuf.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_nat.c,v 1.43 2018/05/11 13:52:48 maxv Exp $ */
/*-
* Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
* Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@ -72,7 +70,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.43 2018/05/11 13:52:48 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.44 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -194,19 +192,20 @@ npf_nat_sysfini(void)
* => Shares portmap if policy is on existing translation address.
*/
npf_natpolicy_t *
npf_nat_newpolicy(npf_t *npf, prop_dictionary_t natdict, npf_ruleset_t *rset)
npf_nat_newpolicy(npf_t *npf, const nvlist_t *nat, npf_ruleset_t *rset)
{
npf_natpolicy_t *np;
prop_object_t obj;
npf_portmap_t *pm;
const void *addr;
size_t len;
np = kmem_zalloc(sizeof(npf_natpolicy_t), KM_SLEEP);
np->n_npfctx = npf;
/* The translation type, flags and policy ID. */
prop_dictionary_get_int32(natdict, "type", &np->n_type);
prop_dictionary_get_uint32(natdict, "flags", &np->n_flags);
prop_dictionary_get_uint64(natdict, "nat-policy", &np->n_id);
np->n_type = dnvlist_get_number(nat, "type", 0);
np->n_flags = dnvlist_get_number(nat, "flags", 0);
np->n_id = dnvlist_get_number(nat, "nat-policy", 0);
/* Should be exclusively either inbound or outbound NAT. */
if (((np->n_type == NPF_NATIN) ^ (np->n_type == NPF_NATOUT)) == 0) {
@ -216,20 +215,20 @@ npf_nat_newpolicy(npf_t *npf, prop_dictionary_t natdict, npf_ruleset_t *rset)
LIST_INIT(&np->n_nat_list);
/* Translation IP, mask and port (if applicable). */
obj = prop_dictionary_get(natdict, "nat-ip");
np->n_alen = prop_data_size(obj);
if (np->n_alen == 0 || np->n_alen > sizeof(npf_addr_t)) {
addr = dnvlist_get_binary(nat, "nat-ip", &len, NULL, 0);
if (!addr || len == 0 || len > sizeof(npf_addr_t)) {
goto err;
}
memcpy(&np->n_taddr, prop_data_data_nocopy(obj), np->n_alen);
prop_dictionary_get_uint8(natdict, "nat-mask", &np->n_tmask);
prop_dictionary_get_uint16(natdict, "nat-port", &np->n_tport);
memcpy(&np->n_taddr, addr, len);
np->n_alen = len;
prop_dictionary_get_uint32(natdict, "nat-algo", &np->n_algo);
np->n_tmask = dnvlist_get_number(nat, "nat-mask", 0);
np->n_tport = dnvlist_get_number(nat, "nat-port", 0);
np->n_algo = dnvlist_get_number(nat, "nat-algo", 0);
switch (np->n_algo) {
case NPF_ALGO_NPT66:
prop_dictionary_get_uint16(natdict, "npt66-adj",
&np->n_npt66_adj);
np->n_npt66_adj = dnvlist_get_number(nat, "npt66-adj", 0);
break;
default:
if (np->n_tmask != NPF_NO_NETMASK)
@ -266,26 +265,22 @@ err:
}
int
npf_nat_policyexport(const npf_natpolicy_t *np, prop_dictionary_t natdict)
npf_nat_policyexport(const npf_natpolicy_t *np, nvlist_t *nat)
{
prop_data_t d;
nvlist_add_number(nat, "type", np->n_type);
nvlist_add_number(nat, "flags", np->n_flags);
prop_dictionary_set_int32(natdict, "type", np->n_type);
prop_dictionary_set_uint32(natdict, "flags", np->n_flags);
d = prop_data_create_data(&np->n_taddr, np->n_alen);
prop_dictionary_set_and_rel(natdict, "nat-ip", d);
prop_dictionary_set_uint8(natdict, "nat-mask", np->n_tmask);
prop_dictionary_set_uint16(natdict, "nat-port", np->n_tport);
prop_dictionary_set_uint32(natdict, "nat-algo", np->n_algo);
nvlist_add_binary(nat, "nat-ip", &np->n_taddr, np->n_alen);
nvlist_add_number(nat, "nat-mask", np->n_tmask);
nvlist_add_number(nat, "nat-port", np->n_tport);
nvlist_add_number(nat, "nat-algo", np->n_algo);
switch (np->n_algo) {
case NPF_ALGO_NPT66:
prop_dictionary_set_uint16(natdict, "npt66-adj", np->n_npt66_adj);
nvlist_add_number(nat, "npt66-adj", np->n_npt66_adj);
break;
}
prop_dictionary_set_uint64(natdict, "nat-policy", np->n_id);
nvlist_add_number(nat, "nat-policy", np->n_id);
return 0;
}
@ -845,49 +840,47 @@ npf_nat_destroy(npf_nat_t *nt)
* npf_nat_export: serialise the NAT entry with a NAT policy ID.
*/
void
npf_nat_export(prop_dictionary_t condict, npf_nat_t *nt)
npf_nat_export(nvlist_t *condict, npf_nat_t *nt)
{
npf_natpolicy_t *np = nt->nt_natpolicy;
prop_dictionary_t natdict;
prop_data_t d;
nvlist_t *nat;
natdict = prop_dictionary_create();
d = prop_data_create_data(&nt->nt_oaddr, sizeof(npf_addr_t));
prop_dictionary_set_and_rel(natdict, "oaddr", d);
prop_dictionary_set_uint16(natdict, "oport", nt->nt_oport);
prop_dictionary_set_uint16(natdict, "tport", nt->nt_tport);
prop_dictionary_set_uint64(natdict, "nat-policy", np->n_id);
prop_dictionary_set_and_rel(condict, "nat", natdict);
nat = nvlist_create(0);
nvlist_add_binary(nat, "oaddr", &nt->nt_oaddr, sizeof(npf_addr_t));
nvlist_add_number(nat, "oport", nt->nt_oport);
nvlist_add_number(nat, "tport", nt->nt_tport);
nvlist_add_number(nat, "nat-policy", np->n_id);
nvlist_move_nvlist(condict, "nat", nat);
}
/*
* npf_nat_import: find the NAT policy and unserialise the NAT entry.
*/
npf_nat_t *
npf_nat_import(npf_t *npf, prop_dictionary_t natdict,
npf_nat_import(npf_t *npf, const nvlist_t *nat,
npf_ruleset_t *natlist, npf_conn_t *con)
{
npf_natpolicy_t *np;
npf_nat_t *nt;
const void *oaddr;
uint64_t np_id;
const void *d;
size_t len;
prop_dictionary_get_uint64(natdict, "nat-policy", &np_id);
np_id = dnvlist_get_number(nat, "nat-policy", UINT64_MAX);
if ((np = npf_ruleset_findnat(natlist, np_id)) == NULL) {
return NULL;
}
nt = pool_cache_get(nat_cache, PR_WAITOK);
memset(nt, 0, sizeof(npf_nat_t));
prop_object_t obj = prop_dictionary_get(natdict, "oaddr");
if ((d = prop_data_data_nocopy(obj)) == NULL ||
prop_data_size(obj) != sizeof(npf_addr_t)) {
oaddr = dnvlist_get_binary(nat, "oaddr", &len, NULL, 0);
if (!oaddr || len != sizeof(npf_addr_t)) {
pool_cache_put(nat_cache, nt);
return NULL;
}
memcpy(&nt->nt_oaddr, d, sizeof(npf_addr_t));
prop_dictionary_get_uint16(natdict, "oport", &nt->nt_oport);
prop_dictionary_get_uint16(natdict, "tport", &nt->nt_tport);
memcpy(&nt->nt_oaddr, oaddr, sizeof(npf_addr_t));
nt->nt_oport = dnvlist_get_number(nat, "oport", 0);
nt->nt_tport = dnvlist_get_number(nat, "tport", 0);
/* Take a specific port from port-map. */
if ((np->n_flags & NPF_NAT_PORTMAP) != 0 && nt->nt_tport &&

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_os.c,v 1.9 2017/12/11 03:25:46 ozaki-r Exp $ */
/*-
* Copyright (c) 2009-2016 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.9 2017/12/11 03:25:46 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.10 2018/09/29 14:41:36 rmind Exp $");
#ifdef _KERNEL_OPT
#include "pf.h"

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_rproc.c,v 1.16 2017/01/29 00:15:54 christos Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -176,7 +174,7 @@ npf_ext_unregister(npf_t *npf, void *extid)
int
npf_ext_construct(npf_t *npf, const char *name,
npf_rproc_t *rp, prop_dictionary_t params)
npf_rproc_t *rp, const nvlist_t *params)
{
const npf_ext_ops_t *extops;
npf_ext_t *ext;
@ -262,19 +260,23 @@ npf_rprocset_insert(npf_rprocset_t *rpset, npf_rproc_t *rp)
}
int
npf_rprocset_export(const npf_rprocset_t *rpset, prop_array_t rprocs)
npf_rprocset_export(const npf_rprocset_t *rpset, nvlist_t *npf_dict)
{
prop_dictionary_t rpdict;
const npf_rproc_t *rp;
LIST_FOREACH(rp, &rpset->rps_list, rp_entry) {
rpdict = prop_dictionary_create();
prop_array_t extcalls = prop_array_create();
prop_dictionary_set_and_rel(rpdict, "extcalls", extcalls);
prop_dictionary_set_cstring(rpdict, "name", rp->rp_name);
prop_dictionary_set_uint32(rpdict, "flags", rp->rp_flags);
prop_array_add(rprocs, rpdict);
prop_object_release(rpdict);
nvlist_t *rproc = nvlist_create(0);
#if 0 // FIXME/TODO
for (unsigned i = 0; i < rp->rp_ext_count; i++) {
nvlist_t *meta = rp->rp_ext_meta[i];
...
nvlist_append_nvlist_array(rproc, "extcalls", meta);
}
#endif
nvlist_add_string(rproc, "name", rp->rp_name);
nvlist_add_number(rproc, "flags", rp->rp_flags);
nvlist_append_nvlist_array(npf_dict, "rprocs", rproc);
nvlist_destroy(rproc);
}
return 0;
}
@ -284,12 +286,12 @@ npf_rprocset_export(const npf_rprocset_t *rpset, prop_array_t rprocs)
* the extension calls with it.
*/
npf_rproc_t *
npf_rproc_create(prop_dictionary_t rpdict)
npf_rproc_create(const nvlist_t *rproc)
{
const char *name;
npf_rproc_t *rp;
if (!prop_dictionary_get_cstring_nocopy(rpdict, "name", &name)) {
if ((name = dnvlist_get_string(rproc, "name", NULL)) == NULL) {
return NULL;
}
@ -297,7 +299,7 @@ npf_rproc_create(prop_dictionary_t rpdict)
rp->rp_refcnt = 1;
strlcpy(rp->rp_name, name, RPROC_NAME_LEN);
prop_dictionary_get_uint32(rpdict, "flags", &rp->rp_flags);
rp->rp_flags = dnvlist_get_number(rproc, "flags", 0);
return rp;
}

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_ruleset.c,v 1.46 2017/12/10 01:18:21 rmind Exp $ */
/*-
* Copyright (c) 2009-2015 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.46 2017/12/10 01:18:21 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.47 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -117,14 +115,14 @@ struct npf_rule {
/* All-list entry and the auxiliary info. */
LIST_ENTRY(npf_rule) r_aentry;
prop_data_t r_info;
nvlist_t * r_info;
size_t r_info_len;
};
#define SKIPTO_ADJ_FLAG (1U << 31)
#define SKIPTO_MASK (SKIPTO_ADJ_FLAG - 1)
static int npf_rule_export(npf_t *, const npf_ruleset_t *,
const npf_rule_t *, prop_dictionary_t);
static nvlist_t * npf_rule_export(npf_t *, const npf_rule_t *);
/*
* Private attributes - must be in the NPF_RULE_PRIVMASK range.
@ -359,11 +357,10 @@ npf_ruleset_remkey(npf_ruleset_t *rlset, const char *rname,
/*
* npf_ruleset_list: serialise and return the dynamic rules.
*/
prop_dictionary_t
nvlist_t *
npf_ruleset_list(npf_t *npf, npf_ruleset_t *rlset, const char *rname)
{
prop_dictionary_t rgdict;
prop_array_t rules;
nvlist_t *rgroup;
npf_rule_t *rg;
KASSERT(npf_config_locked_p(npf));
@ -371,36 +368,24 @@ npf_ruleset_list(npf_t *npf, npf_ruleset_t *rlset, const char *rname)
if ((rg = npf_ruleset_lookup(rlset, rname)) == NULL) {
return NULL;
}
if ((rgdict = prop_dictionary_create()) == NULL) {
if ((rgroup = nvlist_create(0)) == NULL) {
return NULL;
}
if ((rules = prop_array_create()) == NULL) {
prop_object_release(rgdict);
return NULL;
}
for (npf_rule_t *rl = rg->r_subset; rl; rl = rl->r_next) {
prop_dictionary_t rldict;
nvlist_t *rule;
KASSERT(rl->r_parent == rg);
KASSERT(NPF_DYNAMIC_RULE_P(rl->r_attr));
rldict = prop_dictionary_create();
if (npf_rule_export(npf, rlset, rl, rldict)) {
prop_object_release(rldict);
prop_object_release(rules);
rule = npf_rule_export(npf, rl);
if (!rule) {
nvlist_destroy(rgroup);
return NULL;
}
prop_array_add(rules, rldict);
prop_object_release(rldict);
nvlist_append_nvlist_array(rgroup, "rules", rule);
nvlist_destroy(rule);
}
if (!prop_dictionary_set(rgdict, "rules", rules)) {
prop_object_release(rgdict);
rgdict = NULL;
}
prop_object_release(rules);
return rgdict;
return rgroup;
}
/*
@ -449,30 +434,31 @@ npf_ruleset_gc(npf_ruleset_t *rlset)
* npf_ruleset_export: serialise and return the static rules.
*/
int
npf_ruleset_export(npf_t *npf, const npf_ruleset_t *rlset, prop_array_t rules)
npf_ruleset_export(npf_t *npf, const npf_ruleset_t *rlset,
const char *key, nvlist_t *npf_dict)
{
const u_int nitems = rlset->rs_nitems;
const unsigned nitems = rlset->rs_nitems;
unsigned n = 0;
int error = 0;
u_int n = 0;
KASSERT(npf_config_locked_p(npf));
while (n < nitems) {
const npf_rule_t *rl = rlset->rs_rules[n];
const npf_natpolicy_t *natp = rl->r_natp;
prop_dictionary_t rldict;
nvlist_t *rule;
rldict = prop_dictionary_create();
if ((error = npf_rule_export(npf, rlset, rl, rldict)) != 0) {
prop_object_release(rldict);
rule = npf_rule_export(npf, rl);
if (!rule) {
error = ENOMEM;
break;
}
if (natp && (error = npf_nat_policyexport(natp, rldict)) != 0) {
prop_object_release(rldict);
if (natp && (error = npf_nat_policyexport(natp, rule)) != 0) {
nvlist_destroy(rule);
break;
}
prop_array_add(rules, rldict);
prop_object_release(rldict);
nvlist_append_nvlist_array(npf_dict, key, rule);
nvlist_destroy(rule);
n++;
}
return error;
@ -649,37 +635,43 @@ npf_ruleset_freealg(npf_ruleset_t *rlset, npf_alg_t *alg)
* npf_rule_alloc: allocate a rule and initialise it.
*/
npf_rule_t *
npf_rule_alloc(npf_t *npf, prop_dictionary_t rldict)
npf_rule_alloc(npf_t *npf, const nvlist_t *rule)
{
npf_rule_t *rl;
const char *rname;
prop_data_t d;
const void *key, *info;
size_t len;
/* Allocate a rule structure. */
/* Allocate a rule structure and keep the information. */
rl = kmem_zalloc(sizeof(npf_rule_t), KM_SLEEP);
info = dnvlist_get_binary(rule, "info", &rl->r_info_len, NULL, 0);
if (info) {
rl->r_info = kmem_alloc(rl->r_info_len, KM_SLEEP);
memcpy(rl->r_info, info, rl->r_info_len);
}
rl->r_natp = NULL;
/* Name (optional) */
if (prop_dictionary_get_cstring_nocopy(rldict, "name", &rname)) {
if ((rname = dnvlist_get_string(rule, "name", NULL)) != NULL) {
strlcpy(rl->r_name, rname, NPF_RULE_MAXNAMELEN);
} else {
rl->r_name[0] = '\0';
}
/* Attributes, priority and interface ID (optional). */
prop_dictionary_get_uint32(rldict, "attr", &rl->r_attr);
rl->r_attr = dnvlist_get_number(rule, "attr", 0);
rl->r_attr &= ~NPF_RULE_PRIVMASK;
if (NPF_DYNAMIC_RULE_P(rl->r_attr)) {
/* Priority of the dynamic rule. */
prop_dictionary_get_int32(rldict, "prio", &rl->r_priority);
rl->r_priority = dnvlist_get_number(rule, "prio", 0);
} else {
/* The skip-to index. No need to validate it. */
prop_dictionary_get_uint32(rldict, "skip-to", &rl->r_skip_to);
rl->r_skip_to = dnvlist_get_number(rule, "skip-to", 0);
}
/* Interface name; register and get the npf-if-id. */
if (prop_dictionary_get_cstring_nocopy(rldict, "ifname", &rname)) {
if ((rname = dnvlist_get_string(rule, "ifname", NULL)) != NULL) {
if ((rl->r_ifid = npf_ifmap_register(npf, rname)) == 0) {
kmem_free(rl, sizeof(npf_rule_t));
return NULL;
@ -689,68 +681,54 @@ npf_rule_alloc(npf_t *npf, prop_dictionary_t rldict)
}
/* Key (optional). */
prop_object_t obj = prop_dictionary_get(rldict, "key");
const void *key = prop_data_data_nocopy(obj);
if (key) {
size_t len = prop_data_size(obj);
if ((key = dnvlist_get_binary(rule, "key", &len, NULL, 0)) != NULL) {
if (len > NPF_RULE_MAXKEYLEN) {
kmem_free(rl, sizeof(npf_rule_t));
return NULL;
}
memcpy(rl->r_key, key, len);
}
if ((d = prop_dictionary_get(rldict, "info")) != NULL) {
rl->r_info = prop_data_copy(d);
}
return rl;
}
static int
npf_rule_export(npf_t *npf, const npf_ruleset_t *rlset,
const npf_rule_t *rl, prop_dictionary_t rldict)
static nvlist_t *
npf_rule_export(npf_t *npf, const npf_rule_t *rl)
{
u_int skip_to = 0;
prop_data_t d;
nvlist_t *rule = nvlist_create(0);
unsigned skip_to = 0;
npf_rproc_t *rp;
prop_dictionary_set_uint32(rldict, "attr", rl->r_attr);
prop_dictionary_set_int32(rldict, "prio", rl->r_priority);
nvlist_add_number(rule, "attr", rl->r_attr);
nvlist_add_number(rule, "prio", rl->r_priority);
if ((rl->r_skip_to & SKIPTO_ADJ_FLAG) == 0) {
skip_to = rl->r_skip_to & SKIPTO_MASK;
}
prop_dictionary_set_uint32(rldict, "skip-to", skip_to);
prop_dictionary_set_int32(rldict, "code-type", rl->r_type);
nvlist_add_number(rule, "skip-to", skip_to);
nvlist_add_number(rule, "code-type", rl->r_type);
if (rl->r_code) {
d = prop_data_create_data(rl->r_code, rl->r_clen);
prop_dictionary_set_and_rel(rldict, "code", d);
nvlist_add_binary(rule, "code", rl->r_code, rl->r_clen);
}
if (rl->r_ifid) {
const char *ifname = npf_ifmap_getname(npf, rl->r_ifid);
prop_dictionary_set_cstring(rldict, "ifname", ifname);
nvlist_add_string(rule, "ifname", ifname);
}
prop_dictionary_set_uint64(rldict, "id", rl->r_id);
nvlist_add_number(rule, "id", rl->r_id);
if (rl->r_name[0]) {
prop_dictionary_set_cstring(rldict, "name", rl->r_name);
nvlist_add_string(rule, "name", rl->r_name);
}
if (NPF_DYNAMIC_RULE_P(rl->r_attr)) {
d = prop_data_create_data(rl->r_key, NPF_RULE_MAXKEYLEN);
prop_dictionary_set_and_rel(rldict, "key", d);
nvlist_add_binary(rule, "key", rl->r_key, NPF_RULE_MAXKEYLEN);
}
if (rl->r_info) {
prop_dictionary_set(rldict, "info", rl->r_info);
nvlist_add_binary(rule, "info", rl->r_info, rl->r_info_len);
}
npf_rproc_t *rp = npf_rule_getrproc(rl);
if (rp != NULL) {
prop_dictionary_set_cstring(rldict, "rproc",
npf_rproc_getname(rp));
if ((rp = npf_rule_getrproc(rl)) != NULL) {
const char *rname = npf_rproc_getname(rp);
nvlist_add_string(rule, "rproc", rname);
npf_rproc_release(rp);
}
return 0;
return rule;
}
/*
@ -806,7 +784,7 @@ npf_rule_free(npf_rule_t *rl)
bpf_jit_freecode(rl->r_jcode);
}
if (rl->r_info) {
prop_object_release(rl->r_info);
kmem_free(rl->r_info, rl->r_info_len);
}
kmem_free(rl, sizeof(npf_rule_t));
}

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_sendpkt.c,v 1.19 2018/04/10 04:29:57 mrg Exp $ */
/*-
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.19 2018/04/10 04:29:57 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.20 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -67,6 +65,24 @@ __KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.19 2018/04/10 04:29:57 mrg Exp $")
#define in6_cksum(...) 0
#define ip6_output(...) 0
#define icmp6_error(m, ...) m_freem(m)
#define npf_ip6_setscope(n, i) 0
#endif
#if defined(INET6)
static int
npf_ip6_setscope(const npf_cache_t *npc, struct ip6_hdr *ip6)
{
const struct ifnet *rcvif = npc->npc_nbuf->nb_ifp;
if (in6_clearscope(&ip6->ip6_src) || in6_clearscope(&ip6->ip6_dst)) {
return EINVAL;
}
if (in6_setscope(&ip6->ip6_src, rcvif, NULL) ||
in6_setscope(&ip6->ip6_dst, rcvif, NULL)) {
return EINVAL;
}
return 0;
}
#endif
/*
@ -176,21 +192,10 @@ npf_return_tcp(npf_cache_t *npc)
sizeof(struct tcphdr));
}
#if defined(INET6)
/* Handle IPv6 scopes */
if (npf_iscached(npc, NPC_IP6)) {
const struct ifnet *rcvif = npc->npc_nbuf->nb_ifp;
if (in6_clearscope(&ip6->ip6_src) ||
in6_clearscope(&ip6->ip6_dst)) {
goto bad;
}
if (in6_setscope(&ip6->ip6_src, rcvif, NULL) ||
in6_setscope(&ip6->ip6_dst, rcvif, NULL)) {
goto bad;
}
if (npf_iscached(npc, NPC_IP6) && npf_ip6_setscope(npc, ip6) != 0) {
goto bad;
}
#endif
/* Pass to IP layer. */
if (npf_iscached(npc, NPC_IP4)) {
@ -198,7 +203,6 @@ npf_return_tcp(npf_cache_t *npc)
}
#if defined(INET6)
return ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
bad:
#endif
m_freem(m);
@ -216,23 +220,15 @@ npf_return_icmp(const npf_cache_t *npc)
if (npf_iscached(npc, NPC_IP4)) {
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_ADMIN_PROHIBIT, 0, 0);
return 0;
#if defined(INET6)
} else if (npf_iscached(npc, NPC_IP6)) {
/* Handle IPv6 scopes */
const struct ifnet *rcvif = npc->npc_nbuf->nb_ifp;
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
if (in6_clearscope(&ip6->ip6_src) ||
in6_clearscope(&ip6->ip6_dst)) {
return EINVAL;
}
if (in6_setscope(&ip6->ip6_src, rcvif, NULL) ||
in6_setscope(&ip6->ip6_dst, rcvif, NULL)) {
return EINVAL;
}
if (npf_ip6_setscope(npc, ip6) != 0) {
return EINVAL;
}
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN, 0);
return 0;
#endif
}
return EINVAL;
}

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_state.c,v 1.18 2016/12/26 23:05:06 christos Exp $ */
/*-
* Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.18 2016/12/26 23:05:06 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.19 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_state_tcp.c,v 1.18 2016/12/26 23:10:46 rmind Exp $ */
/*-
* Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +33,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.18 2016/12/26 23:10:46 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.19 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_tableset.c,v 1.27 2017/03/10 02:21:37 christos Exp $ */
/*-
* Copyright (c) 2009-2016 The NetBSD Foundation, Inc.
* All rights reserved.
@ -42,7 +40,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.27 2017/03/10 02:21:37 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.28 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -54,7 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.27 2017/03/10 02:21:37 christos E
#include <sys/malloc.h>
#include <sys/pool.h>
#include <sys/queue.h>
#include <sys/rwlock.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/types.h>
@ -99,7 +97,7 @@ struct npf_table {
*/
int t_type;
u_int t_id;
krwlock_t t_lock;
kmutex_t t_lock;
/* The number of items, reference count and table name. */
u_int t_nitems;
@ -275,23 +273,25 @@ npf_tableset_reload(npf_t *npf, npf_tableset_t *nts, npf_tableset_t *ots)
}
int
npf_tableset_export(npf_t *npf, const npf_tableset_t *ts, prop_array_t tables)
npf_tableset_export(npf_t *npf, const npf_tableset_t *ts, nvlist_t *npf_dict)
{
const npf_table_t *t;
KASSERT(npf_config_locked_p(npf));
for (u_int tid = 0; tid < ts->ts_nitems; tid++) {
nvlist_t *table;
if ((t = ts->ts_map[tid]) == NULL) {
continue;
}
prop_dictionary_t tdict = prop_dictionary_create();
prop_dictionary_set_cstring(tdict, "name", t->t_name);
prop_dictionary_set_uint32(tdict, "type", t->t_type);
prop_dictionary_set_uint32(tdict, "id", tid);
table = nvlist_create(0);
nvlist_add_string(table, "name", t->t_name);
nvlist_add_number(table, "type", t->t_type);
nvlist_add_number(table, "id", tid);
prop_array_add(tables, tdict);
prop_object_release(tdict);
nvlist_append_nvlist_array(npf_dict, "tables", table);
nvlist_destroy(table);
}
return 0;
}
@ -354,7 +354,7 @@ table_tree_flush(npf_table_t *t)
*/
npf_table_t *
npf_table_create(const char *name, u_int tid, int type,
void *blob, size_t size)
const void *blob, size_t size)
{
npf_table_t *t;
@ -369,18 +369,24 @@ npf_table_create(const char *name, u_int tid, int type,
LIST_INIT(&t->t_list);
break;
case NPF_TABLE_HASH:
size = MAX(size, 128);
size = MIN(MAX(size, 1024 * 1024), 8); // XXX
t->t_hashl = hashinit(size, HASH_LIST, true, &t->t_hashmask);
if (t->t_hashl == NULL) {
goto out;
}
break;
case NPF_TABLE_CDB:
t->t_blob = blob;
t->t_blob = kmem_alloc(size, KM_SLEEP);
if (t->t_blob == NULL) {
goto out;
}
memcpy(t->t_blob, blob, size);
t->t_bsize = size;
t->t_cdb = cdbr_open_mem(blob, size, CDBR_DEFAULT, NULL, NULL);
t->t_cdb = cdbr_open_mem(t->t_blob, size,
CDBR_DEFAULT, NULL, NULL);
if (t->t_cdb == NULL) {
free(blob, M_TEMP);
kmem_free(t->t_blob, t->t_bsize);
goto out;
}
t->t_nitems = cdbr_entries(t->t_cdb);
@ -388,7 +394,7 @@ npf_table_create(const char *name, u_int tid, int type,
default:
KASSERT(false);
}
rw_init(&t->t_lock);
mutex_init(&t->t_lock, MUTEX_DEFAULT, IPL_NET);
t->t_type = type;
t->t_id = tid;
return t;
@ -416,12 +422,12 @@ npf_table_destroy(npf_table_t *t)
break;
case NPF_TABLE_CDB:
cdbr_close(t->t_cdb);
free(t->t_blob, M_TEMP);
kmem_free(t->t_blob, t->t_bsize);
break;
default:
KASSERT(false);
}
rw_destroy(&t->t_lock);
mutex_destroy(&t->t_lock);
kmem_free(t, sizeof(npf_table_t));
}
@ -435,9 +441,9 @@ npf_table_getid(npf_table_t *t)
* npf_table_check: validate the name, ID and type.
*/
int
npf_table_check(npf_tableset_t *ts, const char *name, u_int tid, int type)
npf_table_check(npf_tableset_t *ts, const char *name, uint64_t tid, uint64_t type)
{
if ((u_int)tid >= ts->ts_nitems) {
if (tid >= ts->ts_nitems) {
return EINVAL;
}
if (ts->ts_map[tid] != NULL) {
@ -503,7 +509,7 @@ npf_table_insert(npf_table_t *t, const int alen,
/*
* Insert the entry. Return an error on duplicate.
*/
rw_enter(&t->t_lock, RW_WRITER);
mutex_enter(&t->t_lock);
switch (t->t_type) {
case NPF_TABLE_HASH: {
struct npf_hashl *htbl;
@ -543,7 +549,7 @@ npf_table_insert(npf_table_t *t, const int alen,
default:
KASSERT(false);
}
rw_exit(&t->t_lock);
mutex_exit(&t->t_lock);
if (error) {
pool_cache_put(tblent_cache, ent);
@ -567,7 +573,7 @@ npf_table_remove(npf_table_t *t, const int alen,
return error;
}
rw_enter(&t->t_lock, RW_WRITER);
mutex_enter(&t->t_lock);
switch (t->t_type) {
case NPF_TABLE_HASH: {
struct npf_hashl *htbl;
@ -596,7 +602,7 @@ npf_table_remove(npf_table_t *t, const int alen,
KASSERT(false);
ent = NULL;
}
rw_exit(&t->t_lock);
mutex_exit(&t->t_lock);
if (ent) {
pool_cache_put(tblent_cache, ent);
@ -623,14 +629,14 @@ npf_table_lookup(npf_table_t *t, const int alen, const npf_addr_t *addr)
switch (t->t_type) {
case NPF_TABLE_HASH:
rw_enter(&t->t_lock, RW_READER);
mutex_enter(&t->t_lock);
found = table_hash_lookup(t, addr, alen, &htbl) != NULL;
rw_exit(&t->t_lock);
mutex_exit(&t->t_lock);
break;
case NPF_TABLE_TREE:
rw_enter(&t->t_lock, RW_READER);
mutex_enter(&t->t_lock);
found = lpm_lookup(t->t_lpm, addr, alen) != NULL;
rw_exit(&t->t_lock);
mutex_exit(&t->t_lock);
break;
case NPF_TABLE_CDB:
if (cdbr_find(t->t_cdb, addr, alen, &data, &dlen) == 0) {
@ -726,7 +732,7 @@ npf_table_list(npf_table_t *t, void *ubuf, size_t len)
{
int error = 0;
rw_enter(&t->t_lock, RW_READER);
mutex_enter(&t->t_lock);
switch (t->t_type) {
case NPF_TABLE_HASH:
error = table_hash_list(t, ubuf, len);
@ -740,7 +746,7 @@ npf_table_list(npf_table_t *t, void *ubuf, size_t len)
default:
KASSERT(false);
}
rw_exit(&t->t_lock);
mutex_exit(&t->t_lock);
return error;
}
@ -753,7 +759,7 @@ npf_table_flush(npf_table_t *t)
{
int error = 0;
rw_enter(&t->t_lock, RW_WRITER);
mutex_enter(&t->t_lock);
switch (t->t_type) {
case NPF_TABLE_HASH:
table_hash_flush(t);
@ -769,6 +775,6 @@ npf_table_flush(npf_table_t *t)
default:
KASSERT(false);
}
rw_exit(&t->t_lock);
mutex_exit(&t->t_lock);
return error;
}

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_worker.c,v 1.4 2017/12/10 01:18:21 rmind Exp $ */
/*-
* Copyright (c) 2010-2015 The NetBSD Foundation, Inc.
* All rights reserved.
@ -31,7 +29,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_worker.c,v 1.4 2017/12/10 01:18:21 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: npf_worker.c,v 1.5 2018/09/29 14:41:36 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>

View File

@ -70,6 +70,7 @@ void npf_gc(npf_t *);
void npf_destroy(npf_t *);
void npf_thread_register(npf_t *);
void npf_thread_unregister(npf_t *);
int npf_packet_handler(npf_t *, struct mbuf **, struct ifnet *, int);
void npf_ifmap_attach(npf_t *, struct ifnet *);
void npf_ifmap_detach(npf_t *, struct ifnet *);

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.20 2017/01/03 03:47:51 christos Exp $
# $NetBSD: Makefile,v 1.21 2018/09/29 14:41:36 rmind Exp $
#
# Public Domain.
#
@ -27,6 +27,8 @@ SRCS+= npf_component.c
.include <bsd.own.mk>
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.if ${RUMP_NPF_TESTING:Uyes} == "yes"
CPPFLAGS+= -D_NPF_TESTING
.endif

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.ioctl-c,v 1.37 2018/06/12 15:41:35 christos Exp $
# $NetBSD: Makefile.ioctl-c,v 1.38 2018/09/29 14:41:36 rmind Exp $
# NOTE: <bsd.own.mk> needs to be previously .included for NETBSDSRCDIR
@ -42,6 +42,7 @@ DPSRCS+= ${PROG}-ioctl.c
CPPFLAGS+= -I${DESTDIR}/usr/X11R7/include/libdrm
CPPFLAGS+= -I${DESTDIR}/usr/X11R7/include/pixman-1
CPPFLAGS+= -I${DESTDIR}/usr/X11R7/include
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
.if ${MKDTRACE} != "no"
CPPFLAGS+= -I${NETBSDSRCDIR}/external/cddl/osnet/sys
CPPFLAGS+= -I${NETBSDSRCDIR}/external/cddl/osnet/dist/uts/common

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $NetBSD: mkioctls,v 1.52 2018/06/12 15:40:39 christos Exp $
# $NetBSD: mkioctls,v 1.53 2018/09/29 14:41:36 rmind Exp $
#
# Copyright (c) 1994
# The Regents of the University of California. All rights reserved.
@ -78,6 +78,7 @@ echo "#include <netinet6/nd6.h>"
echo "#include <dev/ic/hd44780reg.h>"
echo "#include <dev/pci/mlyreg.h>"
echo "#include <prop/proplib.h>"
echo "#include <nv.h>"
echo
# kernel headers <sys/*.h> and <net/*.h> should not include stdbool.h

2
usr.sbin/npf/README Normal file
View File

@ -0,0 +1,2 @@
The NPF project upstream repository: https://github.com/rmind/npf/
Please submit the pull requests to the upstream when possible.

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.12 2016/06/29 21:40:10 christos Exp $
# $NetBSD: Makefile,v 1.13 2018/09/29 14:41:36 rmind Exp $
.include <bsd.own.mk>
@ -13,8 +13,11 @@ CPPFLAGS+= -I${.CURDIR}
SRCS+= npf_scan.l npf_parse.y
YHEADER= 1
LDADD+= -lnpf -lprop -lpcap -lutil -ly
DPADD+= ${LIBNPF} ${LIBPROP} ${LIBUTIL} ${LIBPCAP} ${LIBUTIL} ${LIBY}
PROGDPLIBS+= nv ${NETBSDSRCDIR}/external/bsd/libnv/lib
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
LDADD+= -lnpf -lpcap -lutil -ly
DPADD+= ${LIBNPF} ${LIBUTIL} ${LIBPCAP} ${LIBUTIL} ${LIBY}
WARNS= 5
NOLINT= # disabled deliberately

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_bpf_comp.c,v 1.10 2016/12/27 22:35:33 rmind Exp $ */
/*-
* Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -34,7 +32,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_bpf_comp.c,v 1.10 2016/12/27 22:35:33 rmind Exp $");
__RCSID("$NetBSD: npf_bpf_comp.c,v 1.11 2018/09/29 14:41:36 rmind Exp $");
#include <stdlib.h>
#include <stdbool.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_build.c,v 1.45 2017/12/10 22:04:41 rmind Exp $ */
/*-
* Copyright (c) 2011-2017 The NetBSD Foundation, Inc.
* All rights reserved.
@ -34,11 +32,9 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_build.c,v 1.45 2017/12/10 22:04:41 rmind Exp $");
__RCSID("$NetBSD: npf_build.c,v 1.46 2018/09/29 14:41:36 rmind Exp $");
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
@ -52,7 +48,6 @@ __RCSID("$NetBSD: npf_build.c,v 1.45 2017/12/10 22:04:41 rmind Exp $");
#include <err.h>
#include <pcap/pcap.h>
#include <cdbw.h>
#include "npfctl.h"
@ -62,9 +57,9 @@ static nl_config_t * npf_conf = NULL;
static bool npf_debug = false;
static nl_rule_t * the_rule = NULL;
static bool defgroup = false;
static nl_rule_t * current_group[MAX_RULE_NESTING];
static unsigned rule_nesting_level = 0;
static nl_rule_t * defgroup = NULL;
static unsigned npfctl_tid_counter = 0;
static void npfctl_dump_bpf(struct bpf_program *);
@ -81,7 +76,7 @@ npfctl_config_init(bool debug)
}
int
npfctl_config_send(int fd, const char *out)
npfctl_config_send(int fd)
{
npf_error_t errinfo;
int error = 0;
@ -89,13 +84,7 @@ npfctl_config_send(int fd, const char *out)
if (!defgroup) {
errx(EXIT_FAILURE, "default group was not defined");
}
npf_rule_insert(npf_conf, NULL, defgroup);
if (out) {
printf("\nSaving to %s\n", out);
npfctl_config_save(npf_conf, out);
} else {
error = npf_config_submit(npf_conf, fd, &errinfo);
}
error = npf_config_submit(npf_conf, fd, &errinfo);
if (error == EEXIST) { /* XXX */
errx(EXIT_FAILURE, "(re)load failed: "
"some table has a duplicate entry?");
@ -126,6 +115,17 @@ npfctl_config_save(nl_config_t *ncf, const char *outfile)
close(fd);
}
void
npfctl_config_debug(const char *outfile)
{
printf("\nConfiguration:\n\n");
_npf_config_dump(npf_conf, STDOUT_FILENO);
printf("\nSaving binary to %s\n", outfile);
npfctl_config_save(npf_conf, outfile);
npf_config_destroy(npf_conf);
}
nl_config_t *
npfctl_config_ref(void)
{
@ -474,12 +474,12 @@ npfctl_build_rproc(const char *name, npfvar_t *procs)
if (rp == NULL) {
errx(EXIT_FAILURE, "%s failed", __func__);
}
npf_rproc_insert(npf_conf, rp);
for (i = 0; i < npfvar_get_count(procs); i++) {
proc_call_t *pc = npfvar_get_data(procs, NPFVAR_PROC, i);
npfctl_build_rpcall(rp, pc->pc_name, pc->pc_opts);
}
npf_rproc_insert(npf_conf, rp);
}
void
@ -499,8 +499,8 @@ npfctl_build_maprset(const char *name, int attr, const char *ifname)
}
/*
* npfctl_build_group: create a group, insert into the global ruleset,
* update the current group pointer and increase the nesting level.
* npfctl_build_group: create a group, update the current group pointer
* and increase the nesting level.
*/
void
npfctl_build_group(const char *name, int attr, const char *ifname, bool def)
@ -521,10 +521,7 @@ npfctl_build_group(const char *name, int attr, const char *ifname, bool def)
if (rule_nesting_level) {
yyerror("default group can only be at the top level");
}
defgroup = rl;
} else {
nl_rule_t *cg = current_group[rule_nesting_level];
npf_rule_insert(npf_conf, cg, rl);
defgroup = true;
}
/* Set the current group and increase the nesting level. */
@ -537,8 +534,15 @@ npfctl_build_group(const char *name, int attr, const char *ifname, bool def)
void
npfctl_build_group_end(void)
{
nl_rule_t *parent, *group;
assert(rule_nesting_level > 0);
parent = current_group[rule_nesting_level - 1];
group = current_group[rule_nesting_level];
current_group[rule_nesting_level--] = NULL;
/* Note: if the parent is NULL, then it is a global rule. */
npf_rule_insert(npf_conf, parent, group);
}
/*
@ -612,7 +616,6 @@ npfctl_build_nat(int type, const char *ifname, const addr_port_t *ap,
nat = npf_nat_create(type, flags, ifname, am->fam_family,
&am->fam_addr, am->fam_mask, port);
npfctl_build_code(nat, am->fam_family, op, fopts);
npf_nat_insert(npf_conf, nat, NPF_PRI_LAST);
return nat;
}
@ -719,6 +722,13 @@ npfctl_build_natseg(int sd, int type, unsigned mflags, const char *ifname,
npf_nat_setnpt66(nt1, ~adj);
npf_nat_setnpt66(nt2, adj);
}
if (nt1) {
npf_nat_insert(npf_conf, nt1, NPF_PRI_LAST);
}
if (nt2) {
npf_nat_insert(npf_conf, nt2, NPF_PRI_LAST);
}
}
/*
@ -727,15 +737,11 @@ npfctl_build_natseg(int sd, int type, unsigned mflags, const char *ifname,
static void
npfctl_fill_table(nl_table_t *tl, u_int type, const char *fname)
{
struct cdbw *cdbw = NULL; /* XXX: gcc */
char *buf = NULL;
int l = 0;
FILE *fp;
size_t n;
if (type == NPF_TABLE_CDB && (cdbw = cdbw_open()) == NULL) {
err(EXIT_FAILURE, "cdbw_open");
}
fp = fopen(fname, "r");
if (fp == NULL) {
err(EXIT_FAILURE, "open '%s'", fname);
@ -757,53 +763,10 @@ npfctl_fill_table(nl_table_t *tl, u_int type, const char *fname)
"non-tree table", fname, l);
}
/*
* Create and add a table entry.
*/
if (type == NPF_TABLE_CDB) {
const npf_addr_t *addr = &fam.fam_addr;
if (cdbw_put(cdbw, addr, alen, addr, alen) == -1) {
err(EXIT_FAILURE, "cdbw_put");
}
} else {
npf_table_add_entry(tl, fam.fam_family,
&fam.fam_addr, fam.fam_mask);
}
}
if (buf != NULL) {
free(buf);
}
if (type == NPF_TABLE_CDB) {
struct stat sb;
char sfn[32];
void *cdb;
int fd;
strncpy(sfn, "/tmp/npfcdb.XXXXXX", sizeof(sfn));
sfn[sizeof(sfn) - 1] = '\0';
if ((fd = mkstemp(sfn)) == -1) {
err(EXIT_FAILURE, "mkstemp");
}
unlink(sfn);
if (cdbw_output(cdbw, fd, "npf-table-cdb", NULL) == -1) {
err(EXIT_FAILURE, "cdbw_output");
}
cdbw_close(cdbw);
if (fstat(fd, &sb) == -1) {
err(EXIT_FAILURE, "fstat");
}
if ((cdb = mmap(NULL, sb.st_size, PROT_READ,
MAP_FILE | MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
err(EXIT_FAILURE, "mmap");
}
npf_table_setdata(tl, cdb, sb.st_size);
close(fd);
npf_table_add_entry(tl, fam.fam_family,
&fam.fam_addr, fam.fam_mask);
}
free(buf);
}
/*
@ -818,15 +781,15 @@ npfctl_build_table(const char *tname, u_int type, const char *fname)
tl = npf_table_create(tname, npfctl_tid_counter++, type);
assert(tl != NULL);
if (npf_table_insert(npf_conf, tl)) {
yyerror("table '%s' is already defined", tname);
}
if (fname) {
npfctl_fill_table(tl, type, fname);
} else if (type == NPF_TABLE_CDB) {
errx(EXIT_FAILURE, "tables of cdb type must be static");
}
if (npf_table_insert(npf_conf, tl)) {
yyerror("table '%s' is already defined", tname);
}
}
npfvar_t *

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_data.c,v 1.28 2017/01/19 20:18:17 rmind Exp $ */
/*-
* Copyright (c) 2009-2017 The NetBSD Foundation, Inc.
* All rights reserved.
@ -31,7 +29,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_data.c,v 1.28 2017/01/19 20:18:17 rmind Exp $");
__RCSID("$NetBSD: npf_data.c,v 1.29 2018/09/29 14:41:36 rmind Exp $");
#include <stdlib.h>
#include <stddef.h>
@ -511,6 +509,8 @@ npfctl_icmptype(int proto, const char *type)
default:
assert(false);
}
#else
(void)proto;
#endif
yyerror("unknown icmp-type %s", type);
return ~0;
@ -602,13 +602,15 @@ npfctl_icmpcode(int proto, uint8_t type, const char *code)
if (strcmp(arr[ul], code) == 0)
return ul;
}
#else
(void)proto;
#endif
yyerror("unknown code %s for icmp-type %d", code, type);
return ~0;
}
npfvar_t *
npfctl_parse_icmp(int proto, int type, int code)
npfctl_parse_icmp(int proto __unused, int type, int code)
{
npfvar_t *vp = npfvar_create();

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_extmod.c,v 1.4 2013/03/10 23:57:07 christos Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -34,7 +32,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_extmod.c,v 1.4 2013/03/10 23:57:07 christos Exp $");
__RCSID("$NetBSD: npf_extmod.c,v 1.5 2018/09/29 14:41:36 rmind Exp $");
#include <stdlib.h>
#include <inttypes.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_parse.y,v 1.46 2017/12/10 22:04:41 rmind Exp $ */
/*-
* Copyright (c) 2011-2017 The NetBSD Foundation, Inc.
* All rights reserved.

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_scan.l,v 1.26 2017/12/10 22:04:41 rmind Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
* All rights reserved.

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_show.c,v 1.25 2017/12/10 22:04:41 rmind Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
@ -36,7 +34,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_show.c,v 1.25 2017/12/10 22:04:41 rmind Exp $");
__RCSID("$NetBSD: npf_show.c,v 1.26 2018/09/29 14:41:36 rmind Exp $");
#include <sys/socket.h>
#define __FAVOR_BSD
@ -119,7 +117,7 @@ tcpflags2string(char *buf, u_int tfl)
}
static char *
print_family(npf_conf_info_t *ctx, const uint32_t *words)
print_family(npf_conf_info_t *ctx __unused, const uint32_t *words)
{
const int af = words[0];
@ -135,7 +133,7 @@ print_family(npf_conf_info_t *ctx, const uint32_t *words)
}
static char *
print_address(npf_conf_info_t *ctx, const uint32_t *words)
print_address(npf_conf_info_t *ctx __unused, const uint32_t *words)
{
const int af = *words++;
const u_int mask = *words++;
@ -157,7 +155,7 @@ print_address(npf_conf_info_t *ctx, const uint32_t *words)
}
static char *
print_number(npf_conf_info_t *ctx, const uint32_t *words)
print_number(npf_conf_info_t *ctx __unused, const uint32_t *words)
{
char *p;
easprintf(&p, "%u", words[0]);
@ -198,7 +196,7 @@ print_proto(npf_conf_info_t *ctx, const uint32_t *words)
}
static char *
print_tcpflags(npf_conf_info_t *ctx, const uint32_t *words)
print_tcpflags(npf_conf_info_t *ctx __unused, const uint32_t *words)
{
const u_int tf = words[0], tf_mask = words[1];
char buf[16];

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_var.c,v 1.10 2017/01/11 02:11:21 christos Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -30,7 +28,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npf_var.c,v 1.10 2017/01/11 02:11:21 christos Exp $");
__RCSID("$NetBSD: npf_var.c,v 1.11 2018/09/29 14:41:36 rmind Exp $");
#include <stdlib.h>
#include <string.h>

View File

@ -1,5 +1,3 @@
/* $NetBSD: npf_var.h,v 1.8 2013/11/19 00:28:41 rmind Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
* All rights reserved.

View File

@ -1,5 +1,3 @@
/* $NetBSD: npfctl.c,v 1.55 2018/04/13 17:43:37 maxv Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
@ -30,7 +28,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: npfctl.c,v 1.55 2018/04/13 17:43:37 maxv Exp $");
__RCSID("$NetBSD: npfctl.c,v 1.56 2018/09/29 14:41:36 rmind Exp $");
#include <sys/stat.h>
#include <sys/types.h>
@ -155,9 +153,6 @@ usage(void)
fprintf(stderr,
"\t%s list [-46hNnw] [-i <ifname>]\n",
progname);
fprintf(stderr,
"\t%s debug [<rule-file>] [<raw-output>]\n",
progname);
exit(EXIT_FAILURE);
}
@ -686,20 +681,20 @@ npfctl_conn_list(int fd, int argc, char **argv)
static int
npfctl_open_dev(const char *path)
{
int fd, ver;
int fd, kernver;
fd = open(path, O_RDONLY);
if (fd == -1) {
err(EXIT_FAILURE, "cannot open '%s'", path);
}
if (ioctl(fd, IOC_NPF_VERSION, &ver) == -1) {
if (ioctl(fd, IOC_NPF_VERSION, &kernver) == -1) {
err(EXIT_FAILURE, "ioctl(IOC_NPF_VERSION)");
}
if (ver != NPF_VERSION) {
if (kernver != NPF_VERSION) {
errx(EXIT_FAILURE,
"incompatible NPF interface version (%d, kernel %d)\n"
"Hint: update %s?", NPF_VERSION, ver,
NPF_VERSION > ver ? "userland" : "kernel");
"Hint: update %s?", NPF_VERSION, kernver,
kernver > NPF_VERSION ? "userland" : "kernel");
}
return fd;
}
@ -735,7 +730,7 @@ npfctl(int action, int argc, char **argv)
npfctl_config_init(false);
npfctl_parse_file(argc < 3 ? NPF_CONF_PATH : argv[2]);
npfctl_preload_bpfjit();
errno = ret = npfctl_config_send(fd, NULL);
errno = ret = npfctl_config_send(fd);
fun = "npfctl_config_send";
break;
case NPFCTL_SHOWCONF:
@ -792,7 +787,7 @@ npfctl(int action, int argc, char **argv)
case NPFCTL_DEBUG:
npfctl_config_init(true);
npfctl_parse_file(argc > 2 ? argv[2] : NPF_CONF_PATH);
npfctl_config_send(0, argc > 3 ? argv[3] : "/tmp/npf.plist");
npfctl_config_debug(argc > 3 ? argv[3] : "/tmp/npf.nvlist");
break;
}
if (ret) {

View File

@ -1,5 +1,3 @@
/* $NetBSD: npfctl.h,v 1.45 2017/12/10 22:04:41 rmind Exp $ */
/*-
* Copyright (c) 2009-2017 The NetBSD Foundation, Inc.
* All rights reserved.
@ -184,10 +182,11 @@ void npfctl_bpf_table(npf_bpf_t *, u_int, u_int);
#define NPFCTL_NAT_STATIC 2
void npfctl_config_init(bool);
int npfctl_config_send(int, const char *);
int npfctl_config_send(int);
nl_config_t * npfctl_config_ref(void);
int npfctl_config_show(int);
void npfctl_config_save(nl_config_t *, const char *);
void npfctl_config_debug(const char *);
void npfctl_show_init(void);
int npfctl_ruleset_show(int, const char *);

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.5 2017/01/07 16:48:03 christos Exp $
# $NetBSD: Makefile,v 1.6 2018/09/29 14:41:36 rmind Exp $
#
# Public Domain
#
@ -9,6 +9,9 @@ MAN= npfd.8
SRCS= npfd.c npfd_log.c
CPPFLAGS+= -I${.CURDIR}
PROGDPLIBS+= nv ${NETBSDSRCDIR}/external/bsd/libnv/lib
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
LDADD+= -lnpf -lpcap -lutil
DPADD+= ${LIBNPF} ${LIBPCAP} ${LIBUTIL}

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.10 2016/08/08 16:31:53 kre Exp $
# $NetBSD: Makefile,v 1.11 2018/09/29 14:41:36 rmind Exp $
#
# Public Domain
#
@ -27,9 +27,11 @@ LDADD+= -lrumpdev
LDADD+= -lrumpkern_sljit -lrumpnet_bpfjit
.endif
LDADD+= -lrumpnet_npf
LDADD+= -lrumpkern_nv -lrumpnet_npf
LDADD+= -lpcap -lpthread
LDADD+= -lpcap -lprop -lpthread
PROGDPLIBS+= nv ${NETBSDSRCDIR}/external/bsd/libnv/lib
CPPFLAGS+= -I ${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
SUBDIR+= libnpftest

View File

@ -1,4 +1,4 @@
$NetBSD: README,v 1.6 2014/06/25 00:21:42 rmind Exp $
$NetBSD: README,v 1.7 2018/09/29 14:41:36 rmind Exp $
npftest - a tool for regression testing and debugging NPF.
It uses RUMP framework to run NPF kernel module in the userspace.
@ -7,20 +7,20 @@ It uses RUMP framework to run NPF kernel module in the userspace.
Test:
npfctl debug npftest.conf /tmp/npf.plist
npftest -c /tmp/npf.plist -t
npfctl debug npftest.conf /tmp/npf.nvlist
npftest -c /tmp/npf.nvlist -t
Stream:
tcpdump -w stream.pcap -i $interface "host $host and tcp"
npfctl debug npftest.conf /tmp/npf.plist
npftest -c /tmp/npf.plist -s stream.pcap > stream_npf_data.txt
npfctl debug npftest.conf /tmp/npf.nvlist
npftest -c /tmp/npf.nvlist -s stream.pcap > stream_npf_data.txt
Preferably, use MALLOC_OPTIONS="AJ" and/or other facilities.
Benchmark:
npftest -b rule -c /tmp/npf.plist -p $ncpu
npftest -b rule -c /tmp/npf.nvlist -p $ncpu
---

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.8 2013/11/16 01:41:43 rmind Exp $
# $NetBSD: Makefile,v 1.9 2018/09/29 14:41:36 rmind Exp $
#
# Public Domain
#
@ -24,6 +24,8 @@ CPPFLAGS+= -D_NPF_TESTING
CPPFLAGS+= -I${.CURDIR}/../../../../sys/net/npf
CPPFLAGS+= -I${RUMPTOP}/librump/rumpkern
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/external/bsd/libnv/dist
WARNS= 5
.include "${RUMPTOP}/Makefile.rump"

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_bpf_test.c,v 1.8 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npf_bpf_test.c,v 1.9 2018/09/29 14:41:36 rmind Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -51,7 +51,7 @@ fill_packet(int proto)
struct ip *ip;
struct tcphdr *th;
m = mbuf_construct(IPPROTO_TCP);
m = mbuf_construct(proto);
th = mbuf_return_hdrs(m, false, &ip);
ip->ip_src.s_addr = inet_addr("192.168.2.100");
ip->ip_dst.s_addr = inet_addr("10.0.0.1");
@ -93,7 +93,7 @@ test_bpf_code(void *code, size_t size)
jcode = npf_bpf_compile(code, size);
if (jcode) {
jret = npf_bpf_filter(&bc_args, NULL, jcode);
assert(ret == jret);
assert(ret == jret); (void)jret;
bpf_jit_freecode(jcode);
} else if (lverbose) {
printf("JIT-compilation failed\n");

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_mbuf_subr.c,v 1.6 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npf_mbuf_subr.c,v 1.7 2018/09/29 14:41:36 rmind Exp $ */
/*
* NPF testing - helper routines.
@ -22,7 +22,7 @@ npfkern_m_get(int flags, int space)
unsigned mlen = offsetof(struct mbuf, m_data0[space]);
struct mbuf *m;
m = calloc(1, sizeof(struct mbuf));
m = calloc(1, mlen);
if (m) {
m->m_type = 1;
m->m_flags = flags;
@ -104,6 +104,7 @@ npfkern_m_ensure_contig(struct mbuf **m0, size_t len)
dptr += m->m_len;
}
*m0 = m1;
(void)len;
return true;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_perf_test.c,v 1.5 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npf_perf_test.c,v 1.6 2018/09/29 14:41:36 rmind Exp $ */
/*
* NPF benchmarking.
@ -60,7 +60,7 @@ worker(void *arg)
int error;
error = npf_packet_handler(npf, &m, ifp, PFIL_OUT);
KASSERT(error == 0);
KASSERT(error == 0); (void)error;
n++;
}
npackets[i] = n;
@ -86,7 +86,7 @@ npf_test_conc(bool st, unsigned nthreads)
error = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN |
KTHREAD_MPSAFE, NULL, worker, (void *)(uintptr_t)i,
&l[i], "npfperf");
KASSERT(error == 0);
KASSERT(error == 0); (void)error;
}
/* Let them spin! */

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_rule_test.c,v 1.14 2017/01/29 04:12:52 christos Exp $ */
/* $NetBSD: npf_rule_test.c,v 1.15 2018/09/29 14:41:36 rmind Exp $ */
/*
* NPF ruleset test.
@ -74,7 +74,7 @@ fill_packet(const struct test_case *t)
}
static int
npf_rule_raw_test(bool verbose, struct mbuf *m, ifnet_t *ifp, int di)
npf_rule_raw_test(struct mbuf *m, ifnet_t *ifp, int di)
{
npf_t *npf = npf_getkernctx();
npf_cache_t npc = { .npc_info = 0, .npc_ctx = npf };
@ -100,14 +100,14 @@ npf_rule_raw_test(bool verbose, struct mbuf *m, ifnet_t *ifp, int di)
}
static int
npf_test_case(u_int i, bool verbose)
npf_test_case(unsigned i)
{
const struct test_case *t = &test_cases[i];
ifnet_t *ifp = npf_test_getif(t->ifname);
int error;
struct mbuf *m = fill_packet(t);
error = npf_rule_raw_test(verbose, m, ifp, t->di);
error = npf_rule_raw_test(m, ifp, t->di);
m_freem(m);
return error;
}
@ -116,12 +116,11 @@ static npf_rule_t *
npf_blockall_rule(void)
{
npf_t *npf = npf_getkernctx();
prop_dictionary_t rldict;
nvlist_t *rule = nvlist_create(0);
rldict = prop_dictionary_create();
prop_dictionary_set_uint32(rldict, "attr",
nvlist_add_number(rule, "attr",
NPF_RULE_IN | NPF_RULE_OUT | NPF_RULE_DYNAMIC);
return npf_rule_alloc(npf, rldict);
return npf_rule_alloc(npf, rule);
}
bool
@ -145,7 +144,7 @@ npf_rule_test(bool verbose)
}
struct mbuf *m = fill_packet(t);
error = npf_rule_raw_test(verbose, m, ifp, t->di);
error = npf_rule_raw_test(m, ifp, t->di);
serror = npf_packet_handler(npf, &m, ifp, t->di);
if (m) {
@ -164,7 +163,7 @@ npf_rule_test(bool verbose)
* Test dynamic NPF rules.
*/
error = npf_test_case(0, verbose);
error = npf_test_case(0);
assert(error == RESULT_PASS);
npf_config_enter(npf);
@ -174,7 +173,7 @@ npf_rule_test(bool verbose)
error = npf_ruleset_add(rlset, "test-rules", rl);
fail |= error != 0;
error = npf_test_case(0, verbose);
error = npf_test_case(0);
fail |= (error != RESULT_BLOCK);
id = npf_rule_getid(rl);
@ -183,7 +182,7 @@ npf_rule_test(bool verbose)
npf_config_exit(npf);
error = npf_test_case(0, verbose);
error = npf_test_case(0);
fail |= (error != RESULT_PASS);
return !fail;

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_table_test.c,v 1.9 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npf_table_test.c,v 1.10 2018/09/29 14:41:36 rmind Exp $ */
/*
* NPF tableset test.
@ -39,22 +39,22 @@ static const char *ip_list[] = {
static const uint16_t ip6_list[][8] = {
{
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff),
U16_TO_LE(0xfe10), U16_TO_LE(0x1234)
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff),
U16_TO_LE(0xfe10), U16_TO_LE(0x1234)
},
{
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff), 0x00, 0x0
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff), 0x00, 0x0
},
{
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0
},
{
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff),
U16_TO_LE(0xfe10), U16_TO_LE(0x1230)
U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff),
U16_TO_LE(0xfe10), U16_TO_LE(0x1230)
}
};
@ -103,8 +103,9 @@ npf_table_test(bool verbose, void *blob, size_t size)
npf_tableset_t *tblset;
int error, alen;
bool fail = false;
void *cdb;
u_int i;
unsigned i;
(void)verbose;
tblset = npf_tableset_create(3);
fail |= !check_ok(tblset != NULL);
@ -126,10 +127,7 @@ npf_table_test(bool verbose, void *blob, size_t size)
fail |= !check_ok(error == 0);
/* Table ID 3, using a CDB. */
cdb = malloc(size, M_TEMP, M_WAITOK);
memcpy(cdb, blob, size);
t3 = npf_table_create(CDB_TID, 2, NPF_TABLE_CDB, cdb, size);
t3 = npf_table_create(CDB_TID, 2, NPF_TABLE_CDB, blob, size);
fail |= !(t3 != NULL);
error = npf_tableset_insert(tblset, t3);
fail |= !check_ok(error == 0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_test.h,v 1.16 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npf_test.h,v 1.17 2018/09/29 14:41:36 rmind Exp $ */
/*
* Public Domain.
@ -88,7 +88,7 @@ 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 *);
int npf_test_load(const void *, size_t, bool);
ifnet_t * npf_test_addif(const char *, bool, bool);
ifnet_t * npf_test_getif(const char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: npf_test_subr.c,v 1.12 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npf_test_subr.c,v 1.13 2018/09/29 14:41:36 rmind Exp $ */
/*
* NPF initialisation and handler routines.
@ -9,6 +9,7 @@
#ifdef _KERNEL
#include <sys/types.h>
#include <sys/cprng.h>
#include <sys/kmem.h>
#include <net/if.h>
#include <net/if_types.h>
#endif
@ -27,6 +28,8 @@ static const char * (*_ntop_func)(int, const void *, char *, socklen_t);
static void npf_state_sample(npf_state_t *, bool);
static void load_npf_config_ifs(nvlist_t *, bool);
#ifndef __NetBSD__
/*
* Standalone NPF: we define the same struct ifnet members
@ -82,17 +85,27 @@ npf_test_fini(void)
}
int
npf_test_load(const void *xml)
npf_test_load(const void *buf, size_t len, bool verbose)
{
prop_dictionary_t npf_dict = prop_dictionary_internalize(xml);
return npfctl_load(npf_getkernctx(), 0, npf_dict);
nvlist_t *npf_dict;
npf_error_t error;
npf_dict = nvlist_unpack(buf, len, 0);
if (!npf_dict) {
printf("%s: could not unpack the nvlist\n", __func__);
return EINVAL;
}
load_npf_config_ifs(npf_dict, verbose);
// Note: npf_dict will be consumed by npf_load().
return npf_load(npf_getkernctx(), npf_dict, &error);
}
ifnet_t *
npf_test_addif(const char *ifname, bool reg, bool verbose)
{
npf_t *npf = npf_getkernctx();
ifnet_t *ifp = malloc(sizeof(*ifp), M_TEST, M_WAITOK|M_ZERO);
ifnet_t *ifp = kmem_zalloc(sizeof(*ifp), KM_SLEEP);
/*
* This is a "fake" interface with explicitly set index.
@ -113,6 +126,31 @@ npf_test_addif(const char *ifname, bool reg, bool verbose)
return ifp;
}
static void
load_npf_config_ifs(nvlist_t *npf_dict, bool verbose)
{
const nvlist_t * const *iflist;
const nvlist_t *dbg_dict;
size_t nitems;
dbg_dict = dnvlist_get_nvlist(npf_dict, "debug", NULL);
if (!dbg_dict) {
return;
}
if (!nvlist_exists_nvlist_array(dbg_dict, "interfaces")) {
return;
}
iflist = nvlist_get_nvlist_array(dbg_dict, "interfaces", &nitems);
for (unsigned i = 0; i < nitems; i++) {
const nvlist_t *ifdict = iflist[i];
const char *ifname;
if ((ifname = nvlist_get_string(ifdict, "name")) != NULL) {
(void)npf_test_addif(ifname, true, verbose);
}
}
}
static const char *
npftest_ifop_getname(ifnet_t *ifp)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: npftest.c,v 1.21 2017/05/17 18:55:13 christos Exp $ */
/* $NetBSD: npftest.c,v 1.22 2018/09/29 14:41:36 rmind Exp $ */
/*
* NPF testing framework.
@ -22,7 +22,8 @@
#include <net/if.h>
#include <arpa/inet.h>
#include <prop/proplib.h>
#include <dnv.h>
#include <nv.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
@ -81,51 +82,40 @@ result(const char *testcase, bool ok)
}
static void
load_npf_config_ifs(prop_dictionary_t dbg_dict)
load_npf_config(const char *fpath)
{
prop_array_t iflist = prop_dictionary_get(dbg_dict, "interfaces");
prop_object_iterator_t it = prop_array_iterator(iflist);
prop_dictionary_t ifdict;
struct stat sb;
int error, fd;
size_t len;
void *buf;
while ((ifdict = prop_object_iterator_next(it)) != NULL) {
const char *ifname = NULL;
prop_dictionary_get_cstring_nocopy(ifdict, "name", &ifname);
(void)rumpns_npf_test_addif(ifname, true, verbose);
/*
* Read the configuration from the specified file.
*/
if ((fd = open(fpath, O_RDONLY)) == -1) {
err(EXIT_FAILURE, "open");
}
prop_object_iterator_release(it);
}
static void
load_npf_config(const char *config)
{
prop_dictionary_t npf_dict, dbg_dict;
void *xml;
int error;
/* Read the configuration from the specified file. */
npf_dict = prop_dictionary_internalize_from_file(config);
if (!npf_dict) {
err(EXIT_FAILURE, "prop_dictionary_internalize_from_file");
if (fstat(fd, &sb) == -1) {
err(EXIT_FAILURE, "fstat");
}
xml = prop_dictionary_externalize(npf_dict);
/* Inspect the debug data. Create the interfaces, if any. */
dbg_dict = prop_dictionary_get(npf_dict, "debug");
if (dbg_dict) {
load_npf_config_ifs(dbg_dict);
len = sb.st_size;
buf = mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
if (buf == MAP_FAILED) {
err(EXIT_FAILURE, "mmap");
}
prop_object_release(npf_dict);
close(fd);
/* Pass the XML configuration for NPF kernel component to load. */
error = rumpns_npf_test_load(xml);
/*
* Load the NPF configuration.
*/
error = rumpns_npf_test_load(buf, len, verbose);
if (error) {
errx(EXIT_FAILURE, "npf_test_load: %s\n", strerror(error));
}
free(xml);
munmap(buf, len);
if (verbose) {
printf("Loaded NPF config at '%s'\n", config);
printf("Loaded NPF config at '%s'\n", fpath);
}
}
@ -195,8 +185,6 @@ npf_kern_fini(void)
#endif
}
extern int rumpns_npfctl_testing;
int
main(int argc, char **argv)
{
@ -278,7 +266,6 @@ main(int argc, char **argv)
/*
* Initialise the NPF kernel component.
*/
rumpns_npfctl_testing = 1;
npf_kern_init();
rumpns_npf_test_init(inet_pton, inet_ntop, random);

View File

@ -1,4 +1,4 @@
/* $NetBSD: npftest.h,v 1.14 2016/12/26 23:05:05 christos Exp $ */
/* $NetBSD: npftest.h,v 1.15 2018/09/29 14:41:36 rmind Exp $ */
/*
* Public Domain.
@ -34,7 +34,7 @@ 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 *);
int rumpns_npf_test_load(const void *, size_t, bool);
ifnet_t * rumpns_npf_test_addif(const char *, bool, bool);
ifnet_t * rumpns_npf_test_getif(const char *);