diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2014-08-31 06:46:21 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2014-08-31 06:46:21 +0000 |
commit | e6485f73de7d0375c1f64553de05adcae9da62b3 (patch) | |
tree | 14bbbb2fbcb15cc9c9d3468958b19e7041eb0d3c /sys/net/if.c | |
parent | 546451a2e557e382e7d1c277be2018cf2f1d471e (diff) | |
download | src-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.c | 84 |
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); } |