From owner-freebsd-current@FreeBSD.ORG Wed Apr 2 09:31:05 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1516A37B401 for ; Wed, 2 Apr 2003 09:31:05 -0800 (PST) Received: from ion.gank.org (ion.gank.org [198.78.66.164]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7034843F75 for ; Wed, 2 Apr 2003 09:31:04 -0800 (PST) (envelope-from craig@xfoil.gank.org) Received: from owen1492.uf.corelab.com (unknown [206.50.138.222]) by ion.gank.org (GankMail) with ESMTP id 2D32D2BF58 for ; Wed, 2 Apr 2003 11:31:04 -0600 (CST) From: Craig Boston To: freebsd-current@freebsd.org Content-Type: text/plain Organization: Message-Id: <1049304662.10796.27.camel@owen1492.uf.corelab.com> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.2.2 Date: 02 Apr 2003 11:31:02 -0600 Content-Transfer-Encoding: 7bit Subject: IPv6 MTU bug? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Apr 2003 17:31:05 -0000 I was trying some network diagnostics yesterday and needed to generate a continuous stream of small packets going across a few routers. So I used ifconfig to set my MTU to some very low values (100, 300, 500, and a few others). I know there's probably a better way to accomplish that, but couldn't think of any at the time so that's what I did :) Anyway, when I was done, I reset the MTU on my ethernet interface back to 1500. IPv4 is working fine, but IPv6 is still acting like I have a low MTU set. All IPv6 TCP connections are limiting the MSS to around 28 bytes of data per packet, and ping6 complains with ping sizes more than around 50. I think I've tracked down the problem to this code in nd6.c, specifically in nd6_setmtu(ifp). Note that at this point ndi->maxmtu has just been set to MIN([user-requested MTU], [biggest MTU possible for this interface type]). ndi->linkmtu hasn't been touched yet and is still set to whatever the previous linkmtu was. if (ndi->linkmtu == 0 || ndi->maxmtu < ndi->linkmtu) { ndi->linkmtu = ndi->maxmtu; /* also adjust in6_maxmtu if necessary. */ if (oldlinkmtu == 0) { /* * XXX: the case analysis is grotty, but * it is not efficient to call in6_setmaxmtu() * here when we are during the initialization * procedure. */ if (in6_maxmtu < ndi->linkmtu) in6_maxmtu = ndi->linkmtu; } else in6_setmaxmtu(); } It looks to me that in the case of raising an interface's MTU, ndi->maxmtu will be >= ndi->linkmtu, causing linkmtu to never get reset. I may be missing something, but I can't quite figure out the logical reason for that test. Luckily I had a kernel.debug lying around so I used gdb to peek into the kernel memory. In the nd_ifinfo for that interface, linkmtu=100 and maxmtu=1500. Once I manually reset linkmtu to 1500, IPv6 started working properly again, without having to sacrifice my uptime :) Anyway, the behavior looks like a bug, but the code makes it look like this may be an intentional effect. Any kernel networking gurus care to comment? Thanks, Craig