From 5806ca5a3e1cc51ce5d75b8c8850a092087a1d34 Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Wed, 18 Nov 2015 10:31:06 -0600 Subject: Importing pfSense patch bridge_lagg_altq.diff --- sys/net/if_bridge.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ sys/net/if_lagg.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 6e060f0..fdd43b1 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -243,6 +243,7 @@ static void bridge_ifdetach(void *arg __unused, struct ifnet *); 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 *); @@ -607,10 +608,13 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params) if_initname(ifp, bridge_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); + IFQ_SET_READY(&ifp->if_snd); /* * Generate an ethernet address with a locally administered address. @@ -2074,6 +2078,47 @@ bridge_qflush(struct ifnet *ifp __unused) } /* + * bridge_start: + * + * Start output on a bridge. + * + */ +static void +bridge_start(struct ifnet *ifp) +{ + struct bridge_softc *sc; + struct mbuf *m; + struct ether_header *eh; + struct ifnet *dst_if; + + 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); + + eh = mtod(m, struct ether_header *); + dst_if = NULL; + + BRIDGE_LOCK(sc); + if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { + dst_if = bridge_rtlookup(sc, eh->ether_dhost, 1); + } + + 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; +} + +/* * bridge_forward: * * The forwarding function of the bridge. diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 4d41e63..2348f1e 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -116,6 +116,7 @@ static int lagg_setflag(struct lagg_port *, int, int, int (*func)(struct ifnet *, int)); static int lagg_setflags(struct lagg_port *, int status); static int lagg_transmit(struct ifnet *, struct mbuf *); +static void lagg_start(struct ifnet *); static void lagg_qflush(struct ifnet *); static int lagg_media_change(struct ifnet *); static void lagg_media_status(struct ifnet *, struct ifmediareq *); @@ -353,11 +354,14 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params) if_initname(ifp, laggname, unit); ifp->if_softc = sc; ifp->if_transmit = lagg_transmit; + ifp->if_start = lagg_start; ifp->if_qflush = lagg_qflush; ifp->if_init = lagg_init; ifp->if_ioctl = lagg_ioctl; ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; ifp->if_capenable = ifp->if_capabilities = IFCAP_HWSTATS; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); /* * Attach as an ordinary ethernet device, children will be attached @@ -1345,6 +1349,40 @@ lagg_transmit(struct ifnet *ifp, struct mbuf *m) return (error); } +static void +lagg_start(struct ifnet *ifp) +{ + struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; + struct rm_priotracker tracker; + struct mbuf *m; + int error = 0, len; + + LAGG_RLOCK(sc, &tracker); + /* We need a Tx algorithm and at least one port */ + if (sc->sc_proto == LAGG_PROTO_NONE || sc->sc_count == 0) { + IF_DRAIN(&ifp->if_snd); + LAGG_RUNLOCK(sc, &tracker); + return; + } + + for (;; error = 0) { + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + + ETHER_BPF_MTAP(ifp, m); + + len = m->m_pkthdr.len; + error = (*sc->sc_start)(sc, m); + if (error == 0) { + counter_u64_add(sc->sc_opackets, 1); + counter_u64_add(sc->sc_obytes, len); + } else + ifp->if_oerrors++; + } + LAGG_RUNLOCK(sc, &tracker); +} + /* * The ifp->if_qflush entry point for lagg(4) is no-op. */ -- cgit v1.1