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>