cleanup secasvar management; refcnt is key.c responsibility;
alloc/free is keydb.c responsibility. Obtained from: KAME
This commit is contained in:
parent
02f4f60ad5
commit
9712142383
131
sys/netkey/key.c
131
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:
|
||||
@ -2772,65 +2830,6 @@ key_newsav(m, mhp, sah, errp)
|
||||
return newsav;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user