svn commit: r308831 - projects/ipsec/sys/netipsec
Andrey V. Elsukov
ae at FreeBSD.org
Sat Nov 19 14:40:20 UTC 2016
Author: ae
Date: Sat Nov 19 14:40:18 2016
New Revision: 308831
URL: https://svnweb.freebsd.org/changeset/base/308831
Log:
Change some IPsec structures.
Change the fields order of struct secpolicyindex to match layout of
struct secasindex. Remove unused fields.
Change struct ipsecrequest. Remove most of fields and rwlock, keep
only secasindex selector and required level of IPsec transform.
Selector has src/dst addresses, security protocol (ESP/AH), IPsec
mode (transport/tunnel) and request id. This will help to go away
from nontrivial locking with IPSECREQUEST_LOCK().
Change struct secpolicy to keep ipsecrequests in the limited size
array of pointers and add tcount (transforms count) field to specify
number of transforms in the array. Limit maximum number of transforms
with IPSEC_MAXREQ macro (it is 4 for now).
Previously it was possible to specify unlimited number of IPsec
transforms that should be handled in a sequence (this also called
"SA bundle"). Actually such ability was not implemented in IPv6
code. Also modern IPsec RFC 4301 doesn't requires this support (p4.3).
From a practical point of view support too many ipsec request in a
chain also useless.
The main idea is that ipsecrequest just defines transforms that
we should do to conform to given security policy. Now we will not save
used by policy SA for each packet in the policy's ipsecrequest.
Instead we always will do new SA lookup and use the result as is.
Holding the IPSECREQUEST_LOCK probably had another purpose. TCP code
has used stored in ipsecrequest SA to determine the size consumed by
IPsec headers. We will use hdrsz field in struct inpcbpolicy for this
purpose.
Add two new LIST_ENTRY to struct secpolicy. idhash will be used
for fast SP lookup by id. drainq will be used by expiring code.
Introduce several new SP states:
* IPSEC_SPSTATE_LARVAL will be used by SP added by SADB_X_SPDSETIDX
message.
* IPSEC_SPSTATE_PCB will be used by SP added by setsockopt() call.
* IPSEC_SPSTATE_IFNET will be used by SP added by IPsec virtual
tunneling interface.
Change struct inpcbpolicy. Now sp_in/sp_out fields can be used by
kernel to cache security policies used by packets that have inpcb.
In case when application set own security policy or configured IPsec
bypass, flags field will have correspondig value.
genid field will be used to check that SP pointer isn't expired.
hdrsz field will be used by TCP code to determine size of headers
consumed by IPsec.
Modified:
projects/ipsec/sys/netipsec/ipsec.h
projects/ipsec/sys/netipsec/keydb.h
Modified: projects/ipsec/sys/netipsec/ipsec.h
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.h Sat Nov 19 13:57:21 2016 (r308830)
+++ projects/ipsec/sys/netipsec/ipsec.h Sat Nov 19 14:40:18 2016 (r308831)
@@ -65,35 +65,41 @@
* specifies ICMPv6 type, and the port field in "dst" specifies ICMPv6 code.
*/
struct secpolicyindex {
- u_int8_t dir; /* direction of packet flow, see below */
union sockaddr_union src; /* IP src address for SP */
union sockaddr_union dst; /* IP dst address for SP */
- u_int8_t prefs; /* prefix length in bits for src */
- u_int8_t prefd; /* prefix length in bits for dst */
- u_int16_t ul_proto; /* upper layer Protocol */
-#ifdef notyet
- uid_t uids;
- uid_t uidd;
- gid_t gids;
- gid_t gidd;
-#endif
+ uint8_t ul_proto; /* upper layer Protocol */
+ uint8_t dir; /* direction of packet flow */
+ uint8_t prefs; /* prefix length in bits for src */
+ uint8_t prefd; /* prefix length in bits for dst */
+};
+
+/* Request for IPsec */
+struct ipsecrequest {
+ struct secasindex saidx;/* hint for search proper SA */
+ /* if __ss_len == 0 then no address specified.*/
+ u_int level; /* IPsec level defined below. */
};
/* Security Policy Data Base */
struct secpolicy {
TAILQ_ENTRY(secpolicy) chain;
+ LIST_ENTRY(secpolicy) idhash;
+ LIST_ENTRY(secpolicy) drainq;
struct secpolicyindex spidx; /* selector */
- struct ipsecrequest *req;
- /* pointer to the ipsec request tree, */
- /* if policy == IPSEC else this value == NULL.*/
- u_int refcnt; /* reference count */
+#define IPSEC_MAXREQ 4
+ struct ipsecrequest *req[IPSEC_MAXREQ];
+ u_int tcount; /* IPsec transforms count */
+ volatile u_int refcnt; /* reference count */
u_int policy; /* policy_type per pfkeyv2.h */
u_int state;
#define IPSEC_SPSTATE_DEAD 0
-#define IPSEC_SPSTATE_ALIVE 1
- u_int32_t priority; /* priority of this policy */
- u_int32_t id; /* It's unique number on the system. */
+#define IPSEC_SPSTATE_LARVAL 1
+#define IPSEC_SPSTATE_ALIVE 2
+#define IPSEC_SPSTATE_PCB 3
+#define IPSEC_SPSTATE_IFNET 4
+ uint32_t priority; /* priority of this policy */
+ uint32_t id; /* It's unique number on the system. */
/*
* lifetime handler.
* the policy can be used without limitiation if both lifetime and
@@ -107,41 +113,25 @@ struct secpolicy {
long validtime; /* duration this policy is valid without use */
};
-/* Request for IPsec */
-struct ipsecrequest {
- struct ipsecrequest *next;
- /* pointer to next structure */
- /* If NULL, it means the end of chain. */
- struct secasindex saidx;/* hint for search proper SA */
- /* if __ss_len == 0 then no address specified.*/
- u_int level; /* IPsec level defined below. */
-
- struct secasvar *sav; /* place holder of SA for use */
- struct secpolicy *sp; /* back pointer to SP */
- struct rwlock lock; /* to interlock updates */
-};
-
/*
- * Need recursion for when crypto callbacks happen directly,
- * as in the case of software crypto. Need to look at how
- * hard it is to remove this...
+ * PCB security policies.
+ * Application can setup private security policies for socket.
+ * Such policies can have IPSEC, BYPASS and ENTRUST type.
+ * By default policies set to NULL, this mean that they have ENTRUST type.
+ * When application sets BYPASS or IPSEC type policy, flags field
+ * also updated. In case when flags is not set, the system could store
+ * used security policy into the sp_in/sp_out pointer to speedup further
+ * lookups.
*/
-#define IPSECREQUEST_LOCK_INIT(_isr) \
- rw_init_flags(&(_isr)->lock, "ipsec request", RW_RECURSE)
-#define IPSECREQUEST_LOCK(_isr) rw_rlock(&(_isr)->lock)
-#define IPSECREQUEST_UNLOCK(_isr) rw_runlock(&(_isr)->lock)
-#define IPSECREQUEST_WLOCK(_isr) rw_wlock(&(_isr)->lock)
-#define IPSECREQUEST_WUNLOCK(_isr) rw_wunlock(&(_isr)->lock)
-#define IPSECREQUEST_UPGRADE(_isr) rw_try_upgrade(&(_isr)->lock)
-#define IPSECREQUEST_DOWNGRADE(_isr) rw_downgrade(&(_isr)->lock)
-#define IPSECREQUEST_LOCK_DESTROY(_isr) rw_destroy(&(_isr)->lock)
-#define IPSECREQUEST_LOCK_ASSERT(_isr) rw_assert(&(_isr)->lock, RA_LOCKED)
-
-/* security policy in PCB */
struct inpcbpolicy {
- struct secpolicy *sp_in;
- struct secpolicy *sp_out;
- int priv; /* privileged socket ? */
+ struct secpolicy *sp_in;
+ struct secpolicy *sp_out;
+
+ uint32_t genid;
+ uint16_t flags;
+#define INP_INBOUND_POLICY 0x0001
+#define INP_OUTBOUND_POLICY 0x0002
+ uint16_t hdrsz;
};
/* SP acquiring list table. */
Modified: projects/ipsec/sys/netipsec/keydb.h
==============================================================================
--- projects/ipsec/sys/netipsec/keydb.h Sat Nov 19 13:57:21 2016 (r308830)
+++ projects/ipsec/sys/netipsec/keydb.h Sat Nov 19 14:40:18 2016 (r308831)
@@ -54,9 +54,9 @@ union sockaddr_union {
struct secasindex {
union sockaddr_union src; /* source address for SA */
union sockaddr_union dst; /* destination address for SA */
- u_int16_t proto; /* IPPROTO_ESP or IPPROTO_AH */
- u_int8_t mode; /* mode of protocol, see ipsec.h */
- u_int32_t reqid; /* reqid id who owned this SA */
+ uint8_t proto; /* IPPROTO_ESP or IPPROTO_AH */
+ uint8_t mode; /* mode of protocol, see ipsec.h */
+ uint32_t reqid; /* reqid id who owned this SA */
/* see IPSEC_MANUAL_REQID_MAX. */
};
More information about the svn-src-projects
mailing list