aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2014-08-31 06:46:21 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2014-08-31 06:46:21 +0000
commite6485f73de7d0375c1f64553de05adcae9da62b3 (patch)
tree14bbbb2fbcb15cc9c9d3468958b19e7041eb0d3c /sys/net/if.c
parent546451a2e557e382e7d1c277be2018cf2f1d471e (diff)
downloadsrc-e6485f73de7d0375c1f64553de05adcae9da62b3.tar.gz
src-e6485f73de7d0375c1f64553de05adcae9da62b3.zip
o Remove struct if_data from struct ifnet. Now it is merely API structure
for route(4) socket and ifmib(4) sysctl. o Move fields from if_data to ifnet, but keep all statistic counters separate, since they should disappear later. o Provide function if_data_copy() to fill if_data, utilize it in routing socket and ifmib handler. o Provide overridable ifnet(9) method to fetch counters. If no provided, if_get_counters_compat() would be used, that returns old counters. Sponsored by: Netflix Sponsored by: Nginx, Inc.
Notes
Notes: svn path=/head/; revision=270870
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index eaa771966049..853f887e0c21 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -605,8 +605,7 @@ if_attach_internal(struct ifnet *ifp, int vmove)
if_addgroup(ifp, IFG_ALL);
getmicrotime(&ifp->if_lastchange);
- ifp->if_data.ifi_epoch = time_uptime;
- ifp->if_data.ifi_datalen = sizeof(struct if_data);
+ ifp->if_epoch = time_uptime;
KASSERT((ifp->if_transmit == NULL && ifp->if_qflush == NULL) ||
(ifp->if_transmit != NULL && ifp->if_qflush != NULL),
@@ -615,7 +614,10 @@ if_attach_internal(struct ifnet *ifp, int vmove)
ifp->if_transmit = if_transmit;
ifp->if_qflush = if_qflush;
}
-
+
+ if (ifp->if_get_counter == NULL)
+ ifp->if_get_counter = if_get_counter_compat;
+
if (!vmove) {
#ifdef MAC
mac_ifnet_create(ifp);
@@ -1384,6 +1386,77 @@ if_rtdel(struct radix_node *rn, void *arg)
}
/*
+ * Return counter values from old racy non-pcpu counters.
+ */
+uint64_t
+if_get_counter_compat(struct ifnet *ifp, ifnet_counter cnt)
+{
+
+ switch (cnt) {
+ case IFCOUNTER_IPACKETS:
+ return (ifp->if_ipackets);
+ case IFCOUNTER_IERRORS:
+ return (ifp->if_ierrors);
+ case IFCOUNTER_OPACKETS:
+ return (ifp->if_opackets);
+ case IFCOUNTER_OERRORS:
+ return (ifp->if_oerrors);
+ case IFCOUNTER_COLLISIONS:
+ return (ifp->if_collisions);
+ case IFCOUNTER_IBYTES:
+ return (ifp->if_ibytes);
+ case IFCOUNTER_OBYTES:
+ return (ifp->if_obytes);
+ case IFCOUNTER_IMCASTS:
+ return (ifp->if_imcasts);
+ case IFCOUNTER_OMCASTS:
+ return (ifp->if_omcasts);
+ case IFCOUNTER_IQDROPS:
+ return (ifp->if_iqdrops);
+ case IFCOUNTER_OQDROPS:
+ return (ifp->if_oqdrops);
+ case IFCOUNTER_NOPROTO:
+ return (ifp->if_noproto);
+ }
+ panic("%s: unknown counter %d", __func__, cnt);
+}
+
+/*
+ * Copy data from ifnet to userland API structure if_data.
+ */
+void
+if_data_copy(struct ifnet *ifp, struct if_data *ifd)
+{
+
+ ifd->ifi_type = ifp->if_type;
+ ifd->ifi_physical = 0;
+ ifd->ifi_addrlen = ifp->if_addrlen;
+ ifd->ifi_hdrlen = ifp->if_hdrlen;
+ ifd->ifi_link_state = ifp->if_link_state;
+ ifd->ifi_vhid = 0;
+ ifd->ifi_datalen = sizeof(struct if_data);
+ ifd->ifi_mtu = ifp->if_mtu;
+ ifd->ifi_metric = ifp->if_metric;
+ ifd->ifi_baudrate = ifp->if_baudrate;
+ ifd->ifi_hwassist = ifp->if_hwassist;
+ ifd->ifi_epoch = ifp->if_epoch;
+ ifd->ifi_lastchange = ifp->if_lastchange;
+
+ ifd->ifi_ipackets = ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS);
+ ifd->ifi_ierrors = ifp->if_get_counter(ifp, IFCOUNTER_IERRORS);
+ ifd->ifi_opackets = ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS);
+ ifd->ifi_oerrors = ifp->if_get_counter(ifp, IFCOUNTER_OERRORS);
+ ifd->ifi_collisions = ifp->if_get_counter(ifp, IFCOUNTER_COLLISIONS);
+ ifd->ifi_ibytes = ifp->if_get_counter(ifp, IFCOUNTER_IBYTES);
+ ifd->ifi_obytes = ifp->if_get_counter(ifp, IFCOUNTER_OBYTES);
+ ifd->ifi_imcasts = ifp->if_get_counter(ifp, IFCOUNTER_IMCASTS);
+ ifd->ifi_omcasts = ifp->if_get_counter(ifp, IFCOUNTER_OMCASTS);
+ ifd->ifi_iqdrops = ifp->if_get_counter(ifp, IFCOUNTER_IQDROPS);
+ ifd->ifi_oqdrops = ifp->if_get_counter(ifp, IFCOUNTER_OQDROPS);
+ ifd->ifi_noproto = ifp->if_get_counter(ifp, IFCOUNTER_NOPROTO);
+}
+
+/*
* Wrapper functions for struct ifnet address list locking macros. These are
* used by kernel modules to avoid encoding programming interface or binary
* interface assumptions that may be violated when kernel-internal locking
@@ -2167,7 +2240,8 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
break;
case SIOCGIFPHYS:
- ifr->ifr_phys = ifp->if_physical;
+ /* XXXGL: did this ever worked? */
+ ifr->ifr_phys = 0;
break;
case SIOCGIFDESCR:
@@ -3915,7 +3989,7 @@ if_sendq_prepend(if_t ifp, struct mbuf *m)
int
if_setifheaderlen(if_t ifp, int len)
{
- ((struct ifnet *)ifp)->if_data.ifi_hdrlen = len;
+ ((struct ifnet *)ifp)->if_hdrlen = len;
return (0);
}