Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys - NPF connection tracking: rework synchronisation on tra...



details:   https://anonhg.NetBSD.org/src/rev/517f73ffdb2c
branches:  trunk
changeset: 787095:517f73ffdb2c
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sun Jun 02 02:20:04 2013 +0000

description:
- NPF connection tracking: rework synchronisation on tracking disable/enable
  points and document it.  Split the worker thread into a separate module
  with an interface, so it could be re-used for other tasks.
- Replace ALG list with arrays and thus hit fewer cache lines.
- Misc bug fixes.

diffstat:

 sys/modules/npf/Makefile         |    4 +-
 sys/net/npf/files.npf            |    3 +-
 sys/net/npf/npf.c                |    8 +-
 sys/net/npf/npf_alg.c            |  175 ++++++++++++---------
 sys/net/npf/npf_alg_icmp.c       |   11 +-
 sys/net/npf/npf_ctl.c            |   24 +-
 sys/net/npf/npf_impl.h           |   13 +-
 sys/net/npf/npf_inet.c           |    6 +-
 sys/net/npf/npf_nat.c            |   13 +-
 sys/net/npf/npf_session.c        |  310 ++++++++++++++++----------------------
 sys/net/npf/npf_worker.c         |  161 ++++++++++++++++++++
 sys/rump/net/lib/libnpf/Makefile |    4 +-
 12 files changed, 436 insertions(+), 296 deletions(-)

diffs (truncated from 1257 to 300 lines):

diff -r dbbda348ab56 -r 517f73ffdb2c sys/modules/npf/Makefile
--- a/sys/modules/npf/Makefile  Sat Jun 01 21:21:36 2013 +0000
+++ b/sys/modules/npf/Makefile  Sun Jun 02 02:20:04 2013 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.12 2013/02/09 03:35:33 rmind Exp $
+# $NetBSD: Makefile,v 1.13 2013/06/02 02:20:05 rmind Exp $
 
 .include "../Makefile.inc"
 
@@ -10,7 +10,7 @@
 SRCS+=         npf_inet.c npf_instr.c npf_mbuf.c npf_nat.c
 SRCS+=         npf_processor.c npf_ruleset.c npf_rproc.c npf_sendpkt.c
 SRCS+=         npf_session.c npf_state.c npf_state_tcp.c
-SRCS+=         npf_tableset.c npf_tableset_ptree.c
+SRCS+=         npf_tableset.c npf_tableset_ptree.c npf_worker.c
 
 CPPFLAGS+=     -DINET6
 
diff -r dbbda348ab56 -r 517f73ffdb2c sys/net/npf/files.npf
--- a/sys/net/npf/files.npf     Sat Jun 01 21:21:36 2013 +0000
+++ b/sys/net/npf/files.npf     Sun Jun 02 02:20:04 2013 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.npf,v 1.12 2013/03/12 20:47:48 christos Exp $
+# $NetBSD: files.npf,v 1.13 2013/06/02 02:20:04 rmind Exp $
 #
 # Public Domain.
 #
@@ -28,6 +28,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_worker.c                    npf
 
 # Built-in extensions.
 file   net/npf/npf_ext_log.c                   npf
diff -r dbbda348ab56 -r 517f73ffdb2c sys/net/npf/npf.c
--- a/sys/net/npf/npf.c Sat Jun 01 21:21:36 2013 +0000
+++ b/sys/net/npf/npf.c Sun Jun 02 02:20:04 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.c,v 1.15 2013/02/09 03:35:31 rmind Exp $   */
+/*     $NetBSD: npf.c,v 1.16 2013/06/02 02:20:04 rmind Exp $   */
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.15 2013/02/09 03:35:31 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.16 2013/06/02 02:20:04 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -88,6 +88,7 @@
        npf_stats_percpu = percpu_alloc(NPF_STATS_SIZE);
        npf_sysctl = NULL;
 
+       npf_worker_sysinit();
        npf_tableset_sysinit();
        npf_session_sysinit();
        npf_nat_sysinit();
@@ -129,6 +130,9 @@
        npf_session_sysfini();
        npf_tableset_sysfini();
 
+       /* Note: worker is the last. */
+       npf_worker_sysfini();
+
        if (npf_sysctl) {
                sysctl_teardown(&npf_sysctl);
        }
diff -r dbbda348ab56 -r 517f73ffdb2c sys/net/npf/npf_alg.c
--- a/sys/net/npf/npf_alg.c     Sat Jun 01 21:21:36 2013 +0000
+++ b/sys/net/npf/npf_alg.c     Sun Jun 02 02:20:04 2013 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: npf_alg.c,v 1.8 2013/03/20 00:29:47 christos Exp $     */
+/*     $NetBSD: npf_alg.c,v 1.9 2013/06/02 02:20:04 rmind Exp $        */
 
 /*-
- * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -30,11 +30,11 @@
  */
 
 /*
- * NPF interface for application level gateways (ALGs).
+ * NPF interface for the Application Level Gateways (ALGs).
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.8 2013/03/20 00:29:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.9 2013/06/02 02:20:04 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -47,67 +47,63 @@
 
 #include "npf_impl.h"
 
-/* NAT ALG structure for registration. */
+/*
+ * NAT ALG description structure.  For more compact use of cache,
+ * the functions are separated in their own arrays.  The number of
+ * ALGs is expected to be very small.
+ */
+
 struct npf_alg {
-       LIST_ENTRY(npf_alg)     na_entry;
-       const char *            na_name;
-       npf_alg_t *             na_bptr;
-       npf_alg_func_t          na_match_func;
-       npf_alg_func_t          na_tr_func;
-       npf_alg_sfunc_t         na_se_func;
+       const char *    na_name;
+       u_int           na_slot;
 };
 
-static LIST_HEAD(, npf_alg)    nat_alg_list    __cacheline_aligned;
-static kmutex_t                        nat_alg_lock    __cacheline_aligned;
-static pserialize_t            nat_alg_psz     __cacheline_aligned;
+#define        NPF_MAX_ALGS    8
+
+/* List of ALGs and the count. */
+static pserialize_t    alg_psz                 __cacheline_aligned;
+static npf_alg_t       alg_list[NPF_MAX_ALGS]  __read_mostly;
+static u_int           alg_count               __read_mostly;
+
+/* Session, matching and translation functions. */
+static npf_alg_sfunc_t alg_sfunc[NPF_MAX_ALGS] __read_mostly;
+static npf_alg_func_t  alg_mfunc[NPF_MAX_ALGS] __read_mostly;
+static npf_alg_func_t  alg_tfunc[NPF_MAX_ALGS] __read_mostly;
+
+static const char      alg_prefix[] = "npf_alg_";
+#define        NPF_EXT_PREFLEN (sizeof(alg_prefix) - 1)
 
 void
 npf_alg_sysinit(void)
 {
+       alg_psz = pserialize_create();
+       memset(&alg_list, 0, sizeof(alg_list));
+       alg_count = 0;
 
-       mutex_init(&nat_alg_lock, MUTEX_DEFAULT, IPL_NONE);
-       nat_alg_psz = pserialize_create();
-       LIST_INIT(&nat_alg_list);
+       memset(&alg_mfunc, 0, sizeof(alg_mfunc));
+       memset(&alg_tfunc, 0, sizeof(alg_tfunc));
+       memset(&alg_sfunc, 0, sizeof(alg_sfunc));
 }
 
 void
 npf_alg_sysfini(void)
 {
-
-       KASSERT(LIST_EMPTY(&nat_alg_list));
-       pserialize_destroy(nat_alg_psz);
-       mutex_destroy(&nat_alg_lock);
+       pserialize_destroy(alg_psz);
 }
 
-static const char npf_alg_prefix[] = "npf_alg_";
-#define NPF_EXT_PREFLEN (sizeof(npf_alg_prefix) - 1)
-
 static npf_alg_t *
-npf_alg_lookup(const char *name, bool autoload)
+npf_alg_lookup(const char *name)
 {
-       npf_alg_t *alg;
-       char modname[64 + NPF_EXT_PREFLEN];
-       int error;
-
-       KASSERT(mutex_owned(&nat_alg_lock));
-
-again:
-       LIST_FOREACH(alg, &nat_alg_list, na_entry)
-               if (strcmp(alg->na_name, name) == 0)
-                       break;
+       KASSERT(npf_config_locked_p());
 
-       if (alg != NULL || !autoload)
-               return alg;
+       for (u_int i = 0; i < alg_count; i++) {
+               npf_alg_t *alg = &alg_list[i];
+               const char *aname = alg->na_name;
 
-       mutex_exit(&nat_alg_lock);
-       autoload = false;
-       snprintf(modname, sizeof(modname), "%s%s", npf_alg_prefix, name);
-       error = module_autoload(modname, MODULE_CLASS_MISC);
-       mutex_enter(&nat_alg_lock);
-
-       if (error)
-               return NULL;
-       goto again;
+               if (aname && strcmp(aname, name) == 0)
+                       return alg;
+       }
+       return NULL;
 }
 
 npf_alg_t *
@@ -115,9 +111,19 @@
 {
        npf_alg_t *alg;
 
-       mutex_enter(&nat_alg_lock);
-       alg = npf_alg_lookup(name, true);
-       mutex_exit(&nat_alg_lock);
+       npf_config_enter();
+       if ((alg = npf_alg_lookup(name)) == NULL) {
+               char modname[NPF_EXT_PREFLEN + 64];
+               snprintf(modname, sizeof(modname), "%s%s", alg_prefix, name);
+               npf_config_exit();
+
+               if (module_autoload(modname, MODULE_CLASS_MISC) != 0) {
+                       return NULL;
+               }
+               npf_config_enter();
+               alg = npf_alg_lookup(name);
+       }
+       npf_config_exit();
        return alg;
 }
 
@@ -129,23 +135,37 @@
     npf_alg_sfunc_t sfunc)
 {
        npf_alg_t *alg;
+       u_int i;
 
-       alg = kmem_zalloc(sizeof(npf_alg_t), KM_SLEEP);
-       alg->na_name = name;
-       alg->na_bptr = alg;
-       alg->na_match_func = mfunc;
-       alg->na_tr_func = tfunc;
-       alg->na_se_func = sfunc;
-
-       mutex_enter(&nat_alg_lock);
-       if (npf_alg_lookup(name, false) != NULL) {
-               mutex_exit(&nat_alg_lock);
-               kmem_free(alg, sizeof(npf_alg_t));
+       npf_config_enter();
+       if (npf_alg_lookup(name) != NULL) {
+               npf_config_exit();
                return NULL;
        }
-       LIST_INSERT_HEAD(&nat_alg_list, alg, na_entry);
-       mutex_exit(&nat_alg_lock);
 
+       /* Find a spare slot. */
+       for (i = 0; i < NPF_MAX_ALGS; i++) {
+               alg = &alg_list[i];
+               if (alg->na_name == NULL) {
+                       break;
+               }
+       }
+       if (i == NPF_MAX_ALGS) {
+               npf_config_exit();
+               return NULL;
+       }
+
+       /* Register the ALG. */
+       alg->na_name = name;
+       alg->na_slot = i;
+
+       /* Assign the functions. */
+       alg_mfunc[i] = mfunc;
+       alg_tfunc[i] = tfunc;
+       alg_sfunc[i] = sfunc;
+
+       alg_count = MAX(alg_count, i + 1);
+       npf_config_exit();
        return alg;
 }
 
@@ -155,16 +175,20 @@
 int
 npf_alg_unregister(npf_alg_t *alg)
 {
-       mutex_enter(&nat_alg_lock);
-       LIST_REMOVE(alg, na_entry);
-       pserialize_perform(nat_alg_psz);
-       mutex_exit(&nat_alg_lock);
+       u_int i = alg->na_slot;
 
+       /* Deactivate the functions first. */
        npf_config_enter();
+       alg_mfunc[i] = NULL;
+       alg_tfunc[i] = NULL;
+       alg_sfunc[i] = NULL;
+       pserialize_perform(alg_psz);
+
+       /* Finally, unregister the ALG. */
        npf_ruleset_freealg(npf_config_natset(), alg);
+       alg->na_name = NULL;
        npf_config_exit();
 



Home | Main Index | Thread Index | Old Index