From owner-freebsd-bugs@FreeBSD.ORG Wed Nov 7 14:30:02 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2289E9B9 for ; Wed, 7 Nov 2012 14:30:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id DD6518FC0A for ; Wed, 7 Nov 2012 14:30:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id qA7EU1KG048206 for ; Wed, 7 Nov 2012 14:30:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id qA7EU12Q048205; Wed, 7 Nov 2012 14:30:01 GMT (envelope-from gnats) Resent-Date: Wed, 7 Nov 2012 14:30:01 GMT Resent-Message-Id: <201211071430.qA7EU12Q048205@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Mark Andrews Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5BB2C937 for ; Wed, 7 Nov 2012 14:23:59 +0000 (UTC) (envelope-from marka@isc.org) Received: from mx.ams1.isc.org (mx.ams1.isc.org [IPv6:2001:500:60::65]) by mx1.freebsd.org (Postfix) with ESMTP id DAFBA8FC0A for ; Wed, 7 Nov 2012 14:23:58 +0000 (UTC) Received: from bikeshed.isc.org (bikeshed.isc.org [IPv6:2001:4f8:3:d::19]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client CN "mail.isc.org", Issuer "RapidSSL CA" (not verified)) by mx.ams1.isc.org (Postfix) with ESMTPS id A46A65FA7C2 for ; Wed, 7 Nov 2012 14:23:47 +0000 (UTC) (envelope-from marka@isc.org) Received: from sex.dv.isc.org (sex.dv.isc.org [IPv6:2001:470:1f00:820:218:f3ff:feba:9a37]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bikeshed.isc.org (Postfix) with ESMTPSA id 71879216C3D for ; Wed, 7 Nov 2012 14:23:45 +0000 (UTC) (envelope-from marka@isc.org) Received: from sex.dv.isc.org (localhost [127.0.0.1]) by sex.dv.isc.org (8.14.5/8.14.5) with ESMTP id qA7ENg2O076244 for ; Thu, 8 Nov 2012 01:23:42 +1100 (EST) (envelope-from marka@sex.dv.isc.org) Received: (from marka@localhost) by sex.dv.isc.org (8.14.5/8.14.5/Submit) id qA7ENfHK076243; Thu, 8 Nov 2012 01:23:41 +1100 (EST) (envelope-from marka) Message-Id: <201211071423.qA7ENfHK076243@sex.dv.isc.org> Date: Thu, 8 Nov 2012 01:23:41 +1100 (EST) From: Mark Andrews To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: kern/173444: IPV6_USE_MIN_MTU and TCP is broken X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: Mark Andrews List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Nov 2012 14:30:02 -0000 >Number: 173444 >Category: kern >Synopsis: IPV6_USE_MIN_MTU and TCP is broken >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Nov 07 14:30:01 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Mark Andrews >Release: FreeBSD 8.3-STABLE i386 >Organization: ISC >Environment: System: FreeBSD sex.dv.isc.org 8.3-STABLE FreeBSD 8.3-STABLE #18: Mon Jun 18 11:57:52 EST 2012 root@sex.dv.isc.org:/usr/obj/usr/src/sys/DEBUG i386 >Description: Setting IPV6_USE_MIN_MTU to one (1) on a IPv6 TCP socket results in fragmented IPv6 packets being sent rather than the TCP segment size being adjusted to reflect the MTU limit on the socket. 00:56:44.177930 IP6 2001:470:1f00:820:218:f3ff:feba:9a37 > 2001:470:1f00:820:6233:4bff:fe01:7585: frag (0|1232) 5555 > 63656: Flags [.], ack 42, win 8211, options [nop,nop,TS val 2829969063 ecr 1028520077], length 1200 00:56:44.177936 IP6 2001:470:1f00:820:218:f3ff:feba:9a37 > 2001:470:1f00:820:6233:4bff:fe01:7585: frag (1232|228) 00:56:44.177953 IP6 2001:470:1f00:820:218:f3ff:feba:9a37 > 2001:470:1f00:820:6233:4bff:fe01:7585: frag (0|1232) 5555 > 63656: Flags [.], ack 42, win 8211, options [nop,nop,TS val 2829969063 ecr 1028520077], length 1200 00:56:44.177957 IP6 2001:470:1f00:820:218:f3ff:feba:9a37 > 2001:470:1f00:820:6233:4bff:fe01:7585: frag (1232|228) 00:56:44.177974 IP6 2001:470:1f00:820:218:f3ff:feba:9a37 > 2001:470:1f00:820:6233:4bff:fe01:7585: frag (0|1232) 5555 > 63656: Flags [.], ack 42, win 8211, options [nop,nop,TS val 2829969063 ecr 1028520077], length 1200 >How-To-Repeat: Apply the following patch to named and transfer a zone. [The intent of the patch is to avoid PMTUD issues. Too many nameservers are behind load balancers / firewalls that don't pass PTB messages.] diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index ffe7e02..6fb8860 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -2262,6 +2264,31 @@ clear_bsdcompat(void) { } #endif +static void +use_min_mtu(isc__socket_t *sock) { +#if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU) + UNUSED(sock); +#endif +#ifdef IPV6_USE_MIN_MTU + /* use minimum MTU */ + if (sock->pf == AF_INET6) { + int on = 1; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *)&on, sizeof(on)); + } +#endif +#if defined(IPV6_MTU) + /* + * Use minimum MTU on IPv6 sockets. + */ + if (sock->pf == AF_INET6) { + int mtu = 1280; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, + &mtu, sizeof(mtu)); + } +#endif +} + static isc_result_t opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, isc__socket_t *dup_socket) @@ -2426,6 +2453,11 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, } #endif + /* + * Use minimum mtu if possible. + */ + use_min_mtu(sock); + #if defined(USE_CMSG) || defined(SO_RCVBUF) if (sock->type == isc_sockettype_udp) { @@ -2490,32 +2522,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, } #endif /* IPV6_RECVPKTINFO */ #endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ -#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/ - /* use minimum MTU */ - if (sock->pf == AF_INET6 && - setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_USE_MIN_MTU) " - "%s: %s", sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } -#endif -#if defined(IPV6_MTU) - /* - * Use minimum MTU on IPv6 sockets. - */ - if (sock->pf == AF_INET6) { - int mtu = 1280; - (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, - &mtu, sizeof(mtu)); - } -#endif #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) /* * Turn off Path MTU discovery on IPv6/UDP sockets. @@ -3313,6 +3319,11 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { NEWCONNSOCK(dev)->connected = 1; /* + * Use minimum mtu if possible. + */ + use_min_mtu(NEWCONNSOCK(dev)); + + /* * Save away the remote address */ dev->address = NEWCONNSOCK(dev)->peer_address; >Fix: The TCP layer should check whether ip6po_minmtu is set on the socket and adjust the maxmtu appropriately. The code fragment below should do that but has not been tested. sys/netinet/tcp_input.c: if (isipv6) { struct ip6_pktopts *opt; maxmtu = tcp_maxmtu6(&inp->inp_inc, mtuflags); opt = inp->inp_depend6.inp6_outputopts; if (opt && opt->ip6po_minmtu) maxmtu = min(maxmtu, IPV6_MMTU); tp->t_maxopd = tp->t_maxseg = V_tcp_v6mssdflt; } else >Release-Note: >Audit-Trail: >Unformatted: