Date: Mon, 3 Sep 2012 10:08:20 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r240071 - head/sys/net Message-ID: <201209031008.q83A8KYn063383@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) +{ } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209031008.q83A8KYn063383>