kern/115261: incorrect 'ipfw: pullup failed' with IPv6
no-next-header
Pekka Savola
pekkas at netcore.fi
Tue Aug 7 01:30:02 PDT 2007
>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 at 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:
More information about the freebsd-bugs
mailing list