Subject: kern/30844: IPv6/GRE: pcap mishandling of received non-AF_INET packets
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Gert Doering <gert@kirk.greenie.muc.de>
List: netbsd-bugs
Date: 07/26/2005 21:13:00
>Number:         30844
>Category:       kern
>Synopsis:       all (multiprotocol!) packets received on GRE tunnels are passed to bpf_mtap() as AF_INET
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 26 21:13:00 +0000 2005
>Originator:     Gert Doering
>Release:        NetBSD 3.99.7
>Organization:
>Environment:
System: NetBSD epsilon 3.99.7 NetBSD 3.99.7 (SCOTTY-IPSEC) #2: Tue Jul 26 21:58:22 CEST 2005 gert@epsilon:/home/sparc64.current/obj/home/src-current/sys/arch/sparc64/compile/SCOTTY-IPSEC sparc64
Architecture: sparc64
Machine: sparc64
>Description:
	when running "tcpdump -i gre0" on a GRE tunnel that carries
	non-IPv4 packets (e.g. IPv6, Appletalk, NS), tcpdump will
	report 
		"IP6 , wrong link-layer encapsulationbad-hlen 0"
	for all received packets.

	Sent packets are decoded correctly.

>How-To-Repeat:
	Setup an IPv6-over-GRE tunnel, e.g.:
	    ifconfig gre0 create
	    ifconfig gre0 tunnel 193.149.48.172 195.30.70.42 up
	    ifconfig gre0 inet6 2001:609:1003::1/64
	    route add -inet6 default 2001:608::1 -ifp gre0
	(please do not use these numbers verbatim)

	then run "tcpdump -n -s0 -i gre0" and run a ping through the tunnel.

	What you'll see is similar to this:

16:16:28.835438 IP6 2001:609:1003::1 > 2001:608:4::3: ICMP6, echo request, seq
+0, length 16
16:16:28.937041 IP6 , wrong link-layer encapsulationbad-hlen 0

	(the ping is working, and getting the response packets back,
	and if you do "tcpdump -i <lan-interface>" it will also
	print fine)

>Fix:
	Here's the patch.  The original code in if_gre.c neglects to
	set the address family correctly before calling bpf_mtap()
	- which nobody ever noticed for NS and Appletalk, but I found
	it today when debugging IPv6 stuff.

-------- snip ----------
Index: ip_gre.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_gre.c,v
retrieving revision 1.34
diff -u -r1.34 ip_gre.c
--- ip_gre.c	30 Mar 2005 16:34:54 -0000	1.34
+++ ip_gre.c	26 Jul 2005 20:18:19 -0000
@@ -151,6 +151,9 @@
 	struct ifqueue *ifq;
 	struct gre_softc *sc;
 	u_int16_t flags;
+#if NBPFILTER > 0
+	u_int32_t af = AF_INET;		/* af passed to BPF tap */
+#endif
 
 	if ((sc = gre_lookup(m, proto)) == NULL) {
 		/* No matching tunnel or tunnel is down. */
@@ -194,12 +197,18 @@
 		case ETHERTYPE_NS:
 			ifq = &nsintrq;
 			isr = NETISR_NS;
+#if NBPFILTER > 0
+			af = AF_NS;
+#endif
 			break;
 #endif
 #ifdef NETATALK
 		case ETHERTYPE_ATALK:
 			ifq = &atintrq1;
 			isr = NETISR_ATALK;
+#if NBPFILTER > 0
+			af = AF_APPLETALK;
+#endif
 			break;
 #endif
 #ifdef INET6
@@ -209,6 +218,9 @@
 #endif
 			ifq = &ip6intrq;
 			isr = NETISR_IPV6;
+#if NBPFILTER > 0
+			af = AF_INET6;
+#endif
 			break;
 #endif
 		default:	   /* others not yet supported */
@@ -230,7 +242,6 @@
 #if NBPFILTER > 0
 	if (sc->sc_if.if_bpf) {
 		struct mbuf m0;
-		u_int32_t af = AF_INET;
 
 		m0.m_flags = 0;
 		m0.m_next = m;

>Unformatted:
 	CVS checkout of HEAD as of July 25st, 2005
 	but affects all releases that have ip_gre.c