summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/key.c
diff options
context:
space:
mode:
authorfabient <fabient@FreeBSD.org>2011-03-31 15:23:32 +0000
committerfabient <fabient@FreeBSD.org>2011-03-31 15:23:32 +0000
commitd56170701edd485dd31c6c68254daab567f5d249 (patch)
tree67cb0da741da7bd58b8f2eaa65607147ebf7f0af /sys/netipsec/key.c
parent3666785171ab6fafe3466579d69d661e79599f96 (diff)
downloadFreeBSD-src-d56170701edd485dd31c6c68254daab567f5d249.zip
FreeBSD-src-d56170701edd485dd31c6c68254daab567f5d249.tar.gz
Optimisation in IPSEC(4):
- Remove contention on ISR during the crypto operation by using rwlock(9). - Remove a second lookup of the SA in the callback. Gain on 6 cores CPU with SHA1/AES128 can be up to 30%. Reviewed by: vanhu MFC after: 1 month
Diffstat (limited to 'sys/netipsec/key.c')
-rw-r--r--sys/netipsec/key.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index 56942e7..7329539 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -809,6 +809,7 @@ key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx)
{
u_int level;
int error;
+ struct secasvar *sav;
IPSEC_ASSERT(isr != NULL, ("null isr"));
IPSEC_ASSERT(saidx != NULL, ("null saidx"));
@@ -826,45 +827,31 @@ key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx)
/* get current level */
level = ipsec_get_reqlevel(isr);
-#if 0
- /*
- * We do allocate new SA only if the state of SA in the holder is
- * SADB_SASTATE_DEAD. The SA for outbound must be the oldest.
- */
- if (isr->sav != NULL) {
- if (isr->sav->sah == NULL)
- panic("%s: sah is null.\n", __func__);
- if (isr->sav == (struct secasvar *)LIST_FIRST(
- &isr->sav->sah->savtree[SADB_SASTATE_DEAD])) {
- KEY_FREESAV(&isr->sav);
- isr->sav = NULL;
- }
- }
-#else
+
/*
- * we free any SA stashed in the IPsec request because a different
+ * We check new SA in the IPsec request because a different
* SA may be involved each time this request is checked, either
* because new SAs are being configured, or this request is
* associated with an unconnected datagram socket, or this request
* is associated with a system default policy.
*
- * The operation may have negative impact to performance. We may
- * want to check cached SA carefully, rather than picking new SA
- * every time.
- */
- if (isr->sav != NULL) {
- KEY_FREESAV(&isr->sav);
- isr->sav = NULL;
- }
-#endif
-
- /*
- * new SA allocation if no SA found.
* key_allocsa_policy should allocate the oldest SA available.
* See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt.
*/
- if (isr->sav == NULL)
- isr->sav = key_allocsa_policy(saidx);
+ sav = key_allocsa_policy(saidx);
+ if (sav != isr->sav) {
+ /* SA need to be updated. */
+ if (!IPSECREQUEST_UPGRADE(isr)) {
+ /* Kick everyone off. */
+ IPSECREQUEST_UNLOCK(isr);
+ IPSECREQUEST_WLOCK(isr);
+ }
+ if (isr->sav != NULL)
+ KEY_FREESAV(&isr->sav);
+ isr->sav = sav;
+ IPSECREQUEST_DOWNGRADE(isr);
+ } else if (sav != NULL)
+ KEY_FREESAV(&sav);
/* When there is SA. */
if (isr->sav != NULL) {
@@ -1240,6 +1227,16 @@ key_freesp_so(struct secpolicy **sp)
KEY_FREESP(sp);
}
+void
+key_addrefsa(struct secasvar *sav, const char* where, int tag)
+{
+
+ IPSEC_ASSERT(sav != NULL, ("null sav"));
+ IPSEC_ASSERT(sav->refcnt > 0, ("refcount must exist"));
+
+ sa_addref(sav);
+}
+
/*
* Must be called after calling key_allocsa().
* This function is called by key_freesp() to free some SA allocated
OpenPOWER on IntegriCloud