svn commit: r308838 - projects/ipsec/sys/netipsec
Andrey V. Elsukov
ae at FreeBSD.org
Sat Nov 19 15:37:14 UTC 2016
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 */
};
More information about the svn-src-projects
mailing list