Date: Sun, 20 Nov 2016 17:50:18 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308893 - projects/ipsec/sys/netipsec Message-ID: <201611201750.uAKHoIjT087192@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611201750.uAKHoIjT087192>