tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

SOLVED: Multicast problems with bridge(4) ports



Hi all,
I have found the bug that causes this and I've got a fix. 

The problem is that bridge_broadcast() only puts broadcast packets onto the 
output queue of the interfaces it is broadcasting the packet to and doesn't put 
a copy onto their input queues. I just added a small lump of code to copy the 
packet appropriately and I used M_LINK2 to avoid broadcasting packets that have 
already been broadcast.

The NetBSD bridge(4) code for handling unicast packets has a short circuit in 
it that allows an input packet to be switched onto another interface as 
ether_input() passes it up the protocol stack, but this can't be done for 
broadcasts because each interface needs its own copy of the packet.

I'll raise a PR for this, and here's the code I'll be submitting with it. I'll 
also copy my test configuration into the PR for reference. I'm more than happy 
to take suggestions on better ways to fix this.

Cheers,
Lloyd

Index: sys/net/if_bridge.c
===================================================================
RCS file: /vol/src/rsync-src/src/sys/net/if_bridge.c,v
retrieving revision 1.74
diff -u -r1.74 if_bridge.c
--- sys/net/if_bridge.c 19 Nov 2011 22:51:25 -0000      1.74
+++ sys/net/if_bridge.c 5 Aug 2013 00:05:32 -0000
@@ -1633,6 +1633,13 @@
                }

                bridge_enqueue(sc, dst_if, mc, 1);
+               mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
+               if (mc == NULL) {
+                       sc->sc_if.if_oerrors++;
+                       continue;
+               }
+               mc->m_pkthdr.rcvif = dst_if;
+               (*dst_if->if_input)(dst_if, mc);
        }
        if (used == 0)
                m_freem(m);
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /vol/src/rsync-src/src/sys/net/if_ethersubr.c,v
retrieving revision 1.188.8.3
diff -u -r1.188.8.3 if_ethersubr.c
--- sys/net/if_ethersubr.c      31 Oct 2012 16:07:46 -0000      1.188.8.3
+++ sys/net/if_ethersubr.c      4 Aug 2013 06:53:32 -0000
@@ -703,7 +703,8 @@
         * will always return the original packet if we need to
         * process it locally.
         */
-       if (ifp->if_bridge) {
+       if (ifp->if_bridge && (m->m_flags & M_LINK2) == 0) {
+               m->m_flags |= M_LINK2;
                /* clear M_PROMISC, in case the packets comes from a vlan */
                m->m_flags &= ~M_PROMISC;
                m = bridge_input(ifp, m);


Home | Main Index | Thread Index | Old Index