Module Name:    src
Committed By:   rmind
Date:           Sat Jun  8 13:50:22 UTC 2013

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

Log Message:
Split IPsec code in ip_input() and ip_forward() into the separate routines
ipsec4_input() and ipsec4_forward().  Tested by christos@.


To generate a diff of this commit:
cvs rdiff -u -r1.304 -r1.305 src/sys/netinet/ip_input.c
cvs rdiff -u -r1.221 -r1.222 src/sys/netinet/ip_output.c
cvs rdiff -u -r1.59 -r1.60 src/sys/netipsec/ipsec.c
cvs rdiff -u -r1.33 -r1.34 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_input.c
diff -u src/sys/netinet/ip_input.c:1.304 src/sys/netinet/ip_input.c:1.305
--- src/sys/netinet/ip_input.c:1.304	Wed Jun  5 19:01:26 2013
+++ src/sys/netinet/ip_input.c	Sat Jun  8 13:50:22 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.304 2013/06/05 19:01:26 christos Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.305 2013/06/08 13:50:22 rmind 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.304 2013/06/05 19:01:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.305 2013/06/08 13:50:22 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -143,8 +143,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v
 
 #ifdef IPSEC
 #include <netipsec/ipsec.h>
-#include <netipsec/key.h>
-#endif	/* IPSEC*/
+#endif
 
 #ifndef	IPFORWARDING
 #ifdef GATEWAY
@@ -405,12 +404,6 @@ ip_input(struct mbuf *m)
 	int downmatch;
 	int checkif;
 	int srcrt = 0;
-#ifdef IPSEC
-	struct m_tag *mtag;
-	struct tdb_ident *tdbi;
-	struct secpolicy *sp;
-	int error, s;
-#endif /* IPSEC */
 
 	MCLAIM(m, &ip_rx_mowner);
 	KASSERT((m->m_flags & M_PKTHDR) != 0);
@@ -733,54 +726,12 @@ ip_input(struct mbuf *m)
 			return;
 		}
 #ifdef IPSEC
-		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) {	/* NB: can happen if error */
-			splx(s);
-			/*XXX error stat???*/
-			DPRINTF(("ip_input: no SP for forwarding\n"));	/*XXX*/
-			goto bad;
-		}
-
-		/*
-		 * Check security policy against packet attributes.
-		 */
-		error = ipsec_in_reject(sp, m);
-		KEY_FREESP(&sp);
-		splx(s);
-		if (error) {
-			IP_STATINC(IP_STAT_CANTFORWARD);
+		/* Perform IPsec, if any. */
+		if (ipsec4_input(m, IP_FORWARDING | (ip_directedbcast ?
+		    IP_ALLOWBROADCAST : 0)) != 0) {
 			goto bad;
 		}
-
-		/*
-		 * Peek at the outbound SP for this packet to determine if
-		 * it's a Fast Forward candidate.
-		 */
-		mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
-		if (mtag != NULL)
-			m->m_flags &= ~M_CANFASTFWD;
-		else {
-			s = splsoftnet();
-			sp = ipsec4_checkpolicy(m, IPSEC_DIR_OUTBOUND,
-			    (IP_FORWARDING |
-			     (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
-			    &error, NULL);
-			if (sp != NULL) {
-				m->m_flags &= ~M_CANFASTFWD;
-				KEY_FREESP(&sp);
-			}
-			splx(s);
-		}
-#endif	/* IPSEC */
-
+#endif
 		ip_forward(m, srcrt);
 	}
 	return;
@@ -811,42 +762,16 @@ ours:
 
 #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.
+	 * 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 ((inetsw[ip_protox[ip->ip_p]].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(("ip_input: no SP, packet discarded\n"));/*XXX*/
-		}
-		splx(s);
-		if (error)
+		if (ipsec4_input(m, 0) != 0) {
 			goto bad;
+		}
 	}
-#endif /* IPSEC */
+#endif
 
 	/*
 	 * Switch out to protocol's input routine.
@@ -1422,53 +1347,9 @@ ip_forward(struct mbuf *m, int srcrt)
 
 		if ((rt = rtcache_validate(&ipforward_rt)) != NULL)
 			destmtu = rt->rt_ifp->if_mtu;
-
-#if defined(IPSEC)
-		{
-			/*
-			 * If the packet is routed over IPsec tunnel, tell the
-			 * originator the tunnel MTU.
-			 *	tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
-			 * XXX quickhack!!!
-			 */
-
-			struct secpolicy *sp;
-			int ipsecerror;
-			size_t ipsechdr;
-			struct route *ro;
-
-			sp = ipsec4_getpolicybyaddr(mcopy,
-			    IPSEC_DIR_OUTBOUND, IP_FORWARDING,
-			    &ipsecerror);
-
-			if (sp != NULL) {
-				/* count IPsec header size */
-				ipsechdr = ipsec4_hdrsiz(mcopy,
-				    IPSEC_DIR_OUTBOUND, NULL);
-
-				/*
-				 * find the correct route for outer IPv4
-				 * header, compute tunnel MTU.
-				 */
-
-				if (sp->req != NULL
-				 && sp->req->sav != NULL
-				 && sp->req->sav->sah != NULL) {
-					ro = &sp->req->sav->sah->sa_route;
-					rt = rtcache_validate(ro);
-					if (rt && rt->rt_ifp) {
-						destmtu =
-						    rt->rt_rmx.rmx_mtu ?
-						    rt->rt_rmx.rmx_mtu :
-						    rt->rt_ifp->if_mtu;
-						destmtu -= ipsechdr;
-					}
-				}
-
-				KEY_FREESP(&sp);
-			}
-		}
-#endif /*defined(IPSEC)*/
+#ifdef IPSEC
+		(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.221 src/sys/netinet/ip_output.c:1.222
--- src/sys/netinet/ip_output.c:1.221	Sat Jun  8 03:26:05 2013
+++ src/sys/netinet/ip_output.c	Sat Jun  8 13:50:22 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.221 2013/06/08 03:26:05 rmind Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.222 2013/06/08 13:50:22 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.221 2013/06/08 03:26:05 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.222 2013/06/08 13:50:22 rmind Exp $");
 
 #include "opt_pfil_hooks.h"
 #include "opt_inet.h"
@@ -474,7 +474,7 @@ sendit:
 		ip->ip_off |= htons(IP_DF);
 
 #ifdef IPSEC
-	/* Perform IPSec processing, if any. */
+	/* Perform IPsec processing, if any. */
 	error = ipsec4_output(m, so, flags, &sp, &mtu, &natt_frag, &done);
 	if (error || done) {
 		goto done;
@@ -611,7 +611,7 @@ sendit:
 #endif
 			/*
 			 * If we get there, the packet has not been handled by
-			 * IPSec whereas it should have. Now that it has been
+			 * IPsec whereas it should have. Now that it has been
 			 * fragmented, re-inject it in ip_output so that IPsec
 			 * processing can occur.
 			 */

Index: src/sys/netipsec/ipsec.c
diff -u src/sys/netipsec/ipsec.c:1.59 src/sys/netipsec/ipsec.c:1.60
--- src/sys/netipsec/ipsec.c:1.59	Sat Jun  8 03:26:05 2013
+++ src/sys/netipsec/ipsec.c	Sat Jun  8 13:50:22 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.c,v 1.59 2013/06/08 03:26:05 rmind Exp $	*/
+/*	$NetBSD: ipsec.c,v 1.60 2013/06/08 13:50:22 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.59 2013/06/08 03:26:05 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.60 2013/06/08 13:50:22 rmind Exp $");
 
 /*
  * IPsec controller part.
@@ -73,6 +73,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 #include <netinet/ip_icmp.h>
+#include <netinet/ip_private.h>
 
 #include <netinet/ip6.h>
 #ifdef INET6
@@ -829,6 +830,110 @@ ipsec4_output(struct mbuf *m, struct soc
 	return error;
 }
 
+int
+ipsec4_input(struct mbuf *m, int flags)
+{
+	struct m_tag *mtag;
+	struct tdb_ident *tdbi;
+	struct secpolicy *sp;
+	int error, s;
+
+	/*
+	 * 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) {
+		splx(s);
+		return EINVAL;
+	}
+
+	/*
+	 * Check security policy against packet attributes.
+	 */
+	error = ipsec_in_reject(sp, m);
+	KEY_FREESP(&sp);
+	splx(s);
+	if (error) {
+		return error;
+	}
+
+	if (flags == 0) {
+		/* We are done. */
+		return 0;
+	}
+
+	/*
+	 * Peek at the outbound SP for this packet to determine if
+	 * it is a Fast Forward candidate.
+	 */
+	mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
+	if (mtag != NULL) {
+		m->m_flags &= ~M_CANFASTFWD;
+		return 0;
+	}
+
+	s = splsoftnet();
+	sp = ipsec4_checkpolicy(m, IPSEC_DIR_OUTBOUND, flags, &error, NULL);
+	if (sp != NULL) {
+		m->m_flags &= ~M_CANFASTFWD;
+		KEY_FREESP(&sp);
+	}
+	splx(s);
+	return 0;
+}
+
+int
+ipsec4_forward(struct mbuf *m, int *destmtu)
+{
+	/*
+	 * If the packet is routed over IPsec tunnel, tell the
+	 * originator the tunnel MTU.
+	 *	tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
+	 * XXX quickhack!!!
+	 */
+	struct secpolicy *sp;
+	size_t ipsechdr;
+	int error;
+
+	sp = ipsec4_getpolicybyaddr(m,
+	    IPSEC_DIR_OUTBOUND, IP_FORWARDING, &error);
+	if (sp == NULL) {
+		return EINVAL;
+	}
+
+	/* Count IPsec header size. */
+	ipsechdr = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, NULL);
+
+	/*
+	 * Find the correct route for outer IPv4 header, compute tunnel MTU.
+	 */
+	if (sp->req && sp->req->sav && sp->req->sav->sah) {
+		struct route *ro;
+		struct rtentry *rt;
+
+		ro = &sp->req->sav->sah->sa_route;
+		rt = rtcache_validate(ro);
+		if (rt && rt->rt_ifp) {
+			*destmtu = rt->rt_rmx.rmx_mtu ?
+			    rt->rt_rmx.rmx_mtu : rt->rt_ifp->if_mtu;
+			*destmtu -= ipsechdr;
+		}
+	}
+	KEY_FREESP(&sp);
+	return 0;
+}
+
 #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.33 src/sys/netipsec/ipsec.h:1.34
--- src/sys/netipsec/ipsec.h:1.33	Sat Jun  8 03:26:05 2013
+++ src/sys/netipsec/ipsec.h	Sat Jun  8 13:50:22 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.h,v 1.33 2013/06/08 03:26:05 rmind Exp $	*/
+/*	$NetBSD: ipsec.h,v 1.34 2013/06/08 13:50:22 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 $	*/
 
@@ -258,6 +258,8 @@ struct secpolicy * ipsec_getpolicybyaddr
 	int, int *);
 int ipsec4_output(struct mbuf *, struct socket *, int,
 	struct secpolicy **, u_long *, bool *, bool *);
+int ipsec4_input(struct mbuf *, int);
+int ipsec4_forward(struct mbuf *, int *);
 
 static __inline struct secpolicy*
 ipsec4_getpolicybysock(

Reply via email to