From owner-svn-src-projects@freebsd.org Mon Nov 21 13:07:58 2016 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C9750C4C430 for ; Mon, 21 Nov 2016 13:07:58 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9880ECB1; Mon, 21 Nov 2016 13:07:58 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uALD7vc5059457; Mon, 21 Nov 2016 13:07:57 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uALD7vOA059452; Mon, 21 Nov 2016 13:07:57 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201611211307.uALD7vOA059452@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Mon, 21 Nov 2016 13:07:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308924 - in projects/ipsec/sys: netinet netipsec X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Nov 2016 13:07:58 -0000 Author: ae Date: Mon Nov 21 13:07:57 2016 New Revision: 308924 URL: https://svnweb.freebsd.org/changeset/base/308924 Log: Modify PCB-related functions and unify its names. Some background. When IPsec compiled in the kernel, each inpcb allocates inpcbpolicy structure. This structure keeps two security policies (for INBOUND and OUTBOUND directions). By default these policies have IPSEC_POLICY_ENTRUST type. This means that application has not any preference for used security policies and kernel will use system-wide security policies. Some application could want to bypass IPsec processing (e.g. IKE daemons). Such applications use IP_IPSEC_POLICY/IPV6_IPSEC_POLICY socket option to configure IPsec bypass. In this case policies stored in the inpcbpolicy structure will have type IPSEC_POLICY_BYPASS. Only privileged socket can use this policy type. The last allowed for use by application policy type is IPSEC_POLICY_IPSEC. It also allowed only for privileged sockets. In theory application could configure security policy, that requires IPsec processing (ESP/AH transforms). In reality there are a bunch of problems: 1) ENTRUST policies for each inpcb just waste the memory, even if system doesn't have any security policies; 2) setsockopt/getsockopt interface was broken, only setsockopt worked partially; 3) even if application has configured IPSEC policy, there is no way to set corresponding SA. It looks like all IKEd always require security policy that acquired SA should be visible via PF_KEY. *) I failed to find some application that uses IPSEC type of policies. What I did and plan to do to resolve issues: 1) Now secpolicy pointers in the inpcbpolicy structure will not be initialized with ENTRUST policies. NULL pointer will mean ENTRUST policy. Also, if application didn't set BYPASS/IPSEC policies, the kernel will use these pointers to cache used security policies. 2) Rework IP_IPSEC_POLICY/IPV6_IPSEC_POLICY socket options handling. To get needed policy we need a hint from application, user should correctly fill sadb_x_policy->sadb_x_policy_dir before doing getsockopt(). If passed buffer size is not enough, needed size will be returned in the sadb_x_policy_len field and ENOBUFS will be returned as return code. 3) To resolve this issue we probably need to make PCB policies visible through PF_KEY interface. We can create additional list and link all such policies into it. This also will help when ipsec.ko module will unloaded. We can correctly free all created security policies. TBD. What changed: ipsec_init_pcbpolicy() allocates inpcbpolicy that stored in given inpcb. Now it requires only one inpcb argument. ipsec_control_pcbpolicy() used by IPv4/IPv6 control code to set or get security policies stored in PCB. Make ipsec_set_pcbpolicy() and ipsec_get_pcbpolicy() static. ipsec_delete_pcbpolicy() releases security polices if they are configured, then releases memory from inpcbpolicy structure. Update ipsec_newisr() and ipsec_delisr() to reflect changes in struct ipsecrequest. Modified: projects/ipsec/sys/netinet/in_pcb.c projects/ipsec/sys/netinet/sctp_pcb.c projects/ipsec/sys/netinet/tcp_syncache.c projects/ipsec/sys/netipsec/ipsec.c projects/ipsec/sys/netipsec/ipsec.h Modified: projects/ipsec/sys/netinet/in_pcb.c ============================================================================== --- projects/ipsec/sys/netinet/in_pcb.c Mon Nov 21 12:00:31 2016 (r308923) +++ projects/ipsec/sys/netinet/in_pcb.c Mon Nov 21 13:07:57 2016 (r308924) @@ -304,7 +304,7 @@ in_pcballoc(struct socket *so, struct in mac_inpcb_create(so, inp); #endif #ifdef IPSEC - error = ipsec_init_policy(so, &inp->inp_sp); + error = ipsec_init_pcbpolicy(inp); if (error != 0) { #ifdef MAC mac_inpcb_destroy(inp); Modified: projects/ipsec/sys/netinet/sctp_pcb.c ============================================================================== --- projects/ipsec/sys/netinet/sctp_pcb.c Mon Nov 21 12:00:31 2016 (r308923) +++ projects/ipsec/sys/netinet/sctp_pcb.c Mon Nov 21 13:07:57 2016 (r308924) @@ -2460,7 +2460,7 @@ sctp_inpcb_alloc(struct socket *so, uint return (ENOBUFS); } #ifdef IPSEC - error = ipsec_init_policy(so, &inp->ip_inp.inp.inp_sp); + error = ipsec_init_pcbpolicy(&inp->ip_inp.inp); if (error != 0) { crfree(inp->ip_inp.inp.inp_cred); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); Modified: projects/ipsec/sys/netinet/tcp_syncache.c ============================================================================== --- projects/ipsec/sys/netinet/tcp_syncache.c Mon Nov 21 12:00:31 2016 (r308923) +++ projects/ipsec/sys/netinet/tcp_syncache.c Mon Nov 21 13:07:57 2016 (r308924) @@ -738,7 +738,7 @@ syncache_socket(struct syncache *sc, str } #ifdef IPSEC /* Copy old policy into new socket's. */ - if (ipsec_copy_policy(sotoinpcb(lso)->inp_sp, inp->inp_sp)) + if (ipsec_copy_pcbpolicy(sotoinpcb(lso), inp) != 0) printf("syncache_socket: could not copy policy\n"); #endif #ifdef INET6 Modified: projects/ipsec/sys/netipsec/ipsec.c ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.c Mon Nov 21 12:00:31 2016 (r308923) +++ projects/ipsec/sys/netipsec/ipsec.c Mon Nov 21 13:07:57 2016 (r308924) @@ -255,8 +255,6 @@ static void ipsec6_get_ulp(const struct static void ipsec6_setspidx_ipaddr(const struct mbuf *, struct secpolicyindex *); #endif -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"); @@ -801,246 +799,213 @@ ipsec_run_hhooks(struct ipsec_ctx_data * return (0); } -static void -ipsec_delpcbpolicy(struct inpcbpolicy *p) -{ - - free(p, M_IPSEC_INPCB); -} - -/* Initialize policy in PCB. */ +/* Initialize PCB policy. */ int -ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp) +ipsec_init_pcbpolicy(struct inpcb *inp) { - struct inpcbpolicy *new; - /* Sanity check. */ - if (so == NULL || pcb_sp == NULL) - panic("%s: NULL pointer was passed.\n", __func__); + IPSEC_ASSERT(inp != NULL, ("null inp")); + IPSEC_ASSERT(inp->inp_sp == NULL, ("inp_sp already initialized")); - new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy), - M_IPSEC_INPCB, M_NOWAIT|M_ZERO); - if (new == NULL) { + inp->inp_sp = 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__)); return (ENOBUFS); } - - new->priv = IPSEC_IS_PRIVILEGED_SO(so); - - 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); } -/* Copy old IPsec policy into new. */ +/* Delete PCB policy. */ int -ipsec_copy_policy(struct inpcbpolicy *old, struct inpcbpolicy *new) +ipsec_delete_pcbpolicy(struct inpcb *inp) { - struct secpolicy *sp; - sp = ipsec_deepcopy_policy(old->sp_in); - if (sp) { - KEY_FREESP(&new->sp_in); - new->sp_in = sp; - } else - return (ENOBUFS); + if (inp->inp_sp == NULL) + return (0); - sp = ipsec_deepcopy_policy(old->sp_out); - if (sp) { - KEY_FREESP(&new->sp_out); - new->sp_out = sp; - } else - return (ENOBUFS); + if (inp->inp_sp->flags & INP_INBOUND_POLICY) + key_freesp(&inp->inp_sp->sp_in); - new->priv = old->priv; + if (inp->inp_sp->flags & INP_OUTBOUND_POLICY) + key_freesp(&inp->inp_sp->sp_out); + free(inp->inp_sp, M_IPSEC_INPCB); + inp->inp_sp = NULL; 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) - IPSECREQUEST_LOCK_INIT(p); - return (p); -} - -void -ipsec_delisr(struct ipsecrequest *p) -{ - - IPSECREQUEST_LOCK_DESTROY(p); - free(p, M_IPSEC_SR); -} - /* Deep-copy a policy in PCB. */ static struct secpolicy * -ipsec_deepcopy_policy(struct secpolicy *src) +ipsec_deepcopy_pcbpolicy(struct secpolicy *src) { - struct ipsecrequest *newchain = NULL; - struct ipsecrequest *p; - struct ipsecrequest **q; - struct ipsecrequest *r; struct secpolicy *dst; + int i; 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)); + IPSEC_ASSERT(src->state == IPSEC_SPSTATE_PCB, ("SP isn't PCB")); - (*q)->sp = dst; - - q = &((*q)->next); - } + dst = key_newsp(); + if (dst == NULL) + return (NULL); - 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; + dst->state = src->state; + dst->priority = src->priority; + /* Do not touch the refcnt field. */ + + /* Copy IPsec request chain. */ + for (i = 0; i < src->tcount; i++) { + dst->req[i] = ipsec_newisr(); + if (dst->req[i] == NULL) { + key_freesp(&dst); + return (NULL); + } + bcopy(src->req[i], dst->req[i], sizeof(struct ipsecrequest)); + dst->tcount++; } - KEY_FREESP(&dst); - return (NULL); + KEYDBG(IPSEC_DUMP, + printf("%s: copied SP(%p) -> SP(%p)\n", __func__, src, dst); + kdebug_secpolicy(dst)); + return (dst); } -/* Set policy and IPsec request if present. */ -static int -ipsec_set_policy_internal(struct secpolicy **pcb_sp, int optname, - caddr_t request, size_t len, struct ucred *cred) +/* Copy old IPsec policy into new. */ +int +ipsec_copy_pcbpolicy(struct inpcb *old, struct inpcb *new) { - struct sadb_x_policy *xpl; - struct secpolicy *newsp = NULL; - int error; + struct secpolicy *sp; - /* Sanity check. */ - if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL) - return (EINVAL); - if (len < sizeof(*xpl)) - return (EINVAL); - xpl = (struct sadb_x_policy *)request; + /* + * old->inp_sp can be NULL if PCB was created when an IPsec + * support was unavailable. This is not an error, we don't have + * policies in this PCB, so nothing to copy. + */ + if (old->inp_sp == NULL) + return (0); - KEYDEBUG(KEYDEBUG_IPSEC_DUMP, - printf("%s: passed policy\n", __func__); - kdebug_sadb_x_policy((struct sadb_ext *)xpl)); - - /* Check policy type. */ - /* ipsec_set_policy_internal() accepts IPSEC, ENTRUST and BYPASS. */ - if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD - || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE) - return (EINVAL); + IPSEC_ASSERT(new->inp_sp != NULL, ("new inp_sp is NULL")); + INP_WLOCK_ASSERT(new); - /* Check privileged socket. */ - if (cred != NULL && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS) { - error = priv_check_cred(cred, PRIV_NETINET_IPSEC, 0); - if (error) - return (EACCES); - } + if (old->inp_sp->flags & INP_INBOUND_POLICY) { + sp = ipsec_deepcopy_pcbpolicy(old->inp_sp->sp_in); + if (sp == NULL) + return (ENOBUFS); + } else + sp = NULL; - /* Allocating new SP entry. */ - if ((newsp = key_msg2sp(xpl, len, &error)) == NULL) - return (error); + if (new->inp_sp->flags & INP_INBOUND_POLICY) + key_freesp(&new->inp_sp->sp_in); - /* Clear old SP and set new SP. */ - KEY_FREESP(pcb_sp); - *pcb_sp = newsp; - KEYDEBUG(KEYDEBUG_IPSEC_DUMP, - printf("%s: new policy\n", __func__); - kdebug_secpolicy(newsp)); + new->inp_sp->sp_in = sp; + if (sp != NULL) + new->inp_sp->flags |= INP_INBOUND_POLICY; + else + new->inp_sp->flags &= ~INP_INBOUND_POLICY; + + if (old->inp_sp->flags & INP_OUTBOUND_POLICY) { + sp = ipsec_deepcopy_pcbpolicy(old->inp_sp->sp_out); + if (sp == NULL) + return (ENOBUFS); + } else + sp = NULL; + + if (new->inp_sp->flags & INP_OUTBOUND_POLICY) + key_freesp(&new->inp_sp->sp_out); + new->inp_sp->sp_out = sp; + if (sp != NULL) + new->inp_sp->flags |= INP_OUTBOUND_POLICY; + else + new->inp_sp->flags &= ~INP_OUTBOUND_POLICY; return (0); } -int -ipsec_set_policy(struct inpcb *inp, int optname, caddr_t request, - size_t len, struct ucred *cred) +static int +ipsec_set_pcbpolicy(struct inpcb *inp, struct ucred *cred, + void *request, size_t len) { struct sadb_x_policy *xpl; - struct secpolicy **pcb_sp; + struct secpolicy **spp, *newsp; + int error, flags; - /* Sanity check. */ - if (inp == NULL || request == NULL) - return (EINVAL); - if (len < sizeof(*xpl)) - return (EINVAL); xpl = (struct sadb_x_policy *)request; - /* Select direction. */ switch (xpl->sadb_x_policy_dir) { case IPSEC_DIR_INBOUND: - pcb_sp = &inp->inp_sp->sp_in; + spp = &inp->inp_sp->sp_in; + flags = INP_INBOUND_POLICY; break; case IPSEC_DIR_OUTBOUND: - pcb_sp = &inp->inp_sp->sp_out; + spp = &inp->inp_sp->sp_out; + flags = INP_OUTBOUND_POLICY; break; default: ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__, xpl->sadb_x_policy_dir)); return (EINVAL); } + /* + * Privileged sockets are allowed to set own security policy + * and configure IPsec bypass. Unprivileged sockets only can + * have ENTRUST policy. + */ + switch (xpl->sadb_x_policy_type) { + case IPSEC_POLICY_IPSEC: + case IPSEC_POLICY_BYPASS: + if (cred != NULL && + priv_check_cred(cred, PRIV_NETINET_IPSEC, 0) != 0) + return (EACCES); + /* Allocate new SP entry. */ + newsp = key_msg2sp(xpl, len, &error); + if (newsp == NULL) + return (error); + newsp->state = IPSEC_SPSTATE_PCB; + break; + case IPSEC_POLICY_ENTRUST: + /* We just use NULL pointer for ENTRUST policy */ + newsp = NULL; + break; + default: + /* Other security policy types aren't allowed for PCB */ + return (EINVAL); + } - return (ipsec_set_policy_internal(pcb_sp, optname, request, len, cred)); + /* Clear old SP and set new SP. */ + if (*spp != NULL) + key_freesp(spp); + *spp = newsp; + KEYDBG(IPSEC_DUMP, + printf("%s: new SP(%p)\n", __func__, newsp)); + if (newsp == NULL) + inp->inp_sp->flags &= ~flags; + else { + inp->inp_sp->flags |= flags; + KEYDBG(IPSEC_DUMP, kdebug_secpolicy(newsp)); + } + return (0); } -int -ipsec_get_policy(struct inpcb *inp, caddr_t request, size_t len, - struct mbuf **mp) +static int +ipsec_get_pcbpolicy(struct inpcb *inp, void *request, size_t *len) { struct sadb_x_policy *xpl; - struct secpolicy *pcb_sp; + struct secpolicy *sp; + int error, flags; - /* Sanity check. */ - if (inp == NULL || request == NULL || mp == NULL) - return (EINVAL); - IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp")); - if (len < sizeof(*xpl)) - return (EINVAL); xpl = (struct sadb_x_policy *)request; - + flags = inp->inp_sp->flags; /* Select direction. */ switch (xpl->sadb_x_policy_dir) { case IPSEC_DIR_INBOUND: - pcb_sp = inp->inp_sp->sp_in; + sp = inp->inp_sp->sp_in; + flags &= INP_INBOUND_POLICY; break; case IPSEC_DIR_OUTBOUND: - pcb_sp = inp->inp_sp->sp_out; + sp = inp->inp_sp->sp_out; + flags &= INP_OUTBOUND_POLICY; break; default: ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__, @@ -1048,42 +1013,86 @@ ipsec_get_policy(struct inpcb *inp, cadd return (EINVAL); } - /* Sanity check. Should be an IPSEC_ASSERT. */ - if (pcb_sp == NULL) - return (EINVAL); - - *mp = key_sp2msg(pcb_sp); - if (!*mp) { - ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); - return (ENOBUFS); + if (flags == 0) { + /* Return ENTRUST policy */ + xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + xpl->sadb_x_policy_type = IPSEC_POLICY_ENTRUST; + xpl->sadb_x_policy_id = 0; + xpl->sadb_x_policy_priority = 0; + xpl->sadb_x_policy_len = PFKEY_UNIT64(sizeof(*xpl)); + *len = sizeof(*xpl); + return (0); } - (*mp)->m_type = MT_DATA; - KEYDEBUG(KEYDEBUG_IPSEC_DUMP, - printf("%s:\n", __func__); kdebug_mbuf(*mp)); + IPSEC_ASSERT(sp != NULL, + ("sp is NULL, but flags is 0x%04x", inp->inp_sp->flags)); + key_addref(sp); + error = key_sp2msg(sp, request, len); + key_freesp(&sp); + if (error == EINVAL) + return (error); + /* + * We return "success", but user should check *len. + * *len will be set to size of valid data and + * sadb_x_policy_len will contain needed size. + */ return (0); } -/* Delete policy in PCB. */ +/* Handle socket option control request for PCB */ int -ipsec_delete_pcbpolicy(struct inpcb *inp) +ipsec_control_pcbpolicy(struct inpcb *inp, struct sockopt *sopt) { - IPSEC_ASSERT(inp != NULL, ("null inp")); + void *optdata; + size_t optlen; + int error; if (inp->inp_sp == NULL) - return (0); + return (ENOPROTOOPT); - if (inp->inp_sp->sp_in != NULL) - KEY_FREESP(&inp->inp_sp->sp_in); + /* Limit maximum request size to PAGE_SIZE */ + optlen = sopt->sopt_valsize; + if (optlen < sizeof(struct sadb_x_policy) || optlen > PAGE_SIZE) + return (EINVAL); - if (inp->inp_sp->sp_out != NULL) - KEY_FREESP(&inp->inp_sp->sp_out); + optdata = malloc(optlen, M_TEMP, sopt->sopt_td ? M_WAITOK: M_NOWAIT); + if (optdata == NULL) + return (ENOBUFS); + /* + * We need a hint from the user, what policy is requested - input + * or output? User should specify it in the buffer, even for + * setsockopt(). + */ + error = sooptcopyin(sopt, optdata, optlen, optlen); + if (error == 0) { + if (sopt->sopt_dir == SOPT_SET) + error = ipsec_set_pcbpolicy(inp, + sopt->sopt_td ? sopt->sopt_td->td_ucred: NULL, + optdata, optlen); + else { + error = ipsec_get_pcbpolicy(inp, optdata, &optlen); + if (error == 0) + error = sooptcopyout(sopt, optdata, optlen); + } + } + free(optdata, M_TEMP); + return (error); +} - ipsec_delpcbpolicy(inp->inp_sp); - inp->inp_sp = NULL; +struct ipsecrequest * +ipsec_newisr(void) +{ - return (0); + return (malloc(sizeof(struct ipsecrequest), M_IPSEC_SR, + M_NOWAIT | M_ZERO)); +} + +void +ipsec_delisr(struct ipsecrequest *p) +{ + + free(p, M_IPSEC_SR); } /* Modified: projects/ipsec/sys/netipsec/ipsec.h ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.h Mon Nov 21 12:00:31 2016 (r308923) +++ projects/ipsec/sys/netipsec/ipsec.h Mon Nov 21 13:07:57 2016 (r308924) @@ -298,29 +298,24 @@ VNET_DECLARE(int, crypto_support); /* for openbsd compatibility */ #define DPRINTF(x) do { if (V_ipsec_debug) printf x; } while (0) -extern struct ipsecrequest *ipsec_newisr(void); -extern void ipsec_delisr(struct ipsecrequest *); - struct inpcb; +struct secasvar; +struct sockopt; + +struct ipsecrequest *ipsec_newisr(void); +void ipsec_delisr(struct ipsecrequest *); struct secpolicy *ipsec4_checkpolicy(const struct mbuf *, struct inpcb *, int *); -extern struct secpolicy * ipsec_getpolicybyaddr(const struct mbuf *, u_int, - int *); - -extern int ipsec_init_policy(struct socket *so, struct inpcbpolicy **); -extern int ipsec_copy_policy(struct inpcbpolicy *, struct inpcbpolicy *); u_int ipsec_get_reqlevel(struct secpolicy *, u_int); int ipsec4_in_reject(const struct mbuf *, struct inpcb *); size_t ipsec_hdrsiz_inpcb(struct inpcb *); -extern int ipsec_set_policy(struct inpcb *inp, int optname, - 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 *); +int ipsec_init_pcbpolicy(struct inpcb *); +int ipsec_delete_pcbpolicy(struct inpcb *); +int ipsec_copy_pcbpolicy(struct inpcb *, struct inpcb *); +int ipsec_control_pcbpolicy(struct inpcb *, struct sockopt *); -struct secas; extern int ipsec_chkreplay(u_int32_t, struct secasvar *); extern int ipsec_updatereplay(u_int32_t, struct secasvar *);