Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  4 Jan 2006 18:13:10 +0000 (GMT)
From:      Nate Nielsen <nielsen-list@memberwebs.com>
To:        freebsd-net@freebsd.org
Subject:   Problem with PMTU Discovery / DF / IPSEC / GIF Tunnels (FreeBSD 6.0 patch)
Message-ID:  <20060104181309.8C756DCA990@mail.npubs.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------070001070905060004070601
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

I encountered a strange problem with PMTU discovery not working properly
on various machines when the packets were tunneled over a GIF / IPSEC
Transport type tunnel (both ends running FreeBSD 6.0). Configuration
files attached.

Various older FreeBSD systems (it seemed systems that had jails running)
and also Windows Virtual Machines running in Microsoft's Virtual Server
2005 system, did not perform PMTU discovery properly.

The FreeBSD 6.0 routers were sending out ICMP host-unreachable
need-fragment packets without an MTU hint. Most machines handle this
fine, but the ones noted above did not decrease PMTU for the connection.

The attached patch makes sure that the FreeBSD 6.0 router will include
an MTU hint in the ICMP packet. The problem was caused by the IPSec
lookup in ip_forward() returning an secpolicy pointer, but then that
pointer having no details (such as request, etc...) contained in it. The
attached patch (against 6.0) covers that eventuality.

The 'bug' is obviously in the machines that don't handle the missing MTU
hint properly, but since we can't patch Windows, this patch helps
alleviate the problem from the other side.

Cheers,
Nate


--------------070001070905060004070601
Content-Type: text/x-patch;
 name="pmtu-gif-ipsec.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="pmtu-gif-ipsec.patch"

--- sys/netinet/ip_input.c.orig	Wed Jan  4 10:18:01 2006
+++ sys/netinet/ip_input.c	Wed Jan  4 10:39:35 2006
@@ -1918,29 +1918,29 @@ ip_forward(struct mbuf *m, int srcrt)
 					}
 				}
 
 #ifdef IPSEC
 				key_freesp(sp);
 #else /* FAST_IPSEC */
 				KEY_FREESP(&sp);
 #endif
-				ipstat.ips_cantfrag++;
-				break;
-			} else 
+			}
 #endif /*IPSEC || FAST_IPSEC*/
-		/*
-		 * When doing source routing 'ia' can be NULL.  Fall back
-		 * to the minimum guaranteed routeable packet size and use
-		 * the same hack as IPSEC to setup a dummyifp for icmp.
-		 */
-		if (ia == NULL)
-			mtu = IP_MSS;
-		else
-			mtu = ia->ia_ifp->if_mtu;
+		if (!mtu) {
+			/*
+			 * When doing source routing 'ia' can be NULL.  Fall back
+			 * to the minimum guaranteed routeable packet size and use
+			 * the same hack as IPSEC to setup a dummyifp for icmp.
+			 */
+			if (ia == NULL)
+				mtu = IP_MSS;
+			else
+				mtu = ia->ia_ifp->if_mtu;
+		}
 #if defined(IPSEC) || defined(FAST_IPSEC)
 		}
 #endif /*IPSEC || FAST_IPSEC*/
 		ipstat.ips_cantfrag++;
 		break;
 
 	case ENOBUFS:
 		/*

--------------070001070905060004070601--




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