Page MenuHomeFreeBSD

D38425.1790955683.diff
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

D38425.1790955683.diff

diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -2302,6 +2302,32 @@
{
}
+static bool
+bridge_learn(struct bridge_softc *sc, struct bridge_iflist *sbif,
+ const struct ether_header *eh, uint16_t vlan)
+{
+ if ((sbif->bif_flags & IFBIF_LEARNING) != 0) {
+ int error;
+
+ error = bridge_rtupdate(sc, eh->ether_shost, vlan, sbif, 0,
+ IFBAF_DYNAMIC);
+
+ /*
+ * If the interface has addresses limits then deny any source
+ * that is not already in the cache.
+ */
+ if (error != 0 && sbif->bif_addrmax != 0)
+ return (false);
+ }
+ return (true);
+}
+
+#ifdef INET6
+#define PFIL_HOOKED_INET6 PFIL_HOOKED_IN(V_inet6_pfil_head)
+#else
+#define PFIL_HOOKED_INET6 false
+#endif
+
/*
* bridge_forward:
*
@@ -2318,7 +2344,6 @@
struct ether_header *eh;
uint16_t vlan;
uint8_t *dst;
- int error;
NET_EPOCH_ASSERT();
@@ -2337,16 +2362,8 @@
dst = eh->ether_dhost;
/* If the interface is learning, record the address. */
- if (sbif->bif_flags & IFBIF_LEARNING) {
- error = bridge_rtupdate(sc, eh->ether_shost, vlan,
- sbif, 0, IFBAF_DYNAMIC);
- /*
- * If the interface has addresses limits then deny any source
- * that is not in the cache.
- */
- if (error && sbif->bif_addrmax)
- goto drop;
- }
+ if (!bridge_learn(sc, sbif, eh, vlan))
+ goto drop;
if ((sbif->bif_flags & IFBIF_STP) != 0 &&
sbif->bif_stp.bp_state == BSTP_IFSTATE_LEARNING)
@@ -2395,11 +2412,7 @@
ETHER_BPF_MTAP(ifp, m);
/* run the packet filter */
- if (PFIL_HOOKED_IN(V_inet_pfil_head)
-#ifdef INET6
- || PFIL_HOOKED_IN(V_inet6_pfil_head)
-#endif
- ) {
+ if (PFIL_HOOKED_IN(V_inet_pfil_head) || PFIL_HOOKED_INET6) {
if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
return;
if (m == NULL)
@@ -2431,11 +2444,7 @@
dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
goto drop;
- if (PFIL_HOOKED_OUT(V_inet_pfil_head)
-#ifdef INET6
- || PFIL_HOOKED_OUT(V_inet6_pfil_head)
-#endif
- ) {
+ if (PFIL_HOOKED_OUT(V_inet_pfil_head) || PFIL_HOOKED_INET6) {
if (bridge_pfil(&m, ifp, dst_if, PFIL_OUT) != 0)
return;
if (m == NULL)
@@ -2449,6 +2458,46 @@
m_freem(m);
}
+/*
+ * Consume the input packet from sifp destined to ifp.
+ */
+static inline struct mbuf *
+bridge_grab(struct bridge_softc *sc, struct ifnet *sifp, struct ifnet *ifp,
+ struct bridge_iflist *sbif, struct mbuf *m, uint16_t vlan)
+{
+ struct ifnet *bifp;
+
+ if (!bridge_learn(sc, sbif, mtod(m, struct ether_header *), vlan)) {
+ m_freem(m);
+ return (NULL);
+ }
+ m->m_pkthdr.rcvif = ifp;
+ if (sifp == ifp) {
+ /* Skip bridge processing... src == dest */
+ return (m);
+ }
+
+ /* It's passing over or to the bridge, locally. */
+ bifp = sc->sc_ifp;
+ ETHER_BPF_MTAP(bifp, m);
+ if_inc_counter(bifp, IFCOUNTER_IPACKETS, 1);
+ if_inc_counter(bifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
+
+ /* Filter on the physical interface. */
+ if (V_pfil_local_phys && (PFIL_HOOKED_IN(V_inet_pfil_head) ||
+ PFIL_HOOKED_INET6)) {
+ if (bridge_pfil(&m, NULL, ifp, PFIL_IN) != 0 ||
+ m == NULL) {
+ return (NULL);
+ }
+ }
+ if (sifp != bifp)
+ ETHER_BPF_MTAP(sifp, m);
+ return (m);
+}
+
+#undef PFIL_HOOKED_INET6
+
/*
* bridge_input:
*
@@ -2464,7 +2513,6 @@
struct ether_header *eh;
struct mbuf *mc, *mc2;
uint16_t vlan;
- int error;
NET_EPOCH_ASSERT();
@@ -2561,78 +2609,58 @@
#define CARP_CHECK_WE_ARE_SRC(iface) false
#endif
-#ifdef INET6
-#define PFIL_HOOKED_INET6 PFIL_HOOKED_IN(V_inet6_pfil_head)
-#else
-#define PFIL_HOOKED_INET6 false
-#endif
-
-#define GRAB_OUR_PACKETS(iface) \
- if ((iface)->if_type == IFT_GIF) \
- continue; \
- /* It is destined for us. */ \
- if (memcmp(IF_LLADDR(iface), eh->ether_dhost, ETHER_ADDR_LEN) == 0 || \
- CARP_CHECK_WE_ARE_DST(iface)) { \
- if (bif->bif_flags & IFBIF_LEARNING) { \
- error = bridge_rtupdate(sc, eh->ether_shost, \
- vlan, bif, 0, IFBAF_DYNAMIC); \
- if (error && bif->bif_addrmax) { \
- m_freem(m); \
- return (NULL); \
- } \
- } \
- m->m_pkthdr.rcvif = iface; \
- if ((iface) == ifp) { \
- /* Skip bridge processing... src == dest */ \
- return (m); \
- } \
- /* It's passing over or to the bridge, locally. */ \
- ETHER_BPF_MTAP(bifp, m); \
- if_inc_counter(bifp, IFCOUNTER_IPACKETS, 1); \
- if_inc_counter(bifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); \
- /* Filter on the physical interface. */ \
- if (V_pfil_local_phys && (PFIL_HOOKED_IN(V_inet_pfil_head) || \
- PFIL_HOOKED_INET6)) { \
- if (bridge_pfil(&m, NULL, ifp, \
- PFIL_IN) != 0 || m == NULL) { \
- return (NULL); \
- } \
- } \
- if ((iface) != bifp) \
- ETHER_BPF_MTAP(iface, m); \
- return (m); \
- } \
- \
- /* We just received a packet that we sent out. */ \
- if (memcmp(IF_LLADDR(iface), eh->ether_shost, ETHER_ADDR_LEN) == 0 || \
- CARP_CHECK_WE_ARE_SRC(iface)) { \
- m_freem(m); \
- return (NULL); \
- }
+#define PACKET_IS_FOR(iface) \
+ (memcmp(if_getlladdr(iface), eh->ether_dhost, ETHER_ADDR_LEN) == 0 || \
+ CARP_CHECK_WE_ARE_DST(iface))
+#define PACKET_IS_FROM(iface) \
+ (memcmp(if_getlladdr(iface), eh->ether_shost, ETHER_ADDR_LEN) == 0 || \
+ CARP_CHECK_WE_ARE_SRC(iface))
/*
* Unicast. Make sure it's not for the bridge.
*/
- do { GRAB_OUR_PACKETS(bifp) } while (0);
+ if (PACKET_IS_FOR(bifp))
+ return (bridge_grab(sc, ifp, bifp, bif, m, vlan));
+ if (PACKET_IS_FROM(bifp)) {
+ m_freem(m);
+ return (NULL);
+ }
/*
- * Give a chance for ifp at first priority. This will help when the
- * packet comes through the interface like VLAN's with the same MACs
- * on several interfaces from the same bridge. This also will save
- * some CPU cycles in case the destination interface and the input
- * interface (eq ifp) are the same.
+ * Give a chance for ifp (the source interface) at first priority. This
+ * will help when the packet comes through the interface like VLAN's
+ * with the same MACs on several interfaces from the same bridge. This
+ * also will save some CPU cycles in case the destination interface and
+ * the input interface (eq ifp) are the same.
*/
- do { GRAB_OUR_PACKETS(ifp) } while (0);
+ if (if_gettype(ifp) != IFT_GIF) {
+ if (PACKET_IS_FOR(ifp))
+ return (bridge_grab(sc, ifp, ifp, bif, m, vlan));
+ if (PACKET_IS_FROM(ifp)) {
+ m_freem(m);
+ return (NULL);
+ }
+ }
/* Now check the all bridge members. */
CK_LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) {
- GRAB_OUR_PACKETS(bif2->bif_ifp)
+ struct ifnet *mifp;
+
+ mifp = bif2->bif_ifp;
+ if (if_gettype(mifp) == IFT_GIF)
+ continue;
+ if (PACKET_IS_FOR(bif2->bif_ifp))
+ return (bridge_grab(sc, ifp, mifp, bif, m, vlan));
+ if (PACKET_IS_FROM(mifp)) {
+ m_freem(m);
+ return (NULL);
+ }
}
-#undef OR_CARP_CHECK_WE_ARE_DST
-#undef OR_CARP_CHECK_WE_ARE_SRC
-#undef OR_PFIL_HOOKED_INET6
-#undef GRAB_OUR_PACKETS
+#undef CARP_CHECK_WE_ARE_DST
+#undef CARP_CHECK_WE_ARE_SRC
+#undef PACKET_IS_FOR
+#undef PACKET_IS_FROM
/* Perform the bridge forwarding function. */
bridge_forward(sc, bif, m);

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 2, 3:41 PM (6 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30088669
Default Alt Text
D38425.1790955683.diff (7 KB)

Event Timeline