Source-Changes-HG archive

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

[src/netbsd-7]: src Pull up following revision(s) (requested by rmind in tick...



details:   https://anonhg.NetBSD.org/src/rev/441fc61d373b
branches:  netbsd-7
changeset: 798947:441fc61d373b
user:      snj <snj%NetBSD.org@localhost>
date:      Wed Feb 04 07:13:04 2015 +0000

description:
Pull up following revision(s) (requested by rmind in ticket #479):
        lib/libnpf/npf.c: revision 1.35
        lib/libnpf/npf.h: revision 1.28
        sys/net/npf/npf_conn.c: revision 1.15
        sys/net/npf/npf_impl.h: revision 1.61
        sys/net/npf/npf_ruleset.c: revision 1.41
        usr.sbin/npf/npfctl/npf.conf.5: revision 1.44
        usr.sbin/npf/npfctl/npf_parse.y: revision 1.37
        usr.sbin/npf/npfctl/npf_show.c: revisions 1.16, 1.17
        usr.sbin/npf/npfctl/npfctl.c: revision 1.46
load the config file before bpfjit so that we can disable the warning.
--
Don't depend on yacc to include stdlib.h or string.h.
--
- npf_conn_establish: remove a rare race condition when we might destroy a
  connection when it is still referenced by another thread.
- npf_conn_destroy: remove the backwards entry using the saved key, PR/49488.
- Sprinkle some asserts.
--
npf.conf(5): mention alg, include in the example, minor fix.
--
npfctl(8): report dynamic rule ID in a comment, print the case when libpcap
is used correctly.  Also, add npf_ruleset_dump() helper in the kernel.
--
libnpf: add npf_rule_getid() and npf_rule_getcode().
Missed in the previous commit.
--
npfctl_print_rule: print the ID in hex, not decimal.

diffstat:

 lib/libnpf/npf.c                |  27 +++++++++++++-
 lib/libnpf/npf.h                |   4 +-
 sys/net/npf/npf_conn.c          |  74 +++++++++++++++++++++++++++-------------
 sys/net/npf/npf_impl.h          |   3 +-
 sys/net/npf/npf_ruleset.c       |  28 +++++++++++++-
 usr.sbin/npf/npfctl/npf.conf.5  |  23 ++++++++----
 usr.sbin/npf/npfctl/npf_parse.y |   8 ++-
 usr.sbin/npf/npfctl/npf_show.c  |  34 +++++++++++++++---
 usr.sbin/npf/npfctl/npfctl.c    |   6 +-
 9 files changed, 154 insertions(+), 53 deletions(-)

diffs (truncated from 493 to 300 lines):

diff -r d291932cce4a -r 441fc61d373b lib/libnpf/npf.c
--- a/lib/libnpf/npf.c  Wed Feb 04 06:58:54 2015 +0000
+++ b/lib/libnpf/npf.c  Wed Feb 04 07:13:04 2015 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: npf.c,v 1.32.2.1 2014/08/29 11:14:14 martin Exp $      */
+/*     $NetBSD: npf.c,v 1.32.2.2 2015/02/04 07:13:04 snj Exp $ */
 
 /*-
- * Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010-2015 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.32.2.1 2014/08/29 11:14:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.32.2.2 2015/02/04 07:13:04 snj Exp $");
 
 #include <sys/types.h>
 #include <netinet/in_systm.h>
@@ -715,6 +715,27 @@
        return rpname;
 }
 
+uint64_t
+npf_rule_getid(nl_rule_t *rl)
+{
+       prop_dictionary_t rldict = rl->nrl_dict;
+       uint64_t id = 0;
+
+       (void)prop_dictionary_get_uint64(rldict, "id", &id);
+       return id;
+}
+
+const void *
+npf_rule_getcode(nl_rule_t *rl, int *type, size_t *len)
+{
+       prop_dictionary_t rldict = rl->nrl_dict;
+       prop_object_t obj = prop_dictionary_get(rldict, "code");
+
+       prop_dictionary_get_uint32(rldict, "code-type", (uint32_t *)type);
+       *len = prop_data_size(obj);
+       return prop_data_data_nocopy(obj);
+}
+
 int
 _npf_ruleset_list(int fd, const char *rname, nl_config_t *ncf)
 {
diff -r d291932cce4a -r 441fc61d373b lib/libnpf/npf.h
--- a/lib/libnpf/npf.h  Wed Feb 04 06:58:54 2015 +0000
+++ b/lib/libnpf/npf.h  Wed Feb 04 07:13:04 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.h,v 1.27 2014/07/23 01:25:34 rmind Exp $   */
+/*     $NetBSD: npf.h,v 1.27.2.1 2015/02/04 07:13:04 snj Exp $ */
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -129,6 +129,8 @@
 const char *   npf_rule_getinterface(nl_rule_t *);
 const void *   npf_rule_getinfo(nl_rule_t *, size_t *);
 const char *   npf_rule_getproc(nl_rule_t *);
+uint64_t       npf_rule_getid(nl_rule_t *);
+const void *   npf_rule_getcode(nl_rule_t *, int *, size_t *);
 
 nl_table_t *   npf_table_iterate(nl_config_t *);
 const char *   npf_table_getname(nl_table_t *);
diff -r d291932cce4a -r 441fc61d373b sys/net/npf/npf_conn.c
--- a/sys/net/npf/npf_conn.c    Wed Feb 04 06:58:54 2015 +0000
+++ b/sys/net/npf/npf_conn.c    Wed Feb 04 07:13:04 2015 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: npf_conn.c,v 1.10.2.3 2014/12/22 02:10:30 msaitoh Exp $        */
+/*     $NetBSD: npf_conn.c,v 1.10.2.4 2015/02/04 07:13:04 snj Exp $    */
 
 /*-
- * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
+ * Copyright (c) 2014-2015 Mindaugas Rasiukevicius <rmind at netbsd org>
  * Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.10.2.3 2014/12/22 02:10:30 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.10.2.4 2015/02/04 07:13:04 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -369,7 +369,6 @@
        /* Check if connection is active and not expired. */
        flags = con->c_flags;
        ok = (flags & (CONN_ACTIVE | CONN_EXPIRE)) == CONN_ACTIVE;
-
        if (__predict_false(!ok)) {
                atomic_dec_uint(&con->c_refcnt);
                return NULL;
@@ -453,6 +452,7 @@
 {
        const nbuf_t *nbuf = npc->npc_nbuf;
        npf_conn_t *con;
+       int error = 0;
 
        KASSERT(!nbuf_flag_p(nbuf, NBUF_DATAREF_RESET));
 
@@ -468,16 +468,16 @@
        NPF_PRINTF(("NPF: create conn %p\n", con));
        npf_stats_inc(NPF_STAT_CONN_CREATE);
 
-       /* Reference count and flags (indicate direction). */
        mutex_init(&con->c_lock, MUTEX_DEFAULT, IPL_SOFTNET);
        con->c_flags = (di & PFIL_ALL);
-       con->c_refcnt = 1;
+       con->c_refcnt = 0;
        con->c_rproc = NULL;
        con->c_nat = NULL;
 
-       /* Initialize protocol state. */
+       /* Initialize the protocol state. */
        if (!npf_state_init(npc, &con->c_state)) {
-               goto err;
+               npf_conn_destroy(con);
+               return NULL;
        }
 
        KASSERT(npf_iscached(npc, NPC_IP46));
@@ -488,45 +488,65 @@
         * Construct "forwards" and "backwards" keys.  Also, set the
         * interface ID for this connection (unless it is global).
         */
-       if (!npf_conn_conkey(npc, fw, true)) {
-               goto err;
-       }
-       if (!npf_conn_conkey(npc, bk, false)) {
-               goto err;
+       if (!npf_conn_conkey(npc, fw, true) ||
+           !npf_conn_conkey(npc, bk, false)) {
+               npf_conn_destroy(con);
+               return NULL;
        }
        fw->ck_backptr = bk->ck_backptr = con;
        con->c_ifid = per_if ? nbuf->nb_ifid : 0;
        con->c_proto = npc->npc_proto;
 
-       /* Set last activity time for a new connection. */
+       /*
+        * Set last activity time for a new connection and acquire
+        * a reference for the caller before we make it visible.
+        */
        getnanouptime(&con->c_atime);
+       con->c_refcnt = 1;
 
        /*
         * Insert both keys (entries representing directions) of the
-        * connection.  At this point, it becomes visible.
+        * connection.  At this point it becomes visible, but we activate
+        * the connection later.
         */
+       mutex_enter(&con->c_lock);
        if (!npf_conndb_insert(conn_db, fw, con)) {
+               error = EISCONN;
                goto err;
        }
        if (!npf_conndb_insert(conn_db, bk, con)) {
-               /* We have hit the duplicate. */
-               npf_conndb_remove(conn_db, fw);
+               npf_conn_t *ret __diagused;
+               ret = npf_conndb_remove(conn_db, fw);
+               KASSERT(ret == con);
+               error = EISCONN;
+               goto err;
+       }
+err:
+       /*
+        * If we have hit the duplicate: mark the connection as expired
+        * and let the G/C thread to take care of it.  We cannot do it
+        * here since there might be references acquired already.
+        */
+       if (error) {
+               const u_int dflags = CONN_REMOVED | CONN_EXPIRE;
+               atomic_or_uint(&con->c_flags, dflags);
                npf_stats_inc(NPF_STAT_RACE_CONN);
-               goto err;
+       } else {
+               NPF_PRINTF(("NPF: establish conn %p\n", con));
        }
 
        /* Finally, insert into the connection list. */
-       NPF_PRINTF(("NPF: establish conn %p\n", con));
        npf_conndb_enqueue(conn_db, con);
-       return con;
-err:
-       npf_conn_destroy(con);
-       return NULL;
+       mutex_exit(&con->c_lock);
+
+       return error ? NULL : con;
 }
 
 static void
 npf_conn_destroy(npf_conn_t *con)
 {
+       KASSERT(con->c_refcnt == 0);
+
        if (con->c_nat) {
                /* Release any NAT structures. */
                npf_nat_destroy(con->c_nat);
@@ -582,6 +602,8 @@
                mutex_exit(&con->c_lock);
                return EINVAL;
        }
+       KASSERT((con->c_flags & CONN_REMOVED) == 0);
+
        if (__predict_false(con->c_nat != NULL)) {
                /* Race with a duplicate packet. */
                mutex_exit(&con->c_lock);
@@ -590,7 +612,7 @@
        }
 
        /* Remove the "backwards" entry. */
-       ret = npf_conndb_remove(conn_db, &key);
+       ret = npf_conndb_remove(conn_db, &con->c_back_entry);
        KASSERT(ret == con);
 
        /* Set the source/destination IDs to the translation values. */
@@ -606,7 +628,9 @@
                 * Race: we have hit the duplicate, remove the "forwards"
                 * entry and expire our connection; it is no longer valid.
                 */
-               (void)npf_conndb_remove(conn_db, &con->c_forw_entry);
+               ret = npf_conndb_remove(conn_db, &con->c_forw_entry);
+               KASSERT(ret == con);
+
                atomic_or_uint(&con->c_flags, CONN_REMOVED | CONN_EXPIRE);
                mutex_exit(&con->c_lock);
 
diff -r d291932cce4a -r 441fc61d373b sys/net/npf/npf_impl.h
--- a/sys/net/npf/npf_impl.h    Wed Feb 04 06:58:54 2015 +0000
+++ b/sys/net/npf/npf_impl.h    Wed Feb 04 07:13:04 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_impl.h,v 1.58.2.2 2014/12/01 13:05:26 martin Exp $ */
+/*     $NetBSD: npf_impl.h,v 1.58.2.3 2015/02/04 07:13:04 snj Exp $    */
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -344,6 +344,7 @@
 const char *   npf_addr_dump(const npf_addr_t *, int);
 void           npf_state_dump(const npf_state_t *);
 void           npf_nat_dump(const npf_nat_t *);
+void           npf_ruleset_dump(const char *);
 void           npf_state_setsampler(void (*)(npf_state_t *, bool));
 
 #endif /* _NPF_IMPL_H_ */
diff -r d291932cce4a -r 441fc61d373b sys/net/npf/npf_ruleset.c
--- a/sys/net/npf/npf_ruleset.c Wed Feb 04 06:58:54 2015 +0000
+++ b/sys/net/npf/npf_ruleset.c Wed Feb 04 07:13:04 2015 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: npf_ruleset.c,v 1.37.2.2 2014/12/01 13:05:26 martin Exp $      */
+/*     $NetBSD: npf_ruleset.c,v 1.37.2.3 2015/02/04 07:13:04 snj Exp $ */
 
 /*-
- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2015 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.37.2.2 2014/12/01 13:05:26 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.37.2.3 2015/02/04 07:13:04 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -936,3 +936,25 @@
        *retfl = rl->r_attr;
        return (rl->r_attr & NPF_RULE_PASS) ? 0 : ENETUNREACH;
 }
+
+
+#if defined(DDB) || defined(_NPF_TESTING)
+
+void
+npf_ruleset_dump(const char *name)
+{
+       npf_ruleset_t *rlset = npf_config_ruleset();
+       npf_rule_t *rg, *rl;
+
+       LIST_FOREACH(rg, &rlset->rs_dynamic, r_dentry) {
+               printf("ruleset '%s':\n", rg->r_name);
+               TAILQ_FOREACH(rl, &rg->r_subset, r_entry) {
+                       printf("\tid %"PRIu64", key: ", rl->r_id);
+                       for (u_int i = 0; i < NPF_RULE_MAXKEYLEN; i++)
+                               printf("%x", rl->r_key[i]);
+                       printf("\n");
+               }
+       }
+}



Home | Main Index | Thread Index | Old Index