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 +#ifdef IPSEC +#include +#endif #include #include #include @@ -92,12 +95,6 @@ #include #endif /* INET6 */ - -#ifdef IPSEC -#include -#include -#endif /* IPSEC */ - #include 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 +#ifdef IPSEC +#include +#endif #include #include #include @@ -85,7 +88,7 @@ #ifdef IPSEC #include #include -#endif /* IPSEC */ +#endif #ifdef INET6 #include 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 +#ifdef IPSEC +#include +#endif #include #include #include @@ -91,14 +94,6 @@ #include #endif -#ifdef IPSEC -#include -#ifdef INET6 -#include -#endif -#include -#endif /*IPSEC*/ - #include #include @@ -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 +#include #include +#include #include #include #include #include #include +#include #include #include #include @@ -53,6 +56,7 @@ #include #include #include +#include #include #include @@ -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_ */