From owner-svn-src-all@FreeBSD.ORG Mon Sep 3 10:08:21 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 13F741065673; Mon, 3 Sep 2012 10:08:21 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id F314B8FC0A; Mon, 3 Sep 2012 10:08:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q83A8KV2063385; Mon, 3 Sep 2012 10:08:20 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q83A8KYn063383; Mon, 3 Sep 2012 10:08:20 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201209031008.q83A8KYn063383@svn.freebsd.org> From: Gleb Smirnoff Date: Mon, 3 Sep 2012 10:08:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240071 - head/sys/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Sep 2012 10:08:21 -0000 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) +{ } /*