Subject: Re: FYI: Fix for (non-IPsec) IPv6 with FAST_IPSEC
To: None <tls@rek.tjls.com>
From: Jonathan Stone <jonathan@dsg.stanford.edu>
List: tech-net
Date: 04/27/2004 14:21:33
In message <20040426213550.GA13945@panix.com>Thor Lancelot Simon writes

I alrady committed a manpage for fast_ispec(4) that warns very thorougly
against attempting to apply FAST_IPSEC IPsec protection to IPv6
traffic. I plan to request  a pullup for that manpage.

The following patch has rather klunky wording, but finds and rejects,
and warns about, all my attempts to set a v6-related SPD.

I intend to commit it and request a pullup; then make the check
sysctl'able (purely for development purposes: I cant work on V6 for
FAST_IPSEC unless I can create SPDs). So please give any comments,
feedback, improved wording now, to make the pullup process easier.

Index: sys/netipsec/key.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/key.c,v
retrieving revision 1.13
diff -u -r1.13 key.c
--- sys/netipsec/key.c	26 Apr 2004 01:41:15 -0000	1.13
+++ sys/netipsec/key.c	27 Apr 2004 20:14:00 -0000
@@ -1731,6 +1731,32 @@
 	dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
 	xpl0 = (struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY];
 
+#if defined(__NetBSD__) && defined(INET6)
+	/*
+	 * On NetBSD, FAST_IPSEC and INET6 can be configured together,
+	 * but FAST_IPSEC does not protect IPv6 traffic.
+	 * Rather than silently leaking IPv6 traffic for which IPsec
+	 * is configured, forbid  specifying IPsec for IPv6 traffic.
+	 *
+	 * (On FreeBSD, both FAST_IPSEC and INET6 gives a compile-time error.)
+	 */
+	if (((const struct sockaddr *)(src0 + 1))->sa_family == AF_INET6 ||
+	    ((const struct sockaddr *)(dst0 + 1))->sa_family == AF_INET6) {
+		static int v6_warned = 0;
+
+		if (v6_warned == 0) {
+			printf("key_spdadd: FAST_IPSEC does not support IPv6.");
+			printf("Check syslog for more per-SPD warnings.\n");
+			v6_warned++;
+		}
+		log(LOG_WARNING,
+		    "FAST_IPSEC does not support PF_INET6 SPDs. "
+		    "Request refused.\n");
+
+		return EOPNOTSUPP;	/* EPROTOTYPE?  EAFNOSUPPORT? */
+	}
+#endif /* __NetBSD__ && INET6 */
+
 	/* make secindex */
 	/* XXX boundary check against sa_len */
 	KEY_SETSECSPIDX(xpl0->sadb_x_policy_dir,