Index: if_lagg.c =================================================================== --- if_lagg.c (revision 249398) +++ if_lagg.c (working copy) @@ -153,6 +153,8 @@ static struct mbuf *lagg_lacp_input(struct lagg_so struct mbuf *); static void lagg_lacp_lladdr(struct lagg_softc *); +static void lagg_callout(void *); + /* lagg protocol table */ static const struct { int ti_proto; @@ -278,6 +280,11 @@ lagg_clone_create(struct if_clone *ifc, int unit, return (ENOSPC); } + sc->sc_ipackets = counter_u64_alloc(M_WAITOK); + sc->sc_opackets = counter_u64_alloc(M_WAITOK); + sc->sc_ibytes = counter_u64_alloc(M_WAITOK); + sc->sc_obytes = counter_u64_alloc(M_WAITOK); + sysctl_ctx_init(&sc->ctx); snprintf(num, sizeof(num), "%u", unit); sc->use_flowid = def_use_flowid; @@ -307,6 +314,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, LAGG_LOCK_INIT(sc); SLIST_INIT(&sc->sc_ports); TASK_INIT(&sc->sc_lladdr_task, 0, lagg_port_setlladdr, sc); + callout_init_rw(&sc->sc_callout, &sc->sc_mtx, CALLOUT_SHAREDLOCK); /* Initialise pseudo media types */ ifmedia_init(&sc->sc_media, 0, lagg_media_change, @@ -338,6 +346,8 @@ lagg_clone_create(struct if_clone *ifc, int unit, SLIST_INSERT_HEAD(&lagg_list, sc, sc_entries); mtx_unlock(&lagg_list_mtx); + callout_reset(&sc->sc_callout, hz, lagg_callout, sc); + return (0); } @@ -369,6 +379,12 @@ lagg_clone_destroy(struct ifnet *ifp) ether_ifdetach(ifp); if_free(ifp); + callout_drain(&sc->sc_callout); + counter_u64_free(sc->sc_ipackets); + counter_u64_free(sc->sc_opackets); + counter_u64_free(sc->sc_ibytes); + counter_u64_free(sc->sc_obytes); + mtx_lock(&lagg_list_mtx); SLIST_REMOVE(&lagg_list, sc, lagg_softc, sc_entries); mtx_unlock(&lagg_list_mtx); @@ -1243,9 +1259,9 @@ lagg_transmit(struct ifnet *ifp, struct mbuf *m) LAGG_RUNLOCK(sc); if (error == 0) { - ifp->if_opackets++; + counter_u64_add(sc->sc_opackets, 1); + counter_u64_add(sc->sc_obytes, len); ifp->if_omcasts += mcast; - ifp->if_obytes += len; } else ifp->if_oerrors++; @@ -1281,8 +1297,8 @@ lagg_input(struct ifnet *ifp, struct mbuf *m) m = (*sc->sc_input)(sc, lp, m); if (m != NULL) { - scifp->if_ipackets++; - scifp->if_ibytes += m->m_pkthdr.len; + counter_u64_add(sc->sc_ipackets, 1); + counter_u64_add(sc->sc_ibytes, m->m_pkthdr.len); if (scifp->if_flags & IFF_MONITOR) { m_freem(m); @@ -1892,3 +1908,17 @@ lagg_lacp_input(struct lagg_softc *sc, struct lagg m->m_pkthdr.rcvif = ifp; return (m); } + +static void +lagg_callout(void *arg) +{ + struct lagg_softc *sc = (struct lagg_softc *)arg; + struct ifnet *ifp = sc->sc_ifp; + + ifp->if_ipackets = counter_u64_fetch(sc->sc_ipackets); + ifp->if_opackets = counter_u64_fetch(sc->sc_opackets); + ifp->if_ibytes = counter_u64_fetch(sc->sc_ibytes); + ifp->if_obytes = counter_u64_fetch(sc->sc_obytes); + + callout_reset(&sc->sc_callout, hz, lagg_callout, sc); +} Index: if_lagg.h =================================================================== --- if_lagg.h (revision 249398) +++ if_lagg.h (working copy) @@ -21,8 +21,6 @@ #ifndef _NET_LAGG_H #define _NET_LAGG_H -#include - /* * Global definitions */ @@ -137,6 +135,9 @@ struct lagg_reqflags { #define SIOCSLAGGHASH _IOW('i', 146, struct lagg_reqflags) #ifdef _KERNEL + +#include + /* * Internal kernel part */ @@ -195,6 +196,11 @@ struct lagg_softc { uint32_t sc_seq; /* sequence counter */ uint32_t sc_flags; + counter_u64_t sc_ipackets; + counter_u64_t sc_opackets; + counter_u64_t sc_ibytes; + counter_u64_t sc_obytes; + SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */ SLIST_ENTRY(lagg_softc) sc_entries; @@ -217,6 +223,7 @@ struct lagg_softc { void (*sc_portreq)(struct lagg_port *, caddr_t); eventhandler_tag vlan_attach; eventhandler_tag vlan_detach; + struct callout sc_callout; struct sysctl_ctx_list ctx; /* sysctl variables */ int use_flowid; /* use M_FLOWID */ };