From nobody@FreeBSD.org  Tue Aug  7 08:21:38 2007
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 4449B16A418
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  7 Aug 2007 08:21:38 +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 1DF7313C442
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  7 Aug 2007 08:21:38 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l778LcvJ009582
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 7 Aug 2007 08:21:38 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.1/8.14.1/Submit) id l778Lb6i009581;
	Tue, 7 Aug 2007 08:21:38 GMT
	(envelope-from nobody)
Message-Id: <200708070821.l778Lb6i009581@www.freebsd.org>
Date: Tue, 7 Aug 2007 08:21:38 GMT
From: Pekka Savola <pekkas@netcore.fi>
To: freebsd-gnats-submit@FreeBSD.org
Subject: incorrect 'ipfw: pullup failed' with IPv6 no-next-header
X-Send-Pr-Version: www-3.0

>Number:         115261
>Category:       kern
>Synopsis:       [ipfw]: incorrect 'ipfw: pullup failed' with IPv6 no-next-header
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 07 08:30:01 GMT 2007
>Closed-Date:    Tue May 20 11:18:42 UTC 2008
>Last-Modified:  Tue Jul 10 03:39:38 UTC 2012
>Originator:     Pekka Savola
>Release:        6.2-STABLE
>Organization:
>Environment:
FreeBSD sixpack.funet.fi 6.2-STABLE FreeBSD 6.2-STABLE #10: Tue Aug  7 10:59:15 EEST 2007     root@sixpack.funet.fi:/usr/obj/usr/src/sys/SIXPACK  i386

>Description:
I get a lot of following kind of IPv6 packets:

11:35:48.327605 IP6 (hlim 255, next-header: unknown (59), length: 0) 2001:0:4136 :xxxx:yyyy:zzzz:wwww:vvvv > fe80::fc31:b43b:679c:dcb9: no next header

These are used for Teredo bubbles through a Teredo relay.  (There are also occas ional other kinds of no-next-header packets which get the same pull-up failed tr eatment.)

These seem to cause "ipfw: pullup failed" messages in syslogs (I get 300-500 / 1 0 minutes), so a large number of packets are lost before they get to the main ip fw and forwarding code.

The code in ip_fw2.c appears to be:

                        case IPPROTO_NONE:      /* RFC 2460 */
                                PULLUP_TO(hlen, ulp, struct ip6_ext);
                                /* Packet ends here. if ip6e_len!=0 octets
                                * must be ignored. */
                                break;

. but struct ip6_ext is at least 2 bytes long.  The problem here is that the co de expects that in addition to the IPv6 base header, there would be sizeof(struc t ip6_ext) of payload. This is an incorrect assumption as IPPROTO_NONE by defini tion does not need to have any payload, even the skeleton extension header.

Attached patch demonstrates a quick'n'dirty way to avoid these warning messages.   The real fix may or may not require redefining the PULLUP_TO macro to pass a l ength as third argument rather than the struct.

>How-To-Repeat:
Craft an IPv6 packet with next-header set to 59 (no next header) and no payload.
>Fix:
See the patch.

Patch attached with submission follows:

--- sys/netinet/ip_fw2.c.orig	2007-06-07 12:50:53.000000000 +0300
+++ sys/netinet/ip_fw2.c	2007-08-07 10:56:03.000000000 +0300
@@ -2259,6 +2259,18 @@
 	p = (mtod(m, char *) + (len));					\
 } while (0)
 
+/* XXX: pullup with zero-length T, the simplest possible hack.. */
+#define PULLUP(len, p)							\
+do {									\
+	int x = (len);							\
+	if ((m)->m_len < x) {						\
+		args->m = m = m_pullup(m, x);				\
+		if (m == NULL)						\
+			goto pullup_failed;				\
+	}								\
+	p = (mtod(m, char *) + (len));					\
+} while (0)
+
 	/*
 	 * if we have an ether header,
 	 */
@@ -2373,7 +2385,7 @@
 				break;
 
 			case IPPROTO_NONE:	/* RFC 2460 */
-				PULLUP_TO(hlen, ulp, struct ip6_ext);
+				PULLUP(hlen, ulp);
 				/* Packet ends here. if ip6e_len!=0 octets
 				 * must be ignored. */
 				break;
@@ -2473,6 +2485,7 @@
 		args->f_id.dst_ip = ntohl(dst_ip.s_addr);
 	}
 #undef PULLUP_TO
+#undef PULLUP
 	if (proto) { /* we may have port numbers, store them */
 		args->f_id.proto = proto;
 		args->f_id.src_port = src_port = ntohs(src_port);


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-ipfw 
Responsible-Changed-By: remko 
Responsible-Changed-When: Tue Aug 7 08:39:04 UTC 2007 
Responsible-Changed-Why:  
Reassign to ipfw team. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115261 
Responsible-Changed-From-To: freebsd-ipfw->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Wed Sep 19 12:33:31 UTC 2007 
Responsible-Changed-Why:  
I'll take a look at this one, as I've had a look at this code before. 

David. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/115261: commit references a PR
Date: Sun,  9 Dec 2007 15:35:18 +0000 (UTC)

 dwmalone    2007-12-09 15:35:09 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/netinet          ip_fw2.c 
   Log:
   If we are walking the IPv6 header chain and we hit an IPPROTO_NONE
   header, then don't try to pullup anything, because there is no next
   header if we hit IPPROTO_NONE. Set ulp to a non-NULL value so the
   search for an upper layer header terinates.
   
   This is based on Pekka's diagnosis, but I chose a simpler fix.
   
   PR:             115261
   Submitted by:   Pekka Savola <pekkas@netcore.fi>
   Reviewed by:    mlaier
   MFC after:      2 weeks
   
   Revision  Changes    Path
   1.179     +6 -3      src/sys/netinet/ip_fw2.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: linimon 
State-Changed-When: Fri Feb 29 02:02:29 UTC 2008 
State-Changed-Why:  
Apparently still needs to be MFCed to RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115261 
State-Changed-From-To: patched->closed 
State-Changed-By: dwmalone 
State-Changed-When: Tue May 20 11:18:04 UTC 2008 
State-Changed-Why:  
Now merged to RELENG_6 and RELENG_7. Thanks for the PR and sorry 
for the delay! 

David. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115261 
Responsible-Changed-From-To: dwmalone->freebsd-bugs 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Tue Jul 10 03:39:38 UTC 2012 
Responsible-Changed-Why:  
over to the pool (approved by bugmeister) 

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