Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Allow multicast/broadcast packets from a bridge memb...
details: https://anonhg.NetBSD.org/src/rev/72e6286b7886
branches: trunk
changeset: 345052:72e6286b7886
user: roy <roy%NetBSD.org@localhost>
date: Wed May 04 18:59:55 2016 +0000
description:
Allow multicast/broadcast packets from a bridge member to other members.
Note this should just call bridge_broadcast when more locking issues are
resolved.
diffstat:
sys/net/if_bridge.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 47 insertions(+), 4 deletions(-)
diffs (97 lines):
diff -r 478a8e5fc6eb -r 72e6286b7886 sys/net/if_bridge.c
--- a/sys/net/if_bridge.c Wed May 04 18:36:46 2016 +0000
+++ b/sys/net/if_bridge.c Wed May 04 18:59:55 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridge.c,v 1.121 2016/04/28 01:37:17 knakahara Exp $ */
+/* $NetBSD: if_bridge.c,v 1.122 2016/05/04 18:59:55 roy Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.121 2016/04/28 01:37:17 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.122 2016/05/04 18:59:55 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_bridge_ipf.h"
@@ -1422,6 +1422,14 @@
eh = mtod(m, struct ether_header *);
sc = ifp->if_bridge;
+ if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ if (memcmp(etherbroadcastaddr,
+ eh->ether_dhost, ETHER_ADDR_LEN) == 0)
+ m->m_flags |= M_BCAST;
+ else
+ m->m_flags |= M_MCAST;
+ }
+
/*
* If bridge is down, but the original output interface is up,
* go ahead and send out that interface. Otherwise, the packet
@@ -1437,11 +1445,13 @@
* If the packet is a multicast, or we don't know a better way to
* get there, send to all interfaces.
*/
- if (ETHER_IS_MULTICAST(eh->ether_dhost))
+ if ((m->m_flags & (M_MCAST | M_BCAST)) != 0)
dst_if = NULL;
else
dst_if = bridge_rtlookup(sc, eh->ether_dhost);
if (dst_if == NULL) {
+ /* XXX Should call bridge_broadcast, but there are locking
+ * issues which need resolving first. */
struct bridge_iflist *bif;
struct mbuf *mc;
bool used = false;
@@ -1474,7 +1484,10 @@
}
if (PSLIST_READER_NEXT(bif, struct bridge_iflist,
- bif_next) == NULL) {
+ bif_next) == NULL &&
+ ((m->m_flags & (M_MCAST | M_BCAST)) == 0 ||
+ dst_if == ifp))
+ {
used = true;
mc = m;
} else {
@@ -1492,6 +1505,36 @@
#ifndef NET_MPSAFE
splx(s);
#endif
+
+ if ((m->m_flags & (M_MCAST | M_BCAST)) != 0 &&
+ dst_if != ifp)
+ {
+ if (PSLIST_READER_NEXT(bif,
+ struct bridge_iflist, bif_next) == NULL)
+ {
+ used = true;
+ mc = m;
+ } else {
+ mc = m_copym(m, 0, M_COPYALL,
+ M_DONTWAIT);
+ if (mc == NULL) {
+ sc->sc_if.if_oerrors++;
+ goto next;
+ }
+ }
+
+ mc->m_pkthdr.rcvif = dst_if;
+ mc->m_flags &= ~M_PROMISC;
+
+#ifndef NET_MPSAFE
+ s = splnet();
+#endif
+ ether_input(dst_if, mc);
+#ifndef NET_MPSAFE
+ splx(s);
+#endif
+ }
+
next:
BRIDGE_PSZ_RENTER(s);
bridge_release_member(sc, bif, &psref);
Home |
Main Index |
Thread Index |
Old Index