Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src Pull up following revision(s) (requested by rmind in tick...
details: https://anonhg.NetBSD.org/src/rev/14286488da15
branches: netbsd-9
changeset: 933478:14286488da15
user: martin <martin%NetBSD.org@localhost>
date: Mon May 25 17:25:28 2020 +0000
description:
Pull up following revision(s) (requested by rmind in ticket #930):
usr.sbin/npf/npfctl/npf_build.c: revision 1.54
sys/net/npf/npf_conn.h: revision 1.19
usr.sbin/npf/npfctl/npfctl.h: revision 1.52
usr.sbin/npf/npfctl/npf_show.c: revision 1.31
sys/net/npf/npf_conf.c: revision 1.16
sys/net/npf/npf_nat.c: revision 1.49
sys/net/npf/npf_inet.c: revision 1.56
sys/net/npf/npf_conndb.c: revision 1.8
sys/net/npf/npf_conn.c: revision 1.31
Backport selected NPF fixes from the upstream (to be pulled up):
- npf_conndb_lookup: protect the connection lookup with pserialize(9),
instead of incorrectly assuming that the handler always runs at IPL_SOFNET.
Should fix crashes reported on high load (PR/55182).
- npf_config_destroy: handle partially initialized config; fixes crashes
with some invalid configurations.
- NAT policy creation / destruction: set the initial reference and do not
wait for reference draining on destruction; destroy the policy on the
last reference drop instead. Fixes a lockup with the dynamic NAT rules.
- npf_nat_{export,import}: fix a regression since dynamic NAT rules.
- npfctl: fix a regression and restore the default group behaviour.
- Add npf_cache_tcp() and validate the TCP data offset (from maxv@).
diffstat:
sys/net/npf/npf_conf.c | 18 +++++--
sys/net/npf/npf_conn.c | 6 +-
sys/net/npf/npf_conn.h | 2 +-
sys/net/npf/npf_conndb.c | 8 ++-
sys/net/npf/npf_inet.c | 22 +++++++-
sys/net/npf/npf_nat.c | 93 ++++++++++++++++++++++++++++------------
usr.sbin/npf/npfctl/npf_build.c | 48 +++++++++++++++++---
usr.sbin/npf/npfctl/npf_show.c | 4 +-
usr.sbin/npf/npfctl/npfctl.h | 1 +
9 files changed, 149 insertions(+), 53 deletions(-)
diffs (truncated from 506 to 300 lines):
diff -r 936a2e1b8be5 -r 14286488da15 sys/net/npf/npf_conf.c
--- a/sys/net/npf/npf_conf.c Mon May 25 17:19:37 2020 +0000
+++ b/sys/net/npf/npf_conf.c Mon May 25 17:25:28 2020 +0000
@@ -47,7 +47,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.13.2.2 2019/09/01 13:21:39 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conf.c,v 1.13.2.3 2020/05/25 17:25:28 martin Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -94,10 +94,18 @@
* Note: the rulesets must be destroyed first, in order to drop
* any references to the tableset.
*/
- npf_ruleset_destroy(nc->ruleset);
- npf_ruleset_destroy(nc->nat_ruleset);
- npf_rprocset_destroy(nc->rule_procs);
- npf_tableset_destroy(nc->tableset);
+ if (nc->ruleset) {
+ npf_ruleset_destroy(nc->ruleset);
+ }
+ if (nc->nat_ruleset) {
+ npf_ruleset_destroy(nc->nat_ruleset);
+ }
+ if (nc->rule_procs) {
+ npf_rprocset_destroy(nc->rule_procs);
+ }
+ if (nc->tableset) {
+ npf_tableset_destroy(nc->tableset);
+ }
kmem_free(nc, sizeof(npf_config_t));
}
diff -r 936a2e1b8be5 -r 14286488da15 sys/net/npf/npf_conn.c
--- a/sys/net/npf/npf_conn.c Mon May 25 17:19:37 2020 +0000
+++ b/sys/net/npf/npf_conn.c Mon May 25 17:25:28 2020 +0000
@@ -107,7 +107,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.27.2.2 2019/10/04 08:06:35 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.27.2.3 2020/05/25 17:25:28 martin Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -311,7 +311,7 @@
if (!npf_conn_conkey(npc, &key, true)) {
return NULL;
}
- con = npf_conndb_lookup(npf->conn_db, &key, forw);
+ con = npf_conndb_lookup(npf, &key, forw);
if (con == NULL) {
return NULL;
}
@@ -908,7 +908,7 @@
if (!kdict || !npf_connkey_import(kdict, &key)) {
return EINVAL;
}
- con = npf_conndb_lookup(npf->conn_db, &key, &forw);
+ con = npf_conndb_lookup(npf, &key, &forw);
if (con == NULL) {
return ESRCH;
}
diff -r 936a2e1b8be5 -r 14286488da15 sys/net/npf/npf_conn.h
--- a/sys/net/npf/npf_conn.h Mon May 25 17:19:37 2020 +0000
+++ b/sys/net/npf/npf_conn.h Mon May 25 17:25:28 2020 +0000
@@ -157,7 +157,7 @@
npf_conndb_t * npf_conndb_create(void);
void npf_conndb_destroy(npf_conndb_t *);
-npf_conn_t * npf_conndb_lookup(npf_conndb_t *, const npf_connkey_t *, bool *);
+npf_conn_t * npf_conndb_lookup(npf_t *, const npf_connkey_t *, bool *);
bool npf_conndb_insert(npf_conndb_t *, const npf_connkey_t *,
npf_conn_t *, bool);
npf_conn_t * npf_conndb_remove(npf_conndb_t *, npf_connkey_t *);
diff -r 936a2e1b8be5 -r 14286488da15 sys/net/npf/npf_conndb.c
--- a/sys/net/npf/npf_conndb.c Mon May 25 17:19:37 2020 +0000
+++ b/sys/net/npf/npf_conndb.c Mon May 25 17:25:28 2020 +0000
@@ -46,7 +46,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conndb.c,v 1.6 2019/07/23 00:52:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conndb.c,v 1.6.2.1 2020/05/25 17:25:28 martin Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -143,8 +143,9 @@
* npf_conndb_lookup: find a connection given the key.
*/
npf_conn_t *
-npf_conndb_lookup(npf_conndb_t *cd, const npf_connkey_t *ck, bool *forw)
+npf_conndb_lookup(npf_t *npf, const npf_connkey_t *ck, bool *forw)
{
+ npf_conndb_t *cd = atomic_load_relaxed(&npf->conn_db);
const unsigned keylen = NPF_CONNKEY_LEN(ck);
npf_conn_t *con;
void *val;
@@ -152,8 +153,10 @@
/*
* Lookup the connection key in the key-value map.
*/
+ int s = npf_config_read_enter(npf);
val = thmap_get(cd->cd_map, ck->ck_key, keylen);
if (!val) {
+ npf_config_read_exit(npf, s);
return NULL;
}
@@ -169,6 +172,7 @@
* Acquire a reference and return the connection.
*/
atomic_inc_uint(&con->c_refcnt);
+ npf_config_read_exit(npf, s);
return con;
}
diff -r 936a2e1b8be5 -r 14286488da15 sys/net/npf/npf_inet.c
--- a/sys/net/npf/npf_inet.c Mon May 25 17:19:37 2020 +0000
+++ b/sys/net/npf/npf_inet.c Mon May 25 17:25:28 2020 +0000
@@ -38,7 +38,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.54.2.1 2019/08/13 14:35:55 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.54.2.2 2020/05/25 17:25:28 martin Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -562,6 +562,22 @@
return flags;
}
+static inline int
+npf_cache_tcp(npf_cache_t *npc, nbuf_t *nbuf, unsigned hlen)
+{
+ struct tcphdr *th;
+
+ th = nbuf_advance(nbuf, hlen, sizeof(struct tcphdr));
+ if (__predict_false(th == NULL)) {
+ return NPC_FMTERR;
+ }
+ if (__predict_false(th->th_off < 5)) {
+ return NPC_FMTERR;
+ }
+ npc->npc_l4.tcp = th;
+ return NPC_LAYER4 | NPC_TCP;
+}
+
/*
* npf_cache_all: general routine to cache all relevant IP (v4 or v6)
* and TCP, UDP or ICMP headers.
@@ -601,9 +617,7 @@
switch (npc->npc_proto) {
case IPPROTO_TCP:
/* Cache: layer 4 - TCP. */
- npc->npc_l4.tcp = nbuf_advance(nbuf, hlen,
- sizeof(struct tcphdr));
- l4flags = NPC_LAYER4 | NPC_TCP;
+ l4flags = npf_cache_tcp(npc, nbuf, hlen);
break;
case IPPROTO_UDP:
/* Cache: layer 4 - UDP. */
diff -r 936a2e1b8be5 -r 14286488da15 sys/net/npf/npf_nat.c
--- a/sys/net/npf/npf_nat.c Mon May 25 17:19:37 2020 +0000
+++ b/sys/net/npf/npf_nat.c Mon May 25 17:25:28 2020 +0000
@@ -67,7 +67,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.46.2.2 2019/09/01 13:21:39 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.46.2.3 2020/05/25 17:25:28 martin Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -182,6 +182,7 @@
size_t len;
np = kmem_zalloc(sizeof(npf_natpolicy_t), KM_SLEEP);
+ atomic_store_relaxed(&np->n_refcnt, 1);
np->n_npfctx = npf;
/* The translation type, flags and policy ID. */
@@ -271,37 +272,53 @@
return 0;
}
+static void
+npf_natpolicy_release(npf_natpolicy_t *np)
+{
+ KASSERT(atomic_load_relaxed(&np->n_refcnt) > 0);
+
+ if (atomic_dec_uint_nv(&np->n_refcnt) != 0) {
+ return;
+ }
+ KASSERT(LIST_EMPTY(&np->n_nat_list));
+ mutex_destroy(&np->n_lock);
+ kmem_free(np, sizeof(npf_natpolicy_t));
+}
+
/*
* npf_nat_freepolicy: free the NAT policy.
*
* => Called from npf_rule_free() during the reload via npf_ruleset_destroy().
+ * => At this point, NAT policy cannot acquire new references.
*/
void
npf_nat_freepolicy(npf_natpolicy_t *np)
{
- npf_conn_t *con;
- npf_nat_t *nt;
+ /*
+ * Drain the references. If there are active NAT connections,
+ * then expire them and kick the worker.
+ */
+ if (atomic_load_relaxed(&np->n_refcnt) > 1) {
+ npf_nat_t *nt;
- /*
- * Disassociate all entries from the policy. At this point,
- * new entries can no longer be created for this policy.
- */
- while (np->n_refcnt) {
mutex_enter(&np->n_lock);
LIST_FOREACH(nt, &np->n_nat_list, nt_entry) {
- con = nt->nt_conn;
+ npf_conn_t *con = nt->nt_conn;
KASSERT(con != NULL);
npf_conn_expire(con);
}
mutex_exit(&np->n_lock);
+ npf_worker_signal(np->n_npfctx);
+ }
+ KASSERT(atomic_load_relaxed(&np->n_refcnt) >= 1);
- /* Kick the worker - all references should be going away. */
- npf_worker_signal(np->n_npfctx);
- kpause("npfgcnat", false, 1, NULL);
- }
- KASSERT(LIST_EMPTY(&np->n_nat_list));
- mutex_destroy(&np->n_lock);
- kmem_free(np, sizeof(npf_natpolicy_t));
+ /*
+ * Drop the initial reference, but it might not be the last one.
+ * If so, the last reference will be triggered via:
+ *
+ * npf_conn_destroy() -> npf_nat_destroy() -> npf_natpolicy_release()
+ */
+ npf_natpolicy_release(np);
}
void
@@ -649,7 +666,7 @@
npf_recache(npc);
}
error = npf_nat_algo(npc, np, forw);
- atomic_dec_uint(&np->n_refcnt);
+ npf_natpolicy_release(np);
return error;
}
@@ -662,7 +679,7 @@
if (con == NULL) {
ncon = npf_conn_establish(npc, di, true);
if (ncon == NULL) {
- atomic_dec_uint(&np->n_refcnt);
+ npf_natpolicy_release(np);
return ENOMEM;
}
con = ncon;
@@ -674,7 +691,7 @@
*/
nt = npf_nat_create(npc, np, con);
if (nt == NULL) {
- atomic_dec_uint(&np->n_refcnt);
+ npf_natpolicy_release(np);
error = ENOMEM;
goto out;
}
@@ -757,11 +774,15 @@
}
npf_stats_inc(np->n_npfctx, NPF_STAT_NAT_DESTROY);
+ /*
+ * Remove the connection from the list and drop the reference on
+ * the NAT policy. Note: this might trigger its destruction.
+ */
mutex_enter(&np->n_lock);
LIST_REMOVE(nt, nt_entry);
- KASSERT(np->n_refcnt > 0);
- atomic_dec_uint(&np->n_refcnt);
mutex_exit(&np->n_lock);
+ npf_natpolicy_release(np);
+
pool_cache_put(nat_cache, nt);
}
@@ -772,10 +793,13 @@
Home |
Main Index |
Thread Index |
Old Index