kern/106999: [patch] ng_ksocket fails to clear multicast flag on mbuf before passing to stack

Kevin Lahey lahey at isi.edu
Thu Dec 21 03:50:20 PST 2006


>Number:         106999
>Category:       kern
>Synopsis:       [patch] ng_ksocket fails to clear multicast flag on mbuf before passing to stack
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 21 11:50:18 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Kevin Lahey
>Release:        FreeBSD 6.1
>Organization:
ISI
>Environment:
System:  FreeBSD myboss.elab-tunnel1.detertest.isi.deterlab.net 6.1-RELEASE-p3 FreeBSD 6.1-RELEASE-p3 #0: Tue Aug  8 15:35:11 PDT 2006     root at bpc034:/usr/src/sys/i386/compile/TESTBED  i386

>Description:
I used netgraph to encapsulate an incoming Ethernet frame in UDP and 
send it off to a remote host.  When a multicast Ethernet frame was 
encapsulated in UDP, the Ethernet destination on the resulting packet 
was a multicast address, rather than the correct Ethernet address of 
the default router.  That is:

Original:      [UES:MED][IP Payload]
Encapsulated:  [UES2:MED2][IP][UDP][UES:MED][IP Payload]

UES, UES2 = Unicast Ethernet Source (both different)
MED, MED2 = Multicast Ethernet Destination (both different)
(And, yeah, the IP destination of the encapsulation was *not* multicast)

It appears that ng_ksocket doesn't strip off the mbuf flags on the
incoming mbufs before handing off to the regular network stack.
These flags are obeyed when the encapsulated packet is sent out,
resulting in a bogus Ethernet destination address derived from the
IP destination, rather than from the ARP table.

It looks like ng_ksocket got completely replumbed in -current, so
this probably might have been fixed already.

>How-To-Repeat:
	Here's the script I use to build the tunnel:  

  kldload /boot/kernel/{netgraph,ng_ksocket,ng_eiface,ng_socket,if_bridge}.ko
  
  # Originally from Keith Sklower
  
  ngctl -n self -f /dev/stdin << EOF
  mkpeer eiface dummy ether
  name self:dummy eif
  EOF
  
  # Need a gap to set up eif before creating more goop
  ngctl -f /dev/stdin << EOF
  mkpeer eif: ksocket ether inet/dgram/udp
  name eif:ether ksoc
  msg ksoc: bind inet/0.0.0.0:30000
  msg ksoc: connect inet/192.168.1.188:30000
  EOF
  
  ifconfig em4 up mtu 1500
  ifconfig ngeth0 link 00:14:22:23:89:28 up mtu 1500
  ifconfig bridge0 create
  ifconfig bridge0 addm em4 addm ngeth0 up

Send in a multicast Ethernet packet and watch the fireworks.
(Admittedly, the packet that screwed me up was a STP packet which
I probably *don't* want to forward, but...)
>Fix:


--- /share/freebsd/6.1/src/sys/netgraph/ng_ksocket.c	Fri Feb 24 03:23:05 2006
+++ ./ng_ksocket.c	Fri Dec 15 17:23:24 2006
@@ -919,6 +919,11 @@
 	    (stag->id == NG_NODE_ID(node) || stag->id == 0))
 		sa = &stag->sa;
 
+	/* Turn off any possibly bogus flags in the mbuf */
+
+	if (m->m_flags | (M_BCAST | M_MCAST))
+		m->m_flags &= (~(M_BCAST | M_MCAST));
+
 	/* Send packet */
 	error = (*so->so_proto->pr_usrreqs->pru_sosend)(so, sa, 0, m, 0, 0, td);
 

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list