Date: Thu, 30 Aug 2012 17:10:57 +0400 From: Gleb Smirnoff <glebius@FreeBSD.org> To: net@FreeBSD.org Subject: [CFT] if_transmit method for if_bridge(4) Message-ID: <20120830131057.GE90597@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
--9amGYk9869ThD9tj Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Hi, I have a patch laying around, that makes if_bridge(4) utilize if_transmit method. That should improvide performance. I'd appreciate if someone who actually do use if_bridge(4) tests this patch. -- Totus tuus, Glebius. --9amGYk9869ThD9tj Content-Type: text/x-diff; charset=koi8-r Content-Disposition: attachment; filename="if_bridge_transmit.diff" Index: if_bridge.c =================================================================== --- if_bridge.c (revision 239904) +++ if_bridge.c (working copy) @@ -245,11 +245,12 @@ 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 @@ 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 @@ * 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 @@ if (mflags & M_MCAST) sc->sc_ifp->if_omcasts++; } + + return (err); } /* @@ -1981,44 +1982,43 @@ } /* - * 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) +{ } /* --9amGYk9869ThD9tj--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120830131057.GE90597>