Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147224872
D3019.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D3019.diff
View Options
Index: sys/netinet/in_pcb.h
===================================================================
--- sys/netinet/in_pcb.h
+++ sys/netinet/in_pcb.h
@@ -52,7 +52,6 @@
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
-struct inpcbpolicy;
/*
* struct inpcb is the common protocol control block structure used in most
@@ -192,7 +191,7 @@
/* MAC and IPSEC policy information. */
struct label *inp_label; /* (i) MAC label */
- struct inpcbpolicy *inp_sp; /* (s) for IPSEC */
+ void *inp_sp; /* (s) for IPSEC */
/* Protocol-dependent part; options. */
struct {
Index: sys/netinet/in_pcb.c
===================================================================
--- sys/netinet/in_pcb.c
+++ sys/netinet/in_pcb.c
@@ -46,6 +46,9 @@
#include "opt_rss.h"
#include <sys/param.h>
+#ifdef IPSEC
+#include <sys/eventhandler.h>
+#endif
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@@ -92,12 +95,6 @@
#include <netinet6/ip6_var.h>
#endif /* INET6 */
-
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/key.h>
-#endif /* IPSEC */
-
#include <security/mac/mac_framework.h>
static struct callout ipport_tick_callout;
@@ -290,15 +287,6 @@
goto out;
mac_inpcb_create(so, inp);
#endif
-#ifdef IPSEC
- error = ipsec_init_policy(so, &inp->inp_sp);
- if (error != 0) {
-#ifdef MAC
- mac_inpcb_destroy(inp);
-#endif
- goto out;
- }
-#endif /*IPSEC*/
#ifdef INET6
if (INP_SOCKAF(so) == AF_INET6) {
inp->inp_vflag |= INP_IPV6PROTO;
@@ -316,7 +304,7 @@
INP_WLOCK(inp);
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */
-#if defined(IPSEC) || defined(MAC)
+#ifdef MAC
out:
if (error != 0) {
crfree(inp->inp_cred);
@@ -1249,7 +1237,7 @@
/* XXXRW: Do as much as possible here. */
#ifdef IPSEC
if (inp->inp_sp != NULL)
- ipsec_delete_pcbpolicy(inp);
+ EVENTHANDLER_INVOKE(ipsec_delete_pcbpolicy, inp);
#endif
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
in_pcbremlists(inp);
Index: sys/netinet/sctp_os_bsd.h
===================================================================
--- sys/netinet/sctp_os_bsd.h
+++ sys/netinet/sctp_os_bsd.h
@@ -45,6 +45,9 @@
#include "opt_sctp.h"
#include <sys/param.h>
+#ifdef IPSEC
+#include <sys/eventhandler.h>
+#endif
#include <sys/ktr.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -85,7 +88,7 @@
#ifdef IPSEC
#include <netipsec/ipsec.h>
#include <netipsec/key.h>
-#endif /* IPSEC */
+#endif
#ifdef INET6
#include <sys/domain.h>
Index: sys/netinet/sctp_pcb.c
===================================================================
--- sys/netinet/sctp_pcb.c
+++ sys/netinet/sctp_pcb.c
@@ -2494,22 +2494,6 @@
SCTP_INP_INFO_WUNLOCK();
return (ENOBUFS);
}
-#ifdef IPSEC
- {
- struct inpcbpolicy *pcb_sp = NULL;
-
- error = ipsec_init_policy(so, &pcb_sp);
- /* Arrange to share the policy */
- inp->ip_inp.inp.inp_sp = pcb_sp;
- ((struct in6pcb *)(&inp->ip_inp.inp))->in6p_sp = pcb_sp;
- }
- if (error != 0) {
- crfree(inp->ip_inp.inp.inp_cred);
- SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
- SCTP_INP_INFO_WUNLOCK();
- return error;
- }
-#endif /* IPSEC */
SCTP_INCR_EP_COUNT();
inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
SCTP_INP_INFO_WUNLOCK();
@@ -3642,8 +3626,9 @@
*/
if (so) {
#ifdef IPSEC
- ipsec_delete_pcbpolicy(ip_pcb);
-#endif /* IPSEC */
+ if (ip_pcb->inp_sp != NULL)
+ EVENTHANDLER_INVOKE(ipsec_delete_pcbpolicy, ip_pcb);
+#endif /* IPSEC */
/* Unlocks not needed since the socket is gone now */
}
Index: sys/netinet/sctp_usrreq.c
===================================================================
--- sys/netinet/sctp_usrreq.c
+++ sys/netinet/sctp_usrreq.c
@@ -487,11 +487,6 @@
int error;
uint32_t vrf_id = SCTP_DEFAULT_VRFID;
-#ifdef IPSEC
- uint32_t flags;
-
-#endif
-
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -513,33 +508,6 @@
ip_inp = &inp->ip_inp.inp;
ip_inp->inp_vflag |= INP_IPV4;
ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
-#ifdef IPSEC
- error = ipsec_init_policy(so, &ip_inp->inp_sp);
-#ifdef SCTP_LOG_CLOSING
- sctp_log_closing(inp, NULL, 17);
-#endif
- if (error != 0) {
-try_again:
- flags = inp->sctp_flags;
- if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
- (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
-#ifdef SCTP_LOG_CLOSING
- sctp_log_closing(inp, NULL, 15);
-#endif
- SCTP_INP_WUNLOCK(inp);
- sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
- SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
- } else {
- flags = inp->sctp_flags;
- if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
- goto try_again;
- } else {
- SCTP_INP_WUNLOCK(inp);
- }
- }
- return (error);
- }
-#endif /* IPSEC */
SCTP_INP_WUNLOCK(inp);
return (0);
}
Index: sys/netinet/tcp_syncache.c
===================================================================
--- sys/netinet/tcp_syncache.c
+++ sys/netinet/tcp_syncache.c
@@ -39,6 +39,9 @@
#include "opt_pcbgroup.h"
#include <sys/param.h>
+#ifdef IPSEC
+#include <sys/eventhandler.h>
+#endif
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
@@ -91,14 +94,6 @@
#include <netinet/toecore.h>
#endif
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#ifdef INET6
-#include <netipsec/ipsec6.h>
-#endif
-#include <netipsec/key.h>
-#endif /*IPSEC*/
-
#include <machine/in_cksum.h>
#include <security/mac/mac_framework.h>
@@ -745,11 +740,12 @@
INP_HASH_WUNLOCK(&V_tcbinfo);
goto abort;
}
+
#ifdef IPSEC
- /* Copy old policy into new socket's. */
- if (ipsec_copy_policy(sotoinpcb(lso)->inp_sp, inp->inp_sp))
- printf("syncache_socket: could not copy policy\n");
+ if (sotoinpcb(lso)->inp_sp != NULL)
+ EVENTHANDLER_INVOKE(tcp_syncache_newconn, sotoinpcb(lso), inp);
#endif
+
#ifdef INET6
if (sc->sc_inc.inc_flags & INC_ISIPV6) {
struct inpcb *oinp = sotoinpcb(lso);
Index: sys/netipsec/ipsec.h
===================================================================
--- sys/netipsec/ipsec.h
+++ sys/netipsec/ipsec.h
@@ -138,8 +138,10 @@
/* security policy in PCB */
struct inpcbpolicy {
+ TAILQ_ENTRY(inpcbpolicy) spentry;
struct secpolicy *sp_in;
struct secpolicy *sp_out;
+ volatile u_int refcnt;
int priv; /* privileged socket ? */
};
@@ -306,8 +308,6 @@
extern struct secpolicy * ipsec_getpolicybyaddr(struct mbuf *, u_int, int *);
struct inpcb;
-extern int ipsec_init_policy(struct socket *so, struct inpcbpolicy **);
-extern int ipsec_copy_policy(struct inpcbpolicy *, struct inpcbpolicy *);
extern u_int ipsec_get_reqlevel(struct ipsecrequest *);
extern int ipsec_set_policy(struct inpcb *inp, int optname,
@@ -314,7 +314,6 @@
caddr_t request, size_t len, struct ucred *cred);
extern int ipsec_get_policy(struct inpcb *inpcb, caddr_t request,
size_t len, struct mbuf **mp);
-extern int ipsec_delete_pcbpolicy(struct inpcb *);
extern int ipsec4_in_reject(struct mbuf *, struct inpcb *);
struct secas;
Index: sys/netipsec/ipsec.c
===================================================================
--- sys/netipsec/ipsec.c
+++ sys/netipsec/ipsec.c
@@ -39,12 +39,15 @@
#include "opt_ipsec.h"
#include <sys/param.h>
+#include <sys/eventhandler.h>
#include <sys/systm.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/priv.h>
#include <sys/protosw.h>
+#include <sys/rmlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
@@ -53,6 +56,7 @@
#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <sys/refcount.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -210,6 +214,20 @@
VNET_DEFINE(int, ip6_ah_net_deflev) = IPSEC_LEVEL_USE;
VNET_DEFINE(int, ip6_ipsec_ecn) = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
+static VNET_DEFINE(TAILQ_HEAD(_socketsptree, inpcbpolicy), socketsptree);
+static struct rmlock socksptree_lock;
+#define V_socketsptree VNET(socketsptree)
+#define SOCKSPTREE_LOCK_INIT() rm_init(&socksptree_lock, "socksptree")
+#define SOCKSPTREE_LOCK_DESTROY() rm_destroy(&socksptree_lock)
+#define SOCKSPTREE_RLOCK_TRACKER struct rm_priotracker socksptree_tracker
+#define SOCKSPTREE_RLOCK() rm_rlock(&socksptree_lock, &socksptree_tracker)
+#define SOCKSPTREE_RUNLOCK() rm_runlock(&socksptree_lock, &socksptree_tracker)
+#define SOCKSPTREE_RLOCK_ASSERT() rm_assert(&socksptree_lock, RA_RLOCKED)
+#define SOCKSPTREE_WLOCK() rm_wlock(&socksptree_lock)
+#define SOCKSPTREE_WUNLOCK() rm_wunlock(&socksptree_lock)
+#define SOCKSPTREE_WLOCK_ASSERT() rm_assert(&socksptree_lock, RA_WLOCKED)
+#define SOCKSPTREE_UNLOCK_ASSERT() rm_assert(&socksptree_lock, RA_UNLOCKED)
+
SYSCTL_DECL(_net_inet6_ipsec6);
/* net.inet6.ipsec6 */
@@ -247,8 +265,8 @@
static void ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
static int ipsec6_setspidx_ipaddr(struct mbuf *, struct secpolicyindex *);
#endif
+static void ipsec_copy_policy(void *arg, struct inpcb *, struct inpcb *);
static void ipsec_delpcbpolicy(struct inpcbpolicy *);
-static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
static void vshiftl(unsigned char *, int, int);
MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
@@ -334,12 +352,6 @@
IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
("invalid direction %u", dir));
- if (!key_havesp(dir)) {
- /* No SP found, use system default. */
- sp = KEY_ALLOCSP_DEFAULT();
- return (sp);
- }
-
/* Set spidx in pcb. */
*error = ipsec_setspidx_inpcb(m, inp);
if (*error)
@@ -460,7 +472,7 @@
struct secpolicy *sp;
*error = 0;
- if (inp == NULL)
+ if (inp == NULL || inp->inp_sp == NULL)
sp = ipsec_getpolicybyaddr(m, dir, error);
else
sp = ipsec_getpolicybysock(m, dir, inp, error);
@@ -496,26 +508,31 @@
return (sp);
}
+/* XXX: This seems braindead?! */
static int
ipsec_setspidx_inpcb(struct mbuf *m, struct inpcb *inp)
{
+ struct inpcbpolicy *cursp;
int error;
IPSEC_ASSERT(inp != NULL, ("null inp"));
IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp"));
- IPSEC_ASSERT(inp->inp_sp->sp_out != NULL && inp->inp_sp->sp_in != NULL,
+
+ cursp = (struct inpcbpolicy *)inp->inp_sp;
+
+ IPSEC_ASSERT(cursp->sp_out != NULL && cursp->sp_in != NULL,
("null sp_in || sp_out"));
- error = ipsec_setspidx(m, &inp->inp_sp->sp_in->spidx, 1);
+ error = ipsec_setspidx(m, &cursp->sp_in->spidx, 1);
if (error == 0) {
- inp->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
- inp->inp_sp->sp_out->spidx = inp->inp_sp->sp_in->spidx;
- inp->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
+ cursp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
+ cursp->sp_out->spidx = cursp->sp_in->spidx;
+ cursp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
} else {
- bzero(&inp->inp_sp->sp_in->spidx,
- sizeof (inp->inp_sp->sp_in->spidx));
- bzero(&inp->inp_sp->sp_out->spidx,
- sizeof (inp->inp_sp->sp_in->spidx));
+ bzero(&cursp->sp_in->spidx,
+ sizeof (cursp->sp_in->spidx));
+ bzero(&cursp->sp_out->spidx,
+ sizeof (cursp->sp_in->spidx));
}
return (error);
}
@@ -813,66 +830,28 @@
free(p, M_IPSEC_INPCB);
}
-/* Initialize policy in PCB. */
-int
-ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp)
+/* Copy old IPsec policy into new. */
+static void
+ipsec_copy_policy(void *arg, struct inpcb *old, struct inpcb *new)
{
- struct inpcbpolicy *new;
+ struct inpcbpolicy *spinpcb;
+ SOCKSPTREE_RLOCK_TRACKER;
- /* Sanity check. */
- if (so == NULL || pcb_sp == NULL)
- panic("%s: NULL pointer was passed.\n", __func__);
-
- new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
- M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
- if (new == NULL) {
- ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
- return (ENOBUFS);
+ SOCKSPTREE_RLOCK();
+ TAILQ_FOREACH(spinpcb, &V_socketsptree, spentry) {
+ if (old->inp_sp == spinpcb)
+ break;
}
+ SOCKSPTREE_RUNLOCK();
+ if (spinpcb == NULL)
+ return;
- new->priv = IPSEC_IS_PRIVILEGED_SO(so);
+ new->inp_sp = old->inp_sp;
+ refcount_acquire(&spinpcb->refcnt);
- if ((new->sp_in = KEY_NEWSP()) == NULL) {
- ipsec_delpcbpolicy(new);
- return (ENOBUFS);
- }
- new->sp_in->policy = IPSEC_POLICY_ENTRUST;
- if ((new->sp_out = KEY_NEWSP()) == NULL) {
- KEY_FREESP(&new->sp_in);
- ipsec_delpcbpolicy(new);
- return (ENOBUFS);
- }
- new->sp_out->policy = IPSEC_POLICY_ENTRUST;
- *pcb_sp = new;
-
- return (0);
+ return;
}
-/* Copy old IPsec policy into new. */
-int
-ipsec_copy_policy(struct inpcbpolicy *old, struct inpcbpolicy *new)
-{
- struct secpolicy *sp;
-
- sp = ipsec_deepcopy_policy(old->sp_in);
- if (sp) {
- KEY_FREESP(&new->sp_in);
- new->sp_in = sp;
- } else
- return (ENOBUFS);
-
- sp = ipsec_deepcopy_policy(old->sp_out);
- if (sp) {
- KEY_FREESP(&new->sp_out);
- new->sp_out = sp;
- } else
- return (ENOBUFS);
-
- new->priv = old->priv;
-
- return (0);
-}
-
struct ipsecrequest *
ipsec_newisr(void)
{
@@ -892,59 +871,6 @@
free(p, M_IPSEC_SR);
}
-/* Deep-copy a policy in PCB. */
-static struct secpolicy *
-ipsec_deepcopy_policy(struct secpolicy *src)
-{
- struct ipsecrequest *newchain = NULL;
- struct ipsecrequest *p;
- struct ipsecrequest **q;
- struct ipsecrequest *r;
- struct secpolicy *dst;
-
- if (src == NULL)
- return (NULL);
- dst = KEY_NEWSP();
- if (dst == NULL)
- return (NULL);
-
- /*
- * Deep-copy IPsec request chain. This is required since struct
- * ipsecrequest is not reference counted.
- */
- q = &newchain;
- for (p = src->req; p; p = p->next) {
- *q = ipsec_newisr();
- if (*q == NULL)
- goto fail;
- (*q)->saidx.proto = p->saidx.proto;
- (*q)->saidx.mode = p->saidx.mode;
- (*q)->level = p->level;
- (*q)->saidx.reqid = p->saidx.reqid;
-
- bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
- bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
-
- (*q)->sp = dst;
-
- q = &((*q)->next);
- }
-
- dst->req = newchain;
- dst->policy = src->policy;
- /* Do not touch the refcnt fields. */
-
- return (dst);
-
-fail:
- for (p = newchain; p; p = r) {
- r = p->next;
- ipsec_delisr(p);
- p = NULL;
- }
- return (NULL);
-}
-
/* Set policy and IPsec request if present. */
static int
ipsec_set_policy_internal(struct secpolicy **pcb_sp, int optname,
@@ -983,7 +909,8 @@
return (error);
/* Clear old SP and set new SP. */
- KEY_FREESP(pcb_sp);
+ if (*pcb_sp != NULL)
+ KEY_FREESP(pcb_sp);
*pcb_sp = newsp;
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
printf("%s: new policy\n", __func__);
@@ -998,6 +925,8 @@
{
struct sadb_x_policy *xpl;
struct secpolicy **pcb_sp;
+ struct inpcbpolicy *cursp;
+ int error;
/* Sanity check. */
if (inp == NULL || request == NULL)
@@ -1006,13 +935,29 @@
return (EINVAL);
xpl = (struct sadb_x_policy *)request;
+ INP_WLOCK(inp);
+ if (inp->inp_sp == NULL) {
+ inp->inp_sp = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
+ M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
+ if (inp->inp_sp == NULL) {
+ ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
+ INP_WUNLOCK(inp);
+ return (ENOBUFS);
+ }
+
+ cursp = (struct inpcbpolicy *)inp->inp_sp;
+ cursp->priv = IPSEC_IS_PRIVILEGED_SO(inp->inp_socket);
+ refcount_init(&cursp->refcnt, 1);
+ }
+ INP_WUNLOCK(inp);
+
/* Select direction. */
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_INBOUND:
- pcb_sp = &inp->inp_sp->sp_in;
+ pcb_sp = &cursp->sp_in;
break;
case IPSEC_DIR_OUTBOUND:
- pcb_sp = &inp->inp_sp->sp_out;
+ pcb_sp = &cursp->sp_out;
break;
default:
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
@@ -1020,7 +965,17 @@
return (EINVAL);
}
- return (ipsec_set_policy_internal(pcb_sp, optname, request, len, cred));
+ error = ipsec_set_policy_internal(pcb_sp, optname, request, len, cred);
+ if (error) {
+ ipsec_delpcbpolicy(inp->inp_sp);
+ return (error);
+ }
+
+ SOCKSPTREE_WLOCK();
+ TAILQ_INSERT_HEAD(&V_socketsptree, (struct inpcbpolicy *)inp->inp_sp, spentry);
+ SOCKSPTREE_WUNLOCK();
+
+ return (0);
}
int
@@ -1029,6 +984,7 @@
{
struct sadb_x_policy *xpl;
struct secpolicy *pcb_sp;
+ struct inpcbpolicy *cursp;
/* Sanity check. */
if (inp == NULL || request == NULL || mp == NULL)
@@ -1036,15 +992,19 @@
IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp"));
if (len < sizeof(*xpl))
return (EINVAL);
+ if (inp->inp_sp == NULL)
+ return (ENXIO);
+
xpl = (struct sadb_x_policy *)request;
+ cursp = (struct inpcbpolicy *)inp->inp_sp;
/* Select direction. */
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_INBOUND:
- pcb_sp = inp->inp_sp->sp_in;
+ pcb_sp = cursp->sp_in;
break;
case IPSEC_DIR_OUTBOUND:
- pcb_sp = inp->inp_sp->sp_out;
+ pcb_sp = cursp->sp_out;
break;
default:
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
@@ -1070,24 +1030,33 @@
}
/* Delete policy in PCB. */
-int
-ipsec_delete_pcbpolicy(struct inpcb *inp)
+static void
+ipsec_delete_pcbpolicy(void *arg, struct inpcb *inp)
{
+ struct inpcbpolicy *cursp;
+
IPSEC_ASSERT(inp != NULL, ("null inp"));
if (inp->inp_sp == NULL)
- return (0);
+ return;
- if (inp->inp_sp->sp_in != NULL)
- KEY_FREESP(&inp->inp_sp->sp_in);
+ cursp = (struct inpcbpolicy *)inp->inp_sp;
- if (inp->inp_sp->sp_out != NULL)
- KEY_FREESP(&inp->inp_sp->sp_out);
+ if (cursp->sp_in != NULL)
+ KEY_FREESP(&cursp->sp_in);
- ipsec_delpcbpolicy(inp->inp_sp);
+ if (cursp->sp_out != NULL)
+ KEY_FREESP(&cursp->sp_out);
+
+ if (refcount_release(&cursp->refcnt) == 0) {
+ SOCKSPTREE_WLOCK();
+ TAILQ_REMOVE(&V_socketsptree, cursp, spentry);
+ SOCKSPTREE_WUNLOCK();
+ ipsec_delpcbpolicy(cursp);
+ }
+
inp->inp_sp = NULL;
-
- return (0);
+ return;
}
/*
@@ -1672,10 +1641,17 @@
bzero(&V_def_policy, sizeof(struct secpolicy));
V_def_policy.policy = IPSEC_POLICY_NONE;
V_def_policy.refcnt = 1;
+
+ TAILQ_INIT(&V_socketsptree);
+ SOCKSPTREE_LOCK_INIT();
}
VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY,
def_policy_init, NULL);
+EVENTHANDLER_DEFINE(tcp_syncache_newconn, ipsec_copy_policy, NULL,
+ EVENTHANDLER_PRI_LAST);
+EVENTHANDLER_DEFINE(ipsec_delete_pcbpolicy, ipsec_delete_pcbpolicy,
+ NULL, EVENTHANDLER_PRI_LAST);
/* XXX This stuff doesn't belong here... */
Index: sys/netipsec/key.h
===================================================================
--- sys/netipsec/key.h
+++ sys/netipsec/key.h
@@ -86,7 +86,6 @@
#define KEY_FREESAV(psav) \
key_freesav(psav, __FILE__, __LINE__)
-extern void key_freeso(struct socket *);
extern int key_checktunnelsanity(struct secasvar *, u_int,
caddr_t, caddr_t);
extern int key_checkrequest(struct ipsecrequest *isr,
Index: sys/netipsec/key.c
===================================================================
--- sys/netipsec/key.c
+++ sys/netipsec/key.c
@@ -418,7 +418,6 @@
#endif
static struct secasvar *key_allocsa_policy(const struct secasindex *);
-static void key_freesp_so(struct secpolicy **);
static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int);
static void key_unlink(struct secpolicy *);
static struct secpolicy *key_getsp(struct secpolicyindex *);
@@ -1160,7 +1159,6 @@
/*
* Must be called after calling key_allocsp().
- * For both the packet without socket and key_freeso().
*/
void
_key_freesp(struct secpolicy **spp, const char* where, int tag)
@@ -1208,56 +1206,7 @@
KEY_FREESP(&sp);
}
-/*
- * Must be called after calling key_allocsp().
- * For the packet with socket.
- */
void
-key_freeso(struct socket *so)
-{
- IPSEC_ASSERT(so != NULL, ("null so"));
-
- switch (so->so_proto->pr_domain->dom_family) {
-#if defined(INET) || defined(INET6)
-#ifdef INET
- case PF_INET:
-#endif
-#ifdef INET6
- case PF_INET6:
-#endif
- {
- struct inpcb *pcb = sotoinpcb(so);
-
- /* Does it have a PCB ? */
- if (pcb == NULL)
- return;
- key_freesp_so(&pcb->inp_sp->sp_in);
- key_freesp_so(&pcb->inp_sp->sp_out);
- }
- break;
-#endif /* INET || INET6 */
- default:
- ipseclog((LOG_DEBUG, "%s: unknown address family=%d.\n",
- __func__, so->so_proto->pr_domain->dom_family));
- return;
- }
-}
-
-static void
-key_freesp_so(struct secpolicy **sp)
-{
- IPSEC_ASSERT(sp != NULL && *sp != NULL, ("null sp"));
-
- if ((*sp)->policy == IPSEC_POLICY_ENTRUST ||
- (*sp)->policy == IPSEC_POLICY_BYPASS)
- return;
-
- IPSEC_ASSERT((*sp)->policy == IPSEC_POLICY_IPSEC,
- ("invalid policy %u", (*sp)->policy));
- KEY_FREESP(sp);
-}
-
-void
key_addrefsa(struct secasvar *sav, const char* where, int tag)
{
Index: sys/sys/eventhandler.h
===================================================================
--- sys/sys/eventhandler.h
+++ sys/sys/eventhandler.h
@@ -270,4 +270,10 @@
EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
+struct inpcb;
+typedef void (*tcp_syncache_newcon_fn)(void *,struct inpcb *, struct inpcb *);
+EVENTHANDLER_DECLARE(tcp_syncache_newconn, tcp_syncache_newcon_fn);
+typedef void (*ipsec_delete_pcbpolicy_fn)(void *, struct inpcb *);
+EVENTHANDLER_DECLARE(ipsec_delete_pcbpolicy, ipsec_delete_pcbpolicy_fn);
+
#endif /* _SYS_EVENTHANDLER_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 10, 6:27 AM (4 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29478655
Default Alt Text
D3019.diff (20 KB)
Attached To
Mode
D3019: Reduce overhead of IPSEC on socket creation and destruction
Attached
Detach File
Event Timeline
Log In to Comment