summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2013-10-15 11:37:57 +0000
committerglebius <glebius@FreeBSD.org>2013-10-15 11:37:57 +0000
commit790225cfbce40af294b0962bcba0febee9125487 (patch)
treec8e33cc195b6a05b074a56d713bbf025af1bbdc4 /sys/net/rtsock.c
parentbc71d67cbbd8f45860c1763eb82f7de40d07538c (diff)
downloadFreeBSD-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.c20
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);
OpenPOWER on IntegriCloud