diff options
author | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:26 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:26 -0300 |
commit | fce52da9925f213a049387e0accff1daa3ed0b20 (patch) | |
tree | fd6cf4d16c0e329c62360e1f9d40e4932967442e | |
parent | e47eb2084d73bd81025b9eb23683a704ec9e16e1 (diff) | |
download | FreeBSD-src-fce52da9925f213a049387e0accff1daa3ed0b20.zip FreeBSD-src-fce52da9925f213a049387e0accff1daa3ed0b20.tar.gz |
Importing pfSense patch bridge_lagg_altq.diff
-rw-r--r-- | sys/net/if_bridge.c | 45 | ||||
-rw-r--r-- | sys/net/if_lagg.c | 38 |
2 files changed, 83 insertions, 0 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 25884a4..14d9967 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. @@ -2075,6 +2079,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 45d31a7..ce1365b 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 @@ -1354,6 +1358,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. */ |