Index: if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.475 diff -u -p -r1.475 if.c --- if.c 22 Jan 2017 10:17:39 -0000 1.475 +++ if.c 23 Jan 2017 00:32:53 -0000 @@ -583,8 +583,7 @@ if_start_locked(struct ifnet *ifp) int if_enqueue(struct ifnet *ifp, struct mbuf *m) { - int length, error = 0; - unsigned short mflags; + int error = 0; #if NBRIDGE > 0 if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0) { @@ -595,9 +594,6 @@ if_enqueue(struct ifnet *ifp, struct mbu } #endif - length = m->m_pkthdr.len; - mflags = m->m_flags; - #if NPF > 0 pf_pkt_unlink_state_key(m); #endif /* NPF > 0 */ @@ -610,11 +606,6 @@ if_enqueue(struct ifnet *ifp, struct mbu if (error) return (error); - ifp->if_opackets++; - ifp->if_obytes += length; - if (mflags & M_MCAST) - ifp->if_omcasts++; - if_start(ifp); return (0); @@ -1799,10 +1790,12 @@ ifioctl(struct socket *so, u_long cmd, c ifr->ifr_hardmtu = ifp->if_hardmtu; break; - case SIOCGIFDATA: - error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data, - sizeof(ifp->if_data)); + case SIOCGIFDATA: { + struct if_data ifdata; + if_data(ifp, &ifdata); + error = copyout(&ifdata, &ifr->ifr_data, sizeof(ifdata)); break; + } case SIOCSIFFLAGS: if ((error = suser(p, 0)) != 0) @@ -2167,6 +2160,33 @@ ifconf(u_long cmd, caddr_t data) } ifc->ifc_len -= space; return (error); +} + +void +if_data(struct ifnet *ifp, struct if_data *data) +{ + struct ifqueue *ifq; + uint64_t opackets = 0; + uint64_t obytes = 0; + uint64_t omcasts = 0; + uint64_t oqdrops = 0; + + ifq = &ifp->if_snd; + + mtx_enter(&ifq->ifq_mtx); + opackets += ifq->ifq_packets; + obytes += ifq->ifq_bytes; + oqdrops += ifq->ifq_qdrops; + omcasts += ifq->ifq_mcasts; + /* ifq->ifq_errors */ + mtx_leave(&ifq->ifq_mtx); + + *data = ifp->if_data; + data->ifi_opackets += opackets; + data->ifi_obytes += obytes; + data->ifi_oqdrops += oqdrops; + data->ifi_omcasts += omcasts; + /* ifp->if_data.ifi_oerrors */ } /* Index: if.h =================================================================== RCS file: /cvs/src/sys/net/if.h,v retrieving revision 1.181 diff -u -p -r1.181 if.h --- if.h 12 Dec 2016 09:51:30 -0000 1.181 +++ if.h 23 Jan 2017 00:32:53 -0000 @@ -469,6 +469,7 @@ void if_downall(void); void if_link_state_change(struct ifnet *); void if_up(struct ifnet *); int ifconf(u_long, caddr_t); +void if_data(struct ifnet *, struct if_data *); void ifinit(void); int ifioctl(struct socket *, u_long, caddr_t, struct proc *); int ifpromisc(struct ifnet *, int); Index: rtsock.c =================================================================== RCS file: /cvs/src/sys/net/rtsock.c,v retrieving revision 1.216 diff -u -p -r1.216 rtsock.c --- rtsock.c 22 Jan 2017 04:31:02 -0000 1.216 +++ rtsock.c 23 Jan 2017 00:32:53 -0000 @@ -1268,7 +1268,7 @@ rt_ifmsg(struct ifnet *ifp) ifm->ifm_tableid = ifp->if_rdomain; ifm->ifm_flags = ifp->if_flags; ifm->ifm_xflags = ifp->if_xflags; - ifm->ifm_data = ifp->if_data; + if_data(ifp, &ifm->ifm_data); ifm->ifm_addrs = 0; route_input(m, AF_UNSPEC); } @@ -1473,7 +1473,7 @@ sysctl_iflist(int af, struct walkarg *w) ifm->ifm_index = ifp->if_index; ifm->ifm_tableid = ifp->if_rdomain; ifm->ifm_flags = ifp->if_flags; - ifm->ifm_data = ifp->if_data; + if_data(ifp, &ifm->ifm_data); ifm->ifm_addrs = info.rti_addrs; error = copyout(ifm, w->w_where, len); if (error)