diff options
author | glebius <glebius@FreeBSD.org> | 2013-10-15 11:37:57 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-10-15 11:37:57 +0000 |
commit | 790225cfbce40af294b0962bcba0febee9125487 (patch) | |
tree | c8e33cc195b6a05b074a56d713bbf025af1bbdc4 /sys/net/rtsock.c | |
parent | bc71d67cbbd8f45860c1763eb82f7de40d07538c (diff) | |
download | FreeBSD-src-790225cfbce40af294b0962bcba0febee9125487.zip FreeBSD-src-790225cfbce40af294b0962bcba0febee9125487.tar.gz |
- Utilize counter(9) to accumulate statistics on interface addresses. Add
four counters to struct ifaddr. This kills '+=' on a variables shared
between processors for every packet.
- Nuke struct if_data from struct ifaddr.
- In ip_input() do not put a reference on ifaddr, instead update statistics
right now in place and do IN_IFADDR_RUNLOCK(). These removes atomic(9)
for every packet. [1]
- To properly support NET_RT_IFLISTL sysctl used by getifaddrs(3), in
rtsock.c fill if_data fields using counter_u64_fetch().
- Accidentially fix bug in COMPAT_32 version of NET_RT_IFLISTL, which
took if_data not from the ifaddr, but from ifaddr's ifnet. [2]
Submitted by: melifaro [1], pluknet[2]
Sponsored by: Netflix
Sponsored by: Nginx, Inc.
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r-- | sys/net/rtsock.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 0b5d1c5..e92eb89 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1751,7 +1751,17 @@ sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info, offsetof(struct ifa_msghdrl32, ifam_data); ifam32->ifam_metric = ifa->ifa_metric; - copy_ifdata32(&ifa->ifa_ifp->if_data, &ifam32->ifam_data); + bzero(&ifam32->ifam_data, sizeof(ifam32->ifam_data)); + ifam32->ifam_data.ifi_datalen = sizeof(struct if_data32); + ifam32->ifam_data.ifi_ipackets = + counter_u64_fetch(ifa->ifa_ipackets); + ifam32->ifam_data.ifi_opackets = + counter_u64_fetch(ifa->ifa_opackets); + ifam32->ifam_data.ifi_ibytes = + counter_u64_fetch(ifa->ifa_ibytes); + ifam32->ifam_data.ifi_obytes = + counter_u64_fetch(ifa->ifa_obytes); + /* Fixup if_data carp(4) vhid. */ if (carp_get_vhid_p != NULL) ifam32->ifam_data.ifi_vhid = (*carp_get_vhid_p)(ifa); @@ -1769,7 +1779,13 @@ sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info, ifam->ifam_data_off = offsetof(struct ifa_msghdrl, ifam_data); ifam->ifam_metric = ifa->ifa_metric; - ifam->ifam_data = ifa->if_data; + bzero(&ifam->ifam_data, sizeof(ifam->ifam_data)); + ifam->ifam_data.ifi_datalen = sizeof(struct if_data); + ifam->ifam_data.ifi_ipackets = counter_u64_fetch(ifa->ifa_ipackets); + ifam->ifam_data.ifi_opackets = counter_u64_fetch(ifa->ifa_opackets); + ifam->ifam_data.ifi_ibytes = counter_u64_fetch(ifa->ifa_ibytes); + ifam->ifam_data.ifi_obytes = counter_u64_fetch(ifa->ifa_obytes); + /* Fixup if_data carp(4) vhid. */ if (carp_get_vhid_p != NULL) ifam->ifam_data.ifi_vhid = (*carp_get_vhid_p)(ifa); |