kern/81813: [ PATCH ] ICMP_UNREACH_NEEDFRAG with unspecified icmp_nextmtu are ignored

Dan Lukes dan at obluda.cz
Thu Jun 2 17:10:03 GMT 2005


>Number:         81813
>Category:       kern
>Synopsis:       [ PATCH ] ICMP_UNREACH_NEEDFRAG with unspecified icmp_nextmtu are ignored
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 02 17:10:01 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Dan Lukes
>Release:        FreeBSD 5.4-STABLE i386
>Organization:
Obludarium
>Environment:
System: FreeBSD 5.4-STABLE #7: Wed Jun 1 00:34:28 CEST 2005 dan@:/usr/obj/usr/src/sys/Dan i386

src/sys/netinet/ip_icmp.c,v 1.96.2.2 2005/01/31 23:26:35 imp

>Description:

See dump from A.B.C.232:

16:42:03.520909 A.B.C.41.1816 > A.B.C.232.http: S 0:0(0) win 57344 <mss 1460,...> (DF)
16:42:03.520936 A.B.C.232.http > A.B.C.41.1816: S 0:0(0) ack 0 win 65535 <mss 1460,...> (DF)
16:42:03.565467 A.B.C.41.1816 > A.B.C.232.http: . ack 1 win 57920 <nop,...> (DF)
16:42:03.574552 A.B.C.41.1816 > A.B.C.232.http: P 1:443(442) ack 1 win 57920 <nop,...> (DF)
16:42:03.575489 A.B.C.232.http > A.B.C.41.1816: . 1:1449(1448) ack 443 win 33304 <nop,...> (DF)
16:42:03.575499 A.B.C.232.http > A.B.C.41.1816: P 1449:2108(659) ack 443 win 33304 <nop,...> (DF)
16:42:03.575953 A.B.C.225 > A.B.C.232: icmp: A.B.C.41 unreachable - need to frag (DF)
16:42:03.635175 A.B.C.41.1816 > A.B.C.232.http: . ack 1 win 57920 <nop,...> (DF)
16:42:05.920839 A.B.C.232.http > A.B.C.41.1816: . 1:1449(1448) ack 443 win 33304 <nop,...> (DF)
16:42:05.921312 A.B.C.225 > A.B.C.232: icmp: A.B.C.41 unreachable - need to frag (DF)
16:42:10.420908 A.B.C.232.http > A.B.C.41.1816: . 1:1449(1448) ack 443 win 33304 <nop,...> (DF)
16:42:10.421421 A.B.C.225 > A.B.C.232: icmp: A.B.C.41 unreachable - need to frag (DF)
...

Part of one of ICMP packets:
16:42:03.575953 A.B.C.225 > A.B.C.232: icmp: A.B.C.41 unreachable - need to frag (DF)
0x0000   4500 0038 b25c 4000 4001 6aa0 AABB CCe1
0x0010   AABB CCe8
0x0014             0304 426e                      (type, subtype, cksum)
0x0018                       0000                 (reserved)
0x001A                            0000            (next_mtu)

	When arrive NEEDFRAG icmp which didn't contain a next_mtu proposal
then MTU is not changed. Sender retransmitting the data with unchanged
(large) MTU so communication is impossible. 


>How-To-Repeat:
	See description.
>Fix:

	The relevant part of code is (ip_icmp.c):
/* ------------------------------------------- */
        mtu = ntohs(icp->icmp_nextmtu);
        if (!mtu)
             mtu = ip_next_mtu(mtu, 1);

        if (mtu >= max(296, (tcp_minmss +
                sizeof(struct tcpiphdr))))
                tcp_hc_updatemtu(&inc, mtu);

#ifdef DEBUG_MTUDISC
        printf("MTU for %s reduced to %d\n",
            inet_ntoa(icmpsrc.sin_addr), mtu);
#endif
/* ------------------------------------------- */

	The icmp_nextmtu is zero. The ip_next_mtu is trying to found smaller
value for MTU, but smaller value for zero is zero again.

	Zero didn't pass the sanity check for minimum value, so MTU is not
changed.

	It seems to be error within 'mtu = ip_next_mtu(mtu, 1)' line. It
should not use proposed MTU (which is zero already) as argument but current
MTU from hc cache.


--- patch begins here ---
--- sys/netinet/ip_icmp.c.ORIG	Tue Feb  1 21:02:05 2005
+++ sys/netinet/ip_icmp.c	Thu Jun  2 18:21:55 2005
@@ -438,7 +438,7 @@
 
 			mtu = ntohs(icp->icmp_nextmtu);
 			if (!mtu)
-				mtu = ip_next_mtu(mtu, 1);
+				mtu = ip_next_mtu(tcp_hc_getmtu(&inc), 1);
 
 			if (mtu >= max(296, (tcp_minmss +
 					sizeof(struct tcpiphdr))))
--- patch ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list