Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Aug 2007 08:21:38 GMT
From:      Pekka Savola <pekkas@netcore.fi>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/115261: incorrect 'ipfw: pullup failed' with IPv6 no-next-header
Message-ID:  <200708070821.l778Lb6i009581@www.freebsd.org>
Resent-Message-ID: <200708070830.l778U1Uj001546@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         115261
>Category:       kern
>Synopsis:       incorrect 'ipfw: pullup failed' with IPv6 no-next-header
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 07 08:30:01 GMT 2007
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708070821.l778Lb6i009581>