svn commit: r309358 - projects/ipsec/sys/netipsec

Andrey V. Elsukov ae at FreeBSD.org
Thu Dec 1 11:57:17 UTC 2016


Author: ae
Date: Thu Dec  1 11:57:15 2016
New Revision: 309358
URL: https://svnweb.freebsd.org/changeset/base/309358

Log:
  Add ipsec_setsockaddrs_inpcb() function to fill sockaddr_union unions
  using information from INPCB. Add direction argument, it is used to
  choose local or foreign addresses as source or destination.
  Change ipsec_setspidx_inpcb() function to use ipsec_setsockaddrs_inpcb().

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

Modified: projects/ipsec/sys/netipsec/ipsec.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.c	Thu Dec  1 09:14:58 2016	(r309357)
+++ projects/ipsec/sys/netipsec/ipsec.c	Thu Dec  1 11:57:15 2016	(r309358)
@@ -247,7 +247,8 @@ 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 *);
+static void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *,
+    u_int);
 
 static void ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *, int);
 static void ipsec4_setspidx_ipaddr(const struct mbuf *,
@@ -285,7 +286,7 @@ ipsec_checkpolicy(struct secpolicy *sp, 
 {
 	uint32_t genid;
 
-	if (inp != NULL &&
+	if (inp != NULL && inp->inp_sp != NULL &&
 	    (inp->inp_sp->flags & INP_OUTBOUND_POLICY) == 0 &&
 	    inp->inp_sp->sp_out == NULL) {
 		/*
@@ -369,61 +370,100 @@ ipsec_getpcbpolicy(struct inpcb *inp, u_
 }
 
 static void
-ipsec_setspidx_inpcb(struct inpcb *inp, struct secpolicyindex *spidx)
+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) {
-		bzero(&spidx->src.sin6, sizeof(spidx->src.sin6));
-		spidx->src.sin6.sin6_family = AF_INET6;
-		spidx->src.sin6.sin6_len = sizeof(struct sockaddr_in6);
-		spidx->src.sin6.sin6_addr = inp->in6p_laddr;
-		spidx->src.sin6.sin6_port = inp->inp_lport;
+		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 */
-			spidx->src.sin6.sin6_addr.s6_addr16[1] = 0;
-			spidx->src.sin6.sin6_scope_id = ntohs(
+			sin6->sin6_addr.s6_addr16[1] = 0;
+			sin6->sin6_scope_id = ntohs(
 			    inp->in6p_laddr.s6_addr16[1]);
 		}
-		spidx->prefs = sizeof(struct in6_addr) << 3;
 
-		bzero(&spidx->dst.sin6, sizeof(spidx->dst.sin6));
-		spidx->dst.sin6.sin6_family = AF_INET6;
-		spidx->dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
-		spidx->dst.sin6.sin6_addr = inp->in6p_faddr;
-		spidx->dst.sin6.sin6_port = inp->inp_fport;
+		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 */
-			spidx->dst.sin6.sin6_addr.s6_addr16[1] = 0;
-			spidx->dst.sin6.sin6_scope_id = ntohs(
+			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) {
-		bzero(&spidx->src.sin, sizeof(spidx->src.sin));
-		spidx->src.sin.sin_family = AF_INET;
-		spidx->src.sin.sin_len = sizeof(struct sockaddr_in);
-		spidx->src.sin.sin_addr = inp->inp_laddr;
-		spidx->src.sin.sin_port = inp->inp_lport;
 		spidx->prefs = sizeof(struct in_addr) << 3;
-
-		bzero(&spidx->dst.sin, sizeof(spidx->dst.sin));
-		spidx->dst.sin.sin_family = AF_INET;
-		spidx->dst.sin.sin_len = sizeof(struct sockaddr_in);
-		spidx->dst.sin.sin_addr = inp->inp_faddr;
-		spidx->dst.sin.sin_port = inp->inp_fport;
 		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,
@@ -1408,8 +1448,7 @@ ipsec_hdrsiz_inpcb(struct inpcb *inp)
 
 	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;
+		ipsec_setspidx_inpcb(inp, &spidx, IPSEC_DIR_OUTBOUND);
 		sp = key_allocsp(&spidx, IPSEC_DIR_OUTBOUND);
 	}
 	if (sp == NULL)


More information about the svn-src-projects mailing list