panic

Matthew Dillon dillon at apollo.backplane.com
Sun Apr 9 10:45:29 PDT 2006


:ipw0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1492
:        inet 192.168.1.5 netmask 0xffffff00 broadcast 192.168.1.255
:        ether 00:0c:f1:3b:d1:ef
:        media: IEEE 802.11 Wireless Ethernet autoselect (DS/11Mbps)
:        status: associated
:
:
:Perhaps it's some negotiation with the remote host that reduces t_maxopd?
:And the problem only occurs since I have upgarded my openwrt router...

    A tcpdump may give us a clue.  Something like:

	tcpdump -i ipw0 -s 4096 -l -vvv

    would do the job, but you need to filter out data unrelated to the TCP
    connection causing the problem.  So, e.g. you might have to add
    'not port 22 and not port <blah> and not port <blah>' or things of
    that nature.

    I have enclosed a patch that I believe will stop the crashes.  The TCP
    connection will still fail, because its an unrecoverable situation (the
    MTU must be large enough to hold the packet's options!), but hopefully
    the system will not crash.  It should report problem packets on the
    console/dmesg (limited to one report per second).
    
					-Matt
					Matthew Dillon 
					<dillon at xxxxxxxxxxxxx>

Index: netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.30
diff -u -r1.30 tcp_output.c
--- netinet/tcp_output.c	14 Jan 2006 11:33:50 -0000	1.30
+++ netinet/tcp_output.c	9 Apr 2006 17:34:48 -0000
@@ -631,18 +631,29 @@
 #endif
 
 	/*
-	 * Adjust data length if insertion of options will
-	 * bump the packet length beyond the t_maxopd length.
-	 * Clear the FIN bit because we cut off the tail of
-	 * the segment.
+	 * Adjust data length if insertion of options will bump the packet
+	 * length beyond the t_maxopd length.  Clear FIN to prevent premature
+	 * closure since there is still more data to send after this (now
+	 * truncated) packet.
+	 *
+	 * If just the options do not fit we are in a no-win situation and
+	 * we treat it as an unreachable host.
 	 */
 	if (len + optlen + ipoptlen > tp->t_maxopd) {
-		/*
-		 * If there is still more to send, don't close the connection.
-		 */
-		flags &= ~TH_FIN;
-		len = tp->t_maxopd - optlen - ipoptlen;
-		sendalot = TRUE;
+		if (tp->t_maxopd <= optlen + ipoptlen) {
+			static time_t last_optlen_report;
+
+			if (last_optlen_report != time_second) {
+				last_optlen_report = time_second;
+				printf("tcpcb %p: MSS (%d) too small to hold options!\n", tp, tp->t_maxopd);
+			}
+			error = EHOSTUNREACH;
+			goto out;
+		} else {
+			flags &= ~TH_FIN;
+			len = tp->t_maxopd - optlen - ipoptlen;
+			sendalot = TRUE;
+		}
 	}
 
 #ifdef INET6





More information about the Bugs mailing list