summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netkey/key.c131
-rw-r--r--sys/netkey/keydb.c31
-rw-r--r--sys/netkey/keydb.h3
3 files changed, 66 insertions, 99 deletions
diff --git a/sys/netkey/key.c b/sys/netkey/key.c
index e7b04aa..c91febe 100644
--- a/sys/netkey/key.c
+++ b/sys/netkey/key.c
@@ -123,7 +123,7 @@ __FBSDID("$FreeBSD$");
* referenced from SA header.
* - SAs that are in DEAD state will have (total external reference)
* in reference count field. they are ready to be freed. reference from
- * SA header will be removed in key_delsav(), when the reference count
+ * SA header will be removed in keydb_delsecasvar(), when the reference count
* field hits 0 (= no external reference other than from SA header.
*/
@@ -368,6 +368,7 @@ struct sadb_msghdr {
static struct secasvar *key_allocsa_policy(struct secasindex *);
static void key_freesp_so(struct secpolicy **);
static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int);
+static void key_delsav(struct secasvar *);
static void key_delsp(struct secpolicy *);
static struct secpolicy *key_getsp(struct secpolicyindex *);
static struct secpolicy *key_getspbyid(u_int32_t);
@@ -395,7 +396,6 @@ static struct secashead *key_newsah(struct secasindex *);
static void key_delsah(struct secashead *);
static struct secasvar *key_newsav(struct mbuf *,
const struct sadb_msghdr *, struct secashead *, int *);
-static void key_delsav(struct secasvar *);
static struct secashead *key_getsah(struct secasindex *);
static struct secasvar *key_checkspidup(struct secasindex *, u_int32_t);
static struct secasvar *key_getsavbyspi(struct secashead *, u_int32_t);
@@ -1179,8 +1179,67 @@ key_freesav(sav)
printf("DP freesav cause refcnt--:%d SA:%p SPI %u\n",
sav->refcnt, sav, (u_int32_t)ntohl(sav->spi)));
- if (sav->refcnt == 0)
- key_delsav(sav);
+ if (sav->refcnt > 0)
+ return;
+
+ key_delsav(sav);
+}
+
+/*
+ * free() SA variable entry.
+ */
+static void
+key_delsav(sav)
+ struct secasvar *sav;
+{
+ /* sanity check */
+ if (sav == NULL)
+ panic("key_delsav: NULL pointer is passed.");
+
+ if (sav->refcnt > 0)
+ panic("key_delsav: called with positive refcnt");
+
+ /* remove from SA header */
+ if (__LIST_CHAINED(sav))
+ LIST_REMOVE(sav, chain);
+
+ if (sav->key_auth != NULL) {
+ bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
+ KFREE(sav->key_auth);
+ sav->key_auth = NULL;
+ }
+ if (sav->key_enc != NULL) {
+ bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
+ KFREE(sav->key_enc);
+ sav->key_enc = NULL;
+ }
+ if (sav->sched) {
+ bzero(sav->sched, sav->schedlen);
+ KFREE(sav->sched);
+ sav->sched = NULL;
+ }
+ if (sav->replay != NULL) {
+ keydb_delsecreplay(sav->replay);
+ sav->replay = NULL;
+ }
+ if (sav->lft_c != NULL) {
+ KFREE(sav->lft_c);
+ sav->lft_c = NULL;
+ }
+ if (sav->lft_h != NULL) {
+ KFREE(sav->lft_h);
+ sav->lft_h = NULL;
+ }
+ if (sav->lft_s != NULL) {
+ KFREE(sav->lft_s);
+ sav->lft_s = NULL;
+ }
+ if (sav->iv != NULL) {
+ KFREE(sav->iv);
+ sav->iv = NULL;
+ }
+
+ keydb_delsecasvar(sav);
return;
}
@@ -1202,7 +1261,7 @@ key_delsp(sp)
sp->state = IPSEC_SPSTATE_DEAD;
if (sp->refcnt > 0)
- return; /* can't free */
+ panic("key_delsp: called with positive refcnt");
s = splnet(); /*called from softclock()*/
/* remove from SP index */
@@ -2704,13 +2763,12 @@ key_newsav(m, mhp, sah, errp)
if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL)
panic("key_newsa: NULL pointer is passed.");
- KMALLOC(newsav, struct secasvar *, sizeof(struct secasvar));
+ newsav = keydb_newsecasvar();
if (newsav == NULL) {
ipseclog((LOG_DEBUG, "key_newsa: No more memory.\n"));
*errp = ENOBUFS;
return NULL;
}
- bzero((caddr_t)newsav, sizeof(struct secasvar));
switch (mhp->msg->sadb_msg_type) {
case SADB_GETSPI:
@@ -2773,65 +2831,6 @@ key_newsav(m, mhp, sah, errp)
}
/*
- * free() SA variable entry.
- */
-static void
-key_delsav(sav)
- struct secasvar *sav;
-{
- /* sanity check */
- if (sav == NULL)
- panic("key_delsav: NULL pointer is passed.");
-
- if (sav->refcnt > 0)
- return; /* can't free */
-
- /* remove from SA header */
- if (__LIST_CHAINED(sav))
- LIST_REMOVE(sav, chain);
-
- if (sav->key_auth != NULL) {
- bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
- KFREE(sav->key_auth);
- sav->key_auth = NULL;
- }
- if (sav->key_enc != NULL) {
- bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
- KFREE(sav->key_enc);
- sav->key_enc = NULL;
- }
- if (sav->sched) {
- bzero(sav->sched, sav->schedlen);
- KFREE(sav->sched);
- sav->sched = NULL;
- }
- if (sav->replay != NULL) {
- keydb_delsecreplay(sav->replay);
- sav->replay = NULL;
- }
- if (sav->lft_c != NULL) {
- KFREE(sav->lft_c);
- sav->lft_c = NULL;
- }
- if (sav->lft_h != NULL) {
- KFREE(sav->lft_h);
- sav->lft_h = NULL;
- }
- if (sav->lft_s != NULL) {
- KFREE(sav->lft_s);
- sav->lft_s = NULL;
- }
- if (sav->iv != NULL) {
- KFREE(sav->iv);
- sav->iv = NULL;
- }
-
- KFREE(sav);
-
- return;
-}
-
-/*
* search SAD.
* OUT:
* NULL : not found
diff --git a/sys/netkey/keydb.c b/sys/netkey/keydb.c
index 1ca71f0..309b512 100644
--- a/sys/netkey/keydb.c
+++ b/sys/netkey/keydb.c
@@ -57,8 +57,6 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_SECA, "key mgmt", "security associations, key management");
-static void keydb_delsecasvar(struct secasvar *);
-
/*
* secpolicy management
*/
@@ -120,43 +118,14 @@ keydb_newsecasvar()
if (!p)
return p;
bzero(p, sizeof(*p));
- p->refcnt = 1;
return p;
}
void
-keydb_refsecasvar(p)
- struct secasvar *p;
-{
- int s;
-
- s = splnet();
- p->refcnt++;
- splx(s);
-}
-
-void
-keydb_freesecasvar(p)
- struct secasvar *p;
-{
- int s;
-
- s = splnet();
- p->refcnt--;
- /* negative refcnt will cause panic intentionally */
- if (p->refcnt <= 0)
- keydb_delsecasvar(p);
- splx(s);
-}
-
-static void
keydb_delsecasvar(p)
struct secasvar *p;
{
- if (p->refcnt)
- panic("keydb_delsecasvar called with refcnt != 0");
-
free(p, M_SECA);
}
diff --git a/sys/netkey/keydb.h b/sys/netkey/keydb.h
index 0690ec8..0fce183 100644
--- a/sys/netkey/keydb.h
+++ b/sys/netkey/keydb.h
@@ -150,8 +150,7 @@ extern struct secashead *keydb_newsecashead(void);
extern void keydb_delsecashead(struct secashead *);
/* secasvar */
extern struct secasvar *keydb_newsecasvar(void);
-extern void keydb_refsecasvar(struct secasvar *);
-extern void keydb_freesecasvar(struct secasvar *);
+extern void keydb_delsecasvar(struct secasvar *);
/* secreplay */
extern struct secreplay *keydb_newsecreplay(size_t);
extern void keydb_delsecreplay(struct secreplay *);
OpenPOWER on IntegriCloud