Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Nov 2016 15:37:13 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r308838 - projects/ipsec/sys/netipsec
Message-ID:  <201611191537.uAJFbDLI026649@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Sat Nov 19 15:37:12 2016
New Revision: 308838
URL: https://svnweb.freebsd.org/changeset/base/308838

Log:
  Change some IPsec structures.
  
  Change struct secashead. Replace chain LIST with TAILQ and add two new
  LIST entries. addrhash will be used for lookup in hash by secasindex.
  drainq will be used by flush callout.
  Remove savtree field. Instead two TAILQ will be used. One to keep LARVAL
  SAs, another to keep alive (MATURE and DYING) SAs. Also add refcnt field.
  
  Change struct secasvar. Use TAILQ instead of LIST to keep SAs in a chain.
  Add spihash field for lookups by SPI. drainq field will be used by flush
  callout. Replace CURRENT lifetime expiring counters with PCPU counters
  to avoid locking for updates.
  
  Add two hash entries to struct secacq.
  
  Get rid of tdb_ident and tdb_crypto structures. Instead add two new
  structures xform_history and xform_data.
  
  struct xform_history will be used to store in the mbuf tag information
  about used SA. It contains all needed info to check that INBOUND security
  policy was fully applied to decrypted packet. In case of SA bundle,
  resulting mbuf will have several mbuf tags with such structures.
  
  struct xform_data will be used by crypto callbacks to store and obtain
  needed information before and after crypto processing.
  
  Change prototype of xform output callback. Now it will take as arguments
  referenced security policy, referenced security association and current
  transform's index.

Modified:
  projects/ipsec/sys/netipsec/keydb.h
  projects/ipsec/sys/netipsec/xform.h

Modified: projects/ipsec/sys/netipsec/keydb.h
==============================================================================
--- projects/ipsec/sys/netipsec/keydb.h	Sat Nov 19 15:35:40 2016	(r308837)
+++ projects/ipsec/sys/netipsec/keydb.h	Sat Nov 19 15:37:12 2016	(r308838)
@@ -34,7 +34,7 @@
 #define _NETIPSEC_KEYDB_H_
 
 #ifdef _KERNEL
-
+#include <sys/counter.h>
 #include <netipsec/key_var.h>
 
 #ifndef _SOCKADDR_UNION_DEFINED
@@ -86,8 +86,11 @@ struct seclifetime {
 };
 
 /* Security Association Data Base */
+TAILQ_HEAD(secasvar_queue, secasvar);
 struct secashead {
-	LIST_ENTRY(secashead) chain;
+	TAILQ_ENTRY(secashead) chain;
+	LIST_ENTRY(secashead) addrhash;	/* hash by sproto+src+dst addresses */
+	LIST_ENTRY(secashead) drainq;	/* used ONLY by flush callout */
 
 	struct secasindex saidx;
 
@@ -95,10 +98,10 @@ struct secashead {
 	struct secident *identd;	/* destination identity */
 					/* XXX I don't know how to use them. */
 
-	u_int8_t state;			/* MATURE or DEAD. */
-	LIST_HEAD(_satree, secasvar) savtree[SADB_SASTATE_MAX+1];
-					/* SA chain */
-					/* The first of this list is newer SA */
+	volatile u_int refcnt;		/* reference count */
+	uint8_t state;			/* MATURE or DEAD. */
+	struct secasvar_queue savtree_alive;	/* MATURE and DYING SA */
+	struct secasvar_queue savtree_larval;	/* LARVAL SA */
 };
 
 struct xformsw;
@@ -106,39 +109,53 @@ struct enc_xform;
 struct auth_hash;
 struct comp_algo;
 
-/* Security Association */
+/*
+ * Security Association
+ *
+ * For INBOUND packets we do SA lookup using SPI, thus only SPIHASH is used.
+ * For OUTBOUND packets there may be several SA suitable for packet.
+ * We use key_preferred_oldsa variable to choose better SA. First of we do
+ * lookup for suitable SAH using packet's saidx. Then we use SAH's savtree
+ * to search better candidate. The newer SA (by created time) are placed
+ * in the beginning of the savtree list. There is no preference between
+ * DYING and MATURE.
+ */
 struct secasvar {
-	LIST_ENTRY(secasvar) chain;
-	struct mtx lock;		/* update/access lock */
+	TAILQ_ENTRY(secasvar) chain;
+	LIST_ENTRY(secasvar) spihash;
+	LIST_ENTRY(secasvar) drainq;	/* used ONLY by flush callout */
+
+	uint32_t spi;			/* SPI Value, network byte order */
+	uint32_t flags;			/* holder for SADB_KEY_FLAGS */
 
-	u_int refcnt;			/* reference count */
-	u_int8_t state;			/* Status of this Association */
+	uint32_t seq;			/* sequence number */
+	pid_t pid;			/* message's pid */
+
+	uint8_t state;			/* Status of this SA (pfkeyv2.h) */
+	uint8_t alg_auth;		/* Authentication Algorithm Identifier*/
+	uint8_t alg_enc;		/* Cipher Algorithm Identifier */
+	uint8_t alg_comp;		/* Compression Algorithm Identifier */
 
-	u_int8_t alg_auth;		/* Authentication Algorithm Identifier*/
-	u_int8_t alg_enc;		/* Cipher Algorithm Identifier */
-	u_int8_t alg_comp;		/* Compression Algorithm Identifier */
-	u_int32_t spi;			/* SPI Value, network byte order */
-	u_int32_t flags;		/* holder for SADB_KEY_FLAGS */
+	uint16_t natt_type;		/* IKE/ESP-marker in output. */
+	uint16_t natt_esp_frag_len;	/* MTU for payload fragmentation. */
 
+	struct secashead *sah;		/* back pointer to the secashead */
 	struct seckey *key_auth;	/* Key for Authentication */
 	struct seckey *key_enc;	        /* Key for Encryption */
-	u_int ivlen;			/* length of IV */
-	void *sched;			/* intermediate encryption key */
-	size_t schedlen;
+	struct secreplay *replay;	/* replay prevention */
 	uint64_t cntr;			/* counter for GCM and CTR */
+	u_int ivlen;			/* length of IV */
 
-	struct secreplay *replay;	/* replay prevention */
-	time_t created;			/* for lifetime */
+	volatile u_int refcnt;		/* reference count */
 
-	struct seclifetime *lft_c;	/* CURRENT lifetime, it's constant. */
+	uint64_t created;		/* time when SA was created */
+	uint64_t firstused;		/* time when SA was first used */
+	counter_u64_t lft_c;		/* CURRENT lifetime */
+#define	lft_c_allocations	lft_c
+#define	lft_c_bytes		lft_c + 1
 	struct seclifetime *lft_h;	/* HARD lifetime */
 	struct seclifetime *lft_s;	/* SOFT lifetime */
 
-	u_int32_t seq;			/* sequence number */
-	pid_t pid;			/* message's pid */
-
-	struct secashead *sah;		/* back pointer to the secashead */
-
 	/*
 	 * NB: Fields with a tdb_ prefix are part of the "glue" used
 	 *     to interface to the OpenBSD crypto support.  This was done
@@ -148,13 +165,9 @@ struct secasvar {
 	struct enc_xform *tdb_encalgxform;	/* encoding algorithm */
 	struct auth_hash *tdb_authalgxform;	/* authentication algorithm */
 	struct comp_algo *tdb_compalgxform;	/* compression algorithm */
-	u_int64_t tdb_cryptoid;		/* crypto session id */
+	uint64_t tdb_cryptoid;		/* crypto session id */
 
-	/*
-	 * NAT-Traversal.
-	 */
-	u_int16_t natt_type;		/* IKE/ESP-marker in output. */
-	u_int16_t natt_esp_frag_len;	/* MTU for payload fragmentation. */
+	struct mtx lock;		/* update/access lock */
 };
 
 #define	SECASVAR_LOCK_INIT(_sav) \
@@ -190,10 +203,11 @@ struct secreg {
 /* acquiring list table. */
 struct secacq {
 	LIST_ENTRY(secacq) chain;
+	LIST_ENTRY(secacq) addrhash;
+	LIST_ENTRY(secacq) seqhash;
 
 	struct secasindex saidx;
-
-	u_int32_t seq;		/* sequence number */
+	uint32_t seq;		/* sequence number */
 	time_t created;		/* for lifetime */
 	int count;		/* for lifetime */
 };

Modified: projects/ipsec/sys/netipsec/xform.h
==============================================================================
--- projects/ipsec/sys/netipsec/xform.h	Sat Nov 19 15:35:40 2016	(r308837)
+++ projects/ipsec/sys/netipsec/xform.h	Sat Nov 19 15:37:12 2016	(r308838)
@@ -49,38 +49,33 @@
 #define	AH_HMAC_MAXHASHLEN	(SHA2_512_HASH_LEN/2)	/* Keep this updated */
 #define	AH_HMAC_INITIAL_RPL	1	/* replay counter initial value */
 
+struct secpolicy;
+struct secasvar;
+
 /*
  * Packet tag assigned on completion of IPsec processing; used
- * to speedup processing when/if the packet comes back for more
- * processing.
+ * to speedup security policy checking for INBOUND packets.
  */
-struct tdb_ident {
-	u_int32_t spi;
-	union sockaddr_union dst;
-	u_int8_t proto;
-	/* Cache those two for enc(4) in xform_ipip. */
-	u_int8_t alg_auth;
-	u_int8_t alg_enc;
+struct xform_history {
+	union sockaddr_union	dst;		/* destination address */
+	uint32_t		spi;		/* Security Parameters Index */
+	uint8_t			proto;		/* IPPROTO_ESP or IPPROTO_AH */
+	uint8_t			mode;		/* transport or tunnel */
 };
 
 /*
  * Opaque data structure hung off a crypto operation descriptor.
  */
-struct tdb_crypto {
-	struct ipsecrequest	*tc_isr;	/* ipsec request state */
-	u_int32_t		tc_spi;		/* associated SPI */
-	union sockaddr_union	tc_dst;		/* dst addr of packet */
-	u_int8_t		tc_proto;	/* current protocol, e.g. AH */
-	u_int8_t		tc_nxt;		/* next protocol, e.g. IPV4 */
-	int			tc_protoff;	/* current protocol offset */
-	int			tc_skip;	/* data offset */
-	caddr_t			tc_ptr;		/* associated crypto data */
-	struct secasvar 	*tc_sav;	/* related SA */
+struct xform_data {
+	struct secpolicy	*sp;		/* security policy */
+	struct secasvar		*sav;		/* related SA */
+	uint64_t		cryptoid;	/* used crypto session id */
+	u_int			idx;		/* IPsec request index */
+	int			protoff;	/* current protocol offset */
+	int			skip;		/* data offset */
+	uint8_t			nxt;		/* next protocol, e.g. IPV4 */
 };
 
-struct secasvar;
-struct ipescrequest;
-
 struct xformsw {
 	u_short	xf_type;		/* xform ID */
 #define	XF_IP4		1	/* unused */
@@ -97,8 +92,8 @@ struct xformsw {
 	int	(*xf_zeroize)(struct secasvar*);		/* cleanup */
 	int	(*xf_input)(struct mbuf*, struct secasvar*,	/* input */
 			int, int);
-	int	(*xf_output)(struct mbuf*,	       		/* output */
-			struct ipsecrequest *, struct mbuf **, int, int);
+	int	(*xf_output)(struct mbuf*,			/* output */
+	    struct secpolicy *, struct secasvar *, u_int, int, int);
 	struct xformsw *xf_next;		/* list of registered xforms */
 };
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611191537.uAJFbDLI026649>