Page MenuHomeFreeBSD

D3019.diff
No OneTemporary

D3019.diff

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

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)

Event Timeline