Skip site navigation (1)Skip section navigation (2)
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>