From nobody@FreeBSD.org  Fri Apr 16 13:50:56 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id B0C8B106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 16 Apr 2010 13:50:56 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 93ABC8FC23
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 16 Apr 2010 13:50:56 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o3GDoukh044871
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 16 Apr 2010 13:50:56 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o3GDouM7044870;
	Fri, 16 Apr 2010 13:50:56 GMT
	(envelope-from nobody)
Message-Id: <201004161350.o3GDouM7044870@www.freebsd.org>
Date: Fri, 16 Apr 2010 13:50:56 GMT
From: pluknet <pluknet@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] Add do-not-fragment option support to ping6
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         145759
>Category:       bin
>Synopsis:       [patch] Add do-not-fragment option support to ping6(8)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 16 14:00:08 UTC 2010
>Closed-Date:    Thu May 20 08:03:43 UTC 2010
>Last-Modified:  Thu May 20 08:03:43 UTC 2010
>Originator:     pluknet
>Release:        HEAD r206338
>Organization:
>Environment:
>Description:
There's a conversation that fully disclose the subject.
http://lists.freebsd.org/pipermail/freebsd-net/2009-December/023948.html

Some tests inline:

1. size < lo0 mtu, w/ frag
$ ping6 -s 10000 -b 32000 ::1
PING6(10048=40+8+10000 bytes) ::1 --> ::1
10008 bytes from ::1, icmp_seq=0 hlim=64 time=0.139 ms

17:37:56.521150 IP6 localhost > localhost: frag (0|1232) ICMP6, echo request, seq 0, length 1232
17:37:56.521160 IP6 localhost > localhost: frag (1232|1232)
17:37:56.521164 IP6 localhost > localhost: frag (2464|1232)
17:37:56.521168 IP6 localhost > localhost: frag (3696|1232)
17:37:56.521172 IP6 localhost > localhost: frag (4928|1232)
17:37:56.521175 IP6 localhost > localhost: frag (6160|1232)
17:37:56.521179 IP6 localhost > localhost: frag (7392|1232)
17:37:56.521183 IP6 localhost > localhost: frag (8624|1232)
17:37:56.521186 IP6 localhost > localhost: frag (9856|152)
17:37:56.521203 IP6 localhost > localhost: ICMP6, echo reply, seq 0, length 10008

2. size < lo0 mtu, w/o frag
$ ping6 -s 10000 -b 32000 -D ::1
PING6(10048=40+8+10000 bytes) ::1 --> ::1
10008 bytes from ::1, icmp_seq=0 hlim=64 time=0.080 ms

17:39:52.182947 IP6 localhost > localhost: ICMP6, echo request, seq 0, length 10008
17:39:52.182962 IP6 localhost > localhost: ICMP6, echo reply, seq 0, length 10008

3. size > lo0 mtu, w/ frag
$ ping6 -s 20000 -b 32000 ::1
PING6(20048=40+8+20000 bytes) ::1 --> ::1
20008 bytes from ::1, icmp_seq=0 hlim=64 time=0.234 ms

17:46:22.080945 IP6 localhost > localhost: frag (0|1232) ICMP6, echo request, seq 0, length 1232
17:46:22.080955 IP6 localhost > localhost: frag (1232|1232)
17:46:22.080959 IP6 localhost > localhost: frag (2464|1232)
17:46:22.080962 IP6 localhost > localhost: frag (3696|1232)
17:46:22.080966 IP6 localhost > localhost: frag (4928|1232)
17:46:22.080970 IP6 localhost > localhost: frag (6160|1232)
17:46:22.080973 IP6 localhost > localhost: frag (7392|1232)
17:46:22.080977 IP6 localhost > localhost: frag (8624|1232)
17:46:22.080980 IP6 localhost > localhost: frag (9856|1232)
17:46:22.080984 IP6 localhost > localhost: frag (11088|1232)
17:46:22.080987 IP6 localhost > localhost: frag (12320|1232)
17:46:22.080991 IP6 localhost > localhost: frag (13552|1232)
17:46:22.080994 IP6 localhost > localhost: frag (14784|1232)
17:46:22.080998 IP6 localhost > localhost: frag (16016|1232)
17:46:22.081002 IP6 localhost > localhost: frag (17248|1232)
17:46:22.081005 IP6 localhost > localhost: frag (18480|1232)
17:46:22.081009 IP6 localhost > localhost: frag (19712|296)
17:46:22.081047 IP6 localhost > localhost: frag (0|16336) ICMP6, echo reply, seq 0, length 16336
17:46:22.081048 IP6 localhost > localhost: frag (16336|3672)

4. size > lo0 mtu, w/o frag
$ ping6 -s 20000 -b 32000 -D ::1
PING6(20048=40+8+20000 bytes) ::1 --> ::1
ping6: sendmsg: Message too long
ping6: wrote ::1 20008 chars, ret=-1

>How-To-Repeat:

>Fix:
Patch against HEAD r206338, applicable down to 7.

Patch attached with submission follows:

Index: sbin/ping6/ping6.c
===================================================================
--- sbin/ping6/ping6.c	(revision 206338)
+++ sbin/ping6/ping6.c	(working copy)
@@ -191,6 +191,7 @@
 #define F_ONCE		0x200000
 #define F_AUDIBLE	0x400000
 #define F_MISSED	0x800000
+#define F_DONTFRAG	0x1000000
 #define F_NOUSERDATA	(F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
 u_int options;
 
@@ -349,7 +350,7 @@
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
 	while ((ch = getopt(argc, argv,
-	    "a:b:c:dfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
+	    "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
 #undef ADDOPTS
 		switch (ch) {
 		case 'a':
@@ -415,6 +416,9 @@
 				errx(1,
 				    "illegal number of packets -- %s", optarg);
 			break;
+		case 'D':
+			options |= F_DONTFRAG;
+			break;
 		case 'd':
 			options |= F_SO_DEBUG;
 			break;
@@ -743,8 +747,12 @@
 		*((u_int32_t *)&nonce[i]) = arc4random();
 #endif
 
+	optval = 1;
+	if (options & F_DONTFRAG)
+		if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
+		    &optval, sizeof(optval)) == -1)
+			err(1, "IPV6_DONTFRAG");
 	hold = 1;
-
 	if (options & F_SO_DEBUG)
 		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
 		    sizeof(hold));
@@ -2780,7 +2788,7 @@
 	    "A"
 #endif
 	    "usage: ping6 [-"
-	    "d"
+	    "Dd"
 #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC)
 	    "E"
 #endif
Index: sbin/ping6/ping6.8
===================================================================
--- sbin/ping6/ping6.8	(revision 206338)
+++ sbin/ping6/ping6.8	(working copy)
@@ -40,9 +40,9 @@
 .Sh SYNOPSIS
 .Nm
 .\" without ipsec, or new ipsec
-.Op Fl dfHmnNoqrRtvwW
+.Op Fl DdfHmnNoqrRtvwW
 .\" old ipsec
-.\" .Op Fl AdEfmnNqRtvwW
+.\" .Op Fl ADdEfmnNqRtvwW
 .Bk -words
 .Op Fl a Ar addrtype
 .Ek
@@ -141,6 +141,8 @@
 .Ar count
 .Tn ECHO_RESPONSE
 packets.
+.It Fl D
+Disable IPv6 fragmentation.
 .It Fl d
 Set the
 .Dv SO_DEBUG


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Tue Apr 20 06:17:32 UTC 2010 
State-Changed-Why:  
Committed to HEAD.  Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=145759 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/145759: commit references a PR
Date: Tue, 20 Apr 2010 06:10:14 +0000 (UTC)

 Author: maxim
 Date: Tue Apr 20 06:10:05 2010
 New Revision: 206889
 URL: http://svn.freebsd.org/changeset/base/206889
 
 Log:
   o Add do-not-fragment option support to ping6(8).
   
   PR:		bin/145759
   Submitted by:	pluknet
   MFC after:	1 month
 
 Modified:
   head/sbin/ping6/ping6.8
   head/sbin/ping6/ping6.c
 
 Modified: head/sbin/ping6/ping6.8
 ==============================================================================
 --- head/sbin/ping6/ping6.8	Tue Apr 20 06:08:34 2010	(r206888)
 +++ head/sbin/ping6/ping6.8	Tue Apr 20 06:10:05 2010	(r206889)
 @@ -29,7 +29,7 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd August 27, 2008
 +.Dd April 20, 2010
  .Dt PING6 8
  .Os
  .Sh NAME
 @@ -40,9 +40,9 @@ packets to network hosts
  .Sh SYNOPSIS
  .Nm
  .\" without ipsec, or new ipsec
 -.Op Fl dfHmnNoqrRtvwW
 +.Op Fl DdfHmnNoqrRtvwW
  .\" old ipsec
 -.\" .Op Fl AdEfmnNqRtvwW
 +.\" .Op Fl ADdEfmnNqRtvwW
  .Bk -words
  .Op Fl a Ar addrtype
  .Ek
 @@ -141,6 +141,8 @@ Stop after sending
  .Ar count
  .Tn ECHO_RESPONSE
  packets.
 +.It Fl D
 +Disable IPv6 fragmentation.
  .It Fl d
  Set the
  .Dv SO_DEBUG
 
 Modified: head/sbin/ping6/ping6.c
 ==============================================================================
 --- head/sbin/ping6/ping6.c	Tue Apr 20 06:08:34 2010	(r206888)
 +++ head/sbin/ping6/ping6.c	Tue Apr 20 06:10:05 2010	(r206889)
 @@ -191,6 +191,7 @@ struct tv32 {
  #define F_ONCE		0x200000
  #define F_AUDIBLE	0x400000
  #define F_MISSED	0x800000
 +#define F_DONTFRAG	0x1000000
  #define F_NOUSERDATA	(F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
  u_int options;
  
 @@ -349,7 +350,7 @@ main(argc, argv)
  #endif /*IPSEC_POLICY_IPSEC*/
  #endif
  	while ((ch = getopt(argc, argv,
 -	    "a:b:c:dfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
 +	    "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
  #undef ADDOPTS
  		switch (ch) {
  		case 'a':
 @@ -415,6 +416,9 @@ main(argc, argv)
  				errx(1,
  				    "illegal number of packets -- %s", optarg);
  			break;
 +		case 'D':
 +			options |= F_DONTFRAG;
 +			break;
  		case 'd':
  			options |= F_SO_DEBUG;
  			break;
 @@ -742,7 +746,11 @@ main(argc, argv)
  	for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t))
  		*((u_int32_t *)&nonce[i]) = arc4random();
  #endif
 -
 +	optval = 1;
 +	if (options & F_DONTFRAG)
 +		if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
 +		    &optval, sizeof(optval)) == -1)
 +			err(1, "IPV6_DONTFRAG");
  	hold = 1;
  
  	if (options & F_SO_DEBUG)
 @@ -2780,7 +2788,7 @@ usage()
  	    "A"
  #endif
  	    "usage: ping6 [-"
 -	    "d"
 +	    "Dd"
  #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC)
  	    "E"
  #endif
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Thu May 20 08:03:19 UTC 2010 
State-Changed-Why:  
Merged to RELENG_8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=145759 
>Unformatted:
