Module Name:    src
Committed By:   rmind
Date:           Sat Jun  8 03:26:05 UTC 2013

Modified Files:
        src/sys/netinet: ip_output.c
        src/sys/netipsec: ipsec.c ipsec.h

Log Message:
Split IPSec logic from ip_output() into a separate routine - ipsec4_output().
No change to the mechanism intended.  Tested by christos@.


To generate a diff of this commit:
cvs rdiff -u -r1.220 -r1.221 src/sys/netinet/ip_output.c
cvs rdiff -u -r1.58 -r1.59 src/sys/netipsec/ipsec.c
cvs rdiff -u -r1.32 -r1.33 src/sys/netipsec/ipsec.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/ip_output.c
diff -u src/sys/netinet/ip_output.c:1.220 src/sys/netinet/ip_output.c:1.221
--- src/sys/netinet/ip_output.c:1.220	Wed Jun  5 19:01:26 2013
+++ src/sys/netinet/ip_output.c	Sat Jun  8 03:26:05 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.220 2013/06/05 19:01:26 christos Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.221 2013/06/08 03:26:05 rmind 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.220 2013/06/05 19:01:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.221 2013/06/08 03:26:05 rmind Exp $");
 
 #include "opt_pfil_hooks.h"
 #include "opt_inet.h"
@@ -132,12 +132,8 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c,
 #include <netinet/ip_mroute.h>
 #endif
 
-#ifdef IPSEC
 #include <netipsec/ipsec.h>
 #include <netipsec/key.h>
-#include <netipsec/xform.h>
-#endif	/* IPSEC*/
-
 
 static struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *);
 static struct ifnet *ip_multicast_if(struct in_addr *, int *);
@@ -171,18 +167,14 @@ ip_output(struct mbuf *m0, ...)
 	struct ifaddr *xifa;
 	struct mbuf *opt;
 	struct route *ro;
-	int flags, sw_csum;
-	int *mtu_p;
+	int flags, sw_csum, *mtu_p;
 	u_long mtu;
 	struct ip_moptions *imo;
 	struct socket *so;
 	va_list ap;
-	int natt_frag = 0;
-#ifdef IPSEC
-	struct inpcb *inp;
 	struct secpolicy *sp = NULL;
-	int s;
-#endif
+	bool natt_frag = false;
+	bool __unused done = false;
 	union {
 		struct sockaddr		dst;
 		struct sockaddr_in	dst4;
@@ -205,12 +197,6 @@ ip_output(struct mbuf *m0, ...)
 	va_end(ap);
 
 	MCLAIM(m, &ip_tx_mowner);
-#ifdef IPSEC
-	if (so != NULL && so->so_proto->pr_domain->dom_family == AF_INET)
-		inp = (struct inpcb *)so->so_pcb;
-	else
-		inp = NULL;
-#endif /* IPSEC */
 
 #ifdef	DIAGNOSTIC
 	if ((m->m_flags & M_PKTHDR) == 0)
@@ -488,94 +474,12 @@ sendit:
 		ip->ip_off |= htons(IP_DF);
 
 #ifdef IPSEC
-	/*
-	 * Check the security policy (SP) for the packet and, if
-	 * required, do IPsec-related processing.  There are two
-	 * cases here; the first time a packet is sent through
-	 * it will be untagged and handled by ipsec4_checkpolicy.
-	 * If the packet is resubmitted to ip_output (e.g. after
-	 * AH, ESP, etc. processing), there will be a tag to bypass
-	 * the lookup and related policy checking.
-	 */
-	if (!ipsec_outdone(m)) {
-		s = splsoftnet();
-		if (inp != NULL &&
-		    IPSEC_PCB_SKIP_IPSEC(inp->inp_sp, IPSEC_DIR_OUTBOUND)) {
-			splx(s);
-			goto spd_done;
-		}
-		sp = ipsec4_checkpolicy(m, IPSEC_DIR_OUTBOUND, flags,
-				&error, inp);
-		/*
-		 * There are four return cases:
-		 *    sp != NULL	 	    apply IPsec policy
-		 *    sp == NULL, error == 0	    no IPsec handling needed
-		 *    sp == NULL, error == -EINVAL  discard packet w/o error
-		 *    sp == NULL, error != 0	    discard packet, report error
-		 */
-		if (sp != NULL) {
-			/*
-			 * NAT-T ESP fragmentation: don't do IPSec processing
-			 * now, we'll do it on each fragmented packet.
-			 */
-			if (sp->req->sav && (sp->req->sav->natt_type &
-			    (UDP_ENCAP_ESPINUDP|UDP_ENCAP_ESPINUDP_NON_IKE))) {
-				if (ntohs(ip->ip_len) > sp->req->sav->esp_frag)
-				{
-					natt_frag = 1;
-					mtu = sp->req->sav->esp_frag;
-					splx(s);
-					goto spd_done;
-				}
-			}
-
-			/*
-			 * Do delayed checksums now because we send before
-			 * this is done in the normal processing path.
-			 */
-			if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
-				in_delayed_cksum(m);
-				m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
-			}
-
-#ifdef __FreeBSD__
-			ip->ip_len = htons(ip->ip_len);
-			ip->ip_off = htons(ip->ip_off);
-#endif
-
-			/* NB: callee frees mbuf */
-			error = ipsec4_process_packet(m, sp->req, flags, 0);
-			/*
-			 * Preserve KAME behaviour: ENOENT can be returned
-			 * when an SA acquire is in progress.  Don't propagate
-			 * this to user-level; it confuses applications.
-			 *
-			 * XXX this will go away when the SADB is redone.
-			 */
-			if (error == ENOENT)
-				error = 0;
-			splx(s);
-			goto done;
-		} else {
-			splx(s);
-
-			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 bad;
-			} else {
-				/* No IPsec processing for this packet. */
-			}
-		}
+	/* Perform IPSec processing, if any. */
+	error = ipsec4_output(m, so, flags, &sp, &mtu, &natt_frag, &done);
+	if (error || done) {
+		goto done;
 	}
-spd_done:
-#endif /* IPSEC */
+#endif
 
 #ifdef PFIL_HOOKS
 	/*
@@ -733,13 +637,12 @@ spd_done:
 		IP_STATINC(IP_STAT_FRAGMENTED);
 done:
 	rtcache_free(&iproute);
-
+	if (sp) {
 #ifdef IPSEC
-	if (sp != NULL)
 		KEY_FREESP(&sp);
-#endif /* IPSEC */
-
-	return (error);
+#endif
+	}
+	return error;
 bad:
 	m_freem(m);
 	goto done;

Index: src/sys/netipsec/ipsec.c
diff -u src/sys/netipsec/ipsec.c:1.58 src/sys/netipsec/ipsec.c:1.59
--- src/sys/netipsec/ipsec.c:1.58	Tue Jun  4 22:47:37 2013
+++ src/sys/netipsec/ipsec.c	Sat Jun  8 03:26:05 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.c,v 1.58 2013/06/04 22:47:37 christos Exp $	*/
+/*	$NetBSD: ipsec.c,v 1.59 2013/06/08 03:26:05 rmind 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.58 2013/06/04 22:47:37 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.59 2013/06/08 03:26:05 rmind Exp $");
 
 /*
  * IPsec controller part.
@@ -733,6 +733,102 @@ ipsec4_checkpolicy(struct mbuf *m, u_int
 	return sp;
 }
 
+int
+ipsec4_output(struct mbuf *m, struct socket *so, int flags,
+    struct secpolicy **sp_out, u_long *mtu, bool *natt_frag, bool *done)
+{
+	const struct ip *ip = mtod(m, const struct ip *);
+	struct secpolicy *sp = NULL;
+	struct inpcb *inp;
+	int error, s;
+
+	inp = (so && so->so_proto->pr_domain->dom_family == AF_INET) ?
+	    (struct inpcb *)so->so_pcb : NULL;
+
+	/*
+	 * Check the security policy (SP) for the packet and, if required,
+	 * do IPsec-related processing.  There are two cases here; the first
+	 * time a packet is sent through it will be untagged and handled by
+	 * ipsec4_checkpolicy().  If the packet is resubmitted to ip_output
+	 * (e.g. after AH, ESP, etc. processing), there will be a tag to
+	 * bypass the lookup and related policy checking.
+	 */
+	if (ipsec_outdone(m)) {
+		return 0;
+	}
+	s = splsoftnet();
+	if (inp && IPSEC_PCB_SKIP_IPSEC(inp->inp_sp, IPSEC_DIR_OUTBOUND)) {
+		splx(s);
+		return 0;
+	}
+	sp = ipsec4_checkpolicy(m, IPSEC_DIR_OUTBOUND, flags, &error, inp);
+
+	/*
+	 * There are four return cases:
+	 *	sp != NULL			apply IPsec policy
+	 *	sp == NULL, error == 0		no IPsec handling needed
+	 *	sp == NULL, error == -EINVAL	discard packet w/o error
+	 *	sp == NULL, error != 0		discard packet, report error
+	 */
+	if (sp == NULL) {
+		splx(s);
+		if (error) {
+			/*
+			 * 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;
+			m_freem(m);
+			*done = true;
+			return error;
+		}
+		/* No IPsec processing for this packet. */
+		return 0;
+	}
+	*sp_out = sp;
+
+	/*
+	 * NAT-T ESP fragmentation: do not do IPSec processing now,
+	 * we will do it on each fragmented packet.
+	 */
+	if (sp->req->sav && (sp->req->sav->natt_type &
+	    (UDP_ENCAP_ESPINUDP|UDP_ENCAP_ESPINUDP_NON_IKE))) {
+		if (ntohs(ip->ip_len) > sp->req->sav->esp_frag) {
+			*mtu = sp->req->sav->esp_frag;
+			*natt_frag = true;
+			splx(s);
+			return 0;
+		}
+	}
+
+	/*
+	 * Do delayed checksums now because we send before
+	 * this is done in the normal processing path.
+	 */
+	if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
+		in_delayed_cksum(m);
+		m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
+	}
+
+	/* Note: callee frees mbuf */
+	error = ipsec4_process_packet(m, sp->req, flags, 0);
+	/*
+	 * Preserve KAME behaviour: ENOENT can be returned
+	 * when an SA acquire is in progress.  Don't propagate
+	 * this to user-level; it confuses applications.
+	 *
+	 * XXX this will go away when the SADB is redone.
+	 */
+	if (error == ENOENT)
+		error = 0;
+	splx(s);
+	*done = true;
+	return error;
+}
+
 #ifdef INET6
 struct secpolicy *
 ipsec6_checkpolicy(struct mbuf *m, u_int dir, u_int flag, int *error,

Index: src/sys/netipsec/ipsec.h
diff -u src/sys/netipsec/ipsec.h:1.32 src/sys/netipsec/ipsec.h:1.33
--- src/sys/netipsec/ipsec.h:1.32	Tue Jun  4 22:47:37 2013
+++ src/sys/netipsec/ipsec.h	Sat Jun  8 03:26:05 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.h,v 1.32 2013/06/04 22:47:37 christos Exp $	*/
+/*	$NetBSD: ipsec.h,v 1.33 2013/06/08 03:26:05 rmind 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 $	*/
 
@@ -256,7 +256,8 @@ struct secpolicy *ipsec4_checkpolicy (st
 	int *, struct inpcb *);
 struct secpolicy * ipsec_getpolicybyaddr(struct mbuf *, u_int,
 	int, int *);
-
+int ipsec4_output(struct mbuf *, struct socket *, int,
+	struct secpolicy **, u_long *, bool *, bool *);
 
 static __inline struct secpolicy*
 ipsec4_getpolicybysock(

Reply via email to