Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Restructure bridge_input and bridge_broadcast
details: https://anonhg.NetBSD.org/src/rev/ebdd9a53e680
branches: trunk
changeset: 330031:ebdd9a53e680
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Wed Jun 18 10:51:03 2014 +0000
description:
Restructure bridge_input and bridge_broadcast
There are two changes:
- Assemble the places calling pktq_enqueue (bridge_forward)
for unicast and {b,m}cast frames into one
- Receive {b,m}cast frames in bridge_broadcast, not in
bridge_input
The changes make the code clear and readable. bridge_input
now doesn't need to take care of {b,m}cast frames;
bridge_forward and bridge_broadcast have the responsibility.
The changes are based on a patch of Lloyd Parkes submitted
in PR 48104, but don't fix its issue yet.
diffstat:
sys/net/if_bridge.c | 97 ++++++++++++++++++++++------------------------------
1 files changed, 41 insertions(+), 56 deletions(-)
diffs (167 lines):
diff -r 8fb3fe37434d -r ebdd9a53e680 sys/net/if_bridge.c
--- a/sys/net/if_bridge.c Wed Jun 18 09:41:29 2014 +0000
+++ b/sys/net/if_bridge.c Wed Jun 18 10:51:03 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridge.c,v 1.82 2014/06/18 09:20:46 ozaki-r Exp $ */
+/* $NetBSD: if_bridge.c,v 1.83 2014/06/18 10:51:03 ozaki-r Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.82 2014/06/18 09:20:46 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.83 2014/06/18 10:51:03 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_bridge_ipf.h"
@@ -1612,7 +1612,6 @@
struct bridge_softc *sc = ifp->if_bridge;
struct bridge_iflist *bif;
struct ether_header *eh;
- struct mbuf *mc;
if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
ether_input(ifp, m);
@@ -1635,68 +1634,50 @@
m->m_flags |= M_MCAST;
}
- if (m->m_flags & (M_BCAST|M_MCAST)) {
- if (bif->bif_flags & IFBIF_STP) {
- /* Tap off 802.1D packets; they do not get forwarded. */
- if (memcmp(eh->ether_dhost, bstp_etheraddr,
- ETHER_ADDR_LEN) == 0) {
- bstp_input(sc, bif, m);
+ /*
+ * A 'fast' path for packets addressed to interfaces that are
+ * part of this bridge.
+ */
+ if (!(m->m_flags & (M_BCAST|M_MCAST)) &&
+ !bstp_state_before_learning(bif)) {
+ struct bridge_iflist *_bif;
+
+ LIST_FOREACH(_bif, &sc->sc_iflist, bif_next) {
+ /* It is destined for us. */
+ if (bridge_ourether(_bif, eh, 0)) {
+ if (_bif->bif_flags & IFBIF_LEARNING)
+ (void) bridge_rtupdate(sc,
+ eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
+ m->m_pkthdr.rcvif = _bif->bif_ifp;
+ ether_input(_bif->bif_ifp, m);
return;
}
- if (bstp_state_before_learning(bif)) {
- ether_input(ifp, m);
+ /* We just received a packet that we sent out. */
+ if (bridge_ourether(_bif, eh, 1)) {
+ m_freem(m);
return;
}
}
+ }
- /*
- * Make a deep copy of the packet and enqueue the copy
- * for bridge processing; return the original packet for
- * local processing.
- */
- mc = m_dup(m, 0, M_COPYALL, M_NOWAIT);
- if (mc == NULL) {
- ether_input(ifp, m);
- return;
- }
-
- /* Perform the bridge forwarding function with the copy. */
- if (__predict_false(!pktq_enqueue(sc->sc_fwd_pktq, mc, 0)))
- m_freem(mc);
-
- /* For local processing. */
- ether_input(ifp, m);
+ /* Tap off 802.1D packets; they do not get forwarded. */
+ if (bif->bif_flags & IFBIF_STP &&
+ memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
+ bstp_input(sc, bif, m);
return;
}
+ /*
+ * A normal switch would discard the packet here, but that's not what
+ * we've done historically. This also prevents some obnoxious behaviour.
+ */
if (bstp_state_before_learning(bif)) {
ether_input(ifp, m);
return;
}
- /*
- * Unicast. Make sure it's not for us.
- */
- LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
- /* It is destined for us. */
- if (bridge_ourether(bif, eh, 0)) {
- if (bif->bif_flags & IFBIF_LEARNING)
- (void) bridge_rtupdate(sc,
- eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
- m->m_pkthdr.rcvif = bif->bif_ifp;
- ether_input(bif->bif_ifp, m);
- return;
- }
-
- /* We just received a packet that we sent out. */
- if (bridge_ourether(bif, eh, 1)) {
- m_freem(m);
- return;
- }
- }
-
- /* Perform the bridge forwarding function. */
+ /* Queue the packet for bridge forwarding. */
if (__predict_false(!pktq_enqueue(sc->sc_fwd_pktq, m, 0)))
m_freem(m);
}
@@ -1715,7 +1696,9 @@
struct bridge_iflist *bif;
struct mbuf *mc;
struct ifnet *dst_if;
- int used = 0;
+ bool used, bmcast;
+
+ used = bmcast = m->m_flags & (M_BCAST|M_MCAST);
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
dst_if = bif->bif_ifp;
@@ -1730,16 +1713,15 @@
}
}
- if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
- (m->m_flags & (M_BCAST|M_MCAST)) == 0)
+ if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && !bmcast)
continue;
if ((dst_if->if_flags & IFF_RUNNING) == 0)
continue;
- if (LIST_NEXT(bif, bif_next) == NULL) {
+ if (!used && LIST_NEXT(bif, bif_next) == NULL) {
mc = m;
- used = 1;
+ used = true;
} else {
mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
if (mc == NULL) {
@@ -1750,7 +1732,10 @@
bridge_enqueue(sc, dst_if, mc, 1);
}
- if (used == 0)
+
+ if (bmcast)
+ ether_input(src_if, m);
+ else if (!used)
m_freem(m);
}
Home |
Main Index |
Thread Index |
Old Index