Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149813013
D38425.1790955683.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D38425.1790955683.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D38425: bridge: Further decompose GRAB_OUR_PACKETS
Attached
Detach File
Event Timeline
Log In to Comment