Module Name:    src
Committed By:   christos
Date:           Fri May 30 01:39:03 UTC 2014

Modified Files:
        src/sys/netinet: in.h in_pcb.c in_pcb_hdr.h ip_icmp.c ip_input.c
            ip_output.c raw_ip.c tcp_input.c tcp_output.c udp_usrreq.c
        src/sys/netinet6: icmp6.c in6.h in6_pcb.c ip6_forward.c ip6_input.c
            ip6_output.c raw_ip6.c udp6_usrreq.c
        src/sys/netipsec: ipsec.c ipsec.h ipsec_netbsd.c key.c key.h

Log Message:
Introduce 2 new variables: ipsec_enabled and ipsec_used.
Ipsec enabled is controlled by sysctl and determines if is allowed.
ipsec_used is set automatically based on ipsec being enabled, and
rules existing.


To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.91 src/sys/netinet/in.h
cvs rdiff -u -r1.147 -r1.148 src/sys/netinet/in_pcb.c
cvs rdiff -u -r1.10 -r1.11 src/sys/netinet/in_pcb_hdr.h
cvs rdiff -u -r1.133 -r1.134 src/sys/netinet/ip_icmp.c
cvs rdiff -u -r1.316 -r1.317 src/sys/netinet/ip_input.c
cvs rdiff -u -r1.228 -r1.229 src/sys/netinet/ip_output.c
cvs rdiff -u -r1.123 -r1.124 src/sys/netinet/raw_ip.c
cvs rdiff -u -r1.331 -r1.332 src/sys/netinet/tcp_input.c
cvs rdiff -u -r1.175 -r1.176 src/sys/netinet/tcp_output.c
cvs rdiff -u -r1.198 -r1.199 src/sys/netinet/udp_usrreq.c
cvs rdiff -u -r1.167 -r1.168 src/sys/netinet6/icmp6.c
cvs rdiff -u -r1.75 -r1.76 src/sys/netinet6/in6.h
cvs rdiff -u -r1.124 -r1.125 src/sys/netinet6/in6_pcb.c
cvs rdiff -u -r1.72 -r1.73 src/sys/netinet6/ip6_forward.c
cvs rdiff -u -r1.145 -r1.146 src/sys/netinet6/ip6_input.c
cvs rdiff -u -r1.156 -r1.157 src/sys/netinet6/ip6_output.c
cvs rdiff -u -r1.117 -r1.118 src/sys/netinet6/raw_ip6.c
cvs rdiff -u -r1.97 -r1.98 src/sys/netinet6/udp6_usrreq.c
cvs rdiff -u -r1.62 -r1.63 src/sys/netipsec/ipsec.c
cvs rdiff -u -r1.34 -r1.35 src/sys/netipsec/ipsec.h
cvs rdiff -u -r1.36 -r1.37 src/sys/netipsec/ipsec_netbsd.c
cvs rdiff -u -r1.87 -r1.88 src/sys/netipsec/key.c
cvs rdiff -u -r1.12 -r1.13 src/sys/netipsec/key.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/in.h
diff -u src/sys/netinet/in.h:1.90 src/sys/netinet/in.h:1.91
--- src/sys/netinet/in.h:1.90	Thu May 22 18:01:12 2014
+++ src/sys/netinet/in.h	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.h,v 1.90 2014/05/22 22:01:12 rmind Exp $	*/
+/*	$NetBSD: in.h,v 1.91 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -282,9 +282,7 @@ struct ip_opts {
 #define	IP_PORTRANGE		19   /* int; range to use for ephemeral port */
 #define	IP_RECVIF		20   /* bool; receive reception if w/dgram */
 #define	IP_ERRORMTU		21   /* int; get MTU of last xmit = EMSGSIZE */
-#if 1 /*IPSEC*/
-#define	IP_IPSEC_POLICY		22 /* struct; get/set security policy */
-#endif
+#define	IP_IPSEC_POLICY		22   /* struct; get/set security policy */
 #define	IP_RECVTTL		23   /* bool; receive IP TTL w/dgram */
 #define	IP_MINTTL		24   /* minimum TTL for packet or drop */
 #define	IP_PKTINFO		25   /* int; send interface and src addr */

Index: src/sys/netinet/in_pcb.c
diff -u src/sys/netinet/in_pcb.c:1.147 src/sys/netinet/in_pcb.c:1.148
--- src/sys/netinet/in_pcb.c:1.147	Thu May 22 18:01:12 2014
+++ src/sys/netinet/in_pcb.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_pcb.c,v 1.147 2014/05/22 22:01:12 rmind Exp $	*/
+/*	$NetBSD: in_pcb.c,v 1.148 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.147 2014/05/22 22:01:12 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.148 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -191,9 +191,6 @@ in_pcballoc(struct socket *so, void *v)
 	struct inpcbtable *table = v;
 	struct inpcb *inp;
 	int s;
-#if defined(IPSEC)
-	int error;
-#endif
 
 	s = splnet();
 	inp = pool_get(&inpcb_pool, PR_NOWAIT);
@@ -208,12 +205,14 @@ in_pcballoc(struct socket *so, void *v)
 	inp->inp_portalgo = PORTALGO_DEFAULT;
 	inp->inp_bindportonsend = false;
 #if defined(IPSEC)
-	error = ipsec_init_pcbpolicy(so, &inp->inp_sp);
-	if (error != 0) {
-		s = splnet();
-		pool_put(&inpcb_pool, inp);
-		splx(s);
-		return error;
+	if (ipsec_enabled) {
+		int error = ipsec_init_pcbpolicy(so, &inp->inp_sp);
+		if (error != 0) {
+			s = splnet();
+			pool_put(&inpcb_pool, inp);
+			splx(s);
+			return error;
+		}
 	}
 #endif
 	so->so_pcb = inp;
@@ -556,7 +555,7 @@ in_pcbconnect(void *v, struct mbuf *nam,
 
 	in_pcbstate(inp, INP_CONNECTED);
 #if defined(IPSEC)
-	if (inp->inp_socket->so_type == SOCK_STREAM)
+	if (ipsec_enabled && inp->inp_socket->so_type == SOCK_STREAM)
 		ipsec_pcbconn(inp->inp_sp);
 #endif
 	return (0);
@@ -574,7 +573,8 @@ in_pcbdisconnect(void *v)
 	inp->inp_fport = 0;
 	in_pcbstate(inp, INP_BOUND);
 #if defined(IPSEC)
-	ipsec_pcbdisconn(inp->inp_sp);
+	if (ipsec_enabled)
+		ipsec_pcbdisconn(inp->inp_sp);
 #endif
 	if (inp->inp_socket->so_state & SS_NOFDREF)
 		in_pcbdetach(inp);
@@ -591,8 +591,9 @@ in_pcbdetach(void *v)
 		return;
 
 #if defined(IPSEC)
-	ipsec4_delete_pcbpolicy(inp);
-#endif /*IPSEC*/
+	if (ipsec_enabled)
+		ipsec4_delete_pcbpolicy(inp);
+#endif /* IPSEC */
 	so->so_pcb = 0;
 	if (inp->inp_options)
 		(void)m_free(inp->inp_options);

Index: src/sys/netinet/in_pcb_hdr.h
diff -u src/sys/netinet/in_pcb_hdr.h:1.10 src/sys/netinet/in_pcb_hdr.h:1.11
--- src/sys/netinet/in_pcb_hdr.h:1.10	Sat Nov 23 17:23:26 2013
+++ src/sys/netinet/in_pcb_hdr.h	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_pcb_hdr.h,v 1.10 2013/11/23 22:23:26 christos Exp $	*/
+/*	$NetBSD: in_pcb_hdr.h,v 1.11 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 2003 WIDE Project.
@@ -80,9 +80,7 @@ struct inpcb_hdr {
 	int       inph_portalgo;
 	struct	  socket *inph_socket;	/* back pointer to socket */
 	struct	  inpcbtable *inph_table;
-#if 1 /* IPSEC */
 	struct	  inpcbpolicy *inph_sp;	/* security policy */
-#endif
 };
 
 #define	sotoinpcb_hdr(so)	((struct inpcb_hdr *)(so)->so_pcb)

Index: src/sys/netinet/ip_icmp.c
diff -u src/sys/netinet/ip_icmp.c:1.133 src/sys/netinet/ip_icmp.c:1.134
--- src/sys/netinet/ip_icmp.c:1.133	Sun May 18 22:51:25 2014
+++ src/sys/netinet/ip_icmp.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_icmp.c,v 1.133 2014/05/19 02:51:25 rmind Exp $	*/
+/*	$NetBSD: ip_icmp.c,v 1.134 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -94,7 +94,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.133 2014/05/19 02:51:25 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.134 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_ipsec.h"
 
@@ -638,7 +638,8 @@ reflect:
 
 		pfctlinput(PRC_REDIRECT_HOST, sintosa(&icmpsrc));
 #if defined(IPSEC)
-		key_sa_routechange((struct sockaddr *)&icmpsrc);
+		if (ipsec_used)
+			key_sa_routechange((struct sockaddr *)&icmpsrc);
 #endif
 		break;
 

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.316 src/sys/netinet/ip_input.c:1.317
--- src/sys/netinet/ip_input.c:1.316	Thu May 29 19:02:48 2014
+++ src/sys/netinet/ip_input.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.316 2014/05/29 23:02:48 rmind Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.317 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.316 2014/05/29 23:02:48 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.317 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -522,7 +522,7 @@ ip_input(struct mbuf *m)
 	 * in the list may have previously cleared it.
 	 */
 #if defined(IPSEC)
-	if (!ipsec_indone(m))
+	if (!ipsec_used || !ipsec_indone(m))
 #else
 	if (1)
 #endif
@@ -699,7 +699,8 @@ ip_input(struct mbuf *m)
 		}
 #ifdef IPSEC
 		/* Perform IPsec, if any. */
-		if (ipsec4_input(m, IP_FORWARDING | (ip_directedbcast ?
+		if (ipsec_used &&
+		    ipsec4_input(m, IP_FORWARDING | (ip_directedbcast ?
 		    IP_ALLOWBROADCAST : 0)) != 0) {
 			goto bad;
 		}
@@ -738,7 +739,8 @@ ours:
 	 * Note that we do not visit this with protocols with PCB layer
 	 * code - like UDP/TCP/raw IP.
 	 */
-	if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0) {
+	if (ipsec_used &&
+	    (inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0) {
 		if (ipsec4_input(m, 0) != 0) {
 			goto bad;
 		}
@@ -1289,7 +1291,8 @@ ip_forward(struct mbuf *m, int srcrt)
 		if ((rt = rtcache_validate(&ipforward_rt)) != NULL)
 			destmtu = rt->rt_ifp->if_mtu;
 #ifdef IPSEC
-		(void)ipsec4_forward(mcopy, &destmtu);
+		if (ipsec_used)
+			(void)ipsec4_forward(mcopy, &destmtu);
 #endif
 		IP_STATINC(IP_STAT_CANTFRAG);
 		break;

Index: src/sys/netinet/ip_output.c
diff -u src/sys/netinet/ip_output.c:1.228 src/sys/netinet/ip_output.c:1.229
--- src/sys/netinet/ip_output.c:1.228	Thu May 29 19:02:48 2014
+++ src/sys/netinet/ip_output.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.228 2014/05/29 23:02:48 rmind Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.229 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.228 2014/05/29 23:02:48 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.229 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -169,7 +169,9 @@ ip_output(struct mbuf *m0, ...)
 	struct ip_moptions *imo;
 	struct socket *so;
 	va_list ap;
+#ifdef IPSEC
 	struct secpolicy *sp = NULL;
+#endif
 	bool natt_frag = false;
 	bool __unused done = false;
 	union {
@@ -457,10 +459,12 @@ sendit:
 		ip->ip_off |= htons(IP_DF);
 
 #ifdef IPSEC
-	/* Perform IPsec processing, if any. */
-	error = ipsec4_output(m, so, flags, &sp, &mtu, &natt_frag, &done);
-	if (error || done) {
-		goto done;
+	if (ipsec_used) {
+		/* Perform IPsec processing, if any. */
+		error = ipsec4_output(m, so, flags, &sp, &mtu, &natt_frag,
+		    &done);
+		if (error || done)
+			goto done;
 	}
 #endif
 
@@ -622,11 +626,11 @@ sendit:
 		IP_STATINC(IP_STAT_FRAGMENTED);
 done:
 	rtcache_free(&iproute);
-	if (sp) {
 #ifdef IPSEC
+	if (sp) {
 		KEY_FREESP(&sp);
-#endif
 	}
+#endif
 	return error;
 bad:
 	m_freem(m);
@@ -1030,10 +1034,14 @@ ip_ctloutput(int op, struct socket *so, 
 
 #if defined(IPSEC)
 		case IP_IPSEC_POLICY:
-			error = ipsec4_set_policy(inp, sopt->sopt_name,
-			    sopt->sopt_data, sopt->sopt_size, curlwp->l_cred);
-			break;
-#endif /*IPSEC*/
+			if (ipsec_enabled) {
+				error = ipsec4_set_policy(inp, sopt->sopt_name,
+				    sopt->sopt_data, sopt->sopt_size,
+				    curlwp->l_cred);
+				break;
+			}
+			/*FALLTHROUGH*/
+#endif /* IPSEC */
 
 		default:
 			error = ENOPROTOOPT;

Index: src/sys/netinet/raw_ip.c
diff -u src/sys/netinet/raw_ip.c:1.123 src/sys/netinet/raw_ip.c:1.124
--- src/sys/netinet/raw_ip.c:1.123	Thu May 22 19:42:53 2014
+++ src/sys/netinet/raw_ip.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip.c,v 1.123 2014/05/22 23:42:53 rmind Exp $	*/
+/*	$NetBSD: raw_ip.c,v 1.124 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.123 2014/05/22 23:42:53 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.124 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -212,7 +212,8 @@ rip_input(struct mbuf *m, ...)
 			;
 #if defined(IPSEC)
 		/* check AH/ESP integrity. */
-		else if (ipsec4_in_reject_so(m, last->inp_socket)) {
+		else if (ipsec_used &&
+		    ipsec4_in_reject_so(m, last->inp_socket)) {
 			IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
 			/* do not inject data to pcb */
 		}
@@ -226,7 +227,8 @@ rip_input(struct mbuf *m, ...)
 	}
 #if defined(IPSEC)
 	/* check AH/ESP integrity. */
-	if (last != NULL && ipsec4_in_reject_so(m, last->inp_socket)) {
+	if (ipsec_used && last != NULL
+	    && ipsec4_in_reject_so(m, last->inp_socket)) {
 		m_freem(m);
 		IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
 		IP_STATDEC(IP_STAT_DELIVERED);

Index: src/sys/netinet/tcp_input.c
diff -u src/sys/netinet/tcp_input.c:1.331 src/sys/netinet/tcp_input.c:1.332
--- src/sys/netinet/tcp_input.c:1.331	Sat Mar  1 11:46:14 2014
+++ src/sys/netinet/tcp_input.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcp_input.c,v 1.331 2014/03/01 16:46:14 maxv Exp $	*/
+/*	$NetBSD: tcp_input.c,v 1.332 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.331 2014/03/01 16:46:14 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.332 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -1447,19 +1447,22 @@ findpcb:
 			goto dropwithreset_ratelim;
 		}
 #if defined(IPSEC)
-		if (inp && (inp->inp_socket->so_options & SO_ACCEPTCONN) == 0 &&
-		    ipsec4_in_reject(m, inp)) {
-			IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
-			goto drop;
-		}
+		if (ipsec_used) {
+			if (inp &&
+			    (inp->inp_socket->so_options & SO_ACCEPTCONN) == 0
+			    && ipsec4_in_reject(m, inp)) {
+				IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
+				goto drop;
+			}
 #ifdef INET6
-		else if (in6p &&
-		    (in6p->in6p_socket->so_options & SO_ACCEPTCONN) == 0 &&
-		    ipsec6_in_reject_so(m, in6p->in6p_socket)) {
-			IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
-			goto drop;
-		}
+			else if (in6p &&
+			    (in6p->in6p_socket->so_options & SO_ACCEPTCONN) == 0
+			    && ipsec6_in_reject_so(m, in6p->in6p_socket)) {
+				IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
+				goto drop;
+			}
 #endif
+		}
 #endif /*IPSEC*/
 		break;
 #endif /*INET*/
@@ -1490,7 +1493,7 @@ findpcb:
 			goto dropwithreset_ratelim;
 		}
 #if defined(IPSEC)
-		if (in6p
+		if (ipsec_used && in6p
 		    && (in6p->in6p_socket->so_options & SO_ACCEPTCONN) == 0
 		    && ipsec6_in_reject(m, in6p)) {
 			IPSEC6_STATINC(IPSEC_STAT_IN_POLVIO);
@@ -1799,25 +1802,27 @@ findpcb:
 #endif
 
 #if defined(IPSEC)
-				switch (af) {
+				if (ipsec_used) {
+					switch (af) {
 #ifdef INET
-				case AF_INET:
-					if (ipsec4_in_reject_so(m, so)) {
-						IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
+					case AF_INET:
+						if (!ipsec4_in_reject_so(m, so))
+							break;
+						IPSEC_STATINC(
+						    IPSEC_STAT_IN_POLVIO);
 						tp = NULL;
 						goto dropwithreset;
-					}
-					break;
 #endif
 #ifdef INET6
-				case AF_INET6:
-					if (ipsec6_in_reject_so(m, so)) {
-						IPSEC6_STATINC(IPSEC_STAT_IN_POLVIO);
+					case AF_INET6:
+						if (!ipsec6_in_reject_so(m, so))
+							break;
+						IPSEC6_STATINC(
+						    IPSEC_STAT_IN_POLVIO);
 						tp = NULL;
 						goto dropwithreset;
-					}
-					break;
 #endif /*INET6*/
+					}
 				}
 #endif /*IPSEC*/
 
@@ -3128,10 +3133,6 @@ tcp_signature_apply(void *fstate, void *
 struct secasvar *
 tcp_signature_getsav(struct mbuf *m, struct tcphdr *th)
 {
-	struct secasvar *sav;
-#ifdef IPSEC
-	union sockaddr_union dst;
-#endif
 	struct ip *ip;
 	struct ip6_hdr *ip6;
 
@@ -3150,34 +3151,35 @@ tcp_signature_getsav(struct mbuf *m, str
 	}
 
 #ifdef IPSEC
-	/* Extract the destination from the IP header in the mbuf. */
-	memset(&dst, 0, sizeof(union sockaddr_union));
-	if (ip !=NULL) {
-		dst.sa.sa_len = sizeof(struct sockaddr_in);
-		dst.sa.sa_family = AF_INET;
-		dst.sin.sin_addr = ip->ip_dst;
-	} else {
-		dst.sa.sa_len = sizeof(struct sockaddr_in6);
-		dst.sa.sa_family = AF_INET6;
-		dst.sin6.sin6_addr = ip6->ip6_dst;
-	}
+	if (ipsec_used) {
+		union sockaddr_union dst;
+		/* Extract the destination from the IP header in the mbuf. */
+		memset(&dst, 0, sizeof(union sockaddr_union));
+		if (ip != NULL) {
+			dst.sa.sa_len = sizeof(struct sockaddr_in);
+			dst.sa.sa_family = AF_INET;
+			dst.sin.sin_addr = ip->ip_dst;
+		} else {
+			dst.sa.sa_len = sizeof(struct sockaddr_in6);
+			dst.sa.sa_family = AF_INET6;
+			dst.sin6.sin6_addr = ip6->ip6_dst;
+		}
 
-	/*
-	 * Look up an SADB entry which matches the address of the peer.
-	 */
-	sav = KEY_ALLOCSA(&dst, IPPROTO_TCP, htonl(TCP_SIG_SPI), 0, 0);
+		/*
+		 * Look up an SADB entry which matches the address of the peer.
+		 */
+		return KEY_ALLOCSA(&dst, IPPROTO_TCP, htonl(TCP_SIG_SPI), 0, 0);
+	}
 #else
 	if (ip)
-		sav = key_allocsa(AF_INET, (void *)&ip->ip_src,
+		return key_allocsa(AF_INET, (void *)&ip->ip_src,
 		    (void *)&ip->ip_dst, IPPROTO_TCP,
 		    htonl(TCP_SIG_SPI), 0, 0);
 	else
-		sav = key_allocsa(AF_INET6, (void *)&ip6->ip6_src,
+		return key_allocsa(AF_INET6, (void *)&ip6->ip6_src,
 		    (void *)&ip6->ip6_dst, IPPROTO_TCP,
 		    htonl(TCP_SIG_SPI), 0, 0);
 #endif
-
-	return (sav);	/* freesav must be performed by caller */
 }
 
 int
@@ -4034,23 +4036,26 @@ syn_cache_get(struct sockaddr *src, stru
 #endif
 
 #if defined(IPSEC)
-	/*
-	 * we make a copy of policy, instead of sharing the policy,
-	 * for better behavior in terms of SA lookup and dead SA removal.
-	 */
-	if (inp) {
-		/* copy old policy into new socket's */
-		if (ipsec_copy_pcbpolicy(sotoinpcb(oso)->inp_sp, inp->inp_sp))
-			printf("tcp_input: could not copy policy\n");
-	}
+	if (ipsec_used) {
+		/*
+		 * we make a copy of policy, instead of sharing the policy, for
+		 * better behavior in terms of SA lookup and dead SA removal.
+		 */
+		if (inp) {
+			/* copy old policy into new socket's */
+			if (ipsec_copy_pcbpolicy(sotoinpcb(oso)->inp_sp,
+			    inp->inp_sp))
+				printf("tcp_input: could not copy policy\n");
+		}
 #ifdef INET6
-	else if (in6p) {
-		/* copy old policy into new socket's */
-		if (ipsec_copy_pcbpolicy(sotoin6pcb(oso)->in6p_sp,
-		    in6p->in6p_sp))
-			printf("tcp_input: could not copy policy\n");
-	}
+		else if (in6p) {
+			/* copy old policy into new socket's */
+			if (ipsec_copy_pcbpolicy(sotoin6pcb(oso)->in6p_sp,
+			    in6p->in6p_sp))
+				printf("tcp_input: could not copy policy\n");
+		}
 #endif
+	}
 #endif
 
 	/*

Index: src/sys/netinet/tcp_output.c
diff -u src/sys/netinet/tcp_output.c:1.175 src/sys/netinet/tcp_output.c:1.176
--- src/sys/netinet/tcp_output.c:1.175	Wed Jun  5 15:01:26 2013
+++ src/sys/netinet/tcp_output.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcp_output.c,v 1.175 2013/06/05 19:01:26 christos Exp $	*/
+/*	$NetBSD: tcp_output.c,v 1.176 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -135,7 +135,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.175 2013/06/05 19:01:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.176 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -351,7 +351,8 @@ tcp_segsize(struct tcpcb *tp, int *txseg
 #ifdef INET
 	if (inp) {
 #if defined(IPSEC)
-		if (! IPSEC_PCB_SKIP_IPSEC(inp->inp_sp, IPSEC_DIR_OUTBOUND))
+		if (ipsec_used &&
+		    !IPSEC_PCB_SKIP_IPSEC(inp->inp_sp, IPSEC_DIR_OUTBOUND))
 			optlen += ipsec4_hdrsiz_tcp(tp);
 #endif
 		optlen += ip_optlen(inp);
@@ -361,7 +362,8 @@ tcp_segsize(struct tcpcb *tp, int *txseg
 #ifdef INET
 	if (in6p && tp->t_family == AF_INET) {
 #if defined(IPSEC)
-		if (! IPSEC_PCB_SKIP_IPSEC(in6p->in6p_sp, IPSEC_DIR_OUTBOUND))
+		if (ipsec_used &&
+		    !IPSEC_PCB_SKIP_IPSEC(in6p->in6p_sp, IPSEC_DIR_OUTBOUND))
 			optlen += ipsec4_hdrsiz_tcp(tp);
 #endif
 		/* XXX size -= ip_optlen(in6p); */
@@ -369,7 +371,8 @@ tcp_segsize(struct tcpcb *tp, int *txseg
 #endif
 	if (in6p && tp->t_family == AF_INET6) {
 #if defined(IPSEC)
-		if (! IPSEC_PCB_SKIP_IPSEC(in6p->in6p_sp, IPSEC_DIR_OUTBOUND))
+		if (ipsec_used &&
+		    !IPSEC_PCB_SKIP_IPSEC(in6p->in6p_sp, IPSEC_DIR_OUTBOUND))
 			optlen += ipsec6_hdrsiz_tcp(tp);
 #endif
 		optlen += ip6_optlen(in6p);
@@ -627,20 +630,20 @@ tcp_output(struct tcpcb *tp)
 #if defined(INET)
 	has_tso4 = tp->t_inpcb != NULL &&
 #if defined(IPSEC)
-		  IPSEC_PCB_SKIP_IPSEC(tp->t_inpcb->inp_sp,
-		  		       IPSEC_DIR_OUTBOUND) &&
+	    ipsec_used && IPSEC_PCB_SKIP_IPSEC(tp->t_inpcb->inp_sp,
+	    IPSEC_DIR_OUTBOUND) &&
 #endif
-		  (rt = rtcache_validate(&tp->t_inpcb->inp_route)) != NULL &&
-		  (rt->rt_ifp->if_capenable & IFCAP_TSOv4) != 0;
+	    (rt = rtcache_validate(&tp->t_inpcb->inp_route)) != NULL &&
+	    (rt->rt_ifp->if_capenable & IFCAP_TSOv4) != 0;
 #endif /* defined(INET) */
 #if defined(INET6)
 	has_tso6 = tp->t_in6pcb != NULL &&
 #if defined(IPSEC)
-		  IPSEC_PCB_SKIP_IPSEC(tp->t_in6pcb->in6p_sp,
-		  		       IPSEC_DIR_OUTBOUND) &&
+	    ipsec_used && IPSEC_PCB_SKIP_IPSEC(tp->t_in6pcb->in6p_sp,
+	    IPSEC_DIR_OUTBOUND) &&
 #endif
-		  (rt = rtcache_validate(&tp->t_in6pcb->in6p_route)) != NULL &&
-		  (rt->rt_ifp->if_capenable & IFCAP_TSOv6) != 0;
+	    (rt = rtcache_validate(&tp->t_in6pcb->in6p_route)) != NULL &&
+	    (rt->rt_ifp->if_capenable & IFCAP_TSOv6) != 0;
 #endif /* defined(INET6) */
 	has_tso = (has_tso4 || has_tso6) && !alwaysfrag;
 

Index: src/sys/netinet/udp_usrreq.c
diff -u src/sys/netinet/udp_usrreq.c:1.198 src/sys/netinet/udp_usrreq.c:1.199
--- src/sys/netinet/udp_usrreq.c:1.198	Thu May 22 18:56:53 2014
+++ src/sys/netinet/udp_usrreq.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp_usrreq.c,v 1.198 2014/05/22 22:56:53 rmind Exp $	*/
+/*	$NetBSD: udp_usrreq.c,v 1.199 2014/05/30 01:39:03 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.198 2014/05/22 22:56:53 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.199 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -475,7 +475,7 @@ udp4_sendup(struct mbuf *m, int off /* o
 
 #if defined(IPSEC)
 	/* check AH/ESP integrity. */
-	if (so != NULL && ipsec4_in_reject_so(m, so)) {
+	if (ipsec_used && so != NULL && ipsec4_in_reject_so(m, so)) {
 		IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);
 		if ((n = m_copypacket(m, M_DONTWAIT)) != NULL)
 			icmp_error(n, ICMP_UNREACH, ICMP_UNREACH_ADMIN_PROHIBIT,
@@ -1244,7 +1244,9 @@ udp4_espinudp(struct mbuf **mp, int off,
 	m_tag_prepend(m, tag);
 
 #ifdef IPSEC
-	ipsec4_common_input(m, iphdrlen, IPPROTO_ESP);
+	if (ipsec_used)
+		ipsec4_common_input(m, iphdrlen, IPPROTO_ESP);
+	/* XXX: else */
 #else
 	esp4_input(m, iphdrlen);
 #endif

Index: src/sys/netinet6/icmp6.c
diff -u src/sys/netinet6/icmp6.c:1.167 src/sys/netinet6/icmp6.c:1.168
--- src/sys/netinet6/icmp6.c:1.167	Sun May 18 22:51:25 2014
+++ src/sys/netinet6/icmp6.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: icmp6.c,v 1.167 2014/05/19 02:51:25 rmind Exp $	*/
+/*	$NetBSD: icmp6.c,v 1.168 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.167 2014/05/19 02:51:25 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.168 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -2316,7 +2316,8 @@ icmp6_redirect_input(struct mbuf *m, int
 		sockaddr_in6_init(&sdst, &reddst6, 0, 0, 0);
 		pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&sdst);
 #if defined(IPSEC)
-		key_sa_routechange((struct sockaddr *)&sdst);
+		if (ipsec_used)
+			key_sa_routechange((struct sockaddr *)&sdst);
 #endif
 	}
 

Index: src/sys/netinet6/in6.h
diff -u src/sys/netinet6/in6.h:1.75 src/sys/netinet6/in6.h:1.76
--- src/sys/netinet6/in6.h:1.75	Sat Oct 19 11:44:29 2013
+++ src/sys/netinet6/in6.h	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6.h,v 1.75 2013/10/19 15:44:29 christos Exp $	*/
+/*	$NetBSD: in6.h,v 1.76 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $	*/
 
 /*
@@ -403,9 +403,7 @@ extern const struct in6_addr in6addr_lin
 #define IPV6_CHECKSUM		26 /* int; checksum offset for raw socket */
 #define IPV6_V6ONLY		27 /* bool; make AF_INET6 sockets v6 only */
 
-#if 1 /* IPSEC */
 #define IPV6_IPSEC_POLICY	28 /* struct; get/set security policy */
-#endif
 #define IPV6_FAITH		29 /* bool; accept FAITH'ed connections */
 
 /* new socket options introduced in RFC3542 */

Index: src/sys/netinet6/in6_pcb.c
diff -u src/sys/netinet6/in6_pcb.c:1.124 src/sys/netinet6/in6_pcb.c:1.125
--- src/sys/netinet6/in6_pcb.c:1.124	Sat Nov 23 09:20:22 2013
+++ src/sys/netinet6/in6_pcb.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_pcb.c,v 1.124 2013/11/23 14:20:22 christos Exp $	*/
+/*	$NetBSD: in6_pcb.c,v 1.125 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.124 2013/11/23 14:20:22 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.125 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -157,9 +157,6 @@ in6_pcballoc(struct socket *so, void *v)
 	struct inpcbtable *table = v;
 	struct in6pcb *in6p;
 	int s;
-#if defined(IPSEC)
-	int error;
-#endif
 
 	s = splnet();
 	in6p = pool_get(&in6pcb_pool, PR_NOWAIT);
@@ -175,12 +172,14 @@ in6_pcballoc(struct socket *so, void *v)
 	in6p->in6p_portalgo = PORTALGO_DEFAULT;
 	in6p->in6p_bindportonsend = false;
 #if defined(IPSEC)
-	error = ipsec_init_pcbpolicy(so, &in6p->in6p_sp);
-	if (error != 0) {
-		s = splnet();
-		pool_put(&in6pcb_pool, in6p);
-		splx(s);
-		return error;
+	if (ipsec_enabled) {
+		int error = ipsec_init_pcbpolicy(so, &in6p->in6p_sp);
+		if (error != 0) {
+			s = splnet();
+			pool_put(&in6pcb_pool, in6p);
+			splx(s);
+			return error;
+		}
 	}
 #endif /* IPSEC */
 	s = splnet();
@@ -567,7 +566,7 @@ in6_pcbconnect(void *v, struct mbuf *nam
 		in6p->in6p_flowinfo |=
 		    (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
 #if defined(IPSEC)
-	if (in6p->in6p_socket->so_type == SOCK_STREAM)
+	if (ipsec_enabled && in6p->in6p_socket->so_type == SOCK_STREAM)
 		ipsec_pcbconn(in6p->in6p_sp);
 #endif
 	return (0);
@@ -581,7 +580,8 @@ in6_pcbdisconnect(struct in6pcb *in6p)
 	in6_pcbstate(in6p, IN6P_BOUND);
 	in6p->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
 #if defined(IPSEC)
-	ipsec_pcbdisconn(in6p->in6p_sp);
+	if (ipsec_enabled)
+		ipsec_pcbdisconn(in6p->in6p_sp);
 #endif
 	if (in6p->in6p_socket->so_state & SS_NOFDREF)
 		in6_pcbdetach(in6p);
@@ -597,7 +597,8 @@ in6_pcbdetach(struct in6pcb *in6p)
 		return;
 
 #if defined(IPSEC)
-	ipsec6_delete_pcbpolicy(in6p);
+	if (ipsec_enabled)
+		ipsec6_delete_pcbpolicy(in6p);
 #endif /* IPSEC */
 	so->so_pcb = 0;
 	if (in6p->in6p_options)

Index: src/sys/netinet6/ip6_forward.c
diff -u src/sys/netinet6/ip6_forward.c:1.72 src/sys/netinet6/ip6_forward.c:1.73
--- src/sys/netinet6/ip6_forward.c:1.72	Sat Jun 29 17:06:58 2013
+++ src/sys/netinet6/ip6_forward.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_forward.c,v 1.72 2013/06/29 21:06:58 rmind Exp $	*/
+/*	$NetBSD: ip6_forward.c,v 1.73 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: ip6_forward.c,v 1.109 2002/09/11 08:10:17 sakane Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.72 2013/06/29 21:06:58 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.73 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_gateway.h"
 #include "opt_ipsec.h"
@@ -100,9 +100,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	u_int32_t inzone, outzone;
 	struct in6_addr src_in6, dst_in6;
 #ifdef IPSEC
-	struct secpolicy *sp = NULL;
 	int needipsec = 0;
-	int s;
+	struct secpolicy *sp = NULL;
 #endif
 
 	/*
@@ -155,19 +154,21 @@ ip6_forward(struct mbuf *m, int srcrt)
 	mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN));
 
 #ifdef IPSEC
-	/* Check the security policy (SP) for the packet */
+	if (ipsec_used) {
+		/* Check the security policy (SP) for the packet */
 
-	sp = ipsec6_check_policy(m,NULL,0,&needipsec,&error);
-	if (error != 0) {
-		/*
-		 * Hack: -EINVAL is used to signal that a packet
-		 * should be silently discarded.  This is typically
-		 * because we asked key management for an SA and
-		 * it was delayed (e.g. kicked up to IKE).
-		 */
-	if (error == -EINVAL)
-		error = 0;
-	goto freecopy;
+		sp = ipsec6_check_policy(m, NULL, 0, &needipsec, &error);
+		if (error != 0) {
+			/*
+			 * Hack: -EINVAL is used to signal that a packet
+			 * should be silently discarded.  This is typically
+			 * because we asked key management for an SA and
+			 * it was delayed (e.g. kicked up to IKE).
+			 */
+			if (error == -EINVAL)
+				error = 0;
+			goto freecopy;
+		}
 	}
 #endif /* IPSEC */
 
@@ -261,8 +262,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	 * ipsec6_proces_packet will send the packet using ip6_output 
 	 */
 	if (needipsec) {
-		s = splsoftnet();
-		error = ipsec6_process_packet(m,sp->req);
+		int s = splsoftnet();
+		error = ipsec6_process_packet(m, sp->req);
 		splx(s);
 		if (mcopy)
 			goto freecopy;

Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.145 src/sys/netinet6/ip6_input.c:1.146
--- src/sys/netinet6/ip6_input.c:1.145	Tue Feb 25 13:30:12 2014
+++ src/sys/netinet6/ip6_input.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.145 2014/02/25 18:30:12 pooka Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.146 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.145 2014/02/25 18:30:12 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.146 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -257,12 +257,6 @@ ip6_input(struct mbuf *m)
 		struct sockaddr		dst;
 		struct sockaddr_in6	dst6;
 	} u;
-#ifdef IPSEC
-	struct m_tag *mtag;
-	struct tdb_ident *tdbi;
-	struct secpolicy *sp;
-	int s, error;
-#endif
 
 	/*
 	 * make sure we don't have onion peering information into m_tag.
@@ -345,7 +339,7 @@ ip6_input(struct mbuf *m)
 	 * not the decapsulated packet.
 	 */
 #if defined(IPSEC)
-	if (!ipsec_indone(m))
+	if (!ipsec_used || !ipsec_indone(m))
 #else
 	if (1)
 #endif
@@ -753,45 +747,58 @@ ip6_input(struct mbuf *m)
 		}
 
 #ifdef IPSEC
-	/*
-	 * enforce IPsec policy checking if we are seeing last header.
-	 * note that we do not visit this with protocols with pcb layer
-	 * code - like udp/tcp/raw ip.
-	 */
-	if ((inet6sw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0) {
-		/*
-		 * Check if the packet has already had IPsec processing
-		 * done.  If so, then just pass it along.  This tag gets
-		 * set during AH, ESP, etc. input handling, before the
-		 * packet is returned to the ip input queue for delivery.
-		 */
-		mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
-		s = splsoftnet();
-		if (mtag != NULL) {
-			tdbi = (struct tdb_ident *)(mtag + 1);
-			sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
-		} else {
-			sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
-									IP_FORWARDING, &error);
-		}
-		if (sp != NULL) {
+		if (ipsec_used) {
+			struct m_tag *mtag;
+			struct tdb_ident *tdbi;
+			struct secpolicy *sp;
+			int s, error;
+
 			/*
-			 * Check security policy against packet attributes.
+			 * enforce IPsec policy checking if we are seeing last
+			 * header. note that we do not visit this with
+			 * protocols with pcb layer code - like udp/tcp/raw ip.
 			 */
-			error = ipsec_in_reject(sp, m);
-			KEY_FREESP(&sp);
-		} else {
-			/* XXX error stat??? */
-			error = EINVAL;
-			DPRINTF(("ip6_input: no SP, packet discarded\n"));/*XXX*/
+			if ((inet6sw[ip_protox[nxt]].pr_flags
+			    & PR_LASTHDR) != 0) {
+				/*
+				 * Check if the packet has already had IPsec
+				 * processing done. If so, then just pass it
+				 * along. This tag gets set during AH, ESP,
+				 * etc. input handling, before the packet is
+				 * returned to the ip input queue for delivery.
+				 */
+				mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE,
+				    NULL);
+				s = splsoftnet();
+				if (mtag != NULL) {
+					tdbi = (struct tdb_ident *)(mtag + 1);
+					sp = ipsec_getpolicy(tdbi,
+					    IPSEC_DIR_INBOUND);
+				} else {
+					sp = ipsec_getpolicybyaddr(m,
+					    IPSEC_DIR_INBOUND, IP_FORWARDING,
+					    &error);
+				}
+				if (sp != NULL) {
+					/*
+					 * Check security policy against packet
+					 * attributes.
+					 */
+					error = ipsec_in_reject(sp, m);
+					KEY_FREESP(&sp);
+				} else {
+					/* XXX error stat??? */
+					error = EINVAL;
+					DPRINTF(("ip6_input: no SP, packet"
+					    " discarded\n"));/*XXX*/
+				}
+				splx(s);
+				if (error)
+					goto bad;
+			}
 		}
-		splx(s);
-		if (error)
-			goto bad;
-	}
 #endif /* IPSEC */
 
-
 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
 	}
 	return;

Index: src/sys/netinet6/ip6_output.c
diff -u src/sys/netinet6/ip6_output.c:1.156 src/sys/netinet6/ip6_output.c:1.157
--- src/sys/netinet6/ip6_output.c:1.156	Sat May 17 17:26:20 2014
+++ src/sys/netinet6/ip6_output.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_output.c,v 1.156 2014/05/17 21:26:20 rmind Exp $	*/
+/*	$NetBSD: ip6_output.c,v 1.157 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.156 2014/05/17 21:26:20 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.157 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -181,7 +181,6 @@ ip6_output(
 	int needipsec = 0;
 #ifdef IPSEC
 	struct secpolicy *sp = NULL;
-	int s;
 #endif
 
 	memset(&ip6route, 0, sizeof(ip6route));
@@ -241,20 +240,22 @@ ip6_output(
 	if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
 
 #ifdef IPSEC
-	/* Check the security policy (SP) for the packet */
-    
-	sp = ipsec6_check_policy(m,so,flags,&needipsec,&error);
-	if (error != 0) {
-		/*
-		 * Hack: -EINVAL is used to signal that a packet
-		 * should be silently discarded.  This is typically
-		 * because we asked key management for an SA and
-		 * it was delayed (e.g. kicked up to IKE).
-		 */
-	if (error == -EINVAL) 
-		error = 0;
-	goto freehdrs;
-    }
+	if (ipsec_used) {
+		/* Check the security policy (SP) for the packet */
+	    
+		sp = ipsec6_check_policy(m, so, flags, &needipsec, &error);
+		if (error != 0) {
+			/*
+			 * Hack: -EINVAL is used to signal that a packet
+			 * should be silently discarded.  This is typically
+			 * because we asked key management for an SA and
+			 * it was delayed (e.g. kicked up to IKE).
+			 */
+			if (error == -EINVAL) 
+				error = 0;
+			goto freehdrs;
+		}
+	}
 #endif /* IPSEC */
 
 
@@ -464,8 +465,8 @@ ip6_output(
 
 #ifdef IPSEC
 	if (needipsec) {
-		s = splsoftnet();
-		error = ipsec6_process_packet(m,sp->req);
+		int s = splsoftnet();
+		error = ipsec6_process_packet(m, sp->req);
 
 		/*
 		 * Preserve KAME behaviour: ENOENT can be returned
@@ -480,8 +481,6 @@ ip6_output(
 	}
 #endif /* IPSEC */    
 
-
-
 	/* adjust pointer */
 	ip6 = mtod(m, struct ip6_hdr *);
 
@@ -1652,9 +1651,13 @@ else 					\
 
 #if defined(IPSEC)
 		case IPV6_IPSEC_POLICY:
-			error = ipsec6_set_policy(in6p, optname,
-			    sopt->sopt_data, sopt->sopt_size, kauth_cred_get());
-			break;
+			if (ipsec_enabled) {
+				error = ipsec6_set_policy(in6p, optname,
+				    sopt->sopt_data, sopt->sopt_size,
+				    kauth_cred_get());
+				break;
+			}
+			/*FALLTHROUGH*/
 #endif /* IPSEC */
 
 		default:
@@ -1841,17 +1844,20 @@ else 					\
 
 #if defined(IPSEC)
 		case IPV6_IPSEC_POLICY:
-		    {
-			struct mbuf *m = NULL;
+			if (ipsec_used) {
+				struct mbuf *m = NULL;
 
-			/* XXX this will return EINVAL as sopt is empty */
-			error = ipsec6_get_policy(in6p, sopt->sopt_data,
-			    sopt->sopt_size, &m);
-			if (!error)
-				error = sockopt_setmbuf(sopt, m);
-
-			break;
-		    }
+				/*
+				 * XXX: this will return EINVAL as sopt is
+				 * empty
+				 */
+				error = ipsec6_get_policy(in6p, sopt->sopt_data,
+				    sopt->sopt_size, &m);
+				if (!error)
+					error = sockopt_setmbuf(sopt, m);
+				break;
+			}
+			/*FALLTHROUGH*/
 #endif /* IPSEC */
 
 		default:

Index: src/sys/netinet6/raw_ip6.c
diff -u src/sys/netinet6/raw_ip6.c:1.117 src/sys/netinet6/raw_ip6.c:1.118
--- src/sys/netinet6/raw_ip6.c:1.117	Tue May 20 15:04:00 2014
+++ src/sys/netinet6/raw_ip6.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip6.c,v 1.117 2014/05/20 19:04:00 rmind Exp $	*/
+/*	$NetBSD: raw_ip6.c,v 1.118 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.117 2014/05/20 19:04:00 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.118 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_ipsec.h"
 
@@ -204,7 +204,7 @@ rip6_input(struct mbuf **mp, int *offp, 
 			/*
 			 * Check AH/ESP integrity
 			 */
-			if (!ipsec6_in_reject(m,last)) 
+			if (ipsec_used && !ipsec6_in_reject(m, last)) 
 #endif /* IPSEC */
 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
 				if (last->in6p_flags & IN6P_CONTROLOPTS)
@@ -226,7 +226,7 @@ rip6_input(struct mbuf **mp, int *offp, 
 		last = in6p;
 	}
 #ifdef IPSEC
-	if (last && ipsec6_in_reject(m, last)) {
+	if (ipsec_used && last && ipsec6_in_reject(m, last)) {
 		m_freem(m);
 		/*
 		 * XXX ipsec6_in_reject update stat if there is an error

Index: src/sys/netinet6/udp6_usrreq.c
diff -u src/sys/netinet6/udp6_usrreq.c:1.97 src/sys/netinet6/udp6_usrreq.c:1.98
--- src/sys/netinet6/udp6_usrreq.c:1.97	Thu May 22 18:56:53 2014
+++ src/sys/netinet6/udp6_usrreq.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp6_usrreq.c,v 1.97 2014/05/22 22:56:53 rmind Exp $	*/
+/*	$NetBSD: udp6_usrreq.c,v 1.98 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.97 2014/05/22 22:56:53 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.98 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet_csum.h"
@@ -341,7 +341,7 @@ udp6_sendup(struct mbuf *m, int off /* o
 
 #if defined(IPSEC)
 	/* check AH/ESP integrity. */
-	if (so != NULL && ipsec6_in_reject_so(m, so)) {
+	if (ipsec_used && so != NULL && ipsec6_in_reject_so(m, so)) {
 		IPSEC6_STATINC(IPSEC_STAT_IN_POLVIO);
 		if ((n = m_copypacket(m, M_DONTWAIT)) != NULL)
 			icmp6_error(n, ICMP6_DST_UNREACH,

Index: src/sys/netipsec/ipsec.c
diff -u src/sys/netipsec/ipsec.c:1.62 src/sys/netipsec/ipsec.c:1.63
--- src/sys/netipsec/ipsec.c:1.62	Tue Dec 24 10:48:53 2013
+++ src/sys/netipsec/ipsec.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.c,v 1.62 2013/12/24 15:48:53 christos Exp $	*/
+/*	$NetBSD: ipsec.c,v 1.63 2014/05/30 01:39:03 christos Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $	*/
 /*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.62 2013/12/24 15:48:53 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.63 2014/05/30 01:39:03 christos Exp $");
 
 /*
  * IPsec controller part.
@@ -106,6 +106,9 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.
 
 #include <net/net_osdep.h>
 
+int ipsec_used = 0;
+int ipsec_enabled = 1;
+
 #ifdef IPSEC_DEBUG
 int ipsec_debug = 1;
 

Index: src/sys/netipsec/ipsec.h
diff -u src/sys/netipsec/ipsec.h:1.34 src/sys/netipsec/ipsec.h:1.35
--- src/sys/netipsec/ipsec.h:1.34	Sat Jun  8 09:50:22 2013
+++ src/sys/netipsec/ipsec.h	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.h,v 1.34 2013/06/08 13:50:22 rmind Exp $	*/
+/*	$NetBSD: ipsec.h,v 1.35 2014/05/30 01:39:03 christos Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.h,v 1.2.4.2 2004/02/14 22:23:23 bms Exp $	*/
 /*	$KAME: ipsec.h,v 1.53 2001/11/20 08:32:38 itojun Exp $	*/
 
@@ -354,6 +354,7 @@ int ipsec_clear_socket_cache(struct mbuf
 
 void nat_t_ports_get(struct mbuf *, u_int16_t *, u_int16_t *);
 
+extern int ipsec_used __read_mostly, ipsec_enabled __read_mostly;
 
 #endif /* _KERNEL */
 

Index: src/sys/netipsec/ipsec_netbsd.c
diff -u src/sys/netipsec/ipsec_netbsd.c:1.36 src/sys/netipsec/ipsec_netbsd.c:1.37
--- src/sys/netipsec/ipsec_netbsd.c:1.36	Tue Feb 25 13:30:12 2014
+++ src/sys/netipsec/ipsec_netbsd.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_netbsd.c,v 1.36 2014/02/25 18:30:12 pooka Exp $	*/
+/*	$NetBSD: ipsec_netbsd.c,v 1.37 2014/05/30 01:39:03 christos Exp $	*/
 /*	$KAME: esp_input.c,v 1.60 2001/09/04 08:43:19 itojun Exp $	*/
 /*	$KAME: ah_input.c,v 1.64 2001/09/04 08:43:19 itojun Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.36 2014/02/25 18:30:12 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.37 2014/05/30 01:39:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -473,6 +473,34 @@ sysctl_net_inet_ipip_stats(SYSCTLFN_ARGS
 	return (NETSTAT_SYSCTL(ipipstat_percpu, IPIP_NSTATS));
 }
 
+static int
+sysctl_net_ipsec_enabled(SYSCTLFN_ARGS)
+{
+	int newenabled, error;
+	struct sysctlnode node;
+	node = *rnode;
+	node.sysctl_data = &newenabled;
+
+	newenabled = ipsec_enabled;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	switch (newenabled) {
+	case 0:
+		if (key_get_used())
+			return EBUSY;
+		/*FALLTHROUGH*/
+	case 1:
+	case 2:
+		ipsec_enabled = newenabled;
+		key_update_used();
+		return 0;
+	default:
+		return EINVAL;
+	}
+}
+
 /* XXX will need a different oid at parent */
 SYSCTL_SETUP(sysctl_net_inet_ipsec_setup, "sysctl net.inet.ipsec subtree setup")
 {
@@ -660,6 +688,20 @@ SYSCTL_SETUP(sysctl_net_inet_ipsec_setup
 		       sysctl_net_inet_ipsec_stats, 0, NULL, 0,
 		       CTL_NET, PF_INET, ipproto_ipsec,
 		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "enabled",
+		       SYSCTL_DESCR("Enable IPSec processing"),
+		       sysctl_net_ipsec_enabled, 0, NULL, 0,
+		       CTL_NET, PF_INET, ipproto_ipsec,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
+		       CTLTYPE_INT, "used",
+		       SYSCTL_DESCR("Is IPSec active?"),
+		       NULL, 0, &ipsec_used, 0,
+		       CTL_NET, PF_INET, ipproto_ipsec,
+		       CTL_CREATE, CTL_EOL);
 #ifdef IPSEC_DEBUG
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
@@ -755,7 +797,20 @@ SYSCTL_SETUP(sysctl_net_inet6_ipsec6_set
 		       NULL, 0, &ipsec_debug, 0,
 		       CTL_NET, PF_INET6, IPPROTO_AH,
 		       IPSECCTL_DEBUG, CTL_EOL);
-
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "enabled",
+		       SYSCTL_DESCR("Enable IPSec processing"),
+		       sysctl_net_ipsec_enabled, 0, NULL, 0,
+		       CTL_NET, PF_INET6, IPPROTO_AH,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READONLY,
+		       CTLTYPE_INT, "used",
+		       SYSCTL_DESCR("Is IPSec active?"),
+		       NULL, 0, &ipsec_used, 0,
+		       CTL_NET, PF_INET6, IPPROTO_AH,
+		       CTL_CREATE, CTL_EOL);
 	/*
 	 * "aliases" for the ipsec6 subtree
 	 */

Index: src/sys/netipsec/key.c
diff -u src/sys/netipsec/key.c:1.87 src/sys/netipsec/key.c:1.88
--- src/sys/netipsec/key.c:1.87	Sun May 18 22:51:25 2014
+++ src/sys/netipsec/key.c	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.c,v 1.87 2014/05/19 02:51:25 rmind Exp $	*/
+/*	$NetBSD: key.c,v 1.88 2014/05/30 01:39:03 christos Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $	*/
 /*	$KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.87 2014/05/19 02:51:25 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.88 2014/05/30 01:39:03 christos Exp $");
 
 /*
  * This code is referd to RFC 2367
@@ -2007,6 +2007,7 @@ key_spdadd(struct socket *so, struct mbu
 	xpl->sadb_x_policy_id = newsp->id;
 
 	m_freem(m);
+	key_update_used();
 	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
     }
 }
@@ -2139,6 +2140,7 @@ key_spddelete(struct socket *so, struct 
 	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
 
 	m_freem(m);
+	key_update_used();
 	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
     }
 }
@@ -8082,6 +8084,36 @@ key_setspddump(int *errorp, pid_t pid)
 	return (m);
 }
 
+int
+key_get_used(void) {
+	return !LIST_EMPTY(&sptree[IPSEC_DIR_INBOUND]) ||
+	    !LIST_EMPTY(&sptree[IPSEC_DIR_OUTBOUND]);
+}
+
+void
+key_update_used(void)
+{
+	switch (ipsec_enabled) {
+	default:
+	case 0:
+#ifdef notyet
+		/* XXX: racy */
+		ipsec_used = 0;
+#endif
+		break;
+	case 1:
+#ifndef notyet
+		/* XXX: racy */
+		if (!ipsec_used)
+#endif
+		ipsec_used = key_get_used();
+		break;
+	case 2:
+		ipsec_used = 1;
+		break;
+	}
+}
+
 static int
 sysctl_net_key_dumpsa(SYSCTLFN_ARGS)
 {

Index: src/sys/netipsec/key.h
diff -u src/sys/netipsec/key.h:1.12 src/sys/netipsec/key.h:1.13
--- src/sys/netipsec/key.h:1.12	Tue Jun  4 18:47:37 2013
+++ src/sys/netipsec/key.h	Thu May 29 21:39:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.h,v 1.12 2013/06/04 22:47:37 christos Exp $	*/
+/*	$NetBSD: key.h,v 1.13 2014/05/30 01:39:03 christos Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/key.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$KAME: key.h,v 1.21 2001/07/27 03:51:30 itojun Exp $	*/
 
@@ -106,6 +106,8 @@ int key_parse (struct mbuf *, struct soc
 void key_init (void);
 void key_sa_recordxfer (struct secasvar *, struct mbuf *);
 void key_sa_routechange (struct sockaddr *);
+void key_update_used(void);
+int key_get_used(void);
 
 u_int16_t key_portfromsaddr (const union sockaddr_union *);
 

Reply via email to