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