From owner-svn-src-projects@freebsd.org Sun Nov 20 17:50:19 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 77E6AC4CFE0 for ; Sun, 20 Nov 2016 17:50:19 +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 382D310E5; Sun, 20 Nov 2016 17:50:19 +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 uAKHoIsC087194; Sun, 20 Nov 2016 17:50:18 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uAKHoIjT087192; Sun, 20 Nov 2016 17:50:18 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201611201750.uAKHoIjT087192@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Sun, 20 Nov 2016 17:50:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308893 - projects/ipsec/sys/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: Sun, 20 Nov 2016 17:50:19 -0000 Author: ae Date: Sun Nov 20 17:50:18 2016 New Revision: 308893 URL: https://svnweb.freebsd.org/changeset/base/308893 Log: In ipsec_hdrsiz_internal() reflect the changes of struct ipsecrequest. For now calculate the apporximate size using only information from ipsecrequest. Later we will use information from inpcbpolicy. Add ipsec_hdrsiz_inpcb() it will be called from TCP code. Modified: projects/ipsec/sys/netipsec/ipsec.c projects/ipsec/sys/netipsec/ipsec.h Modified: projects/ipsec/sys/netipsec/ipsec.c ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.c Sun Nov 20 17:17:41 2016 (r308892) +++ projects/ipsec/sys/netipsec/ipsec.c Sun Nov 20 17:50:18 2016 (r308893) @@ -1505,16 +1505,15 @@ ipsec_in_reject(struct secpolicy *sp, st /* * Compute the byte size to be occupied by IPsec header. * In case it is tunnelled, it includes the size of outer IP header. - * NOTE: SP passed is freed in this function. */ static size_t ipsec_hdrsiz_internal(struct secpolicy *sp) { - struct ipsecrequest *isr; size_t size; + int i; - KEYDEBUG(KEYDEBUG_IPSEC_DATA, - printf("%s: using SP\n", __func__); kdebug_secpolicy(sp)); + KEYDBG(IPSEC_STAMP, printf("%s: using SP(%p)\n", __func__, sp)); + KEYDBG(IPSEC_DATA, kdebug_secpolicy(sp)); switch (sp->policy) { case IPSEC_POLICY_DISCARD: @@ -1526,45 +1525,72 @@ ipsec_hdrsiz_internal(struct secpolicy * IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC, ("invalid policy %u", sp->policy)); + /* + * XXX: for each transform we need to lookup suitable SA + * and use info from SA to calculate headers size. + * XXX: for NAT-T we need to cosider UDP header size. + */ size = 0; - for (isr = sp->req; isr != NULL; isr = isr->next) { - size_t clen = 0; - - switch (isr->saidx.proto) { + for (i = 0; i < sp->tcount; i++) { + switch (sp->req[i]->saidx.proto) { case IPPROTO_ESP: - clen = esp_hdrsiz(isr->sav); + size += esp_hdrsiz(NULL); break; case IPPROTO_AH: - clen = ah_hdrsiz(isr->sav); + size += ah_hdrsiz(NULL); break; case IPPROTO_IPCOMP: - clen = sizeof(struct ipcomp); + size += sizeof(struct ipcomp); break; } - if (isr->saidx.mode == IPSEC_MODE_TUNNEL) { - switch (isr->saidx.dst.sa.sa_family) { + if (sp->req[i]->saidx.mode == IPSEC_MODE_TUNNEL) { + switch (sp->req[i]->saidx.dst.sa.sa_family) { +#ifdef INET case AF_INET: - clen += sizeof(struct ip); + size += sizeof(struct ip); break; +#endif #ifdef INET6 case AF_INET6: - clen += sizeof(struct ip6_hdr); + size += sizeof(struct ip6_hdr); break; #endif default: ipseclog((LOG_ERR, "%s: unknown AF %d in " "IPsec tunnel SA\n", __func__, - ((struct sockaddr *)&isr->saidx.dst)->sa_family)); + sp->req[i]->saidx.dst.sa.sa_family)); break; } } - size += clen; } - return (size); } +/* + * Compute ESP/AH header size for protocols with PCB, including + * outer IP header. Currently only tcp_output() uses it. + */ +size_t +ipsec_hdrsiz_inpcb(struct inpcb *inp) +{ + struct secpolicyindex spidx; + struct secpolicy *sp; + size_t sz; + + sp = ipsec_getpcbpolicy(inp, IPSEC_DIR_OUTBOUND); + if (sp == NULL && key_havesp(IPSEC_DIR_OUTBOUND)) { + ipsec_setspidx_inpcb(inp, &spidx); + spidx.dir = IPSEC_DIR_OUTBOUND; + sp = key_allocsp(&spidx, IPSEC_DIR_OUTBOUND); + } + if (sp == NULL) + sp = key_allocsp_default(); + sz = ipsec_hdrsiz_internal(sp); + key_freesp(&sp); + return (sz); +} + /* * This function is called from ipsec_hdrsiz_tcp(), ip_ipsec_mtu(), * disabled ip6_ipsec_mtu() and ip6_forward(). Modified: projects/ipsec/sys/netipsec/ipsec.h ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.h Sun Nov 20 17:17:41 2016 (r308892) +++ projects/ipsec/sys/netipsec/ipsec.h Sun Nov 20 17:50:18 2016 (r308893) @@ -311,21 +311,20 @@ extern int ipsec_init_policy(struct sock 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 *); -extern int ipsec4_in_reject(const struct mbuf *, struct inpcb *); struct secas; -struct tcpcb; extern int ipsec_chkreplay(u_int32_t, struct secasvar *); extern int ipsec_updatereplay(u_int32_t, struct secasvar *); extern size_t ipsec_hdrsiz(const struct mbuf *, u_int, struct inpcb *); -extern size_t ipsec_hdrsiz_tcp(struct tcpcb *); union sockaddr_union; extern char *ipsec_address(union sockaddr_union *, char *, socklen_t);