Locking and misc cleanups; most of which I've been running for >4 months:
o add locking o strip irrelevant spl's o split malloc types to better account for memory use o remove unused IPSEC_NONBLOCK_ACQUIRE code o remove dead code Sponsored by: FreeBSD Foundation
This commit is contained in:
parent
ee6e0476d2
commit
6464079f10
@ -202,6 +202,8 @@ static int ipsec_get_policy __P((struct secpolicy *pcb_sp, struct mbuf **mp));
|
||||
static void vshiftl __P((unsigned char *, int, int));
|
||||
static size_t ipsec_hdrsiz __P((struct secpolicy *));
|
||||
|
||||
MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
|
||||
|
||||
/*
|
||||
* Return a held reference to the default SP.
|
||||
*/
|
||||
@ -836,7 +838,7 @@ static void
|
||||
ipsec_delpcbpolicy(p)
|
||||
struct inpcbpolicy *p;
|
||||
{
|
||||
free(p, M_SECA);
|
||||
free(p, M_IPSEC_INPCB);
|
||||
}
|
||||
|
||||
/* initialize policy in PCB */
|
||||
@ -852,7 +854,7 @@ ipsec_init_policy(so, pcb_sp)
|
||||
panic("ipsec_init_policy: NULL pointer was passed.\n");
|
||||
|
||||
new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
|
||||
M_SECA, M_NOWAIT|M_ZERO);
|
||||
M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
|
||||
if (new == NULL) {
|
||||
ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
|
||||
return ENOBUFS;
|
||||
@ -909,6 +911,24 @@ ipsec_copy_policy(old, new)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ipsecrequest *
|
||||
ipsec_newisr(void)
|
||||
{
|
||||
struct ipsecrequest *p;
|
||||
|
||||
p = malloc(sizeof(struct ipsecrequest), M_IPSEC_SR, M_NOWAIT|M_ZERO);
|
||||
if (p != NULL)
|
||||
mtx_init(&p->lock, "ipsec request", NULL, MTX_DEF);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
ipsec_delisr(struct ipsecrequest *p)
|
||||
{
|
||||
mtx_destroy(&p->lock);
|
||||
free(p, M_IPSEC_SR);
|
||||
}
|
||||
|
||||
/* deep-copy a policy in PCB */
|
||||
static struct secpolicy *
|
||||
ipsec_deepcopy_policy(src)
|
||||
@ -932,13 +952,9 @@ ipsec_deepcopy_policy(src)
|
||||
*/
|
||||
q = &newchain;
|
||||
for (p = src->req; p; p = p->next) {
|
||||
*q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
|
||||
M_SECA, M_NOWAIT);
|
||||
*q = ipsec_newisr();
|
||||
if (*q == NULL)
|
||||
goto fail;
|
||||
bzero(*q, sizeof(**q));
|
||||
(*q)->next = NULL;
|
||||
|
||||
(*q)->saidx.proto = p->saidx.proto;
|
||||
(*q)->saidx.mode = p->saidx.mode;
|
||||
(*q)->level = p->level;
|
||||
@ -947,7 +963,6 @@ ipsec_deepcopy_policy(src)
|
||||
bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
|
||||
bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
|
||||
|
||||
(*q)->sav = NULL;
|
||||
(*q)->sp = dst;
|
||||
|
||||
q = &((*q)->next);
|
||||
@ -963,7 +978,7 @@ ipsec_deepcopy_policy(src)
|
||||
fail:
|
||||
for (p = newchain; p; p = r) {
|
||||
r = p->next;
|
||||
free(p, M_SECA);
|
||||
ipsec_delisr(p);
|
||||
p = NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -71,6 +71,7 @@ struct secpolicyindex {
|
||||
/* Security Policy Data Base */
|
||||
struct secpolicy {
|
||||
LIST_ENTRY(secpolicy) chain;
|
||||
struct mtx lock;
|
||||
|
||||
u_int refcnt; /* reference count */
|
||||
struct secpolicyindex spidx; /* selector */
|
||||
@ -108,6 +109,7 @@ struct ipsecrequest {
|
||||
|
||||
struct secasvar *sav; /* place holder of SA for use */
|
||||
struct secpolicy *sp; /* back pointer to SP */
|
||||
struct mtx lock; /* to interlock updates */
|
||||
};
|
||||
|
||||
/* security policy in PCB */
|
||||
@ -322,6 +324,9 @@ extern int crypto_support;
|
||||
/* for openbsd compatibility */
|
||||
#define DPRINTF(x) do { if (ipsec_debug) printf x; } while (0)
|
||||
|
||||
extern struct ipsecrequest *ipsec_newisr(void);
|
||||
extern void ipsec_delisr(struct ipsecrequest *);
|
||||
|
||||
struct tdb_ident;
|
||||
extern struct secpolicy *ipsec_getpolicy __P((struct tdb_ident*, u_int));
|
||||
struct inpcb;
|
||||
|
@ -108,7 +108,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
union sockaddr_union dst_address;
|
||||
struct secasvar *sav;
|
||||
u_int32_t spi;
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input,
|
||||
ipcompstat.ipcomps_input);
|
||||
@ -178,8 +178,6 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
return EPFNOSUPPORT;
|
||||
}
|
||||
|
||||
s = splnet();
|
||||
|
||||
/* NB: only pass dst since key_allocsa follows RFC2401 */
|
||||
sav = KEY_ALLOCSA(&dst_address, sproto, spi);
|
||||
if (sav == NULL) {
|
||||
@ -189,7 +187,6 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
(u_long) ntohl(spi), sproto));
|
||||
IPSEC_ISTAT(sproto, espstat.esps_notdb, ahstat.ahs_notdb,
|
||||
ipcompstat.ipcomps_notdb);
|
||||
splx(s);
|
||||
m_freem(m);
|
||||
return ENOENT;
|
||||
}
|
||||
@ -202,7 +199,6 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
IPSEC_ISTAT(sproto, espstat.esps_noxform, ahstat.ahs_noxform,
|
||||
ipcompstat.ipcomps_noxform);
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
m_freem(m);
|
||||
return ENXIO;
|
||||
}
|
||||
@ -213,7 +209,6 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
*/
|
||||
error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff);
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -345,12 +345,12 @@ ipsec4_process_packet(
|
||||
struct secasindex saidx;
|
||||
struct secasvar *sav;
|
||||
struct ip *ip;
|
||||
int s, error, i, off;
|
||||
int error, i, off;
|
||||
|
||||
KASSERT(m != NULL, ("ipsec4_process_packet: null mbuf"));
|
||||
KASSERT(isr != NULL, ("ipsec4_process_packet: null isr"));
|
||||
|
||||
s = splnet(); /* insure SA contents don't change */
|
||||
mtx_lock(&isr->lock); /* insure SA contents don't change */
|
||||
|
||||
isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error);
|
||||
if (isr == NULL)
|
||||
@ -469,10 +469,10 @@ ipsec4_process_packet(
|
||||
} else {
|
||||
error = ipsec_process_done(m, isr);
|
||||
}
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
return error;
|
||||
bad:
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return error;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -100,7 +100,14 @@ extern void key_sa_routechange __P((struct sockaddr *));
|
||||
extern void key_sa_stir_iv __P((struct secasvar *));
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_SECA);
|
||||
MALLOC_DECLARE(M_IPSEC_SA);
|
||||
MALLOC_DECLARE(M_IPSEC_SAH);
|
||||
MALLOC_DECLARE(M_IPSEC_SP);
|
||||
MALLOC_DECLARE(M_IPSEC_SR);
|
||||
MALLOC_DECLARE(M_IPSEC_MISC);
|
||||
MALLOC_DECLARE(M_IPSEC_SAQ);
|
||||
MALLOC_DECLARE(M_IPSEC_SAR);
|
||||
MALLOC_DECLARE(M_IPSEC_INPCB);
|
||||
#endif /* MALLOC_DECLARE */
|
||||
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
@ -83,6 +83,7 @@ struct comp_algo;
|
||||
/* Security Association */
|
||||
struct secasvar {
|
||||
LIST_ENTRY(secasvar) chain;
|
||||
struct mtx lock; /* update/access lock */
|
||||
|
||||
u_int refcnt; /* reference count */
|
||||
u_int8_t state; /* Status of this Association */
|
||||
|
@ -738,7 +738,7 @@ ah_input_cb(struct cryptop *crp)
|
||||
struct secasindex *saidx;
|
||||
u_int8_t nxt;
|
||||
caddr_t ptr;
|
||||
int s, authsize;
|
||||
int authsize;
|
||||
|
||||
crd = crp->crp_desc;
|
||||
|
||||
@ -750,8 +750,6 @@ ah_input_cb(struct cryptop *crp)
|
||||
mtag = (struct m_tag *) tc->tc_ptr;
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
s = splnet();
|
||||
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
if (sav == NULL) {
|
||||
ahstat.ahs_notdb++;
|
||||
@ -866,12 +864,11 @@ ah_input_cb(struct cryptop *crp)
|
||||
IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
|
||||
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
|
||||
return error;
|
||||
bad:
|
||||
if (sav)
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
if (tc != NULL)
|
||||
@ -1123,7 +1120,7 @@ ah_output_cb(struct cryptop *crp)
|
||||
struct secasvar *sav;
|
||||
struct mbuf *m;
|
||||
caddr_t ptr;
|
||||
int s, err;
|
||||
int err;
|
||||
|
||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||
KASSERT(tc != NULL, ("ah_output_cb: null opaque data area!"));
|
||||
@ -1132,9 +1129,8 @@ ah_output_cb(struct cryptop *crp)
|
||||
ptr = (caddr_t) (tc + 1);
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
s = splnet();
|
||||
|
||||
isr = tc->tc_isr;
|
||||
mtx_lock(&isr->lock);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
if (sav == NULL) {
|
||||
ahstat.ahs_notdb++;
|
||||
@ -1151,7 +1147,7 @@ ah_output_cb(struct cryptop *crp)
|
||||
|
||||
if (crp->crp_etype == EAGAIN) {
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
return crypto_dispatch(crp);
|
||||
}
|
||||
|
||||
@ -1183,12 +1179,13 @@ ah_output_cb(struct cryptop *crp)
|
||||
/* NB: m is reclaimed by ipsec_process_done. */
|
||||
err = ipsec_process_done(m, isr);
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
|
||||
return err;
|
||||
bad:
|
||||
if (sav)
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
free(tc, M_XDATA);
|
||||
|
@ -447,7 +447,7 @@ static int
|
||||
esp_input_cb(struct cryptop *crp)
|
||||
{
|
||||
u_int8_t lastthree[3], aalg[AH_HMAC_HASHLEN];
|
||||
int s, hlen, skip, protoff, error;
|
||||
int hlen, skip, protoff, error;
|
||||
struct mbuf *m;
|
||||
struct cryptodesc *crd;
|
||||
struct auth_hash *esph;
|
||||
@ -468,8 +468,6 @@ esp_input_cb(struct cryptop *crp)
|
||||
mtag = (struct m_tag *) tc->tc_ptr;
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
s = splnet();
|
||||
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
if (sav == NULL) {
|
||||
espstat.esps_notdb++;
|
||||
@ -497,7 +495,6 @@ esp_input_cb(struct cryptop *crp)
|
||||
|
||||
if (crp->crp_etype == EAGAIN) {
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
return crypto_dispatch(crp);
|
||||
}
|
||||
|
||||
@ -610,12 +607,10 @@ DPRINTF(("esp_input_cb: %x %x\n", lastthree[0], lastthree[1]));
|
||||
IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
|
||||
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
return error;
|
||||
bad:
|
||||
if (sav)
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
if (tc != NULL)
|
||||
@ -868,15 +863,14 @@ esp_output_cb(struct cryptop *crp)
|
||||
struct ipsecrequest *isr;
|
||||
struct secasvar *sav;
|
||||
struct mbuf *m;
|
||||
int s, err, error;
|
||||
int err, error;
|
||||
|
||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||
KASSERT(tc != NULL, ("esp_output_cb: null opaque data area!"));
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
s = splnet();
|
||||
|
||||
isr = tc->tc_isr;
|
||||
mtx_lock(&isr->lock);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
if (sav == NULL) {
|
||||
espstat.esps_notdb++;
|
||||
@ -897,7 +891,7 @@ esp_output_cb(struct cryptop *crp)
|
||||
|
||||
if (crp->crp_etype == EAGAIN) {
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
return crypto_dispatch(crp);
|
||||
}
|
||||
|
||||
@ -925,12 +919,13 @@ esp_output_cb(struct cryptop *crp)
|
||||
/* NB: m is reclaimed by ipsec_process_done. */
|
||||
err = ipsec_process_done(m, isr);
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
|
||||
return err;
|
||||
bad:
|
||||
if (sav)
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
free(tc, M_XDATA);
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/protosw.h>
|
||||
@ -215,7 +217,7 @@ ipcomp_input_cb(struct cryptop *crp)
|
||||
struct mbuf *m;
|
||||
struct secasvar *sav;
|
||||
struct secasindex *saidx;
|
||||
int s, hlen = IPCOMP_HLENGTH, error, clen;
|
||||
int hlen = IPCOMP_HLENGTH, error, clen;
|
||||
u_int8_t nproto;
|
||||
caddr_t addr;
|
||||
|
||||
@ -228,8 +230,6 @@ ipcomp_input_cb(struct cryptop *crp)
|
||||
mtag = (struct mtag *) tc->tc_ptr;
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
|
||||
s = splnet();
|
||||
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
if (sav == NULL) {
|
||||
ipcompstat.ipcomps_notdb++;
|
||||
@ -252,7 +252,6 @@ ipcomp_input_cb(struct cryptop *crp)
|
||||
|
||||
if (crp->crp_etype == EAGAIN) {
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
return crypto_dispatch(crp);
|
||||
}
|
||||
|
||||
@ -306,12 +305,10 @@ ipcomp_input_cb(struct cryptop *crp)
|
||||
IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, NULL);
|
||||
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
return error;
|
||||
bad:
|
||||
if (sav)
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
if (tc != NULL)
|
||||
@ -500,7 +497,7 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
struct ipsecrequest *isr;
|
||||
struct secasvar *sav;
|
||||
struct mbuf *m;
|
||||
int s, error, skip, rlen;
|
||||
int error, skip, rlen;
|
||||
|
||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||
KASSERT(tc != NULL, ("ipcomp_output_cb: null opaque data area!"));
|
||||
@ -508,9 +505,8 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
skip = tc->tc_skip;
|
||||
rlen = crp->crp_ilen - skip;
|
||||
|
||||
s = splnet();
|
||||
|
||||
isr = tc->tc_isr;
|
||||
mtx_lock(&isr->lock);
|
||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||
if (sav == NULL) {
|
||||
ipcompstat.ipcomps_notdb++;
|
||||
@ -528,7 +524,7 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
|
||||
if (crp->crp_etype == EAGAIN) {
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
return crypto_dispatch(crp);
|
||||
}
|
||||
ipcompstat.ipcomps_noxform++;
|
||||
@ -581,12 +577,13 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
/* NB: m is reclaimed by ipsec_process_done. */
|
||||
error = ipsec_process_done(m, isr);
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
|
||||
return error;
|
||||
bad:
|
||||
if (sav)
|
||||
KEY_FREESAV(&sav);
|
||||
splx(s);
|
||||
mtx_unlock(&isr->lock);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
free(tc, M_XDATA);
|
||||
|
Loading…
Reference in New Issue
Block a user