Sat Nov 24 04:34:44 2012 UTC ()
Pull up following revision(s) (requested by rmind in ticket #702):
	sys/net/npf/npf_tableset.c: revision 1.15
	usr.sbin/npf/npfctl/npfctl.h: revision 1.21
	usr.sbin/npf/npftest/libnpftest/npf_table_test.c: revision 1.6
	usr.sbin/npf/npfctl/npf_disassemble.c: revision 1.10
	sys/net/npf/npf_state_tcp.c: revision 1.11
	sys/net/npf/npf_impl.h: revision 1.24
	sys/net/npf/npf.h: revision 1.22
	sys/net/npf/npf_ctl.c: revision 1.19
	sys/net/npf/npf.c: revision 1.14
	usr.sbin/npf/npfctl/npfctl.8: revision 1.10
	usr.sbin/npf/npfctl/npfctl.c: revision 1.21
npf_tcp_inwindow: inspect the sequence numbers even if the packet contains no
data, fixing up only the RST to the initial SYN.  This makes off-path attacks
more difficult.  For the reference, see "Reflection Scan: an Off-Path Attack
on TCP" by Jan Wrobel.
Implement NPF table listing and preservation of entries on reload.
Bump the version.
npfctl(8): mention table listing.


(riz)
diff -r1.7.2.5 -r1.7.2.6 src/sys/net/npf/npf.c
diff -r1.14.2.7 -r1.14.2.8 src/sys/net/npf/npf.h
diff -r1.12.2.5 -r1.12.2.6 src/sys/net/npf/npf_ctl.c
diff -r1.10.2.9 -r1.10.2.10 src/sys/net/npf/npf_impl.h
diff -r1.3.2.5 -r1.3.2.6 src/sys/net/npf/npf_state_tcp.c
diff -r1.9.2.5 -r1.9.2.6 src/sys/net/npf/npf_tableset.c
diff -r1.3.2.7 -r1.3.2.8 src/usr.sbin/npf/npfctl/npf_disassemble.c
diff -r1.6.6.2 -r1.6.6.3 src/usr.sbin/npf/npfctl/npfctl.8
diff -r1.10.2.7 -r1.10.2.8 src/usr.sbin/npf/npfctl/npfctl.c
diff -r1.11.2.7 -r1.11.2.8 src/usr.sbin/npf/npfctl/npfctl.h
diff -r1.2.2.6 -r1.2.2.7 src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c

cvs diff -r1.7.2.5 -r1.7.2.6 src/sys/net/npf/npf.c (expand / switch to unified diff)

--- src/sys/net/npf/npf.c 2012/11/19 09:44:42 1.7.2.5
+++ src/sys/net/npf/npf.c 2012/11/24 04:34:42 1.7.2.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf.c,v 1.7.2.5 2012/11/19 09:44:42 msaitoh Exp $ */ 1/* $NetBSD: npf.c,v 1.7.2.6 2012/11/24 04:34:42 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * NPF main: dynamic load/initialisation and unload routines. 33 * NPF main: dynamic load/initialisation and unload routines.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.7.2.5 2012/11/19 09:44:42 msaitoh Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.7.2.6 2012/11/24 04:34:42 riz Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/types.h> 40#include <sys/types.h>
41 41
42#include <sys/atomic.h> 42#include <sys/atomic.h>
43#include <sys/conf.h> 43#include <sys/conf.h>
44#include <sys/kauth.h> 44#include <sys/kauth.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46#include <sys/lwp.h> 46#include <sys/lwp.h>
47#include <sys/module.h> 47#include <sys/module.h>
48#include <sys/percpu.h> 48#include <sys/percpu.h>
49#include <sys/rwlock.h> 49#include <sys/rwlock.h>
50#include <sys/socketvar.h> 50#include <sys/socketvar.h>
@@ -293,27 +293,29 @@ npf_reload(prop_dictionary_t dict, npf_r @@ -293,27 +293,29 @@ npf_reload(prop_dictionary_t dict, npf_r
293 293
294 /* Setup a new core structure. */ 294 /* Setup a new core structure. */
295 nc = kmem_zalloc(sizeof(npf_core_t), KM_SLEEP); 295 nc = kmem_zalloc(sizeof(npf_core_t), KM_SLEEP);
296 nc->n_rules = rset; 296 nc->n_rules = rset;
297 nc->n_tables = tset; 297 nc->n_tables = tset;
298 nc->n_nat_rules = nset; 298 nc->n_nat_rules = nset;
299 nc->n_dict = dict; 299 nc->n_dict = dict;
300 nc->n_default_pass = flush; 300 nc->n_default_pass = flush;
301 301
302 /* Lock and load the core structure. */ 302 /* Lock and load the core structure. */
303 rw_enter(&npf_lock, RW_WRITER); 303 rw_enter(&npf_lock, RW_WRITER);
304 onc = atomic_swap_ptr(&npf_core, nc); 304 onc = atomic_swap_ptr(&npf_core, nc);
305 if (onc) { 305 if (onc) {
306 /* Reload only necessary NAT policies. */ 306 /* Reload only the static tables. */
 307 npf_tableset_reload(tset, onc->n_tables);
 308 /* Reload only the necessary NAT policies. */
307 npf_ruleset_natreload(nset, onc->n_nat_rules); 309 npf_ruleset_natreload(nset, onc->n_nat_rules);
308 } 310 }
309 /* Unlock. Everything goes "live" now. */ 311 /* Unlock. Everything goes "live" now. */
310 rw_exit(&npf_lock); 312 rw_exit(&npf_lock);
311 313
312 if (onc) { 314 if (onc) {
313 /* Destroy unloaded structures. */ 315 /* Destroy unloaded structures. */
314 npf_core_destroy(onc); 316 npf_core_destroy(onc);
315 } 317 }
316} 318}
317 319
318void 320void
319npf_core_enter(void) 321npf_core_enter(void)

cvs diff -r1.14.2.7 -r1.14.2.8 src/sys/net/npf/npf.h (expand / switch to unified diff)

--- src/sys/net/npf/npf.h 2012/11/18 22:38:26 1.14.2.7
+++ src/sys/net/npf/npf.h 2012/11/24 04:34:42 1.14.2.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf.h,v 1.14.2.7 2012/11/18 22:38:26 riz Exp $ */ 1/* $NetBSD: npf.h,v 1.14.2.8 2012/11/24 04:34:42 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -35,27 +35,27 @@ @@ -35,27 +35,27 @@
35 35
36#ifndef _NPF_NET_H_ 36#ifndef _NPF_NET_H_
37#define _NPF_NET_H_ 37#define _NPF_NET_H_
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/types.h> 40#include <sys/types.h>
41 41
42#include <sys/ioctl.h> 42#include <sys/ioctl.h>
43#include <prop/proplib.h> 43#include <prop/proplib.h>
44 44
45#include <netinet/in_systm.h> 45#include <netinet/in_systm.h>
46#include <netinet/in.h> 46#include <netinet/in.h>
47 47
48#define NPF_VERSION 6 48#define NPF_VERSION 7
49 49
50/* 50/*
51 * Public declarations and definitions. 51 * Public declarations and definitions.
52 */ 52 */
53 53
54/* Storage of address (both for IPv4 and IPv6) and netmask */ 54/* Storage of address (both for IPv4 and IPv6) and netmask */
55typedef struct in6_addr npf_addr_t; 55typedef struct in6_addr npf_addr_t;
56typedef uint8_t npf_netmask_t; 56typedef uint8_t npf_netmask_t;
57 57
58#define NPF_MAX_NETMASK (128) 58#define NPF_MAX_NETMASK (128)
59#define NPF_NO_NETMASK ((npf_netmask_t)~0) 59#define NPF_NO_NETMASK ((npf_netmask_t)~0)
60 60
61#if defined(_KERNEL) 61#if defined(_KERNEL)
@@ -201,35 +201,49 @@ bool npf_autounload_p(void); @@ -201,35 +201,49 @@ bool npf_autounload_p(void);
201#define NPF_TABLE_TREE 2 201#define NPF_TABLE_TREE 2
202 202
203/* Layers. */ 203/* Layers. */
204#define NPF_LAYER_2 2 204#define NPF_LAYER_2 2
205#define NPF_LAYER_3 3 205#define NPF_LAYER_3 3
206 206
207/* XXX mbuf.h: just for now. */ 207/* XXX mbuf.h: just for now. */
208#define PACKET_TAG_NPF 10 208#define PACKET_TAG_NPF 10
209 209
210/* 210/*
211 * IOCTL structures. 211 * IOCTL structures.
212 */ 212 */
213 213
 214#define NPF_IOCTL_TBLENT_LOOKUP 0
214#define NPF_IOCTL_TBLENT_ADD 1 215#define NPF_IOCTL_TBLENT_ADD 1
215#define NPF_IOCTL_TBLENT_REM 2 216#define NPF_IOCTL_TBLENT_REM 2
 217#define NPF_IOCTL_TBLENT_LIST 3
 218
 219typedef struct npf_ioctl_ent {
 220 int alen;
 221 npf_addr_t addr;
 222 npf_netmask_t mask;
 223} npf_ioctl_ent_t;
 224
 225typedef struct npf_ioctl_buf {
 226 void * buf;
 227 size_t len;
 228} npf_ioctl_buf_t;
216 229
217typedef struct npf_ioctl_table { 230typedef struct npf_ioctl_table {
218 int nct_action; 231 int nct_action;
219 u_int nct_tid; 232 u_int nct_tid;
220 int nct_alen; 233 union {
221 npf_addr_t nct_addr; 234 npf_ioctl_ent_t ent;
222 npf_netmask_t nct_mask; 235 npf_ioctl_buf_t buf;
 236 } nct_data;
223} npf_ioctl_table_t; 237} npf_ioctl_table_t;
224 238
225typedef enum { 239typedef enum {
226 /* Packets passed. */ 240 /* Packets passed. */
227 NPF_STAT_PASS_DEFAULT, 241 NPF_STAT_PASS_DEFAULT,
228 NPF_STAT_PASS_RULESET, 242 NPF_STAT_PASS_RULESET,
229 NPF_STAT_PASS_SESSION, 243 NPF_STAT_PASS_SESSION,
230 /* Packets blocked. */ 244 /* Packets blocked. */
231 NPF_STAT_BLOCK_DEFAULT, 245 NPF_STAT_BLOCK_DEFAULT,
232 NPF_STAT_BLOCK_RULESET, 246 NPF_STAT_BLOCK_RULESET,
233 /* Session and NAT entries. */ 247 /* Session and NAT entries. */
234 NPF_STAT_SESSION_CREATE, 248 NPF_STAT_SESSION_CREATE,
235 NPF_STAT_SESSION_DESTROY, 249 NPF_STAT_SESSION_DESTROY,

cvs diff -r1.12.2.5 -r1.12.2.6 src/sys/net/npf/npf_ctl.c (expand / switch to unified diff)

--- src/sys/net/npf/npf_ctl.c 2012/11/18 22:38:26 1.12.2.5
+++ src/sys/net/npf/npf_ctl.c 2012/11/24 04:34:42 1.12.2.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_ctl.c,v 1.12.2.5 2012/11/18 22:38:26 riz Exp $ */ 1/* $NetBSD: npf_ctl.c,v 1.12.2.6 2012/11/24 04:34:42 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * NPF device control. 33 * NPF device control.
34 * 34 *
35 * Implementation of (re)loading, construction of tables and rules. 35 * Implementation of (re)loading, construction of tables and rules.
36 * NPF proplib(9) dictionary consumer. 36 * NPF proplib(9) dictionary consumer.
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.12.2.5 2012/11/18 22:38:26 riz Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.12.2.6 2012/11/24 04:34:42 riz Exp $");
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/conf.h> 43#include <sys/conf.h>
44 44
45#include <prop/proplib.h> 45#include <prop/proplib.h>
46 46
47#include "npf_ncode.h" 47#include "npf_ncode.h"
48#include "npf_impl.h" 48#include "npf_impl.h"
49 49
50#if defined(DEBUG) || defined(DIAGNOSTIC) 50#if defined(DEBUG) || defined(DIAGNOSTIC)
51#define NPF_ERR_DEBUG(e) \ 51#define NPF_ERR_DEBUG(e) \
52 prop_dictionary_set_cstring_nocopy((e), "source-file", __FILE__); \ 52 prop_dictionary_set_cstring_nocopy((e), "source-file", __FILE__); \
53 prop_dictionary_set_uint32((e), "source-line", __LINE__); 53 prop_dictionary_set_uint32((e), "source-line", __LINE__);
@@ -700,35 +700,44 @@ fail: @@ -700,35 +700,44 @@ fail:
700 sess_htable_destroy(sehasht); 700 sess_htable_destroy(sehasht);
701 } 701 }
702 return error; 702 return error;
703} 703}
704 704
705/* 705/*
706 * npfctl_table: add, remove or query entries in the specified table. 706 * npfctl_table: add, remove or query entries in the specified table.
707 * 707 *
708 * For maximum performance, interface is avoiding proplib(3)'s overhead. 708 * For maximum performance, interface is avoiding proplib(3)'s overhead.
709 */ 709 */
710int 710int
711npfctl_table(void *data) 711npfctl_table(void *data)
712{ 712{
713 npf_ioctl_table_t *nct = data; 713 const npf_ioctl_table_t *nct = data;
714 npf_tableset_t *tblset; 714 npf_tableset_t *tblset;
715 int error; 715 int error;
716 716
717 npf_core_enter(); /* XXXSMP */ 717 npf_core_enter(); /* XXXSMP */
718 tblset = npf_core_tableset(); 718 tblset = npf_core_tableset();
719 switch (nct->nct_action) { 719 switch (nct->nct_action) {
 720 case NPF_IOCTL_TBLENT_LOOKUP:
 721 error = npf_table_lookup(tblset, nct->nct_tid,
 722 nct->nct_data.ent.alen, &nct->nct_data.ent.addr);
720 case NPF_IOCTL_TBLENT_ADD: 723 case NPF_IOCTL_TBLENT_ADD:
721 error = npf_table_insert(tblset, nct->nct_tid, 724 error = npf_table_insert(tblset, nct->nct_tid,
722 nct->nct_alen, &nct->nct_addr, nct->nct_mask); 725 nct->nct_data.ent.alen, &nct->nct_data.ent.addr,
 726 nct->nct_data.ent.mask);
723 break; 727 break;
724 case NPF_IOCTL_TBLENT_REM: 728 case NPF_IOCTL_TBLENT_REM:
725 error = npf_table_remove(tblset, nct->nct_tid, 729 error = npf_table_remove(tblset, nct->nct_tid,
726 nct->nct_alen, &nct->nct_addr, nct->nct_mask); 730 nct->nct_data.ent.alen, &nct->nct_data.ent.addr,
 731 nct->nct_data.ent.mask);
 732 break;
 733 case NPF_IOCTL_TBLENT_LIST:
 734 error = npf_table_list(tblset, nct->nct_tid,
 735 nct->nct_data.buf.buf, nct->nct_data.buf.len);
727 break; 736 break;
728 default: 737 default:
729 error = npf_table_lookup(tblset, nct->nct_tid, 738 error = EINVAL;
730 nct->nct_alen, &nct->nct_addr); 739 break;
731 } 740 }
732 npf_core_exit(); /* XXXSMP */ 741 npf_core_exit(); /* XXXSMP */
733 return error; 742 return error;
734} 743}

cvs diff -r1.10.2.9 -r1.10.2.10 src/sys/net/npf/npf_impl.h (expand / switch to unified diff)

--- src/sys/net/npf/npf_impl.h 2012/11/18 22:38:26 1.10.2.9
+++ src/sys/net/npf/npf_impl.h 2012/11/24 04:34:42 1.10.2.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_impl.h,v 1.10.2.9 2012/11/18 22:38:26 riz Exp $ */ 1/* $NetBSD: npf_impl.h,v 1.10.2.10 2012/11/24 04:34:42 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -71,31 +71,29 @@ @@ -71,31 +71,29 @@
71struct npf_ruleset; 71struct npf_ruleset;
72struct npf_rule; 72struct npf_rule;
73struct npf_nat; 73struct npf_nat;
74struct npf_session; 74struct npf_session;
75 75
76typedef struct npf_ruleset npf_ruleset_t; 76typedef struct npf_ruleset npf_ruleset_t;
77typedef struct npf_rule npf_rule_t; 77typedef struct npf_rule npf_rule_t;
78typedef struct npf_nat npf_nat_t; 78typedef struct npf_nat npf_nat_t;
79typedef struct npf_alg npf_alg_t; 79typedef struct npf_alg npf_alg_t;
80typedef struct npf_natpolicy npf_natpolicy_t; 80typedef struct npf_natpolicy npf_natpolicy_t;
81typedef struct npf_session npf_session_t; 81typedef struct npf_session npf_session_t;
82 82
83struct npf_sehash; 83struct npf_sehash;
84struct npf_tblent; 
85struct npf_table; 84struct npf_table;
86 85
87typedef struct npf_sehash npf_sehash_t; 86typedef struct npf_sehash npf_sehash_t;
88typedef struct npf_tblent npf_tblent_t; 
89typedef struct npf_table npf_table_t; 87typedef struct npf_table npf_table_t;
90 88
91typedef npf_table_t * npf_tableset_t; 89typedef npf_table_t * npf_tableset_t;
92 90
93/* 91/*
94 * DEFINITIONS. 92 * DEFINITIONS.
95 */ 93 */
96 94
97typedef bool (*npf_algfunc_t)(npf_cache_t *, nbuf_t *, void *); 95typedef bool (*npf_algfunc_t)(npf_cache_t *, nbuf_t *, void *);
98 96
99#define NPF_NCODE_LIMIT 1024 97#define NPF_NCODE_LIMIT 1024
100#define NPF_TABLE_SLOTS 32 98#define NPF_TABLE_SLOTS 32
101 99
@@ -198,42 +196,39 @@ int npf_match_udp_ports(npf_cache_t *,  @@ -198,42 +196,39 @@ int npf_match_udp_ports(npf_cache_t *,
198int npf_match_icmp4(npf_cache_t *, nbuf_t *, void *, uint32_t); 196int npf_match_icmp4(npf_cache_t *, nbuf_t *, void *, uint32_t);
199int npf_match_icmp6(npf_cache_t *, nbuf_t *, void *, uint32_t); 197int npf_match_icmp6(npf_cache_t *, nbuf_t *, void *, uint32_t);
200int npf_match_tcpfl(npf_cache_t *, nbuf_t *, void *, uint32_t); 198int npf_match_tcpfl(npf_cache_t *, nbuf_t *, void *, uint32_t);
201 199
202/* Tableset interface. */ 200/* Tableset interface. */
203void npf_tableset_sysinit(void); 201void npf_tableset_sysinit(void);
204void npf_tableset_sysfini(void); 202void npf_tableset_sysfini(void);
205 203
206const pt_tree_ops_t npf_table_ptree_ops; 204const pt_tree_ops_t npf_table_ptree_ops;
207 205
208npf_tableset_t *npf_tableset_create(void); 206npf_tableset_t *npf_tableset_create(void);
209void npf_tableset_destroy(npf_tableset_t *); 207void npf_tableset_destroy(npf_tableset_t *);
210int npf_tableset_insert(npf_tableset_t *, npf_table_t *); 208int npf_tableset_insert(npf_tableset_t *, npf_table_t *);
211npf_tableset_t *npf_tableset_reload(npf_tableset_t *); 209void npf_tableset_reload(npf_tableset_t *, npf_tableset_t *);
212 210
213npf_table_t * npf_table_create(u_int, int, size_t); 211npf_table_t * npf_table_create(u_int, int, size_t);
214void npf_table_destroy(npf_table_t *); 212void npf_table_destroy(npf_table_t *);
215void npf_table_ref(npf_table_t *); 
216void npf_table_unref(npf_table_t *); 
217 213
218npf_table_t * npf_table_get(npf_tableset_t *, u_int); 
219void npf_table_put(npf_table_t *); 
220int npf_table_check(const npf_tableset_t *, u_int, int); 214int npf_table_check(const npf_tableset_t *, u_int, int);
221int npf_table_insert(npf_tableset_t *, u_int, 215int npf_table_insert(npf_tableset_t *, u_int,
222 const int, const npf_addr_t *, const npf_netmask_t); 216 const int, const npf_addr_t *, const npf_netmask_t);
223int npf_table_remove(npf_tableset_t *, u_int, 217int npf_table_remove(npf_tableset_t *, u_int,
224 const int, const npf_addr_t *, const npf_netmask_t); 218 const int, const npf_addr_t *, const npf_netmask_t);
225int npf_table_lookup(npf_tableset_t *, u_int, 219int npf_table_lookup(npf_tableset_t *, u_int,
226 const int, const npf_addr_t *); 220 const int, const npf_addr_t *);
 221int npf_table_list(npf_tableset_t *, u_int, void *, size_t);
227 222
228/* Ruleset interface. */ 223/* Ruleset interface. */
229npf_ruleset_t * npf_ruleset_create(void); 224npf_ruleset_t * npf_ruleset_create(void);
230void npf_ruleset_destroy(npf_ruleset_t *); 225void npf_ruleset_destroy(npf_ruleset_t *);
231void npf_ruleset_insert(npf_ruleset_t *, npf_rule_t *); 226void npf_ruleset_insert(npf_ruleset_t *, npf_rule_t *);
232void npf_ruleset_natreload(npf_ruleset_t *, npf_ruleset_t *); 227void npf_ruleset_natreload(npf_ruleset_t *, npf_ruleset_t *);
233npf_rule_t * npf_ruleset_matchnat(npf_ruleset_t *, npf_natpolicy_t *); 228npf_rule_t * npf_ruleset_matchnat(npf_ruleset_t *, npf_natpolicy_t *);
234npf_rule_t * npf_ruleset_sharepm(npf_ruleset_t *, npf_natpolicy_t *); 229npf_rule_t * npf_ruleset_sharepm(npf_ruleset_t *, npf_natpolicy_t *);
235npf_rule_t * npf_ruleset_replace(const char *, npf_ruleset_t *); 230npf_rule_t * npf_ruleset_replace(const char *, npf_ruleset_t *);
236void npf_ruleset_freealg(npf_ruleset_t *, npf_alg_t *); 231void npf_ruleset_freealg(npf_ruleset_t *, npf_alg_t *);
237 232
238npf_rule_t * npf_ruleset_inspect(npf_cache_t *, nbuf_t *, npf_ruleset_t *, 233npf_rule_t * npf_ruleset_inspect(npf_cache_t *, nbuf_t *, npf_ruleset_t *,
239 const ifnet_t *, const int, const int); 234 const ifnet_t *, const int, const int);

cvs diff -r1.3.2.5 -r1.3.2.6 src/sys/net/npf/npf_state_tcp.c (expand / switch to unified diff)

--- src/sys/net/npf/npf_state_tcp.c 2012/07/25 20:45:24 1.3.2.5
+++ src/sys/net/npf/npf_state_tcp.c 2012/11/24 04:34:42 1.3.2.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_state_tcp.c,v 1.3.2.5 2012/07/25 20:45:24 jdc Exp $ */ 1/* $NetBSD: npf_state_tcp.c,v 1.3.2.6 2012/11/24 04:34:42 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * NPF TCP state engine for connection tracking. 33 * NPF TCP state engine for connection tracking.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.3.2.5 2012/07/25 20:45:24 jdc Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.3.2.6 2012/11/24 04:34:42 riz Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/types.h> 40#include <sys/types.h>
41 41
42#ifndef _KERNEL 42#ifndef _KERNEL
43#include <stdio.h> 43#include <stdio.h>
44#include <stdbool.h> 44#include <stdbool.h>
45#include <inttypes.h> 45#include <inttypes.h>
46#endif 46#endif
47#include <netinet/in.h> 47#include <netinet/in.h>
48#include <netinet/tcp.h> 48#include <netinet/tcp.h>
49#include <netinet/tcp_seq.h> 49#include <netinet/tcp_seq.h>
50 50
@@ -84,26 +84,28 @@ static u_int npf_tcp_timeouts[] __read_m @@ -84,26 +84,28 @@ static u_int npf_tcp_timeouts[] __read_m
84 [NPF_TCPS_ESTABLISHED] = 60 * 60 * 24, 84 [NPF_TCPS_ESTABLISHED] = 60 * 60 * 24,
85 /* FIN seen: 4 minutes (2 * MSL). */ 85 /* FIN seen: 4 minutes (2 * MSL). */
86 [NPF_TCPS_FIN_SENT] = 60 * 2 * 2, 86 [NPF_TCPS_FIN_SENT] = 60 * 2 * 2,
87 [NPF_TCPS_FIN_RECEIVED] = 60 * 2 * 2, 87 [NPF_TCPS_FIN_RECEIVED] = 60 * 2 * 2,
88 /* Half-closed cases: 6 hours. */ 88 /* Half-closed cases: 6 hours. */
89 [NPF_TCPS_CLOSE_WAIT] = 60 * 60 * 6, 89 [NPF_TCPS_CLOSE_WAIT] = 60 * 60 * 6,
90 [NPF_TCPS_FIN_WAIT] = 60 * 60 * 6, 90 [NPF_TCPS_FIN_WAIT] = 60 * 60 * 6,
91 /* Full close cases: 30 sec and 2 * MSL. */ 91 /* Full close cases: 30 sec and 2 * MSL. */
92 [NPF_TCPS_CLOSING] = 30, 92 [NPF_TCPS_CLOSING] = 30,
93 [NPF_TCPS_LAST_ACK] = 30, 93 [NPF_TCPS_LAST_ACK] = 30,
94 [NPF_TCPS_TIME_WAIT] = 60 * 2 * 2, 94 [NPF_TCPS_TIME_WAIT] = 60 * 2 * 2,
95}; 95};
96 96
 97static bool npf_strict_order_rst __read_mostly = false;
 98
97#define NPF_TCP_MAXACKWIN 66000 99#define NPF_TCP_MAXACKWIN 66000
98 100
99/* 101/*
100 * List of TCP flag cases and conversion of flags to a case (index). 102 * List of TCP flag cases and conversion of flags to a case (index).
101 */ 103 */
102 104
103#define TCPFC_INVALID 0 105#define TCPFC_INVALID 0
104#define TCPFC_SYN 1 106#define TCPFC_SYN 1
105#define TCPFC_SYNACK 2 107#define TCPFC_SYNACK 2
106#define TCPFC_ACK 3 108#define TCPFC_ACK 3
107#define TCPFC_FIN 4 109#define TCPFC_FIN 4
108#define TCPFC_COUNT 5 110#define TCPFC_COUNT 5
109 111
@@ -381,37 +383,40 @@ npf_tcp_inwindow(const npf_cache_t *npc, @@ -381,37 +383,40 @@ npf_tcp_inwindow(const npf_cache_t *npc,
381 if (tcpfl & TH_SYN) { 383 if (tcpfl & TH_SYN) {
382 (void)npf_fetch_tcpopts(npc, nbuf, NULL, 384 (void)npf_fetch_tcpopts(npc, nbuf, NULL,
383 &fstate->nst_wscale); 385 &fstate->nst_wscale);
384 } 386 }
385 } 387 }
386 388
387 if ((tcpfl & TH_ACK) == 0) { 389 if ((tcpfl & TH_ACK) == 0) {
388 /* Pretend that an ACK was sent. */ 390 /* Pretend that an ACK was sent. */
389 ack = tstate->nst_end; 391 ack = tstate->nst_end;
390 } else if ((tcpfl & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST) && ack == 0) { 392 } else if ((tcpfl & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST) && ack == 0) {
391 /* Workaround for some TCP stacks. */ 393 /* Workaround for some TCP stacks. */
392 ack = tstate->nst_end; 394 ack = tstate->nst_end;
393 } 395 }
394 if (seq == end) { 396
395 /* If packet contains no data - assume it is valid. */ 397 if (__predict_false(tcpfl & TH_RST)) {
396 end = fstate->nst_end; 398 /* RST to the initial SYN may have zero SEQ - fix it up. */
397 seq = end; 399 if (seq == 0 && nst->nst_state == NPF_TCPS_SYN_SENT) {
398 } 400 end = fstate->nst_end;
399#if 0 401 seq = end;
400 /* Strict in-order sequence for RST packets. */ 402 }
401 if ((tcpfl & TH_RST) != 0 && (fstate->nst_end - seq) > 1) { 403
402 return false; 404 /* Strict in-order sequence for RST packets. */
 405 if (npf_strict_order_rst && (fstate->nst_end - seq) > 1) {
 406 return false;
 407 }
403 } 408 }
404#endif 409
405 /* 410 /*
406 * Determine whether the data is within previously noted window, 411 * Determine whether the data is within previously noted window,
407 * that is, upper boundary for valid data (I). 412 * that is, upper boundary for valid data (I).
408 */ 413 */
409 if (!SEQ_LEQ(end, fstate->nst_maxend)) { 414 if (!SEQ_LEQ(end, fstate->nst_maxend)) {
410 npf_stats_inc(NPF_STAT_INVALID_STATE_TCP1); 415 npf_stats_inc(NPF_STAT_INVALID_STATE_TCP1);
411 return false; 416 return false;
412 } 417 }
413 418
414 /* Lower boundary (II), which is no more than one window back. */ 419 /* Lower boundary (II), which is no more than one window back. */
415 if (!SEQ_GEQ(seq, fstate->nst_end - tstate->nst_maxwin)) { 420 if (!SEQ_GEQ(seq, fstate->nst_end - tstate->nst_maxwin)) {
416 npf_stats_inc(NPF_STAT_INVALID_STATE_TCP2); 421 npf_stats_inc(NPF_STAT_INVALID_STATE_TCP2);
417 return false; 422 return false;

cvs diff -r1.9.2.5 -r1.9.2.6 src/sys/net/npf/npf_tableset.c (expand / switch to unified diff)

--- src/sys/net/npf/npf_tableset.c 2012/08/13 17:49:52 1.9.2.5
+++ src/sys/net/npf/npf_tableset.c 2012/11/24 04:34:41 1.9.2.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_tableset.c,v 1.9.2.5 2012/08/13 17:49:52 riz Exp $ */ 1/* $NetBSD: npf_tableset.c,v 1.9.2.6 2012/11/24 04:34:41 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -22,74 +22,80 @@ @@ -22,74 +22,80 @@
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * NPF tableset module. 33 * NPF tableset module.
34 * 34 *
35 * TODO: 35 * Notes
36 * - Dynamic hash growing/shrinking (i.e. re-hash functionality), maybe? 36 *
37 * - Dynamic array resize. 37 * The tableset is an array of tables. After the creation, the array
 38 * is immutable. The caller is responsible to synchronise the access
 39 * to the tableset. The table can either be a hash or a tree. Its
 40 * entries are protected by a read-write lock.
38 */ 41 */
39 42
40#include <sys/cdefs.h> 43#include <sys/cdefs.h>
41__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.9.2.5 2012/08/13 17:49:52 riz Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.9.2.6 2012/11/24 04:34:41 riz Exp $");
42 45
43#include <sys/param.h> 46#include <sys/param.h>
44#include <sys/types.h> 47#include <sys/types.h>
45 48
46#include <sys/atomic.h> 49#include <sys/atomic.h>
47#include <sys/hash.h> 50#include <sys/hash.h>
48#include <sys/kmem.h> 51#include <sys/kmem.h>
49#include <sys/pool.h> 52#include <sys/pool.h>
50#include <sys/queue.h> 53#include <sys/queue.h>
51#include <sys/rwlock.h> 54#include <sys/rwlock.h>
52#include <sys/systm.h> 55#include <sys/systm.h>
53#include <sys/types.h> 56#include <sys/types.h>
54 57
55#include "npf_impl.h" 58#include "npf_impl.h"
56 59
57/* 60/*
58 * Table structures. 61 * Table structures.
59 */ 62 */
60 63
61struct npf_tblent { 64typedef struct npf_tblent {
62 union { 65 union {
63 LIST_ENTRY(npf_tblent) hashq; 66 LIST_ENTRY(npf_tblent) hashq;
64 pt_node_t node; 67 pt_node_t node;
65 } te_entry; 68 } te_entry;
66 int te_alen; 69 int te_alen;
67 npf_addr_t te_addr; 70 npf_addr_t te_addr;
68}; 71} npf_tblent_t;
69 72
70LIST_HEAD(npf_hashl, npf_tblent); 73LIST_HEAD(npf_hashl, npf_tblent);
71 74
72struct npf_table { 75struct npf_table {
73 char t_name[16]; 76 char t_name[16];
74 /* Lock and reference count. */ 77 /* Lock and reference count. */
75 krwlock_t t_lock; 78 krwlock_t t_lock;
76 u_int t_refcnt; 79 u_int t_refcnt;
 80 /* Total number of items. */
 81 u_int t_nitems;
77 /* Table ID. */ 82 /* Table ID. */
78 u_int t_id; 83 u_int t_id;
79 /* The storage type can be: a) hash b) tree. */ 84 /* The storage type can be: a) hash b) tree. */
80 int t_type; 85 int t_type;
81 struct npf_hashl * t_hashl; 86 struct npf_hashl * t_hashl;
82 u_long t_hashmask; 87 u_long t_hashmask;
 88 /* Separate trees for IPv4 and IPv6. */
83 pt_tree_t t_tree[2]; 89 pt_tree_t t_tree[2];
84}; 90};
85 91
86#define NPF_ADDRLEN2TREE(alen) ((alen) >> 4) 92#define NPF_ADDRLEN2TREE(alen) ((alen) >> 4)
87 93
88static pool_cache_t tblent_cache __read_mostly; 94static pool_cache_t tblent_cache __read_mostly;
89 95
90/* 96/*
91 * npf_table_sysinit: initialise tableset structures. 97 * npf_table_sysinit: initialise tableset structures.
92 */ 98 */
93void 99void
94npf_tableset_sysinit(void) 100npf_tableset_sysinit(void)
95{ 101{
@@ -116,56 +122,81 @@ npf_tableset_create(void) @@ -116,56 +122,81 @@ npf_tableset_create(void)
116void 122void
117npf_tableset_destroy(npf_tableset_t *tblset) 123npf_tableset_destroy(npf_tableset_t *tblset)
118{ 124{
119 const size_t sz = NPF_TABLE_SLOTS * sizeof(npf_table_t *); 125 const size_t sz = NPF_TABLE_SLOTS * sizeof(npf_table_t *);
120 npf_table_t *t; 126 npf_table_t *t;
121 u_int tid; 127 u_int tid;
122 128
123 /* 129 /*
124 * Destroy all tables (no references should be held, as ruleset 130 * Destroy all tables (no references should be held, as ruleset
125 * should be destroyed before). 131 * should be destroyed before).
126 */ 132 */
127 for (tid = 0; tid < NPF_TABLE_SLOTS; tid++) { 133 for (tid = 0; tid < NPF_TABLE_SLOTS; tid++) {
128 t = tblset[tid]; 134 t = tblset[tid];
129 if (t != NULL) { 135 if (t && --t->t_refcnt == 0) {
130 npf_table_destroy(t); 136 npf_table_destroy(t);
131 } 137 }
132 } 138 }
133 kmem_free(tblset, sz); 139 kmem_free(tblset, sz);
134} 140}
135 141
136/* 142/*
137 * npf_tableset_insert: insert the table into the specified tableset. 143 * npf_tableset_insert: insert the table into the specified tableset.
138 * 144 *
139 * => Returns 0 on success. Fails and returns error if ID is already used. 145 * => Returns 0 on success. Fails and returns error if ID is already used.
140 */ 146 */
141int 147int
142npf_tableset_insert(npf_tableset_t *tblset, npf_table_t *t) 148npf_tableset_insert(npf_tableset_t *tblset, npf_table_t *t)
143{ 149{
144 const u_int tid = t->t_id; 150 const u_int tid = t->t_id;
145 int error; 151 int error;
146 152
147 KASSERT((u_int)tid < NPF_TABLE_SLOTS); 153 KASSERT((u_int)tid < NPF_TABLE_SLOTS);
148 154
149 if (tblset[tid] == NULL) { 155 if (tblset[tid] == NULL) {
150 tblset[tid] = t; 156 tblset[tid] = t;
 157 t->t_refcnt++;
151 error = 0; 158 error = 0;
152 } else { 159 } else {
153 error = EEXIST; 160 error = EEXIST;
154 } 161 }
155 return error; 162 return error;
156} 163}
157 164
158/* 165/*
 166 * npf_tableset_reload: iterate all tables and if the new table is of the
 167 * same type and has no items, then we preserve the old one and its entries.
 168 *
 169 * => The caller is responsible for providing synchronisation.
 170 */
 171void
 172npf_tableset_reload(npf_tableset_t *ntset, npf_tableset_t *otset)
 173{
 174 for (int i = 0; i < NPF_TABLE_SLOTS; i++) {
 175 npf_table_t *t = ntset[i], *ot = otset[i];
 176
 177 if (t == NULL || ot == NULL) {
 178 continue;
 179 }
 180 if (t->t_nitems || t->t_type != ot->t_type) {
 181 continue;
 182 }
 183 ntset[i] = ot;
 184 ot->t_refcnt++;
 185 npf_table_destroy(t);
 186 }
 187}
 188
 189/*
159 * Few helper routines. 190 * Few helper routines.
160 */ 191 */
161 192
162static npf_tblent_t * 193static npf_tblent_t *
163table_hash_lookup(const npf_table_t *t, const npf_addr_t *addr, 194table_hash_lookup(const npf_table_t *t, const npf_addr_t *addr,
164 const int alen, struct npf_hashl **rhtbl) 195 const int alen, struct npf_hashl **rhtbl)
165{ 196{
166 const uint32_t hidx = hash32_buf(addr, alen, HASH32_BUF_INIT); 197 const uint32_t hidx = hash32_buf(addr, alen, HASH32_BUF_INIT);
167 struct npf_hashl *htbl = &t->t_hashl[hidx & t->t_hashmask]; 198 struct npf_hashl *htbl = &t->t_hashl[hidx & t->t_hashmask];
168 npf_tblent_t *ent; 199 npf_tblent_t *ent;
169 200
170 /* 201 /*
171 * Lookup the hash table and check for duplicates. 202 * Lookup the hash table and check for duplicates.
@@ -218,141 +249,82 @@ npf_table_create(u_int tid, int type, si @@ -218,141 +249,82 @@ npf_table_create(u_int tid, int type, si
218 break; 249 break;
219 case NPF_TABLE_HASH: 250 case NPF_TABLE_HASH:
220 t->t_hashl = hashinit(hsize, HASH_LIST, true, &t->t_hashmask); 251 t->t_hashl = hashinit(hsize, HASH_LIST, true, &t->t_hashmask);
221 if (t->t_hashl == NULL) { 252 if (t->t_hashl == NULL) {
222 kmem_free(t, sizeof(npf_table_t)); 253 kmem_free(t, sizeof(npf_table_t));
223 return NULL; 254 return NULL;
224 } 255 }
225 break; 256 break;
226 default: 257 default:
227 KASSERT(false); 258 KASSERT(false);
228 } 259 }
229 rw_init(&t->t_lock); 260 rw_init(&t->t_lock);
230 t->t_type = type; 261 t->t_type = type;
231 t->t_refcnt = 1; 
232 t->t_id = tid; 262 t->t_id = tid;
 263
233 return t; 264 return t;
234} 265}
235 266
236/* 267/*
237 * npf_table_destroy: free all table entries and table itself. 268 * npf_table_destroy: free all table entries and table itself.
238 */ 269 */
239void 270void
240npf_table_destroy(npf_table_t *t) 271npf_table_destroy(npf_table_t *t)
241{ 272{
242 273
243 switch (t->t_type) { 274 switch (t->t_type) {
244 case NPF_TABLE_HASH: { 275 case NPF_TABLE_HASH:
245 for (unsigned n = 0; n <= t->t_hashmask; n++) { 276 for (unsigned n = 0; n <= t->t_hashmask; n++) {
246 npf_tblent_t *ent; 277 npf_tblent_t *ent;
247 278
248 while ((ent = LIST_FIRST(&t->t_hashl[n])) != NULL) { 279 while ((ent = LIST_FIRST(&t->t_hashl[n])) != NULL) {
249 LIST_REMOVE(ent, te_entry.hashq); 280 LIST_REMOVE(ent, te_entry.hashq);
250 pool_cache_put(tblent_cache, ent); 281 pool_cache_put(tblent_cache, ent);
251 } 282 }
252 } 283 }
253 hashdone(t->t_hashl, HASH_LIST, t->t_hashmask); 284 hashdone(t->t_hashl, HASH_LIST, t->t_hashmask);
254 break; 285 break;
255 } 286 case NPF_TABLE_TREE:
256 case NPF_TABLE_TREE: { 
257 table_tree_destroy(&t->t_tree[0]); 287 table_tree_destroy(&t->t_tree[0]);
258 table_tree_destroy(&t->t_tree[1]); 288 table_tree_destroy(&t->t_tree[1]);
259 break; 289 break;
260 } 
261 default: 290 default:
262 KASSERT(false); 291 KASSERT(false);
263 } 292 }
264 rw_destroy(&t->t_lock); 293 rw_destroy(&t->t_lock);
265 kmem_free(t, sizeof(npf_table_t)); 294 kmem_free(t, sizeof(npf_table_t));
266} 295}
267 296
268/* 297/*
269 * npf_table_ref: holds the reference on table. 
270 * 
271 * => Table must be locked. 
272 */ 
273void 
274npf_table_ref(npf_table_t *t) 
275{ 
276 
277 KASSERT(rw_lock_held(&t->t_lock)); 
278 atomic_inc_uint(&t->t_refcnt); 
279} 
280 
281/* 
282 * npf_table_unref: drop reference from the table and destroy the table if 
283 * it is the last reference. 
284 */ 
285void 
286npf_table_unref(npf_table_t *t) 
287{ 
288 
289 if (atomic_dec_uint_nv(&t->t_refcnt) != 0) { 
290 return; 
291 } 
292 npf_table_destroy(t); 
293} 
294 
295/* 
296 * npf_table_get: find the table according to ID and "get it" by locking it. 
297 */ 
298npf_table_t * 
299npf_table_get(npf_tableset_t *tset, u_int tid) 
300{ 
301 npf_table_t *t; 
302 
303 KASSERT(tset != NULL); 
304 
305 if ((u_int)tid >= NPF_TABLE_SLOTS) { 
306 return NULL; 
307 } 
308 t = tset[tid]; 
309 if (t != NULL) { 
310 rw_enter(&t->t_lock, RW_READER); 
311 } 
312 return t; 
313} 
314 
315/* 
316 * npf_table_put: "put table back" by unlocking it. 
317 */ 
318void 
319npf_table_put(npf_table_t *t) 
320{ 
321 
322 rw_exit(&t->t_lock); 
323} 
324 
325/* 
326 * npf_table_check: validate ID and type. 298 * npf_table_check: validate ID and type.
327 */ 299 */
328int 300int
329npf_table_check(const npf_tableset_t *tset, u_int tid, int type) 301npf_table_check(const npf_tableset_t *tset, u_int tid, int type)
330{ 302{
331 303
332 if ((u_int)tid >= NPF_TABLE_SLOTS) { 304 if ((u_int)tid >= NPF_TABLE_SLOTS) {
333 return EINVAL; 305 return EINVAL;
334 } 306 }
335 if (tset[tid] != NULL) { 307 if (tset[tid] != NULL) {
336 return EEXIST; 308 return EEXIST;
337 } 309 }
338 if (type != NPF_TABLE_TREE && type != NPF_TABLE_HASH) { 310 if (type != NPF_TABLE_TREE && type != NPF_TABLE_HASH) {
339 return EINVAL; 311 return EINVAL;
340 } 312 }
341 return 0; 313 return 0;
342} 314}
343 315
344static int 316static int
345npf_table_validate_cidr(const u_int aidx, const npf_addr_t *addr, 317table_cidr_check(const u_int aidx, const npf_addr_t *addr,
346 const npf_netmask_t mask) 318 const npf_netmask_t mask)
347{ 319{
348 320
349 if (mask > NPF_MAX_NETMASK && mask != NPF_NO_NETMASK) { 321 if (mask > NPF_MAX_NETMASK && mask != NPF_NO_NETMASK) {
350 return EINVAL; 322 return EINVAL;
351 } 323 }
352 if (aidx > 1) { 324 if (aidx > 1) {
353 return EINVAL; 325 return EINVAL;
354 } 326 }
355 327
356 /* 328 /*
357 * For IPv4 (aidx = 0) - 32 and for IPv6 (aidx = 1) - 128. 329 * For IPv4 (aidx = 0) - 32 and for IPv6 (aidx = 1) - 128.
358 * If it is a host - shall use NPF_NO_NETMASK. 330 * If it is a host - shall use NPF_NO_NETMASK.
@@ -365,166 +337,250 @@ npf_table_validate_cidr(const u_int aidx @@ -365,166 +337,250 @@ npf_table_validate_cidr(const u_int aidx
365 337
366/* 338/*
367 * npf_table_insert: add an IP CIDR entry into the table. 339 * npf_table_insert: add an IP CIDR entry into the table.
368 */ 340 */
369int 341int
370npf_table_insert(npf_tableset_t *tset, u_int tid, const int alen, 342npf_table_insert(npf_tableset_t *tset, u_int tid, const int alen,
371 const npf_addr_t *addr, const npf_netmask_t mask) 343 const npf_addr_t *addr, const npf_netmask_t mask)
372{ 344{
373 const u_int aidx = NPF_ADDRLEN2TREE(alen); 345 const u_int aidx = NPF_ADDRLEN2TREE(alen);
374 npf_tblent_t *ent; 346 npf_tblent_t *ent;
375 npf_table_t *t; 347 npf_table_t *t;
376 int error; 348 int error;
377 349
378 error = npf_table_validate_cidr(aidx, addr, mask); 350 if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
 351 return EINVAL;
 352 }
 353
 354 error = table_cidr_check(aidx, addr, mask);
379 if (error) { 355 if (error) {
380 return error; 356 return error;
381 } 357 }
382 ent = pool_cache_get(tblent_cache, PR_WAITOK); 358 ent = pool_cache_get(tblent_cache, PR_WAITOK);
383 memcpy(&ent->te_addr, addr, alen); 359 memcpy(&ent->te_addr, addr, alen);
384 ent->te_alen = alen; 360 ent->te_alen = alen;
385 361
386 /* Get the table (acquire the lock). */ 
387 t = npf_table_get(tset, tid); 
388 if (t == NULL) { 
389 pool_cache_put(tblent_cache, ent); 
390 return EINVAL; 
391 } 
392 
393 /* 362 /*
394 * Insert the entry. Return an error on duplicate. 363 * Insert the entry. Return an error on duplicate.
395 */ 364 */
 365 rw_enter(&t->t_lock, RW_WRITER);
396 switch (t->t_type) { 366 switch (t->t_type) {
397 case NPF_TABLE_HASH: { 367 case NPF_TABLE_HASH: {
398 struct npf_hashl *htbl; 368 struct npf_hashl *htbl;
399 369
400 /* 370 /*
401 * Hash tables by the concept support only IPs. 371 * Hash tables by the concept support only IPs.
402 */ 372 */
403 if (mask != NPF_NO_NETMASK) { 373 if (mask != NPF_NO_NETMASK) {
404 error = EINVAL; 374 error = EINVAL;
405 break; 375 break;
406 } 376 }
407 if (!table_hash_lookup(t, addr, alen, &htbl)) { 377 if (!table_hash_lookup(t, addr, alen, &htbl)) {
408 LIST_INSERT_HEAD(htbl, ent, te_entry.hashq); 378 LIST_INSERT_HEAD(htbl, ent, te_entry.hashq);
 379 t->t_nitems++;
409 } else { 380 } else {
410 error = EEXIST; 381 error = EEXIST;
411 } 382 }
412 break; 383 break;
413 } 384 }
414 case NPF_TABLE_TREE: { 385 case NPF_TABLE_TREE: {
415 pt_tree_t *tree = &t->t_tree[aidx]; 386 pt_tree_t *tree = &t->t_tree[aidx];
416 bool ok; 387 bool ok;
417 388
418 /* 389 /*
419 * If no mask specified, use maximum mask. 390 * If no mask specified, use maximum mask.
420 */ 391 */
421 if (mask != NPF_NO_NETMASK) { 392 ok = (mask != NPF_NO_NETMASK) ?
422 ok = ptree_insert_mask_node(tree, ent, mask); 393 ptree_insert_mask_node(tree, ent, mask) :
 394 ptree_insert_node(tree, ent);
 395 if (ok) {
 396 t->t_nitems++;
 397 error = 0;
423 } else { 398 } else {
424 ok = ptree_insert_node(tree, ent); 399 error = EEXIST;
425 } 400 }
426 error = ok ? 0 : EEXIST; 
427 break; 401 break;
428 } 402 }
429 default: 403 default:
430 KASSERT(false); 404 KASSERT(false);
431 } 405 }
432 npf_table_put(t); 406 rw_exit(&t->t_lock);
433 407
434 if (error) { 408 if (error) {
435 pool_cache_put(tblent_cache, ent); 409 pool_cache_put(tblent_cache, ent);
436 } 410 }
437 return error; 411 return error;
438} 412}
439 413
440/* 414/*
441 * npf_table_remove: remove the IP CIDR entry from the table. 415 * npf_table_remove: remove the IP CIDR entry from the table.
442 */ 416 */
443int 417int
444npf_table_remove(npf_tableset_t *tset, u_int tid, const int alen, 418npf_table_remove(npf_tableset_t *tset, u_int tid, const int alen,
445 const npf_addr_t *addr, const npf_netmask_t mask) 419 const npf_addr_t *addr, const npf_netmask_t mask)
446{ 420{
447 const u_int aidx = NPF_ADDRLEN2TREE(alen); 421 const u_int aidx = NPF_ADDRLEN2TREE(alen);
448 npf_tblent_t *ent; 422 npf_tblent_t *ent;
449 npf_table_t *t; 423 npf_table_t *t;
450 int error; 424 int error;
451 425
452 error = npf_table_validate_cidr(aidx, addr, mask); 426 error = table_cidr_check(aidx, addr, mask);
453 if (error) { 427 if (error) {
454 return error; 428 return error;
455 } 429 }
456 t = npf_table_get(tset, tid); 430
457 if (t == NULL) { 431 if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
458 return EINVAL; 432 return EINVAL;
459 } 433 }
460 434
 435 rw_enter(&t->t_lock, RW_WRITER);
461 switch (t->t_type) { 436 switch (t->t_type) {
462 case NPF_TABLE_HASH: { 437 case NPF_TABLE_HASH: {
463 struct npf_hashl *htbl; 438 struct npf_hashl *htbl;
464 439
465 ent = table_hash_lookup(t, addr, alen, &htbl); 440 ent = table_hash_lookup(t, addr, alen, &htbl);
466 if (__predict_true(ent != NULL)) { 441 if (__predict_true(ent != NULL)) {
467 LIST_REMOVE(ent, te_entry.hashq); 442 LIST_REMOVE(ent, te_entry.hashq);
 443 t->t_nitems--;
468 } 444 }
469 break; 445 break;
470 } 446 }
471 case NPF_TABLE_TREE: { 447 case NPF_TABLE_TREE: {
472 pt_tree_t *tree = &t->t_tree[aidx]; 448 pt_tree_t *tree = &t->t_tree[aidx];
473 449
474 ent = ptree_find_node(tree, addr); 450 ent = ptree_find_node(tree, addr);
475 if (__predict_true(ent != NULL)) { 451 if (__predict_true(ent != NULL)) {
476 ptree_remove_node(tree, ent); 452 ptree_remove_node(tree, ent);
 453 t->t_nitems--;
477 } 454 }
478 break; 455 break;
479 } 456 }
480 default: 457 default:
481 KASSERT(false); 458 KASSERT(false);
482 ent = NULL; 459 ent = NULL;
483 } 460 }
484 npf_table_put(t); 461 rw_exit(&t->t_lock);
485 462
486 if (ent == NULL) { 463 if (ent == NULL) {
487 return ENOENT; 464 return ENOENT;
488 } 465 }
489 pool_cache_put(tblent_cache, ent); 466 pool_cache_put(tblent_cache, ent);
490 return 0; 467 return 0;
491} 468}
492 469
493/* 470/*
494 * npf_table_lookup: find the table according to ID, lookup and match 471 * npf_table_lookup: find the table according to ID, lookup and match
495 * the contents with the specified IP address. 472 * the contents with the specified IP address.
496 */ 473 */
497int 474int
498npf_table_lookup(npf_tableset_t *tset, u_int tid, 475npf_table_lookup(npf_tableset_t *tset, u_int tid,
499 const int alen, const npf_addr_t *addr) 476 const int alen, const npf_addr_t *addr)
500{ 477{
501 const u_int aidx = NPF_ADDRLEN2TREE(alen); 478 const u_int aidx = NPF_ADDRLEN2TREE(alen);
502 npf_tblent_t *ent; 479 npf_tblent_t *ent;
503 npf_table_t *t; 480 npf_table_t *t;
504 481
505 if (__predict_false(aidx > 1)) { 482 if (__predict_false(aidx > 1)) {
506 return EINVAL; 483 return EINVAL;
507 } 484 }
508 485
509 t = npf_table_get(tset, tid); 486 if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
510 if (__predict_false(t == NULL)) { 
511 return EINVAL; 487 return EINVAL;
512 } 488 }
 489
 490 rw_enter(&t->t_lock, RW_READER);
513 switch (t->t_type) { 491 switch (t->t_type) {
514 case NPF_TABLE_HASH: { 492 case NPF_TABLE_HASH: {
515 struct npf_hashl *htbl; 493 struct npf_hashl *htbl;
516 ent = table_hash_lookup(t, addr, alen, &htbl); 494 ent = table_hash_lookup(t, addr, alen, &htbl);
517 break; 495 break;
518 } 496 }
519 case NPF_TABLE_TREE: { 497 case NPF_TABLE_TREE: {
520 ent = ptree_find_node(&t->t_tree[aidx], addr); 498 ent = ptree_find_node(&t->t_tree[aidx], addr);
521 break; 499 break;
522 } 500 }
523 default: 501 default:
524 KASSERT(false); 502 KASSERT(false);
525 ent = NULL; 503 ent = NULL;
526 } 504 }
527 npf_table_put(t); 505 rw_exit(&t->t_lock);
528 506
529 return ent ? 0 : ENOENT; 507 return ent ? 0 : ENOENT;
530} 508}
 509
 510static int
 511table_ent_copyout(npf_tblent_t *ent, npf_netmask_t mask,
 512 void *ubuf, size_t len, size_t *off)
 513{
 514 void *ubufp = (uint8_t *)ubuf + *off;
 515 npf_ioctl_ent_t uent;
 516
 517 if ((*off += sizeof(npf_ioctl_ent_t)) > len) {
 518 return ENOMEM;
 519 }
 520 uent.alen = ent->te_alen;
 521 memcpy(&uent.addr, &ent->te_addr, sizeof(npf_addr_t));
 522 uent.mask = mask;
 523
 524 return copyout(&uent, ubufp, sizeof(npf_ioctl_ent_t));
 525}
 526
 527static int
 528table_tree_list(pt_tree_t *tree, npf_netmask_t maxmask, void *ubuf,
 529 size_t len, size_t *off)
 530{
 531 npf_tblent_t *ent = NULL;
 532 int error = 0;
 533
 534 while ((ent = ptree_iterate(tree, ent, PT_ASCENDING)) != NULL) {
 535 pt_bitlen_t blen;
 536
 537 if (!ptree_mask_node_p(tree, ent, &blen)) {
 538 blen = maxmask;
 539 }
 540 error = table_ent_copyout(ent, blen, ubuf, len, off);
 541 if (error)
 542 break;
 543 }
 544 return error;
 545}
 546
 547/*
 548 * npf_table_list: copy a list of all table entries into a userspace buffer.
 549 */
 550int
 551npf_table_list(npf_tableset_t *tset, u_int tid, void *ubuf, size_t len)
 552{
 553 npf_table_t *t;
 554 size_t off = 0;
 555 int error = 0;
 556
 557 if ((u_int)tid >= NPF_TABLE_SLOTS || (t = tset[tid]) == NULL) {
 558 return EINVAL;
 559 }
 560
 561 rw_enter(&t->t_lock, RW_READER);
 562 switch (t->t_type) {
 563 case NPF_TABLE_HASH:
 564 for (unsigned n = 0; n <= t->t_hashmask; n++) {
 565 npf_tblent_t *ent;
 566
 567 LIST_FOREACH(ent, &t->t_hashl[n], te_entry.hashq)
 568 if ((error = table_ent_copyout(ent, 0, ubuf,
 569 len, &off)) != 0)
 570 break;
 571 }
 572 break;
 573 case NPF_TABLE_TREE:
 574 error = table_tree_list(&t->t_tree[0], 32, ubuf, len, &off);
 575 if (error)
 576 break;
 577 error = table_tree_list(&t->t_tree[1], 128, ubuf, len, &off);
 578 if (error)
 579 break;
 580 default:
 581 KASSERT(false);
 582 }
 583 rw_exit(&t->t_lock);
 584
 585 return error;
 586}

cvs diff -r1.3.2.7 -r1.3.2.8 src/usr.sbin/npf/npfctl/Attic/npf_disassemble.c (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/Attic/npf_disassemble.c 2012/08/13 19:43:44 1.3.2.7
+++ src/usr.sbin/npf/npfctl/Attic/npf_disassemble.c 2012/11/24 04:34:43 1.3.2.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_disassemble.c,v 1.3.2.7 2012/08/13 19:43:44 riz Exp $ */ 1/* $NetBSD: npf_disassemble.c,v 1.3.2.8 2012/11/24 04:34:43 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * NPF n-code disassembler. 33 * NPF n-code disassembler.
34 * 34 *
35 * FIXME: config generation should be redesigned.. 35 * FIXME: config generation should be redesigned..
36 */ 36 */
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__RCSID("$NetBSD: npf_disassemble.c,v 1.3.2.7 2012/08/13 19:43:44 riz Exp $"); 38__RCSID("$NetBSD: npf_disassemble.c,v 1.3.2.8 2012/11/24 04:34:43 riz Exp $");
39 39
40#include <stdio.h> 40#include <stdio.h>
41#include <stdlib.h> 41#include <stdlib.h>
42#include <string.h> 42#include <string.h>
43#include <unistd.h> 43#include <unistd.h>
44#include <errno.h> 44#include <errno.h>
45#include <err.h> 45#include <err.h>
46#include <sys/socket.h> 46#include <sys/socket.h>
47#include <netinet/in.h> 47#include <netinet/in.h>
48#include <netinet/tcp.h> 48#include <netinet/tcp.h>
49#include <net/if.h> 49#include <net/if.h>
50 50
51#include <util.h> 51#include <util.h>
@@ -654,70 +654,51 @@ npfctl_show_nat(nl_rule_t *nrl, unsigned @@ -654,70 +654,51 @@ npfctl_show_nat(nl_rule_t *nrl, unsigned
654 int type; 654 int type;
655 655
656 /* TODO: bi-NAT */ 656 /* TODO: bi-NAT */
657 657
658 _npf_rule_getinfo(nrl, &rg.rg_name, &rg.rg_attr, &rg.rg_ifnum); 658 _npf_rule_getinfo(nrl, &rg.rg_name, &rg.rg_attr, &rg.rg_ifnum);
659 659
660 /* Get the interface, if any. */ 660 /* Get the interface, if any. */
661 char ifnamebuf[IFNAMSIZ], *ifname = NULL; 661 char ifnamebuf[IFNAMSIZ], *ifname = NULL;
662 if (rg.rg_ifnum) { 662 if (rg.rg_ifnum) {
663 ifname = if_indextoname(rg.rg_ifnum, ifnamebuf); 663 ifname = if_indextoname(rg.rg_ifnum, ifnamebuf);
664 } 664 }
665 _npf_nat_getinfo(nt, &type, &flags, &taddr, &alen, &port); 665 _npf_nat_getinfo(nt, &type, &flags, &taddr, &alen, &port);
666 666
667 struct sockaddr_storage ss; 667 char *taddrbuf, tportbuf[16];
668 char taddrbuf[64], tportbuf[16]; 
669 
670 if (alen == 4) { 
671 struct sockaddr_in *sin = (void *)&ss; 
672 sin->sin_len = sizeof(*sin); 
673 sin->sin_family = AF_INET; 
674 sin->sin_port = 0; 
675 memcpy(&sin->sin_addr, &taddr, sizeof(sin->sin_addr)); 
676 sockaddr_snprintf(taddrbuf, sizeof(taddrbuf), 
677 "%a", (struct sockaddr *)sin); 
678 } else { 
679 assert(alen == 16); 
680 struct sockaddr_in6 *sin6 = (void *)&ss; 
681 sin6->sin6_len = sizeof(*sin6); 
682 sin6->sin6_family = AF_INET6; 
683 sin6->sin6_port = 0; 
684 memcpy(&sin6->sin6_addr, &taddr, sizeof(sin6->sin6_addr)); 
685 sockaddr_snprintf(taddrbuf, sizeof(taddrbuf), 
686 "%a", (struct sockaddr *)sin6); 
687 } 
688 668
 669 taddrbuf = npfctl_print_addrmask(alen, &taddr, 0);
689 if (port) { 670 if (port) {
690 snprintf(tportbuf, sizeof(tportbuf), 671 snprintf(tportbuf, sizeof(tportbuf), " port %d", ntohs(port));
691 " port %d", ntohs(port)); 
692 } 672 }
693 673
694 const char *seg1 = "any", *seg2 = "any", *sp1 = "", *sp2 = "", *mt; 674 const char *seg1 = "any", *seg2 = "any", *sp1 = "", *sp2 = "", *mt;
695 switch (type) { 675 switch (type) {
696 case NPF_NATIN: 676 case NPF_NATIN:
697 mt = "<-"; 677 mt = "<-";
698 seg1 = taddrbuf; 678 seg1 = taddrbuf;
699 sp1 = port ? tportbuf : ""; 679 sp1 = port ? tportbuf : "";
700 break; 680 break;
701 case NPF_NATOUT: 681 case NPF_NATOUT:
702 mt = "->"; 682 mt = "->";
703 seg2 = taddrbuf; 683 seg2 = taddrbuf;
704 sp2 = port ? tportbuf : ""; 684 sp2 = port ? tportbuf : "";
705 break; 685 break;
706 default: 686 default:
707 assert(false); 687 assert(false);
708 } 688 }
709 printf("map %s dynamic %s%s %s %s%s pass ", ifname, 689 printf("map %s dynamic %s%s %s %s%s pass ", ifname,
710 seg1, sp1, mt, seg2, sp2); 690 seg1, sp1, mt, seg2, sp2);
 691 free(taddrbuf);
711 692
712 const void *nc; 693 const void *nc;
713 size_t nclen; 694 size_t nclen;
714 695
715 nc = _npf_rule_ncode(nrl, &nclen); 696 nc = _npf_rule_ncode(nrl, &nclen);
716 printf("%s\n", (!nc || !npfctl_show_ncode(nc, nclen)) ? " any " : ""); 697 printf("%s\n", (!nc || !npfctl_show_ncode(nc, nclen)) ? " any " : "");
717} 698}
718 699
719int 700int
720npfctl_config_show(int fd) 701npfctl_config_show(int fd)
721{ 702{
722 nl_config_t *ncf; 703 nl_config_t *ncf;
723 bool active, loaded; 704 bool active, loaded;

cvs diff -r1.6.6.2 -r1.6.6.3 src/usr.sbin/npf/npfctl/npfctl.8 (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/npfctl.8 2012/08/13 19:43:44 1.6.6.2
+++ src/usr.sbin/npf/npfctl/npfctl.8 2012/11/24 04:34:43 1.6.6.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: npfctl.8,v 1.6.6.2 2012/08/13 19:43:44 riz Exp $ 1.\" $NetBSD: npfctl.8,v 1.6.6.3 2012/11/24 04:34:43 riz Exp $
2.\" 2.\"
3.\" Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 3.\" Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" This material is based upon work partially supported by The 6.\" This material is based upon work partially supported by The
7.\" NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 7.\" NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
8.\" 8.\"
9.\" Redistribution and use in source and binary forms, with or without 9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions 10.\" modification, are permitted provided that the following conditions
11.\" are met: 11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright 12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer. 13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17.\" 17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE. 28.\" POSSIBILITY OF SUCH DAMAGE.
29.\" 29.\"
30.Dd August 12, 2012 30.Dd November 15, 2012
31.Dt NPFCTL 8 31.Dt NPFCTL 8
32.Os 32.Os
33.Sh NAME 33.Sh NAME
34.Nm npfctl 34.Nm npfctl
35.Nd control NPF packet filter 35.Nd control NPF packet filter
36.Sh SYNOPSIS 36.Sh SYNOPSIS
37.Nm npfctl 37.Nm npfctl
38.Ar command 38.Ar command
39.Op Ar arguments 39.Op Ar arguments
40.\" ----- 40.\" -----
41.Sh DESCRIPTION 41.Sh DESCRIPTION
42The 42The
43.Nm 43.Nm
@@ -69,41 +69,48 @@ will lose NAT policy due to removal. @@ -69,41 +69,48 @@ will lose NAT policy due to removal.
69NAT policy is determined by the translation type and address. 69NAT policy is determined by the translation type and address.
70Note that change of filter criteria will not expire associated sessions. 70Note that change of filter criteria will not expire associated sessions.
71The reload operation (i.e., replacing the ruleset, NAT policies and tables) 71The reload operation (i.e., replacing the ruleset, NAT policies and tables)
72is atomic. 72is atomic.
73.It Ic flush 73.It Ic flush
74Flush configuration. 74Flush configuration.
75That is, remove all rules, tables and expire all sessions. 75That is, remove all rules, tables and expire all sessions.
76This command does not disable packet inspection. 76This command does not disable packet inspection.
77.It Ic show 77.It Ic show
78Show the current state and configuration. 78Show the current state and configuration.
79Syntax of printed configuration is for the user and may not match the 79Syntax of printed configuration is for the user and may not match the
80.Xr npf.conf 5 80.Xr npf.conf 5
81syntax. 81syntax.
82.\".It Ic table Ar tid 82.It Ic table Ar tid Ic add Aq Ar addr/mask
83.\"List all entries in the currently loaded table specified by 
84.\".Ar tid . 
85.It Ic table Ar tid Ic [ add | rem ] Aq Ar addr/mask 
86In table 83In table
87.Ar tid , 84.Ar tid ,
88add or remove the IP address and optionally netmask, specified by 85add the IP address and optionally netmask, specified by
 86.Aq Ar addr/mask .
 87Only tree-type tables support masks.
 88.It Ic table Ar tid Ic rem Aq Ar addr/mask
 89In table
 90.Ar tid ,
 91remove the IP address and optionally netmask, specified by
89.Aq Ar addr/mask . 92.Aq Ar addr/mask .
90Only tree-type tables support masks. 93Only tree-type tables support masks.
91.It Ic table Ar tid Ic test Aq Ar addr 94.It Ic table Ar tid Ic test Aq Ar addr
92Query the table 95Query the table
93.Ar tid 96.Ar tid
94for a specific IP address, specified by 97for a specific IP address, specified by
95.Ar addr . 98.Ar addr .
96If no mask is specified, a single host is assumed. 99If no mask is specified, a single host is assumed.
 100.It Ic table Ar tid Ic list
 101List all entries in the currently loaded table specified by
 102.Ar tid .
 103This operation is expensive and should be used with caution.
97.It Ic sess-save 104.It Ic sess-save
98Save all active sessions. 105Save all active sessions.
99The data will be stored in the 106The data will be stored in the
100.Pa /var/db/npf_sessions.db 107.Pa /var/db/npf_sessions.db
101file. 108file.
102Administrator may want to stop the packet inspection before the 109Administrator may want to stop the packet inspection before the
103session saving. 110session saving.
104.It Ic sess-load 111.It Ic sess-load
105Load saved sessions from the file. 112Load saved sessions from the file.
106Note that original configuration should be loaded before the session loading. 113Note that original configuration should be loaded before the session loading.
107In a case of NAT policy changes, sessions which lose an associated policy 114In a case of NAT policy changes, sessions which lose an associated policy
108will not be loaded. 115will not be loaded.
109Any existing sessions during the load operation will be expired. 116Any existing sessions during the load operation will be expired.

cvs diff -r1.10.2.7 -r1.10.2.8 src/usr.sbin/npf/npfctl/npfctl.c (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/npfctl.c 2012/11/18 22:38:28 1.10.2.7
+++ src/usr.sbin/npf/npfctl/npfctl.c 2012/11/24 04:34:43 1.10.2.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npfctl.c,v 1.10.2.7 2012/11/18 22:38:28 riz Exp $ */ 1/* $NetBSD: npfctl.c,v 1.10.2.8 2012/11/24 04:34:43 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,40 +20,42 @@ @@ -20,40 +20,42 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: npfctl.c,v 1.10.2.7 2012/11/18 22:38:28 riz Exp $"); 33__RCSID("$NetBSD: npfctl.c,v 1.10.2.8 2012/11/24 04:34:43 riz Exp $");
34 34
35#include <sys/ioctl.h> 35#include <sys/ioctl.h>
36#include <sys/stat.h> 36#include <sys/stat.h>
37#include <sys/types.h> 37#include <sys/types.h>
38 38
39#include <stdio.h> 39#include <stdio.h>
40#include <stdlib.h> 40#include <stdlib.h>
41#include <string.h> 41#include <string.h>
42#include <err.h> 42#include <err.h>
43#include <fcntl.h> 43#include <fcntl.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <errno.h> 45#include <errno.h>
46 46
 47#include <util.h>
 48
47#include "npfctl.h" 49#include "npfctl.h"
48 50
49extern int yylineno, yycolumn; 51extern int yylineno, yycolumn;
50extern const char * yyfilename; 52extern const char * yyfilename;
51extern int yyparse(void); 53extern int yyparse(void);
52extern void yyrestart(FILE *); 54extern void yyrestart(FILE *);
53 55
54enum { 56enum {
55 NPFCTL_START, 57 NPFCTL_START,
56 NPFCTL_STOP, 58 NPFCTL_STOP,
57 NPFCTL_RELOAD, 59 NPFCTL_RELOAD,
58 NPFCTL_SHOWCONF, 60 NPFCTL_SHOWCONF,
59 NPFCTL_FLUSH, 61 NPFCTL_FLUSH,
@@ -132,30 +134,30 @@ xstrndup(const char *s, size_t len) @@ -132,30 +134,30 @@ xstrndup(const char *s, size_t len)
132 134
133__dead static void 135__dead static void
134usage(void) 136usage(void)
135{ 137{
136 const char *progname = getprogname(); 138 const char *progname = getprogname();
137 139
138 fprintf(stderr, 140 fprintf(stderr,
139 "usage:\t%s [ start | stop | reload | flush | show | stats ]\n", 141 "usage:\t%s [ start | stop | reload | flush | show | stats ]\n",
140 progname); 142 progname);
141 fprintf(stderr, 143 fprintf(stderr,
142 "\t%s ( sess-save | sess-load )\n", 144 "\t%s ( sess-save | sess-load )\n",
143 progname); 145 progname);
144 fprintf(stderr, 146 fprintf(stderr,
145 "\t%s table <tid> [ flush ]\n", 147 "\t%s table <tid> { add | rem | test } <address/mask>\n",
146 progname); 148 progname);
147 fprintf(stderr, 149 fprintf(stderr,
148 "\t%s table <tid> { add | rem | test } <address/mask>\n", 150 "\t%s table <tid> { list | flush }\n",
149 progname); 151 progname);
150 152
151 exit(EXIT_FAILURE); 153 exit(EXIT_FAILURE);
152} 154}
153 155
154static void 156static void
155npfctl_parsecfg(const char *cfg) 157npfctl_parsecfg(const char *cfg)
156{ 158{
157 FILE *fp; 159 FILE *fp;
158 160
159 fp = fopen(cfg, "r"); 161 fp = fopen(cfg, "r");
160 if (fp == NULL) { 162 if (fp == NULL) {
161 err(EXIT_FAILURE, "open '%s'", cfg); 163 err(EXIT_FAILURE, "open '%s'", cfg);
@@ -245,82 +247,156 @@ npfctl_print_error(const nl_error_t *ne) @@ -245,82 +247,156 @@ npfctl_print_error(const nl_error_t *ne)
245 247
246 if (srcfile) { 248 if (srcfile) {
247 warnx("source %s line %d", srcfile, ne->ne_source_line); 249 warnx("source %s line %d", srcfile, ne->ne_source_line);
248 } 250 }
249 if (nc_err) { 251 if (nc_err) {
250 warnx("n-code error (%d): %s at offset 0x%x", 252 warnx("n-code error (%d): %s at offset 0x%x",
251 nc_err, ncode_errors[-nc_err], ne->ne_ncode_errat); 253 nc_err, ncode_errors[-nc_err], ne->ne_ncode_errat);
252 } 254 }
253 if (ne->ne_id) { 255 if (ne->ne_id) {
254 warnx("object: %d", ne->ne_id); 256 warnx("object: %d", ne->ne_id);
255 } 257 }
256} 258}
257 259
 260char *
 261npfctl_print_addrmask(int alen, npf_addr_t *addr, npf_netmask_t mask)
 262{
 263 struct sockaddr_storage ss;
 264 char *buf = zalloc(64);
 265 int len;
 266
 267 switch (alen) {
 268 case 4: {
 269 struct sockaddr_in *sin = (void *)&ss;
 270 sin->sin_len = sizeof(*sin);
 271 sin->sin_family = AF_INET;
 272 sin->sin_port = 0;
 273 memcpy(&sin->sin_addr, addr, sizeof(sin->sin_addr));
 274 break;
 275 }
 276 case 16: {
 277 struct sockaddr_in6 *sin6 = (void *)&ss;
 278 sin6->sin6_len = sizeof(*sin6);
 279 sin6->sin6_family = AF_INET6;
 280 sin6->sin6_port = 0;
 281 memcpy(&sin6->sin6_addr, addr, sizeof(sin6->sin6_addr));
 282 break;
 283 }
 284 default:
 285 assert(false);
 286 }
 287 len = sockaddr_snprintf(buf, 64, "%a", (struct sockaddr *)&ss);
 288 if (mask) {
 289 snprintf(&buf[len], 64 - len, "/%u", mask);
 290 }
 291 return buf;
 292}
 293
258__dead static void 294__dead static void
259npfctl_table(int fd, char **argv) 295npfctl_table(int fd, int argc, char **argv)
260{ 296{
261 static const struct tblops_s { 297 static const struct tblops_s {
262 const char * cmd; 298 const char * cmd;
263 int action; 299 int action;
264 } tblops[] = { 300 } tblops[] = {
265 { "add", NPF_IOCTL_TBLENT_ADD }, 301 { "add", NPF_IOCTL_TBLENT_ADD },
266 { "rem", NPF_IOCTL_TBLENT_REM }, 302 { "rem", NPF_IOCTL_TBLENT_REM },
267 { "test", 0 }, 303 { "test", NPF_IOCTL_TBLENT_LOOKUP },
268 { NULL, 0 } 304 { "list", NPF_IOCTL_TBLENT_LIST },
 305 { NULL, 0 }
269 }; 306 };
270 npf_ioctl_table_t nct; 307 npf_ioctl_table_t nct;
271 fam_addr_mask_t fam; 308 fam_addr_mask_t fam;
272 char *cmd = argv[3]; 309 size_t buflen = 512;
273 char *arg = argv[3]; 310 char *cmd, *arg;
274 int n, alen; 311 int n, alen;
275 312
 313 /* Default action is list. */
276 memset(&nct, 0, sizeof(npf_ioctl_table_t)); 314 memset(&nct, 0, sizeof(npf_ioctl_table_t));
277 nct.nct_tid = atoi(argv[2]); 315 nct.nct_tid = atoi(argv[0]);
 316 cmd = argv[1];
278 317
279 for (n = 0; tblops[n].cmd != NULL; n++) { 318 for (n = 0; tblops[n].cmd != NULL; n++) {
280 if (strcmp(cmd, tblops[n].cmd) == 0) { 319 if (strcmp(cmd, tblops[n].cmd) != 0) {
281 nct.nct_action = tblops[n].action; 320 continue;
282 arg = argv[4]; 321 }
283 break; 322 nct.nct_action = tblops[n].action;
 323 break;
 324 }
 325 if (tblops[n].cmd == NULL) {
 326 errx(EXIT_FAILURE, "invalid command '%s'", cmd);
 327 }
 328 if (nct.nct_action != NPF_IOCTL_TBLENT_LIST) {
 329 if (argc < 3) {
 330 usage();
284 } 331 }
 332 arg = argv[2];
285 } 333 }
286 if (!npfctl_parse_cidr(arg, &fam, &alen)) { 334again:
287 errx(EXIT_FAILURE, "invalid CIDR '%s'", arg); 335 if (nct.nct_action == NPF_IOCTL_TBLENT_LIST) {
 336 nct.nct_data.buf.buf = zalloc(buflen);
 337 nct.nct_data.buf.len = buflen;
 338 } else {
 339 if (!npfctl_parse_cidr(arg, &fam, &alen)) {
 340 errx(EXIT_FAILURE, "invalid CIDR '%s'", arg);
 341 }
 342 nct.nct_data.ent.alen = alen;
 343 memcpy(&nct.nct_data.ent.addr, &fam.fam_addr, sizeof(npf_addr_t));
 344 nct.nct_data.ent.mask = fam.fam_mask;
288 } 345 }
289 memcpy(&nct.nct_addr, &fam.fam_addr, sizeof(npf_addr_t)); 
290 nct.nct_mask = fam.fam_mask; 
291 nct.nct_alen = alen; 
292 346
293 if (ioctl(fd, IOC_NPF_TABLE, &nct) != -1) { 347 if (ioctl(fd, IOC_NPF_TABLE, &nct) != -1) {
294 errno = 0; 348 errno = 0;
295 } 349 }
296 switch (errno) { 350 switch (errno) {
297 case EEXIST: 351 case 0:
298 warnx("entry already exists or is conflicting"); 
299 break; 352 break;
 353 case EEXIST:
 354 errx(EXIT_FAILURE, "entry already exists or is conflicting");
300 case ENOENT: 355 case ENOENT:
301 warnx("no matching entry was not found"); 356 errx(EXIT_FAILURE, "no matching entry was not found");
302 break; 
303 case EINVAL: 357 case EINVAL:
304 warnx("invalid address, mask or table ID"); 358 errx(EXIT_FAILURE, "invalid address, mask or table ID");
305 break; 359 case ENOMEM:
306 case 0: 360 if (nct.nct_action == NPF_IOCTL_TBLENT_LIST) {
307 printf("%s: %s\n", getprogname(), nct.nct_action == 0 ? 361 /* XXX */
308 "matching entry found" : "success"); 362 free(nct.nct_data.buf.buf);
309 break; 363 buflen <<= 1;
 364 goto again;
 365 }
 366 /* FALLTHROUGH */
310 default: 367 default:
311 warn("error"); 368 err(EXIT_FAILURE, "ioctl");
 369 }
 370
 371 if (nct.nct_action == NPF_IOCTL_TBLENT_LIST) {
 372 npf_ioctl_ent_t *ent = nct.nct_data.buf.buf;
 373 char *buf;
 374
 375 while (nct.nct_data.buf.len--) {
 376 if (!ent->alen)
 377 break;
 378 buf = npfctl_print_addrmask(ent->alen,
 379 &ent->addr, ent->mask);
 380 puts(buf);
 381 ent++;
 382 }
 383 free(nct.nct_data.buf.buf);
 384 } else {
 385 printf("%s: %s\n", getprogname(),
 386 nct.nct_action == NPF_IOCTL_TBLENT_LOOKUP ?
 387 "matching entry found" : "success");
312 } 388 }
313 exit(errno ? EXIT_FAILURE : EXIT_SUCCESS); 389 exit(EXIT_SUCCESS);
314} 390}
315 391
316static void 392static void
317npfctl(int action, int argc, char **argv) 393npfctl(int action, int argc, char **argv)
318{ 394{
319 int fd, ret, ver, boolval; 395 int fd, ret, ver, boolval;
320 396
321 fd = open(NPF_DEV_PATH, O_RDONLY); 397 fd = open(NPF_DEV_PATH, O_RDONLY);
322 if (fd == -1) { 398 if (fd == -1) {
323 err(EXIT_FAILURE, "cannot open '%s'", NPF_DEV_PATH); 399 err(EXIT_FAILURE, "cannot open '%s'", NPF_DEV_PATH);
324 } 400 }
325 ret = ioctl(fd, IOC_NPF_VERSION, &ver); 401 ret = ioctl(fd, IOC_NPF_VERSION, &ver);
326 if (ret == -1) { 402 if (ret == -1) {
@@ -345,30 +421,31 @@ npfctl(int action, int argc, char **argv @@ -345,30 +421,31 @@ npfctl(int action, int argc, char **argv
345 npfctl_parsecfg(argc < 3 ? NPF_CONF_PATH : argv[2]); 421 npfctl_parsecfg(argc < 3 ? NPF_CONF_PATH : argv[2]);
346 ret = npfctl_config_send(fd, NULL); 422 ret = npfctl_config_send(fd, NULL);
347 if (ret) { 423 if (ret) {
348 errx(EXIT_FAILURE, "ioctl: %s", strerror(ret)); 424 errx(EXIT_FAILURE, "ioctl: %s", strerror(ret));
349 } 425 }
350 break; 426 break;
351 case NPFCTL_SHOWCONF: 427 case NPFCTL_SHOWCONF:
352 ret = npfctl_config_show(fd); 428 ret = npfctl_config_show(fd);
353 break; 429 break;
354 case NPFCTL_FLUSH: 430 case NPFCTL_FLUSH:
355 ret = npf_config_flush(fd); 431 ret = npf_config_flush(fd);
356 break; 432 break;
357 case NPFCTL_TABLE: 433 case NPFCTL_TABLE:
358 if (argc < 5) { 434 if ((argc -= 2) < 2) {
359 usage(); 435 usage();
360 } 436 }
361 npfctl_table(fd, argv); 437 argv += 2;
 438 npfctl_table(fd, argc, argv);
362 break; 439 break;
363 case NPFCTL_STATS: 440 case NPFCTL_STATS:
364 ret = npfctl_print_stats(fd); 441 ret = npfctl_print_stats(fd);
365 break; 442 break;
366 case NPFCTL_SESSIONS_SAVE: 443 case NPFCTL_SESSIONS_SAVE:
367 if (npf_sessions_recv(fd, NPF_SESSDB_PATH) != 0) { 444 if (npf_sessions_recv(fd, NPF_SESSDB_PATH) != 0) {
368 errx(EXIT_FAILURE, "could not save sessions to '%s'", 445 errx(EXIT_FAILURE, "could not save sessions to '%s'",
369 NPF_SESSDB_PATH); 446 NPF_SESSDB_PATH);
370 } 447 }
371 break; 448 break;
372 case NPFCTL_SESSIONS_LOAD: 449 case NPFCTL_SESSIONS_LOAD:
373 if (npf_sessions_send(fd, NPF_SESSDB_PATH) != 0) { 450 if (npf_sessions_send(fd, NPF_SESSDB_PATH) != 0) {
374 errx(EXIT_FAILURE, "no sessions loaded from '%s'", 451 errx(EXIT_FAILURE, "no sessions loaded from '%s'",

cvs diff -r1.11.2.7 -r1.11.2.8 src/usr.sbin/npf/npfctl/npfctl.h (expand / switch to unified diff)

--- src/usr.sbin/npf/npfctl/npfctl.h 2012/11/18 22:38:27 1.11.2.7
+++ src/usr.sbin/npf/npfctl/npfctl.h 2012/11/24 04:34:43 1.11.2.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npfctl.h,v 1.11.2.7 2012/11/18 22:38:27 riz Exp $ */ 1/* $NetBSD: npfctl.h,v 1.11.2.8 2012/11/24 04:34:43 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -86,26 +86,27 @@ typedef struct proc_call { @@ -86,26 +86,27 @@ typedef struct proc_call {
86 86
87typedef struct proc_param { 87typedef struct proc_param {
88 const char * pp_param; 88 const char * pp_param;
89 const char * pp_value; 89 const char * pp_value;
90} proc_param_t; 90} proc_param_t;
91 91
92void yyerror(const char *, ...) __printflike(1, 2) __dead; 92void yyerror(const char *, ...) __printflike(1, 2) __dead;
93void * zalloc(size_t); 93void * zalloc(size_t);
94void * xrealloc(void *, size_t); 94void * xrealloc(void *, size_t);
95char * xstrdup(const char *); 95char * xstrdup(const char *);
96char * xstrndup(const char *, size_t); 96char * xstrndup(const char *, size_t);
97 97
98void npfctl_print_error(const nl_error_t *); 98void npfctl_print_error(const nl_error_t *);
 99char * npfctl_print_addrmask(int, npf_addr_t *, npf_netmask_t);
99bool npfctl_table_exists_p(const char *); 100bool npfctl_table_exists_p(const char *);
100int npfctl_protono(const char *); 101int npfctl_protono(const char *);
101in_port_t npfctl_portno(const char *); 102in_port_t npfctl_portno(const char *);
102uint8_t npfctl_icmpcode(int, uint8_t, const char *); 103uint8_t npfctl_icmpcode(int, uint8_t, const char *);
103uint8_t npfctl_icmptype(int, const char *); 104uint8_t npfctl_icmptype(int, const char *);
104unsigned long npfctl_find_ifindex(const char *); 105unsigned long npfctl_find_ifindex(const char *);
105npfvar_t * npfctl_parse_tcpflag(const char *); 106npfvar_t * npfctl_parse_tcpflag(const char *);
106npfvar_t * npfctl_parse_table_id(const char *); 107npfvar_t * npfctl_parse_table_id(const char *);
107npfvar_t * npfctl_parse_icmp(int, int, int); 108npfvar_t * npfctl_parse_icmp(int, int, int);
108npfvar_t * npfctl_parse_iface(const char *); 109npfvar_t * npfctl_parse_iface(const char *);
109npfvar_t * npfctl_parse_port_range(in_port_t, in_port_t); 110npfvar_t * npfctl_parse_port_range(in_port_t, in_port_t);
110npfvar_t * npfctl_parse_port_range_variable(const char *); 111npfvar_t * npfctl_parse_port_range_variable(const char *);
111npfvar_t * npfctl_parse_fam_addr_mask(const char *, const char *, 112npfvar_t * npfctl_parse_fam_addr_mask(const char *, const char *,

cvs diff -r1.2.2.6 -r1.2.2.7 src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c (expand / switch to unified diff)

--- src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c 2012/11/18 21:48:56 1.2.2.6
+++ src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c 2012/11/24 04:34:44 1.2.2.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_table_test.c,v 1.2.2.6 2012/11/18 21:48:56 riz Exp $ */ 1/* $NetBSD: npf_table_test.c,v 1.2.2.7 2012/11/24 04:34:44 riz Exp $ */
2 2
3/* 3/*
4 * NPF tableset test. 4 * NPF tableset test.
5 * 5 *
6 * Public Domain. 6 * Public Domain.
7 */ 7 */
8 8
9#include <sys/types.h> 9#include <sys/types.h>
10 10
11#include "npf_impl.h" 11#include "npf_impl.h"
12#include "npf_test.h" 12#include "npf_test.h"
13 13
14static const char *ip_list[] = { 14static const char *ip_list[] = {
@@ -34,39 +34,63 @@ static const uint16_t ip6_list[][8] = { @@ -34,39 +34,63 @@ static const uint16_t ip6_list[][8] = {
34 { 34 {
35 htons(0xfe80), 0x0, 0x0, 0x0, 35 htons(0xfe80), 0x0, 0x0, 0x0,
36 0x0, 0x0, 0x0, 0x0 36 0x0, 0x0, 0x0, 0x0
37 }, 37 },
38 { 38 {
39 htons(0xfe80), 0x0, 0x0, 0x0, 39 htons(0xfe80), 0x0, 0x0, 0x0,
40 htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1230) 40 htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1230)
41 } 41 }
42}; 42};
43 43
44#define HASH_TID 1 44#define HASH_TID 1
45#define TREE_TID 2 45#define TREE_TID 2
46 46
 47static bool
 48npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
 49{
 50 const int alen = sizeof(struct in_addr);
 51 const int nm = NPF_NO_NETMASK;
 52 bool fail = false;
 53
 54 /* Fill both tables with IP addresses. */
 55 for (unsigned i = 0; i < __arraycount(ip_list); i++) {
 56 int error;
 57
 58 addr->s6_addr32[0] = inet_addr(ip_list[i]);
 59
 60 error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
 61 fail |= !(error == 0);
 62 error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
 63 fail |= !(error != 0);
 64
 65 error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
 66 fail |= !(error == 0);
 67 error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
 68 fail |= !(error != 0);
 69 }
 70 return fail;
 71}
 72
47bool 73bool
48npf_table_test(bool verbose) 74npf_table_test(bool verbose)
49{ 75{
50 npf_addr_t addr_storage, *addr = &addr_storage; 76 npf_addr_t addr_storage, *addr = &addr_storage;
51 const int nm = NPF_NO_NETMASK; 77 const int nm = NPF_NO_NETMASK;
52 npf_tableset_t *tblset; 78 npf_tableset_t *tblset;
53 npf_table_t *t1, *t2; 79 npf_table_t *t1, *t2;
54 int error, alen; 80 int error, alen;
55 bool fail = false; 81 bool fail = false;
56 u_int i; 82 u_int i;
57 83
58 npf_tableset_sysinit(); 
59 
60 tblset = npf_tableset_create(); 84 tblset = npf_tableset_create();
61 fail |= !(tblset != NULL); 85 fail |= !(tblset != NULL);
62 86
63 /* Table ID 1, using hash table with 256 lists. */ 87 /* Table ID 1, using hash table with 256 lists. */
64 t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256); 88 t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256);
65 fail |= !(t1 != NULL); 89 fail |= !(t1 != NULL);
66 error = npf_tableset_insert(tblset, t1); 90 error = npf_tableset_insert(tblset, t1);
67 fail |= !(error == 0); 91 fail |= !(error == 0);
68 92
69 /* Check for double-insert. */ 93 /* Check for double-insert. */
70 error = npf_tableset_insert(tblset, t1); 94 error = npf_tableset_insert(tblset, t1);
71 fail |= !(error != 0); 95 fail |= !(error != 0);
72 96
@@ -77,59 +101,38 @@ npf_table_test(bool verbose) @@ -77,59 +101,38 @@ npf_table_test(bool verbose)
77 fail |= !(error == 0); 101 fail |= !(error == 0);
78 102
79 /* Attempt to match non-existing entries - should fail. */ 103 /* Attempt to match non-existing entries - should fail. */
80 addr->s6_addr32[0] = inet_addr(ip_list[0]); 104 addr->s6_addr32[0] = inet_addr(ip_list[0]);
81 alen = sizeof(struct in_addr); 105 alen = sizeof(struct in_addr);
82 106
83 error = npf_table_lookup(tblset, HASH_TID, alen, addr); 107 error = npf_table_lookup(tblset, HASH_TID, alen, addr);
84 fail |= !(error != 0); 108 fail |= !(error != 0);
85 109
86 error = npf_table_lookup(tblset, TREE_TID, alen, addr); 110 error = npf_table_lookup(tblset, TREE_TID, alen, addr);
87 fail |= !(error != 0); 111 fail |= !(error != 0);
88 112
89 /* Fill both tables with IP addresses. */ 113 /* Fill both tables with IP addresses. */
90 for (i = 0; i < __arraycount(ip_list); i++) { 114 fail |= npf_table_test_fill4(tblset, addr);
91 addr->s6_addr32[0] = inet_addr(ip_list[i]); 
92 
93 error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); 
94 fail |= !(error == 0); 
95 error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); 
96 fail |= !(error != 0); 
97 
98 error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); 
99 fail |= !(error == 0); 
100 error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); 
101 fail |= !(error != 0); 
102 } 
103 115
104 /* Attempt to add duplicates - should fail. */ 116 /* Attempt to add duplicates - should fail. */
105 addr->s6_addr32[0] = inet_addr(ip_list[0]); 117 addr->s6_addr32[0] = inet_addr(ip_list[0]);
106 alen = sizeof(struct in_addr); 118 alen = sizeof(struct in_addr);
107 119
108 error = npf_table_insert(tblset, HASH_TID, alen, addr, nm); 120 error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
109 fail |= !(error != 0); 121 fail |= !(error != 0);
110 122
111 error = npf_table_insert(tblset, TREE_TID, alen, addr, nm); 123 error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
112 fail |= !(error != 0); 124 fail |= !(error != 0);
113 125
114 /* Reference checks. */ 
115 t1 = npf_table_get(tblset, HASH_TID); 
116 fail |= !(t1 != NULL); 
117 npf_table_put(t1); 
118 
119 t2 = npf_table_get(tblset, TREE_TID); 
120 fail |= !(t2 != NULL); 
121 npf_table_put(t2); 
122 
123 /* Match (validate) each IP entry. */ 126 /* Match (validate) each IP entry. */
124 for (i = 0; i < __arraycount(ip_list); i++) { 127 for (i = 0; i < __arraycount(ip_list); i++) {
125 addr->s6_addr32[0] = inet_addr(ip_list[i]); 128 addr->s6_addr32[0] = inet_addr(ip_list[i]);
126 129
127 error = npf_table_lookup(tblset, HASH_TID, alen, addr); 130 error = npf_table_lookup(tblset, HASH_TID, alen, addr);
128 fail |= !(error == 0); 131 fail |= !(error == 0);
129 132
130 error = npf_table_lookup(tblset, TREE_TID, alen, addr); 133 error = npf_table_lookup(tblset, TREE_TID, alen, addr);
131 fail |= !(error == 0); 134 fail |= !(error == 0);
132 } 135 }
133 136
134 /* IPv6 addresses. */ 137 /* IPv6 addresses. */
135 memcpy(addr, ip6_list[0], sizeof(ip6_list[0])); 138 memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
@@ -196,17 +199,16 @@ npf_table_test(bool verbose) @@ -196,17 +199,16 @@ npf_table_test(bool verbose)
196 199
197 /* Remove all IPv4 entries. */ 200 /* Remove all IPv4 entries. */
198 for (i = 0; i < __arraycount(ip_list); i++) { 201 for (i = 0; i < __arraycount(ip_list); i++) {
199 addr->s6_addr32[0] = inet_addr(ip_list[i]); 202 addr->s6_addr32[0] = inet_addr(ip_list[i]);
200 203
201 error = npf_table_remove(tblset, HASH_TID, alen, addr, nm); 204 error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
202 fail |= !(error == 0); 205 fail |= !(error == 0);
203 206
204 error = npf_table_remove(tblset, TREE_TID, alen, addr, nm); 207 error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
205 fail |= !(error == 0); 208 fail |= !(error == 0);
206 } 209 }
207 210
208 npf_tableset_destroy(tblset); 211 npf_tableset_destroy(tblset);
209 npf_tableset_sysfini(); 
210 212
211 return !fail; 213 return !fail;
212} 214}