Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src NPF checkpoint:
details: https://anonhg.NetBSD.org/src/rev/ed5de796875c
branches: trunk
changeset: 759848:ed5de796875c
user: rmind <rmind%NetBSD.org@localhost>
date: Sat Dec 18 01:07:25 2010 +0000
description:
NPF checkpoint:
- Add support for session saving/restoring.
- Add packet logging support (can tcpdump a pseudo-interface).
- Support reload without flushing of sessions; rework some locking.
- Revisit session mangement, replace linking with npf_sentry_t entries.
- Add some counters for statistics, using percpu(9).
- Add IP_DF flag cleansing.
- Fix various bugs; misc clean-up.
diffstat:
sys/modules/npf/Makefile | 3 +-
sys/net/npf/files.npf | 3 +-
sys/net/npf/npf.c | 219 ++++++++-
sys/net/npf/npf.h | 37 +-
sys/net/npf/npf_alg_icmp.c | 8 +-
sys/net/npf/npf_ctl.c | 253 +++++-----
sys/net/npf/npf_handler.c | 33 +-
sys/net/npf/npf_impl.h | 78 ++-
sys/net/npf/npf_inet.c | 30 +-
sys/net/npf/npf_log.c | 175 +++++++
sys/net/npf/npf_nat.c | 408 ++++++++++++-----
sys/net/npf/npf_ncode.h | 19 +-
sys/net/npf/npf_processor.c | 16 +-
sys/net/npf/npf_ruleset.c | 367 +++++++++------
sys/net/npf/npf_session.c | 887 ++++++++++++++++++++++++--------------
sys/net/npf/npf_state.c | 44 +-
sys/net/npf/npf_tableset.c | 71 +--
usr.sbin/npf/npfctl/npf_data.c | 83 ++-
usr.sbin/npf/npfctl/npf_ncgen.c | 19 +-
usr.sbin/npf/npfctl/npf_parser.c | 38 +-
usr.sbin/npf/npfctl/npfctl.c | 91 +++-
usr.sbin/npf/npfctl/npfctl.h | 7 +-
22 files changed, 1943 insertions(+), 946 deletions(-)
diffs (truncated from 4772 to 300 lines):
diff -r e32309caf39d -r ed5de796875c sys/modules/npf/Makefile
--- a/sys/modules/npf/Makefile Sat Dec 18 00:01:46 2010 +0000
+++ b/sys/modules/npf/Makefile Sat Dec 18 01:07:25 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.3 2010/11/11 06:30:39 rmind Exp $
+# $NetBSD: Makefile,v 1.4 2010/12/18 01:07:26 rmind Exp $
.include "../Makefile.inc"
@@ -9,5 +9,6 @@
SRCS= npf.c npf_ctl.c npf_handler.c npf_instr.c npf_mbuf.c
SRCS+= npf_processor.c npf_ruleset.c npf_tableset.c npf_inet.c
SRCS+= npf_session.c npf_state.c npf_nat.c npf_alg.c npf_sendpkt.c
+SRCS+= npf_log.c
.include <bsd.kmodule.mk>
diff -r e32309caf39d -r ed5de796875c sys/net/npf/files.npf
--- a/sys/net/npf/files.npf Sat Dec 18 00:01:46 2010 +0000
+++ b/sys/net/npf/files.npf Sat Dec 18 01:07:25 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.npf,v 1.3 2010/11/11 06:30:39 rmind Exp $
+# $NetBSD: files.npf,v 1.4 2010/12/18 01:07:25 rmind Exp $
#
# Public Domain.
#
@@ -24,6 +24,7 @@
file net/npf/npf_nat.c npf
file net/npf/npf_alg.c npf
file net/npf/npf_sendpkt.c npf
+file net/npf/npf_log.c npf
# ALGs
file net/npf/npf_alg_icmp.c npf
diff -r e32309caf39d -r ed5de796875c sys/net/npf/npf.c
--- a/sys/net/npf/npf.c Sat Dec 18 00:01:46 2010 +0000
+++ b/sys/net/npf/npf.c Sat Dec 18 01:07:25 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.c,v 1.1 2010/08/22 18:56:22 rmind Exp $ */
+/* $NetBSD: npf.c,v 1.2 2010/12/18 01:07:25 rmind Exp $ */
/*-
* Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -34,15 +34,19 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.1 2010/08/22 18:56:22 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.2 2010/12/18 01:07:25 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
+#include <sys/atomic.h>
#include <sys/conf.h>
#include <sys/kauth.h>
+#include <sys/kmem.h>
#include <sys/lwp.h>
#include <sys/module.h>
+#include <sys/percpu.h>
+#include <sys/rwlock.h>
#include <sys/socketvar.h>
#include <sys/uio.h>
@@ -61,6 +65,19 @@
static int npf_dev_poll(dev_t, int, lwp_t *);
static int npf_dev_read(dev_t, struct uio *, int);
+typedef struct {
+ npf_ruleset_t * n_rules;
+ npf_tableset_t * n_tables;
+ npf_ruleset_t * n_nat_rules;
+} npf_core_t;
+
+static void npf_core_destroy(npf_core_t *);
+static int npfctl_stats(void *);
+
+static krwlock_t npf_lock __cacheline_aligned;
+static npf_core_t * npf_core __cacheline_aligned;
+static percpu_t * npf_stats_percpu __read_mostly;
+
const struct cdevsw npf_cdevsw = {
npf_dev_open, npf_dev_close, npf_dev_read, nowrite, npf_dev_ioctl,
nostop, notty, npf_dev_poll, nommap, nokqfilter, D_OTHER | D_MPSAFE
@@ -72,39 +89,31 @@
#ifdef _MODULE
devmajor_t bmajor = NODEVMAJOR, cmajor = NODEVMAJOR;
#endif
- int error;
-
- /*
- * Initialise ruleset, tables and session structures.
- */
-
- error = npf_ruleset_sysinit();
- if (error)
- return error;
+ npf_ruleset_t *rset, *nset;
+ npf_tableset_t *tset;
+ int error = 0;
- error = npf_tableset_sysinit();
- if (error) {
- npf_ruleset_sysfini();
- return error;
- }
-
- error = npf_session_sysinit();
- if (error) {
- npf_tableset_sysfini();
- npf_ruleset_sysfini();
- return error;
- }
+ rw_init(&npf_lock);
+ npf_stats_percpu = percpu_alloc(NPF_STATS_SIZE);
+ npf_tableset_sysinit();
+ npf_session_sysinit();
npf_nat_sysinit();
npf_alg_sysinit();
+ npflogattach(1);
+
+ /* Load empty configuration. */
+ rset = npf_ruleset_create();
+ tset = npf_tableset_create();
+ nset = npf_ruleset_create();
+ npf_reload(rset, tset, nset);
+ KASSERT(npf_core != NULL);
#ifdef _MODULE
/* Attach /dev/npf device. */
error = devsw_attach("npf", NULL, &bmajor, &npf_cdevsw, &cmajor);
if (error) {
- npf_nat_sysfini();
- npf_session_sysfini();
- npf_tableset_sysfini();
- npf_ruleset_sysfini();
+ /* It will call devsw_detach(), which is safe. */
+ (void)npf_fini();
}
#endif
return error;
@@ -114,15 +123,24 @@
npf_fini(void)
{
+ /*
+ * At first, detach device, remove pfil hooks and unload existing
+ * configuration, destroy structures.
+ */
#ifdef _MODULE
- /* At first, detach device and remove pfil hooks. */
devsw_detach(NULL, &npf_cdevsw);
#endif
+ npf_unregister_pfil();
+ npf_core_destroy(npf_core);
+ npflogdetach();
+
+ /* Note: order is particular. */
npf_nat_sysfini();
npf_alg_sysfini();
npf_session_sysfini();
npf_tableset_sysfini();
- npf_ruleset_sysfini();
+ percpu_free(npf_stats_percpu, NPF_STATS_SIZE);
+ rw_destroy(&npf_lock);
return 0;
}
@@ -194,6 +212,15 @@
case IOC_NPF_TABLE:
error = npfctl_table(data);
break;
+ case IOC_NPF_STATS:
+ error = npfctl_stats(data);
+ break;
+ case IOC_NPF_SESSIONS_SAVE:
+ error = npfctl_sessions_save(cmd, data);
+ break;
+ case IOC_NPF_SESSIONS_LOAD:
+ error = npfctl_sessions_load(cmd, data);
+ break;
default:
error = ENOTTY;
break;
@@ -214,3 +241,137 @@
return ENOTSUP;
}
+
+/*
+ * NPF core loading/reloading/unloading mechanism.
+ */
+
+static void
+npf_core_destroy(npf_core_t *nc)
+{
+
+ npf_tableset_destroy(nc->n_tables);
+ npf_ruleset_destroy(nc->n_rules);
+ npf_ruleset_destroy(nc->n_nat_rules);
+ kmem_free(nc, sizeof(npf_core_t));
+}
+
+/*
+ * npf_reload: atomically load new ruleset, tableset and NAT policies.
+ * Then destroy old (unloaded) structures.
+ */
+void
+npf_reload(npf_ruleset_t *rset, npf_tableset_t *tset, npf_ruleset_t *nset)
+{
+ npf_core_t *nc, *onc;
+
+ /* Setup a new core structure. */
+ nc = kmem_alloc(sizeof(npf_core_t), KM_SLEEP);
+ nc->n_rules = rset;
+ nc->n_tables = tset;
+ nc->n_nat_rules = nset;
+
+ /* Lock and load the core structure. */
+ rw_enter(&npf_lock, RW_WRITER);
+ onc = atomic_swap_ptr(&npf_core, nc);
+ if (onc) {
+ /* Reload only necessary NAT policies. */
+ npf_ruleset_natreload(nset, onc->n_nat_rules);
+ }
+ /* Unlock. Everything goes "live" now. */
+ rw_exit(&npf_lock);
+
+ /* Turn on/off session tracking accordingly. */
+ npf_session_tracking(true);
+
+ if (onc) {
+ /* Destroy unloaded structures. */
+ npf_core_destroy(onc);
+ }
+}
+
+void
+npf_core_enter(void)
+{
+ rw_enter(&npf_lock, RW_READER);
+}
+
+npf_ruleset_t *
+npf_core_ruleset(void)
+{
+ KASSERT(rw_lock_held(&npf_lock));
+ return npf_core->n_rules;
+}
+
+npf_ruleset_t *
+npf_core_natset(void)
+{
+ KASSERT(rw_lock_held(&npf_lock));
+ return npf_core->n_nat_rules;
+}
+
+npf_tableset_t *
+npf_core_tableset(void)
+{
+ KASSERT(rw_lock_held(&npf_lock));
+ return npf_core->n_tables;
+}
+
+void
+npf_core_exit(void)
+{
+ rw_exit(&npf_lock);
+}
+
+bool
+npf_core_locked(void)
+{
+ return rw_lock_held(&npf_lock);
+}
+
+/*
+ * NPF statistics interface.
+ */
+
+void
+npf_stats_inc(npf_stats_t st)
+{
+ uint64_t *stats = percpu_getref(npf_stats_percpu);
+ stats[st]++;
+ percpu_putref(npf_stats_percpu);
+}
+
+void
+npf_stats_dec(npf_stats_t st)
+{
+ uint64_t *stats = percpu_getref(npf_stats_percpu);
+ stats[st]--;
+ percpu_putref(npf_stats_percpu);
+}
+
+static void
+npf_stats_collect(void *mem, void *arg, struct cpu_info *ci)
+{
+ uint64_t *percpu_stats = mem, *full_stats = arg;
+ int i;
Home |
Main Index |
Thread Index |
Old Index