Author: glebius
Date: Mon Sep  3 10:08:20 2012
New Revision: 240071
URL: http://svn.freebsd.org/changeset/base/240071

Log:
  Change bridge(4) to use if_transmit for forwarding packets to underlying
  interfaces instead of queueing.
  
  Tested by:    ray

Modified:
  head/sys/net/if_bridge.c

Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c    Mon Sep  3 09:46:46 2012        (r240070)
+++ head/sys/net/if_bridge.c    Mon Sep  3 10:08:20 2012        (r240071)
@@ -245,11 +245,12 @@ static void       bridge_ifdetach(void *arg __
 static void    bridge_init(void *);
 static void    bridge_dummynet(struct mbuf *, struct ifnet *);
 static void    bridge_stop(struct ifnet *, int);
-static void    bridge_start(struct ifnet *);
+static int     bridge_transmit(struct ifnet *, struct mbuf *);
+static void    bridge_qflush(struct ifnet *);
 static struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
 static int     bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
                    struct rtentry *);
-static void    bridge_enqueue(struct bridge_softc *, struct ifnet *,
+static int     bridge_enqueue(struct bridge_softc *, struct ifnet *,
                    struct mbuf *);
 static void    bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp, int);
 
@@ -600,12 +601,10 @@ bridge_clone_create(struct if_clone *ifc
        if_initname(ifp, ifc->ifc_name, unit);
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = bridge_ioctl;
-       ifp->if_start = bridge_start;
+       ifp->if_transmit = bridge_transmit;
+       ifp->if_qflush = bridge_qflush;
        ifp->if_init = bridge_init;
        ifp->if_type = IFT_BRIDGE;
-       IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
-       ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
-       IFQ_SET_READY(&ifp->if_snd);
 
        /*
         * Generate an ethernet address with a locally administered address.
@@ -1780,7 +1779,7 @@ bridge_stop(struct ifnet *ifp, int disab
  *     Enqueue a packet on a bridge member interface.
  *
  */
-static void
+static int
 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
 {
        int len, err = 0;
@@ -1823,6 +1822,8 @@ bridge_enqueue(struct bridge_softc *sc, 
                if (mflags & M_MCAST)
                        sc->sc_ifp->if_omcasts++;
        }
+
+       return (err);
 }
 
 /*
@@ -1981,44 +1982,43 @@ sendunicast:
 }
 
 /*
- * bridge_start:
+ * bridge_transmit:
  *
- *     Start output on a bridge.
+ *     Do output on a bridge.
  *
  */
-static void
-bridge_start(struct ifnet *ifp)
+static int
+bridge_transmit(struct ifnet *ifp, struct mbuf *m)
 {
        struct bridge_softc *sc;
-       struct mbuf *m;
-       struct ether_header *eh;
-       struct ifnet *dst_if;
+       int error = 0;
 
        sc = ifp->if_softc;
 
-       ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-       for (;;) {
-               IFQ_DEQUEUE(&ifp->if_snd, m);
-               if (m == 0)
-                       break;
-               ETHER_BPF_MTAP(ifp, m);
+       ETHER_BPF_MTAP(ifp, m);
+
+
+       BRIDGE_LOCK(sc);
+       if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
+               struct ether_header *eh;
+               struct ifnet *dst_if;
 
                eh = mtod(m, struct ether_header *);
-               dst_if = NULL;
+               dst_if = bridge_rtlookup(sc, eh->ether_dhost, 1);
+               BRIDGE_UNLOCK(sc);
+               error = bridge_enqueue(sc, dst_if, m);
+       } else
+               bridge_broadcast(sc, ifp, m, 0);
 
-               BRIDGE_LOCK(sc);
-               if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
-                       dst_if = bridge_rtlookup(sc, eh->ether_dhost, 1);
-               }
+       return (error);
+}
 
-               if (dst_if == NULL)
-                       bridge_broadcast(sc, ifp, m, 0);
-               else {
-                       BRIDGE_UNLOCK(sc);
-                       bridge_enqueue(sc, dst_if, m);
-               }
-       }
-       ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+/*
+ * The ifp->if_qflush entry point for if_bridge(4) is no-op.
+ */
+static void
+bridge_qflush(struct ifnet *ifp __unused)
+{
 }
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to