Module Name:    src
Committed By:   christos
Date:           Sat Dec 10 19:05:46 UTC 2016

Modified Files:
        src/sys/net/npf: npf.h npf_conn.c npf_conn.h

Log Message:
Welcome to version 18:
- Connection state keys are not stored and loaded using the logical key
  contents.
- connection finder key is stored in a map that contains the key and the
  direction.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/net/npf/npf.h
cvs rdiff -u -r1.19 -r1.20 src/sys/net/npf/npf_conn.c
cvs rdiff -u -r1.9 -r1.10 src/sys/net/npf/npf_conn.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/npf/npf.h
diff -u src/sys/net/npf/npf.h:1.50 src/sys/net/npf/npf.h:1.51
--- src/sys/net/npf/npf.h:1.50	Sat Dec 10 00:41:10 2016
+++ src/sys/net/npf/npf.h	Sat Dec 10 14:05:45 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.50 2016/12/10 05:41:10 christos Exp $	*/
+/*	$NetBSD: npf.h,v 1.51 2016/12/10 19:05:45 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 
-#define	NPF_VERSION		17
+#define	NPF_VERSION		18
 
 /*
  * Public declarations and definitions.

Index: src/sys/net/npf/npf_conn.c
diff -u src/sys/net/npf/npf_conn.c:1.19 src/sys/net/npf/npf_conn.c:1.20
--- src/sys/net/npf/npf_conn.c:1.19	Sat Dec 10 04:26:16 2016
+++ src/sys/net/npf/npf_conn.c	Sat Dec 10 14:05:45 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.c,v 1.19 2016/12/10 09:26:16 kre Exp $	*/
+/*	$NetBSD: npf_conn.c,v 1.20 2016/12/10 19:05:45 christos Exp $	*/
 
 /*-
  * Copyright (c) 2014-2015 Mindaugas Rasiukevicius <rmind at netbsd org>
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.19 2016/12/10 09:26:16 kre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.20 2016/12/10 19:05:45 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -241,10 +241,10 @@ npf_conn_trackable_p(const npf_cache_t *
 }
 
 static uint32_t
-connkey_setkey(npf_connkey_t *key, uint32_t proto, const void *ipv,
-    uint16_t *id, size_t alen, bool forw)
+connkey_setkey(npf_connkey_t *key, uint16_t proto, const void *ipv,
+    const uint16_t *id, uint16_t alen, bool forw)
 {
-	uint32_t isrc, idst;
+	uint32_t isrc, idst, *k = key->ck_key;
 	const npf_addr_t * const *ips = ipv;
 	if (__predict_true(forw)) {
 		isrc = NPF_SRC, idst = NPF_DST;
@@ -264,21 +264,43 @@ connkey_setkey(npf_connkey_t *key, uint3
 	 * on the 'alen' field; it is a length in bytes, either 4 or 16.
 	 */
 
-	key->ck_key[0] = ((uint32_t)proto << 16) | (alen & 0xffff);
-	key->ck_key[1] = ((uint32_t)id[isrc] << 16) | id[idst];
+	k[0] = ((uint32_t)proto << 16) | (alen & 0xffff);
+	k[1] = ((uint32_t)id[isrc] << 16) | id[idst];
 
 	if (__predict_true(alen == sizeof(in_addr_t))) {
-		key->ck_key[2] = ips[isrc]->s6_addr32[0];
-		key->ck_key[3] = ips[idst]->s6_addr32[0];
+		k[2] = ips[isrc]->s6_addr32[0];
+		k[3] = ips[idst]->s6_addr32[0];
 		return 4 * sizeof(uint32_t);
 	} else {
 		const u_int nwords = alen >> 2;
-		memcpy(&key->ck_key[2], ips[isrc], alen);
-		memcpy(&key->ck_key[2 + nwords], ips[idst], alen);
+		memcpy(&k[2], ips[isrc], alen);
+		memcpy(&k[2 + nwords], ips[idst], alen);
 		return (2 + (nwords * 2)) * sizeof(uint32_t);
 	}
 }
 
+static void
+connkey_getkey(const npf_connkey_t *key, uint16_t *proto, npf_addr_t *ips,
+    uint16_t *id, uint16_t *alen)
+{
+	const uint32_t *k = key->ck_key;
+
+	*proto = k[0] >> 16;
+	*alen = k[0] & 0xffff;
+	id[NPF_SRC] = k[1] >> 16;
+	id[NPF_DST] = k[1] & 0xffff;
+
+	switch (*alen) {
+	case sizeof(struct in6_addr):
+	case sizeof(struct in_addr):
+		memcpy(&ips[NPF_SRC], &k[2], *alen);
+		memcpy(&ips[NPF_DST], &k[2 + ((unsigned)*alen >> 2)], *alen);
+		return;
+	default:
+		KASSERT(0);
+	}
+}
+
 /*
  * npf_conn_conkey: construct a key for the connection lookup.
  *
@@ -287,7 +309,7 @@ connkey_setkey(npf_connkey_t *key, uint3
 unsigned
 npf_conn_conkey(const npf_cache_t *npc, npf_connkey_t *key, const bool forw)
 {
-	const u_int alen = npc->npc_alen;
+	const uint16_t alen = npc->npc_alen;
 	const struct tcphdr *th;
 	const struct udphdr *uh;
 	uint16_t id[2];
@@ -902,13 +924,37 @@ npf_conndb_export(prop_array_t conlist)
 	return 0;
 }
 
+static prop_dictionary_t
+npf_connkey_export(const npf_connkey_t *key)
+{
+	uint16_t id[2], alen, proto;
+	npf_addr_t ips[2];
+	prop_data_t d;
+	prop_dictionary_t kdict = prop_dictionary_create();
+
+	connkey_getkey(key, &proto, ips, id, &alen);
+
+	prop_dictionary_set_uint16(kdict, "proto", proto);
+
+	prop_dictionary_set_uint16(kdict, "sport", id[NPF_SRC]);
+	prop_dictionary_set_uint16(kdict, "dport", id[NPF_DST]);
+
+	d = prop_data_create_data(&ips[NPF_SRC], alen);
+	prop_dictionary_set_and_rel(kdict, "saddr", d);
+
+	d = prop_data_create_data(&ips[NPF_DST], alen);
+	prop_dictionary_set_and_rel(kdict, "daddr", d);
+
+	return kdict;
+}
+
 /*
  * npf_conn_export: serialise a single connection.
  */
 prop_dictionary_t
 npf_conn_export(const npf_conn_t *con)
 {
-	prop_dictionary_t cdict;
+	prop_dictionary_t cdict, kdict;
 	prop_data_t d;
 
 	if ((con->c_flags & (CONN_ACTIVE|CONN_EXPIRE)) != CONN_ACTIVE) {
@@ -925,13 +971,11 @@ npf_conn_export(const npf_conn_t *con)
 	d = prop_data_create_data(&con->c_state, sizeof(npf_state_t));
 	prop_dictionary_set_and_rel(cdict, "state", d);
 
-	const uint32_t *fkey = con->c_forw_entry.ck_key;
-	d = prop_data_create_data(fkey, NPF_CONN_MAXKEYLEN);
-	prop_dictionary_set_and_rel(cdict, "forw-key", d);
+	kdict = npf_connkey_export(&con->c_forw_entry);
+	prop_dictionary_set_and_rel(cdict, "forw-key", kdict);
 
-	const uint32_t *bkey = con->c_back_entry.ck_key;
-	d = prop_data_create_data(bkey, NPF_CONN_MAXKEYLEN);
-	prop_dictionary_set_and_rel(cdict, "back-key", d);
+	kdict = npf_connkey_export(&con->c_back_entry);
+	prop_dictionary_set_and_rel(cdict, "back-key", kdict);
 
 	if (con->c_nat) {
 		npf_nat_export(cdict, con->c_nat);
@@ -940,67 +984,37 @@ npf_conn_export(const npf_conn_t *con)
 }
 
 static uint32_t
-npf_connkey_import(prop_dictionary_t idict, npf_connkey_t *key, uint16_t *dir)
+npf_connkey_import(prop_dictionary_t kdict, npf_connkey_t *key)
 {
 	uint16_t proto;
 	prop_object_t sobj, dobj;
 	uint16_t id[2];
 	npf_addr_t const * ips[2];
 
-	prop_dictionary_get_uint16(idict, "proto", &proto);
-	prop_dictionary_get_uint16(idict, "direction", dir);
+	if (!prop_dictionary_get_uint16(kdict, "proto", &proto))
+		return 0;
+
+	if (!prop_dictionary_get_uint16(kdict, "sport", &id[NPF_SRC]))
+		return 0;
 
-	prop_dictionary_get_uint16(idict, "sport", &id[NPF_SRC]);
-	prop_dictionary_get_uint16(idict, "dport", &id[NPF_DST]);
+	if (!prop_dictionary_get_uint16(kdict, "dport", &id[NPF_DST]))
+		return 0;
 
-	sobj = prop_dictionary_get(idict, "saddr");
+	sobj = prop_dictionary_get(kdict, "saddr");
 	if ((ips[NPF_SRC] = prop_data_data_nocopy(sobj)) == NULL)
 		return 0;
 
-	dobj = prop_dictionary_get(idict, "daddr");
+	dobj = prop_dictionary_get(kdict, "daddr");
 	if ((ips[NPF_DST] = prop_data_data_nocopy(dobj)) == NULL)
 		return 0;
 
-	size_t alen = prop_data_size(sobj);
+	uint16_t alen = prop_data_size(sobj);
 	if (alen != prop_data_size(dobj))
 		return 0;
 
 	return connkey_setkey(key, proto, ips, id, alen, true);
 }
 
-int
-npf_conn_find(prop_dictionary_t idict, prop_dictionary_t *odict)
-{
-	npf_connkey_t key;
-	npf_conn_t *con;
-	uint16_t dir;
-	bool forw;
-
-	if (!npf_connkey_import(idict, &key, &dir)) {
-		return EINVAL;
-	}
-
-	con = npf_conndb_lookup(conn_db, &key, &forw);
-	if (con == NULL) {
-		return ESRCH;
-	}
-
-	dir = dir == PFIL_IN ? PFIL_OUT : PFIL_IN;
-	if (!npf_conn_ok(con, dir, true)) {
-		atomic_dec_uint(&con->c_refcnt);
-		return ESRCH;
-	}
-
-	*odict = npf_conn_export(con);
-	if (*odict == NULL) {
-		atomic_dec_uint(&con->c_refcnt);
-		return ENOSPC;
-	}
-	atomic_dec_uint(&con->c_refcnt);
-
-	return 0;
-}
-
 /*
  * npf_conn_import: fully reconstruct a single connection from a
  * directory and insert into the given database.
@@ -1048,20 +1062,16 @@ npf_conn_import(npf_conndb_t *cd, prop_d
 	 * Fetch and copy the keys for each direction.
 	 */
 	obj = prop_dictionary_get(cdict, "forw-key");
-	if ((d = prop_data_data_nocopy(obj)) == NULL ||
-	    prop_data_size(obj) != NPF_CONN_MAXKEYLEN) {
+	fw = &con->c_forw_entry;
+	if (obj == NULL || !npf_connkey_import(obj, fw)) {
 		goto err;
 	}
-	fw = &con->c_forw_entry;
-	memcpy(&fw->ck_key, d, NPF_CONN_MAXKEYLEN);
 
 	obj = prop_dictionary_get(cdict, "back-key");
-	if ((d = prop_data_data_nocopy(obj)) == NULL ||
-	    prop_data_size(obj) != NPF_CONN_MAXKEYLEN) {
+	bk = &con->c_back_entry;
+	if (obj == NULL || !npf_connkey_import(obj, bk)) {
 		goto err;
 	}
-	bk = &con->c_back_entry;
-	memcpy(&bk->ck_key, d, NPF_CONN_MAXKEYLEN);
 
 	fw->ck_backptr = bk->ck_backptr = con;
 
@@ -1082,6 +1092,45 @@ err:
 	return EINVAL;
 }
 
+int
+npf_conn_find(prop_dictionary_t idict, prop_dictionary_t *odict)
+{
+	npf_connkey_t key;
+	npf_conn_t *con;
+	uint16_t dir;
+	bool forw;
+	prop_dictionary_t kdict;
+
+	if ((kdict = prop_dictionary_get(idict, "key")) == NULL)
+		return EINVAL;
+
+	if (!npf_connkey_import(kdict, &key))
+		return EINVAL;
+
+	if (!prop_dictionary_get_uint16(idict, "direction", &dir))
+		return EINVAL;
+
+	con = npf_conndb_lookup(conn_db, &key, &forw);
+	if (con == NULL) {
+		return ESRCH;
+	}
+
+	dir = dir == PFIL_IN ? PFIL_OUT : PFIL_IN;
+	if (!npf_conn_ok(con, dir, true)) {
+		atomic_dec_uint(&con->c_refcnt);
+		return ESRCH;
+	}
+
+	*odict = npf_conn_export(con);
+	if (*odict == NULL) {
+		atomic_dec_uint(&con->c_refcnt);
+		return ENOSPC;
+	}
+	atomic_dec_uint(&con->c_refcnt);
+
+	return 0;
+}
+
 #if defined(DDB) || defined(_NPF_TESTING)
 
 void

Index: src/sys/net/npf/npf_conn.h
diff -u src/sys/net/npf/npf_conn.h:1.9 src/sys/net/npf/npf_conn.h:1.10
--- src/sys/net/npf/npf_conn.h:1.9	Sat Dec 10 00:41:10 2016
+++ src/sys/net/npf/npf_conn.h	Sat Dec 10 14:05:45 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_conn.h,v 1.9 2016/12/10 05:41:10 christos Exp $	*/
+/*	$NetBSD: npf_conn.h,v 1.10 2016/12/10 19:05:45 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -50,7 +50,6 @@ typedef struct npf_connkey npf_connkey_t
  * See npf_conn_conkey() function for the key layout description.
  */
 #define	NPF_CONN_NKEYWORDS	(2 + ((sizeof(npf_addr_t) * 2) >> 2))
-#define	NPF_CONN_MAXKEYLEN	(NPF_CONN_NKEYWORDS * sizeof(uint32_t))
 #define	NPF_CONN_GETALEN(key)	((key)->ck_key[0] & 0xffff)
 #define	NPF_CONN_KEYLEN(key)	(8 + (2 * NPF_CONN_GETALEN(key)))
 

Reply via email to