Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Apr 2009 11:10:33 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r191621 - head/sys/netinet
Message-ID:  <200904281110.n3SBAXIb047843@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Tue Apr 28 11:10:33 2009
New Revision: 191621
URL: http://svn.freebsd.org/changeset/base/191621

Log:
  Don't require packet to match a route (any route; this information wasn't
  used anyway, so a typical workaround was to add a dummy route) if it's going
  to be sent through IPSec tunnel.
  
  Reviewed by:	bz

Modified:
  head/sys/netinet/ip_ipsec.c
  head/sys/netinet/ip_output.c

Modified: head/sys/netinet/ip_ipsec.c
==============================================================================
--- head/sys/netinet/ip_ipsec.c	Tue Apr 28 09:45:32 2009	(r191620)
+++ head/sys/netinet/ip_ipsec.c	Tue Apr 28 11:10:33 2009	(r191621)
@@ -385,7 +385,8 @@ ip_ipsec_output(struct mbuf **m, struct 
 		 * the interface supports it.
 		 */ 
 		mtag = m_tag_find(*m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL);
-		if (mtag != NULL && ((*ifp)->if_capenable & IFCAP_IPSEC) == 0) {
+		if (mtag != NULL && ifp != NULL &&
+		    ((*ifp)->if_capenable & IFCAP_IPSEC) == 0) {
 			/* notify IPsec to do its own crypto */
 			ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
 			*error = EHOSTUNREACH;

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Tue Apr 28 09:45:32 2009	(r191620)
+++ head/sys/netinet/ip_output.c	Tue Apr 28 11:10:33 2009	(r191621)
@@ -145,6 +145,9 @@ ip_output(struct mbuf *m, struct mbuf *o
 #ifdef IPFIREWALL_FORWARD
 	struct m_tag *fwd_tag = NULL;
 #endif
+#ifdef IPSEC
+	int no_route_but_check_spd = 0;
+#endif
 	M_ASSERTPKTHDR(m);
 
 	if (ro == NULL) {
@@ -272,6 +275,15 @@ again:
 			    inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m));
 #endif
 		if (ro->ro_rt == NULL) {
+#ifdef IPSEC
+			/*
+			 * There is no route for this packet, but it is
+			 * possible that a matching SPD entry exists.
+			 */
+			no_route_but_check_spd = 1;
+			mtu = 0; /* Silence GCC warning. */
+			goto sendit;
+#endif
 			IPSTAT_INC(ips_noroute);
 			error = EHOSTUNREACH;
 			goto bad;
@@ -467,6 +479,14 @@ sendit:
 	default:
 		break;	/* Continue with packet processing. */
 	}
+	/*
+	 * Check if there was a route for this packet; return error if not.
+	 */
+	if (no_route_but_check_spd) {
+		IPSTAT_INC(ips_noroute);
+		error = EHOSTUNREACH;
+		goto bad;
+	}
 	/* Update variables that are affected by ipsec4_output(). */
 	ip = mtod(m, struct ip *);
 	hlen = ip->ip_hl << 2;



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