On 08/06/15(Mon) 15:58, Martin Pieuchot wrote:
> Diff below moves bridge_output() to if_output().  It fixes the case I
> already described some weeks ago where you have a physical interface
> in a bridge and a vlan on top of it which is not in the bridge.
> 
> It also change the loop prevention code to use M_PROTO1 like in the
> input path.
> 
> Tests, comments and oks welcome.

Updated diff to match the recent if_get() change.  I've got one positive
report so far, any ok?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.340
diff -u -p -r1.340 if.c
--- net/if.c    16 Jun 2015 11:09:39 -0000      1.340
+++ net/if.c    17 Jun 2015 12:01:12 -0000
@@ -449,6 +449,19 @@ if_output(struct ifnet *ifp, struct mbuf
        int s, length, error = 0;
        unsigned short mflags;
 
+#ifdef DIAGNOSTIC
+       if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
+               printf("%s: trying to send packet on wrong domain. "
+                   "if %d vs. mbuf %d\n", ifp->if_xname, ifp->if_rdomain,
+                   rtable_l2(m->m_pkthdr.ph_rtableid));
+       }
+#endif
+
+#if NBRIDGE > 0
+       if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0)
+               return (bridge_output(ifp, m, NULL, NULL));
+#endif
+
        length = m->m_pkthdr.len;
        mflags = m->m_flags;
 
Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.244
diff -u -p -r1.244 if_bridge.c
--- net/if_bridge.c     16 Jun 2015 11:09:39 -0000      1.244
+++ net/if_bridge.c     17 Jun 2015 12:01:12 -0000
@@ -2635,10 +2635,12 @@ bridge_ifenqueue(struct bridge_softc *sc
 {
        int error, len;
 
+       /* Loop prevention. */
+       m->m_flags |= M_PROTO1;
+
 #if NGIF > 0
        /* Packet needs etherip encapsulation. */
        if (ifp->if_type == IFT_GIF) {
-               m->m_flags |= M_PROTO1;
 
                /* Count packets input into the gif from outside */
                ifp->if_ipackets++;
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.205
diff -u -p -r1.205 if_ethersubr.c
--- net/if_ethersubr.c  16 Jun 2015 11:09:39 -0000      1.205
+++ net/if_ethersubr.c  17 Jun 2015 12:01:12 -0000
@@ -181,15 +181,6 @@ ether_output(struct ifnet *ifp, struct m
        struct arpcom *ac = (struct arpcom *)ifp;
        int error = 0;
 
-#ifdef DIAGNOSTIC
-       if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
-               printf("%s: trying to send packet on wrong domain. "
-                   "if %d vs. mbuf %d, AF %d\n", ifp->if_xname,
-                   ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid),
-                   dst->sa_family);
-       }
-#endif
-
        esrc = ac->ac_enaddr;
 
        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
@@ -276,47 +267,6 @@ ether_output(struct ifnet *ifp, struct m
        eh->ether_type = etype;
        memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost));
        memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost));
-
-#if NBRIDGE > 0
-       /*
-        * Interfaces that are bridgeports need special handling for output.
-        */
-       if (ifp->if_bridgeport) {
-               struct m_tag *mtag;
-
-               /*
-                * Check if this packet has already been sent out through
-                * this bridgeport, in which case we simply send it out
-                * without further bridge processing.
-                */
-               for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
-                   mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
-#ifdef DEBUG
-                       /* Check that the information is there */
-                       if (mtag->m_tag_len != sizeof(caddr_t)) {
-                               error = EINVAL;
-                               goto bad;
-                       }
-#endif
-                       if (!memcmp(&ifp->if_bridgeport, mtag + 1,
-                           sizeof(caddr_t)))
-                               break;
-               }
-               if (mtag == NULL) {
-                       /* Attach a tag so we can detect loops */
-                       mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
-                           M_NOWAIT);
-                       if (mtag == NULL) {
-                               error = ENOBUFS;
-                               goto bad;
-                       }
-                       memcpy(mtag + 1, &ifp->if_bridgeport, sizeof(caddr_t));
-                       m_tag_prepend(m, mtag);
-                       error = bridge_output(ifp, m, NULL, NULL);
-                       return (error);
-               }
-       }
-#endif
 
        return (if_output(ifp, m));
 bad:
Index: sys/mbuf.h
===================================================================
RCS file: /cvs/src/sys/sys/mbuf.h,v
retrieving revision 1.192
diff -u -p -r1.192 mbuf.h
--- sys/mbuf.h  16 Jun 2015 11:09:40 -0000      1.192
+++ sys/mbuf.h  17 Jun 2015 12:01:12 -0000
@@ -454,7 +454,6 @@ struct m_tag *m_tag_next(struct mbuf *, 
 /* Packet tag types */
 #define PACKET_TAG_IPSEC_IN_DONE       0x0001  /* IPsec applied, in */
 #define PACKET_TAG_IPSEC_OUT_DONE      0x0002  /* IPsec applied, out */
-#define PACKET_TAG_BRIDGE              0x0020  /* Bridge processing done */
 #define PACKET_TAG_GIF                 0x0040  /* GIF processing done */
 #define PACKET_TAG_GRE                 0x0080  /* GRE processing done */
 #define PACKET_TAG_DLT                 0x0100 /* data link layer type */

Reply via email to