summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2014-03-13 03:42:24 +0000
committerglebius <glebius@FreeBSD.org>2014-03-13 03:42:24 +0000
commitb38edcd355dfe9c2ac4080b8837687b0dba7dd41 (patch)
tree23c54b335bf31cd906e8cf3bad37e838d9a80c2d /sys/net/rtsock.c
parent2720ac2544ae02bf5f480a96cc1f9ba096803879 (diff)
downloadFreeBSD-src-b38edcd355dfe9c2ac4080b8837687b0dba7dd41.zip
FreeBSD-src-b38edcd355dfe9c2ac4080b8837687b0dba7dd41.tar.gz
Since 32-bit if_baudrate isn't enough to describe a baud rate of a 10 Gbit
interface, in the r241616 a crutch was provided. It didn't work well, and finally we decided that it is time to break ABI and simply make if_baudrate a 64-bit value. Meanwhile, the entire struct if_data was reviewed. o Remove the if_baudrate_pf crutch. o Make all fields of struct if_data fixed machine independent size. The notion of data (packet counters, etc) are by no means MD. And it is a bug that on amd64 we've got a 64-bit counters, while on i386 32-bit, which at modern speeds overflow within a second. This also removes quite a lot of COMPAT_FREEBSD32 code. o Give 16 bit for the ifi_datalen field. This field was provided to make future changes to if_data less ABI breaking. Unfortunately the 8 bit size of it had effectively limited sizeof if_data to 256 bytes. o Give 32 bits to ifi_mtu and ifi_metric. o Give 64 bits to the rest of fields, since they are counters. __FreeBSD_version bumped. Discussed with: emax Sponsored by: Netflix Sponsored by: Nginx, Inc.
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c193
1 files changed, 58 insertions, 135 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 691eb62..4cb9b07 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -73,34 +73,6 @@
#include <sys/mount.h>
#include <compat/freebsd32/freebsd32.h>
-struct if_data32 {
- uint8_t ifi_type;
- uint8_t ifi_physical;
- uint8_t ifi_addrlen;
- uint8_t ifi_hdrlen;
- uint8_t ifi_link_state;
- uint8_t ifi_vhid;
- uint8_t ifi_baudrate_pf;
- uint8_t ifi_datalen;
- uint32_t ifi_mtu;
- uint32_t ifi_metric;
- uint32_t ifi_baudrate;
- uint32_t ifi_ipackets;
- uint32_t ifi_ierrors;
- uint32_t ifi_opackets;
- uint32_t ifi_oerrors;
- uint32_t ifi_collisions;
- uint32_t ifi_ibytes;
- uint32_t ifi_obytes;
- uint32_t ifi_imcasts;
- uint32_t ifi_omcasts;
- uint32_t ifi_iqdrops;
- uint32_t ifi_noproto;
- uint32_t ifi_hwassist;
- int32_t ifi_epoch;
- struct timeval32 ifi_lastchange;
-};
-
struct if_msghdr32 {
uint16_t ifm_msglen;
uint8_t ifm_version;
@@ -108,7 +80,7 @@ struct if_msghdr32 {
int32_t ifm_addrs;
int32_t ifm_flags;
uint16_t ifm_index;
- struct if_data32 ifm_data;
+ struct if_data ifm_data;
};
struct if_msghdrl32 {
@@ -121,7 +93,7 @@ struct if_msghdrl32 {
uint16_t _ifm_spare1;
uint16_t ifm_len;
uint16_t ifm_data_off;
- struct if_data32 ifm_data;
+ struct if_data ifm_data;
};
struct ifa_msghdrl32 {
@@ -135,7 +107,7 @@ struct ifa_msghdrl32 {
uint16_t ifam_len;
uint16_t ifam_data_off;
int32_t ifam_metric;
- struct if_data32 ifam_data;
+ struct if_data ifam_data;
};
#endif /* COMPAT_FREEBSD32 */
@@ -1598,79 +1570,44 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
return (error);
}
-#ifdef COMPAT_FREEBSD32
-static void
-copy_ifdata32(struct if_data *src, struct if_data32 *dst)
-{
-
- bzero(dst, sizeof(*dst));
- CP(*src, *dst, ifi_type);
- CP(*src, *dst, ifi_physical);
- CP(*src, *dst, ifi_addrlen);
- CP(*src, *dst, ifi_hdrlen);
- CP(*src, *dst, ifi_link_state);
- CP(*src, *dst, ifi_vhid);
- CP(*src, *dst, ifi_baudrate_pf);
- dst->ifi_datalen = sizeof(struct if_data32);
- CP(*src, *dst, ifi_mtu);
- CP(*src, *dst, ifi_metric);
- CP(*src, *dst, ifi_baudrate);
- CP(*src, *dst, ifi_ipackets);
- CP(*src, *dst, ifi_ierrors);
- CP(*src, *dst, ifi_opackets);
- CP(*src, *dst, ifi_oerrors);
- CP(*src, *dst, ifi_collisions);
- CP(*src, *dst, ifi_ibytes);
- CP(*src, *dst, ifi_obytes);
- CP(*src, *dst, ifi_imcasts);
- CP(*src, *dst, ifi_omcasts);
- CP(*src, *dst, ifi_iqdrops);
- CP(*src, *dst, ifi_noproto);
- CP(*src, *dst, ifi_hwassist);
- CP(*src, *dst, ifi_epoch);
- TV_CP(*src, *dst, ifi_lastchange);
-}
-#endif
-
static int
sysctl_iflist_ifml(struct ifnet *ifp, struct rt_addrinfo *info,
struct walkarg *w, int len)
{
struct if_msghdrl *ifm;
+ struct if_data *ifd;
+
+ ifm = (struct if_msghdrl *)w->w_tmem;
#ifdef COMPAT_FREEBSD32
if (w->w_req->flags & SCTL_MASK32) {
struct if_msghdrl32 *ifm32;
- ifm32 = (struct if_msghdrl32 *)w->w_tmem;
+ ifm32 = (struct if_msghdrl32 *)ifm;
ifm32->ifm_addrs = info->rti_addrs;
ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
ifm32->ifm_index = ifp->if_index;
ifm32->_ifm_spare1 = 0;
ifm32->ifm_len = sizeof(*ifm32);
ifm32->ifm_data_off = offsetof(struct if_msghdrl32, ifm_data);
-
- copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
- /* Fixup if_data carp(4) vhid. */
- if (carp_get_vhid_p != NULL)
- ifm32->ifm_data.ifi_vhid =
- (*carp_get_vhid_p)(ifp->if_addr);
-
- return (SYSCTL_OUT(w->w_req, (caddr_t)ifm32, len));
- }
+ ifd = &ifm32->ifm_data;
+ } else
#endif
- ifm = (struct if_msghdrl *)w->w_tmem;
- ifm->ifm_addrs = info->rti_addrs;
- ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
- ifm->ifm_index = ifp->if_index;
- ifm->_ifm_spare1 = 0;
- ifm->ifm_len = sizeof(*ifm);
- ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
+ {
+ ifm->ifm_addrs = info->rti_addrs;
+ ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
+ ifm->ifm_index = ifp->if_index;
+ ifm->_ifm_spare1 = 0;
+ ifm->ifm_len = sizeof(*ifm);
+ ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
+ ifd = &ifm->ifm_data;
+ }
+
+ *ifd = ifp->if_data;
- ifm->ifm_data = ifp->if_data;
/* Fixup if_data carp(4) vhid. */
if (carp_get_vhid_p != NULL)
- ifm->ifm_data.ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
+ ifd->ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
}
@@ -1680,34 +1617,32 @@ sysctl_iflist_ifm(struct ifnet *ifp, struct rt_addrinfo *info,
struct walkarg *w, int len)
{
struct if_msghdr *ifm;
+ struct if_data *ifd;
+
+ ifm = (struct if_msghdr *)w->w_tmem;
#ifdef COMPAT_FREEBSD32
if (w->w_req->flags & SCTL_MASK32) {
struct if_msghdr32 *ifm32;
- ifm32 = (struct if_msghdr32 *)w->w_tmem;
+ ifm32 = (struct if_msghdr32 *)ifm;
ifm32->ifm_addrs = info->rti_addrs;
ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
ifm32->ifm_index = ifp->if_index;
-
- copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
- /* Fixup if_data carp(4) vhid. */
- if (carp_get_vhid_p != NULL)
- ifm32->ifm_data.ifi_vhid =
- (*carp_get_vhid_p)(ifp->if_addr);
-
- return (SYSCTL_OUT(w->w_req, (caddr_t)ifm32, len));
- }
+ ifd = &ifm32->ifm_data;
+ } else
#endif
- ifm = (struct if_msghdr *)w->w_tmem;
- ifm->ifm_addrs = info->rti_addrs;
- ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
- ifm->ifm_index = ifp->if_index;
+ {
+ ifm->ifm_addrs = info->rti_addrs;
+ ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
+ ifm->ifm_index = ifp->if_index;
+ ifd = &ifm->ifm_data;
+ }
- ifm->ifm_data = ifp->if_data;
+ *ifd = ifp->if_data;
/* Fixup if_data carp(4) vhid. */
if (carp_get_vhid_p != NULL)
- ifm->ifm_data.ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
+ ifd->ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
}
@@ -1717,12 +1652,15 @@ sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info,
struct walkarg *w, int len)
{
struct ifa_msghdrl *ifam;
+ struct if_data *ifd;
+
+ ifam = (struct ifa_msghdrl *)w->w_tmem;
#ifdef COMPAT_FREEBSD32
if (w->w_req->flags & SCTL_MASK32) {
struct ifa_msghdrl32 *ifam32;
- ifam32 = (struct ifa_msghdrl32 *)w->w_tmem;
+ ifam32 = (struct ifa_msghdrl32 *)ifam;
ifam32->ifam_addrs = info->rti_addrs;
ifam32->ifam_flags = ifa->ifa_flags;
ifam32->ifam_index = ifa->ifa_ifp->if_index;
@@ -1731,45 +1669,30 @@ sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info,
ifam32->ifam_data_off =
offsetof(struct ifa_msghdrl32, ifam_data);
ifam32->ifam_metric = ifa->ifa_metric;
-
- 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);
-
- return (SYSCTL_OUT(w->w_req, (caddr_t)ifam32, len));
- }
+ ifd = &ifam32->ifam_data;
+ } else
#endif
+ {
+ ifam->ifam_addrs = info->rti_addrs;
+ ifam->ifam_flags = ifa->ifa_flags;
+ ifam->ifam_index = ifa->ifa_ifp->if_index;
+ ifam->_ifam_spare1 = 0;
+ ifam->ifam_len = sizeof(*ifam);
+ ifam->ifam_data_off = offsetof(struct ifa_msghdrl, ifam_data);
+ ifam->ifam_metric = ifa->ifa_metric;
+ ifd = &ifam->ifam_data;
+ }
- ifam = (struct ifa_msghdrl *)w->w_tmem;
- ifam->ifam_addrs = info->rti_addrs;
- ifam->ifam_flags = ifa->ifa_flags;
- ifam->ifam_index = ifa->ifa_ifp->if_index;
- ifam->_ifam_spare1 = 0;
- ifam->ifam_len = sizeof(*ifam);
- ifam->ifam_data_off = offsetof(struct ifa_msghdrl, ifam_data);
- ifam->ifam_metric = ifa->ifa_metric;
-
- 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);
+ bzero(ifd, sizeof(*ifd));
+ ifd->ifi_datalen = sizeof(struct if_data);
+ ifd->ifi_ipackets = counter_u64_fetch(ifa->ifa_ipackets);
+ ifd->ifi_opackets = counter_u64_fetch(ifa->ifa_opackets);
+ ifd->ifi_ibytes = counter_u64_fetch(ifa->ifa_ibytes);
+ ifd->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);
+ ifd->ifi_vhid = (*carp_get_vhid_p)(ifa);
return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
}
OpenPOWER on IntegriCloud