Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Nov 2016 16:16:55 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r308890 - projects/ipsec/sys/netipsec
Message-ID:  <201611201616.uAKGGtSi050603@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Sun Nov 20 16:16:55 2016
New Revision: 308890
URL: https://svnweb.freebsd.org/changeset/base/308890

Log:
  Add ipsec6_getpolicy(), ipsec6_checkpolicy() and ipsec6_in_reject().
  
  They are complete analogue of corresponding IPv4 functions.
  Also change ipsec6_setspidx_ipaddr() to not return value since it
  can't fail.
  Remove now unused ipsec46_in_reject().

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

Modified: projects/ipsec/sys/netipsec/ipsec.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.c	Sun Nov 20 16:03:30 2016	(r308889)
+++ projects/ipsec/sys/netipsec/ipsec.c	Sun Nov 20 16:16:55 2016	(r308890)
@@ -252,7 +252,8 @@ static void ipsec4_setspidx_ipaddr(const
     struct secpolicyindex *);
 #ifdef INET6
 static void ipsec6_get_ulp(const struct mbuf *m, struct secpolicyindex *, int);
-static int ipsec6_setspidx_ipaddr(const struct mbuf *, struct secpolicyindex *);
+static void ipsec6_setspidx_ipaddr(const struct mbuf *,
+    struct secpolicyindex *);
 #endif
 static void ipsec_delpcbpolicy(struct inpcbpolicy *);
 static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
@@ -891,7 +892,7 @@ ipsec6_get_ulp(const struct mbuf *m, str
 }
 
 /* Assumes that m is sane. */
-static int
+static void
 ipsec6_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx)
 {
 	struct ip6_hdr ip6buf;
@@ -926,9 +927,77 @@ ipsec6_setspidx_ipaddr(const struct mbuf
 		sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
 	}
 	spidx->prefd = sizeof(struct in6_addr) << 3;
+}
 
-	return (0);
+static struct secpolicy *
+ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir)
+{
+	struct secpolicyindex spidx;
+	struct secpolicy *sp;
+
+	sp = ipsec_getpcbpolicy(inp, dir);
+	if (sp == NULL && key_havesp(dir)) {
+		/* Make an index to look for a policy. */
+		ipsec6_setspidx_ipaddr(m, &spidx);
+		/* Fill ports in spidx if we have inpcb. */
+		ipsec6_get_ulp(m, &spidx, inp != NULL);
+		spidx.dir = dir;
+		sp = key_allocsp(&spidx, dir);
+	}
+	if (sp == NULL)		/* No SP found, use system default. */
+		sp = key_allocsp_default();
+	return (sp);
 }
+
+/*
+ * Check security policy for *OUTBOUND* IPv6 packet.
+ */
+struct secpolicy *
+ipsec6_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error)
+{
+	struct secpolicy *sp;
+
+	*error = 0;
+	sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_OUTBOUND);
+	if (sp != NULL)
+		sp = ipsec_checkpolicy(sp, inp, error);
+	if (sp == NULL) {
+		switch (*error) {
+		case 0: /* No IPsec required: BYPASS or NONE */
+			break;
+		case -EINVAL:
+			IPSEC6STAT_INC(ips_out_polvio);
+			break;
+		default:
+			IPSEC6STAT_INC(ips_out_inval);
+		}
+	}
+	KEYDBG(IPSEC_STAMP,
+	    printf("%s: using SP(%p), error %d\n", __func__, sp, *error));
+	if (sp != NULL)
+		KEYDBG(IPSEC_DATA, kdebug_secpolicy(sp));
+	return (sp);
+}
+
+/*
+ * Check IPv6 packet against inbound security policy.
+ * This function is called from tcp6_input(), udp6_input(),
+ * rip6_input() and sctp_input().
+ */
+int
+ipsec6_in_reject(const struct mbuf *m, struct inpcb *inp)
+{
+	struct secpolicy *sp;
+	int result;
+
+	sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_INBOUND);
+	result = ipsec_in_reject(sp, inp, m);
+	key_freesp(&sp);
+	if (result)
+		IPSEC6STAT_INC(ips_in_polvio);
+	return (result);
+}
+
 #endif
 
 int
@@ -1478,55 +1547,6 @@ ipsec_in_reject(struct secpolicy *sp, st
 }
 
 /*
- * Non zero return value means security policy DISCARD or policy violation.
- */
-static int
-ipsec46_in_reject(const struct mbuf *m, struct inpcb *inp)
-{
-	struct secpolicy *sp;
-	int error;
-	int result;
-
-	if (!key_havesp(IPSEC_DIR_INBOUND))
-		return 0;
-
-	IPSEC_ASSERT(m != NULL, ("null mbuf"));
-
-	/* Get SP for this packet. */
-	if (inp == NULL)
-		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, &error);
-	else
-		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
-
-	if (sp != NULL) {
-		result = ipsec_in_reject(sp, m);
-		KEY_FREESP(&sp);
-	} else {
-		result = 1;	/* treat errors as policy violation */
-	}
-	return (result);
-}
-
-#ifdef INET6
-/*
- * Check AH/ESP integrity.
- * This function is called from tcp6_input(), udp6_input(),
- * and {ah,esp}6_input for tunnel mode.
- */
-int
-ipsec6_in_reject(const struct mbuf *m, struct inpcb *inp)
-{
-	int result;
-
-	result = ipsec46_in_reject(m, inp);
-	if (result)
-		IPSEC6STAT_INC(ips_in_polvio);
-
-	return (result);
-}
-#endif
-
-/*
  * 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.



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