svn commit: r310502 - projects/ipsec/sys/netipsec

Andrey V. Elsukov ae at FreeBSD.org
Sat Dec 24 11:47:48 UTC 2016


Author: ae
Date: Sat Dec 24 11:47:47 2016
New Revision: 310502
URL: https://svnweb.freebsd.org/changeset/base/310502

Log:
  Add key_delete_xform() function.
  
  It deletes all SAs releated to xform. Use this function when xform is
  removed.

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

Modified: projects/ipsec/sys/netipsec/key.c
==============================================================================
--- projects/ipsec/sys/netipsec/key.c	Sat Dec 24 11:41:16 2016	(r310501)
+++ projects/ipsec/sys/netipsec/key.c	Sat Dec 24 11:47:47 2016	(r310502)
@@ -643,6 +643,7 @@ static int key_delete(struct socket *, s
 	const struct sadb_msghdr *);
 static int key_delete_all(struct socket *, struct mbuf *,
 	const struct sadb_msghdr *, struct secasindex *);
+static void key_delete_xform(const struct xformsw *);
 static int key_get(struct socket *, struct mbuf *,
 	const struct sadb_msghdr *);
 
@@ -5705,6 +5706,52 @@ key_delete_all(struct socket *so, struct
 }
 
 /*
+ * Delete all alive SAs for corresponding xform.
+ * Larval SAs have not initialized tdb_xform, so it is safe to leave them
+ * here when xform disappears.
+ */
+static void
+key_delete_xform(const struct xformsw *xsp)
+{
+	struct secasvar_queue drainq;
+	struct secashead *sah;
+	struct secasvar *sav, *nextsav;
+
+	TAILQ_INIT(&drainq);
+	SAHTREE_WLOCK();
+	TAILQ_FOREACH(sah, &V_sahtree, chain) {
+		sav = TAILQ_FIRST(&sah->savtree_alive);
+		if (sav == NULL)
+			continue;
+		if (sav->tdb_xform != xsp)
+			continue;
+		/*
+		 * It is supposed that all SAs in the chain are related to
+		 * one xform.
+		 */
+		TAILQ_CONCAT(&drainq, &sah->savtree_alive, chain);
+	}
+	/* Unlink all queued SAs from SPI hash */
+	TAILQ_FOREACH(sav, &drainq, chain) {
+		sav->state = SADB_SASTATE_DEAD;
+		LIST_REMOVE(sav, spihash);
+	}
+	SAHTREE_WUNLOCK();
+
+	/* Now we can release reference for all SAs in drainq */
+	sav = TAILQ_FIRST(&drainq);
+	while (sav != NULL) {
+		KEYDBG(KEY_STAMP,
+		    printf("%s: SA(%p)\n", __func__, sav));
+		KEYDBG(KEY_DATA, kdebug_secasv(sav));
+		nextsav = TAILQ_NEXT(sav, chain);
+		key_freesah(&sav->sah); /* release reference from SAV */
+		key_freesav(&sav); /* release last reference */
+		sav = nextsav;
+	}
+}
+
+/*
  * SADB_GET processing
  * receive
  *   <base, SA(*), address(SD)>
@@ -8019,6 +8066,9 @@ xform_detach(void *data)
 	XFORMS_LOCK();
 	LIST_REMOVE(xsp, chain);
 	XFORMS_UNLOCK();
+
+	/* Delete all SAs related to this xform. */
+	key_delete_xform(xsp);
 }
 
 /*


More information about the svn-src-projects mailing list