Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Jan 2017 12:54:12 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r311100 - projects/ipsec/sys/netipsec
Message-ID:  <201701021254.v02CsC44090574@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Mon Jan  2 12:54:12 2017
New Revision: 311100
URL: https://svnweb.freebsd.org/changeset/base/311100

Log:
  Move ipsec_setspidx_inpcb() into ipsec_pcb.c.
  
  Use it to initialize secpolicyindex in ipsec_copy_pcbpolicy().
  If listening socket has PCB security policy, it will be inherited to
  new connection and secpolicyindex will exactly match new TCP session.

Modified:
  projects/ipsec/sys/netipsec/ipsec.c
  projects/ipsec/sys/netipsec/ipsec.h
  projects/ipsec/sys/netipsec/ipsec_pcb.c

Modified: projects/ipsec/sys/netipsec/ipsec.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.c	Mon Jan  2 12:17:31 2017	(r311099)
+++ projects/ipsec/sys/netipsec/ipsec.c	Mon Jan  2 12:54:12 2017	(r311100)
@@ -256,8 +256,6 @@ SYSCTL_VNET_PCPUSTAT(_net_inet6_ipsec6, 
 
 static int ipsec_in_reject(struct secpolicy *, struct inpcb *,
     const struct mbuf *);
-static void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *,
-    u_int);
 
 static void ipsec4_get_ulp(const struct mbuf *, struct secpolicyindex *, int);
 static void ipsec4_setspidx_ipaddr(const struct mbuf *,
@@ -376,101 +374,6 @@ ipsec_getpcbpolicy(struct inpcb *inp, u_
 	return (sp);
 }
 
-static void
-ipsec_setsockaddrs_inpcb(struct inpcb *inp, union sockaddr_union *src,
-    union sockaddr_union *dst, u_int dir)
-{
-
-#ifdef INET6
-	if (inp->inp_vflag & INP_IPV6) {
-		struct sockaddr_in6 *sin6;
-
-		bzero(&src->sin6, sizeof(src->sin6));
-		bzero(&dst->sin6, sizeof(dst->sin6));
-		src->sin6.sin6_family = AF_INET6;
-		src->sin6.sin6_len = sizeof(struct sockaddr_in6);
-		dst->sin6.sin6_family = AF_INET6;
-		dst->sin6.sin6_len = sizeof(struct sockaddr_in6);
-
-		if (dir == IPSEC_DIR_OUTBOUND)
-			sin6 = &src->sin6;
-		else
-			sin6 = &dst->sin6;
-		sin6->sin6_addr = inp->in6p_laddr;
-		sin6->sin6_port = inp->inp_lport;
-		if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_laddr)) {
-			/* XXXAE: use in6p_zoneid */
-			sin6->sin6_addr.s6_addr16[1] = 0;
-			sin6->sin6_scope_id = ntohs(
-			    inp->in6p_laddr.s6_addr16[1]);
-		}
-
-		if (dir == IPSEC_DIR_OUTBOUND)
-			sin6 = &dst->sin6;
-		else
-			sin6 = &src->sin6;
-		sin6->sin6_addr = inp->in6p_faddr;
-		sin6->sin6_port = inp->inp_fport;
-		if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_faddr)) {
-			/* XXXAE: use in6p_zoneid */
-			sin6->sin6_addr.s6_addr16[1] = 0;
-			sin6->sin6_scope_id = ntohs(
-			    inp->in6p_faddr.s6_addr16[1]);
-		}
-	}
-#endif
-#ifdef INET
-	if (inp->inp_vflag & INP_IPV4) {
-		struct sockaddr_in *sin;
-
-		bzero(&src->sin, sizeof(src->sin));
-		bzero(&dst->sin, sizeof(dst->sin));
-		src->sin.sin_family = AF_INET;
-		src->sin.sin_len = sizeof(struct sockaddr_in);
-		dst->sin.sin_family = AF_INET;
-		dst->sin.sin_len = sizeof(struct sockaddr_in);
-
-		if (dir == IPSEC_DIR_OUTBOUND)
-			sin = &src->sin;
-		else
-			sin = &dst->sin;
-		sin->sin_addr = inp->inp_laddr;
-		sin->sin_port = inp->inp_lport;
-
-		if (dir == IPSEC_DIR_OUTBOUND)
-			sin = &dst->sin;
-		else
-			sin = &src->sin;
-		sin->sin_addr = inp->inp_faddr;
-		sin->sin_port = inp->inp_fport;
-	}
-#endif
-}
-
-static void
-ipsec_setspidx_inpcb(struct inpcb *inp, struct secpolicyindex *spidx,
-    u_int dir)
-{
-
-	ipsec_setsockaddrs_inpcb(inp, &spidx->src, &spidx->dst, dir);
-#ifdef INET6
-	if (inp->inp_vflag & INP_IPV6) {
-		spidx->prefs = sizeof(struct in6_addr) << 3;
-		spidx->prefd = sizeof(struct in6_addr) << 3;
-	}
-#endif
-#ifdef INET
-	if (inp->inp_vflag & INP_IPV4) {
-		spidx->prefs = sizeof(struct in_addr) << 3;
-		spidx->prefd = sizeof(struct in_addr) << 3;
-	}
-#endif
-	spidx->ul_proto = inp->inp_ip_p;
-	spidx->dir = dir;
-	KEYDBG(IPSEC_DUMP,
-	    printf("%s: ", __func__); kdebug_secpolicyindex(spidx, NULL));
-}
-
 #ifdef INET
 static void
 ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *spidx,

Modified: projects/ipsec/sys/netipsec/ipsec.h
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.h	Mon Jan  2 12:17:31 2017	(r311099)
+++ projects/ipsec/sys/netipsec/ipsec.h	Mon Jan  2 12:54:12 2017	(r311100)
@@ -320,6 +320,8 @@ int ipsec_chkreplay(uint32_t, struct sec
 int ipsec_updatereplay(uint32_t, struct secasvar *);
 int ipsec_updateid(struct secasvar *, uint64_t *, uint64_t *);
 
+void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *, u_int);
+
 void ipsec4_setsockaddrs(const struct mbuf *, union sockaddr_union *,
     union sockaddr_union *);
 int ipsec4_in_reject(const struct mbuf *, struct inpcb *);

Modified: projects/ipsec/sys/netipsec/ipsec_pcb.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec_pcb.c	Mon Jan  2 12:17:31 2017	(r311099)
+++ projects/ipsec/sys/netipsec/ipsec_pcb.c	Mon Jan  2 12:54:12 2017	(r311100)
@@ -54,6 +54,101 @@ __FBSDID("$FreeBSD$");
 
 MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
 
+static void
+ipsec_setsockaddrs_inpcb(struct inpcb *inp, union sockaddr_union *src,
+    union sockaddr_union *dst, u_int dir)
+{
+
+#ifdef INET6
+	if (inp->inp_vflag & INP_IPV6) {
+		struct sockaddr_in6 *sin6;
+
+		bzero(&src->sin6, sizeof(src->sin6));
+		bzero(&dst->sin6, sizeof(dst->sin6));
+		src->sin6.sin6_family = AF_INET6;
+		src->sin6.sin6_len = sizeof(struct sockaddr_in6);
+		dst->sin6.sin6_family = AF_INET6;
+		dst->sin6.sin6_len = sizeof(struct sockaddr_in6);
+
+		if (dir == IPSEC_DIR_OUTBOUND)
+			sin6 = &src->sin6;
+		else
+			sin6 = &dst->sin6;
+		sin6->sin6_addr = inp->in6p_laddr;
+		sin6->sin6_port = inp->inp_lport;
+		if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_laddr)) {
+			/* XXXAE: use in6p_zoneid */
+			sin6->sin6_addr.s6_addr16[1] = 0;
+			sin6->sin6_scope_id = ntohs(
+			    inp->in6p_laddr.s6_addr16[1]);
+		}
+
+		if (dir == IPSEC_DIR_OUTBOUND)
+			sin6 = &dst->sin6;
+		else
+			sin6 = &src->sin6;
+		sin6->sin6_addr = inp->in6p_faddr;
+		sin6->sin6_port = inp->inp_fport;
+		if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_faddr)) {
+			/* XXXAE: use in6p_zoneid */
+			sin6->sin6_addr.s6_addr16[1] = 0;
+			sin6->sin6_scope_id = ntohs(
+			    inp->in6p_faddr.s6_addr16[1]);
+		}
+	}
+#endif
+#ifdef INET
+	if (inp->inp_vflag & INP_IPV4) {
+		struct sockaddr_in *sin;
+
+		bzero(&src->sin, sizeof(src->sin));
+		bzero(&dst->sin, sizeof(dst->sin));
+		src->sin.sin_family = AF_INET;
+		src->sin.sin_len = sizeof(struct sockaddr_in);
+		dst->sin.sin_family = AF_INET;
+		dst->sin.sin_len = sizeof(struct sockaddr_in);
+
+		if (dir == IPSEC_DIR_OUTBOUND)
+			sin = &src->sin;
+		else
+			sin = &dst->sin;
+		sin->sin_addr = inp->inp_laddr;
+		sin->sin_port = inp->inp_lport;
+
+		if (dir == IPSEC_DIR_OUTBOUND)
+			sin = &dst->sin;
+		else
+			sin = &src->sin;
+		sin->sin_addr = inp->inp_faddr;
+		sin->sin_port = inp->inp_fport;
+	}
+#endif
+}
+
+void
+ipsec_setspidx_inpcb(struct inpcb *inp, struct secpolicyindex *spidx,
+    u_int dir)
+{
+
+	ipsec_setsockaddrs_inpcb(inp, &spidx->src, &spidx->dst, dir);
+#ifdef INET6
+	if (inp->inp_vflag & INP_IPV6) {
+		spidx->prefs = sizeof(struct in6_addr) << 3;
+		spidx->prefd = sizeof(struct in6_addr) << 3;
+	}
+#endif
+#ifdef INET
+	if (inp->inp_vflag & INP_IPV4) {
+		spidx->prefs = sizeof(struct in_addr) << 3;
+		spidx->prefd = sizeof(struct in_addr) << 3;
+	}
+#endif
+	spidx->ul_proto = IPPROTO_TCP; /* XXX: currently only TCP uses this */
+	spidx->dir = dir;
+	KEYDBG(IPSEC_DUMP,
+	    printf("%s: ", __func__); kdebug_secpolicyindex(spidx, NULL));
+}
+
 /* Initialize PCB policy. */
 int
 ipsec_init_pcbpolicy(struct inpcb *inp)
@@ -104,6 +199,7 @@ ipsec_deepcopy_pcbpolicy(struct secpolic
 	if (dst == NULL)
 		return (NULL);
 
+	/* spidx is not copied here */
 	dst->policy = src->policy;
 	dst->state = src->state;
 	dst->priority = src->priority;
@@ -153,6 +249,7 @@ ipsec_copy_pcbpolicy(struct inpcb *old, 
 		sp = ipsec_deepcopy_pcbpolicy(old->inp_sp->sp_in);
 		if (sp == NULL)
 			return (ENOBUFS);
+		ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_INBOUND);
 		new->inp_sp->sp_in = sp;
 		new->inp_sp->flags |= INP_INBOUND_POLICY;
 	}
@@ -160,6 +257,7 @@ ipsec_copy_pcbpolicy(struct inpcb *old, 
 		sp = ipsec_deepcopy_pcbpolicy(old->inp_sp->sp_out);
 		if (sp == NULL)
 			return (ENOBUFS);
+		ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_OUTBOUND);
 		new->inp_sp->sp_out = sp;
 		new->inp_sp->flags |= INP_OUTBOUND_POLICY;
 	}
@@ -206,6 +304,7 @@ ipsec_set_pcbpolicy(struct inpcb *inp, s
 		if (newsp == NULL)
 			return (error);
 		newsp->state = IPSEC_SPSTATE_PCB;
+		newsp->spidx.ul_proto = IPSEC_ULPROTO_ANY;
 #ifdef INET
 		if (inp->inp_vflag & INP_IPV4) {
 			newsp->spidx.src.sin.sin_family =



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701021254.v02CsC44090574>