Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Nov 2016 12:23:55 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r308993 - projects/ipsec/sys/netipsec
Message-ID:  <201611221223.uAMCNtIC028379@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue Nov 22 12:23:55 2016
New Revision: 308993
URL: https://svnweb.freebsd.org/changeset/base/308993

Log:
  Update key_newsah() and key_delsah() to reflect changes in SADB.
  
  Now SA head has refcount. Properly initialize refcnt and both
  savtree_larval and savtree_alive. Add key_freesah() function to
  release refcount and call key_delsah() for last reference.

Modified:
  projects/ipsec/sys/netipsec/key.c

Modified: projects/ipsec/sys/netipsec/key.c
==============================================================================
--- projects/ipsec/sys/netipsec/key.c	Tue Nov 22 11:56:58 2016	(r308992)
+++ projects/ipsec/sys/netipsec/key.c	Tue Nov 22 12:23:55 2016	(r308993)
@@ -2484,74 +2484,59 @@ key_spdexpire(struct secpolicy *sp)
 
 /* %%% SAD management */
 /*
- * allocating a memory for new SA head, and copy from the values of mhp.
+ * allocating and initialize new SA head.
  * OUT:	NULL	: failure due to the lack of memory.
  *	others	: pointer to new SA head.
  */
 static struct secashead *
 key_newsah(struct secasindex *saidx)
 {
-	struct secashead *newsah;
+	struct secashead *sah;
 
-	IPSEC_ASSERT(saidx != NULL, ("null saidx"));
+	sah = malloc(sizeof(struct secashead), M_IPSEC_SAH,
+	    M_NOWAIT | M_ZERO);
+	if (sah == NULL)
+		return (NULL);
+	TAILQ_INIT(&sah->savtree_larval);
+	TAILQ_INIT(&sah->savtree_alive);
+	sah->saidx = *saidx;
+	sah->state = SADB_SASTATE_DEAD;
+	SAH_INITREF(sah);
+
+	KEYDBG(KEY_STAMP,
+	    printf("%s: SAH(%p)\n", __func__, sah));
+	KEYDBG(KEY_DATA, kdebug_secash(sah, NULL));
+	return (sah);
+}
+
+static void
+key_freesah(struct secashead **psah)
+{
+	struct secashead *sah = *psah;
 
-	newsah = malloc(sizeof(struct secashead), M_IPSEC_SAH, M_NOWAIT|M_ZERO);
-	if (newsah != NULL) {
-		int i;
-		for (i = 0; i < sizeof(newsah->savtree)/sizeof(newsah->savtree[0]); i++)
-			LIST_INIT(&newsah->savtree[i]);
-		newsah->saidx = *saidx;
+	if (SAH_DELREF(sah) == 0)
+		return;
 
-		/* add to saidxtree */
-		newsah->state = SADB_SASTATE_MATURE;
+	KEYDBG(KEY_STAMP,
+	    printf("%s: last reference to SAH(%p)\n", __func__, sah));
+	KEYDBG(KEY_DATA, kdebug_secash(sah, NULL));
 
-		SAHTREE_LOCK();
-		LIST_INSERT_HEAD(&V_sahtree, newsah, chain);
-		SAHTREE_UNLOCK();
-	}
-	return(newsah);
+	*psah = NULL;
+	key_delsah(sah);
 }
 
-/*
- * delete SA index and all SA registerd.
- */
 static void
 key_delsah(struct secashead *sah)
 {
-	struct secasvar *sav, *nextsav;
-	u_int stateidx;
-	int zombie = 0;
-
 	IPSEC_ASSERT(sah != NULL, ("NULL sah"));
-	SAHTREE_LOCK_ASSERT();
+	IPSEC_ASSERT(sah->state == SADB_SASTATE_DEAD,
+	    ("Attempt to free non DEAD SAH %p", sah));
+	IPSEC_ASSERT(TAILQ_EMPTY(&sah->savtree_larval),
+	    ("Attempt to free SAH %p with LARVAL SA", sah));
+	IPSEC_ASSERT(TAILQ_EMPTY(&sah->savtree_alive),
+	    ("Attempt to free SAH %p with ALIVE SA", sah));
 
-	/* searching all SA registerd in the secindex. */
-	for (stateidx = 0;
-	     stateidx < _ARRAYLEN(saorder_state_any);
-	     stateidx++) {
-		u_int state = saorder_state_any[stateidx];
-		LIST_FOREACH_SAFE(sav, &sah->savtree[state], chain, nextsav) {
-			if (sav->refcnt == 0) {
-				/* sanity check */
-				KEY_CHKSASTATE(state, sav->state, __func__);
-				/* 
-				 * do NOT call KEY_FREESAV here:
-				 * it will only delete the sav if refcnt == 1,
-				 * where we already know that refcnt == 0
-				 */
-				key_delsav(sav);
-			} else {
-				/* give up to delete this sa */
-				zombie++;
-			}
-		}
-	}
-	if (!zombie) {		/* delete only if there are savs */
-		/* remove from tree of SA index */
-		if (__LIST_CHAINED(sah))
-			LIST_REMOVE(sah, chain);
-		free(sah, M_IPSEC_SAH);
-	}
+	free(sah, M_IPSEC_SAH);
 }
 
 /*



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