diff options
author | Jarod Wilson <jarod@redhat.com> | 2016-02-01 18:51:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-02-06 02:59:50 -0500 |
commit | 9256645af09807bc52fa8b2e66ecd28ab25318c4 (patch) | |
tree | 8b677e50b06f7f5261681967b51db738cb57438e /net/core/dev.c | |
parent | 817298102b0bc936b08dfcc5fbcc2213157050f2 (diff) |
net/core: relax BUILD_BUG_ON in netdev_stats_to_stats64
The netdev_stats_to_stats64 function copies the deprecated
net_device_stats format stats into rtnl_link_stats64 for legacy support
purposes, but with the BUILD_BUG_ON as it was, it wasn't possible to
extend rtnl_link_stats64 without also extending net_device_stats. Relax
the BUILD_BUG_ON to only require that rtnl_link_stats64 is larger, and
zero out all the stat counters that aren't present in net_device_stats.
CC: Eric Dumazet <edumazet@google.com>
CC: netdev@vger.kernel.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 8cba3d852f25..65863e512227 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -7253,24 +7253,31 @@ void netdev_run_todo(void) | |||
7253 | } | 7253 | } |
7254 | } | 7254 | } |
7255 | 7255 | ||
7256 | /* Convert net_device_stats to rtnl_link_stats64. They have the same | 7256 | /* Convert net_device_stats to rtnl_link_stats64. rtnl_link_stats64 has |
7257 | * fields in the same order, with only the type differing. | 7257 | * all the same fields in the same order as net_device_stats, with only |
7258 | * the type differing, but rtnl_link_stats64 may have additional fields | ||
7259 | * at the end for newer counters. | ||
7258 | */ | 7260 | */ |
7259 | void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, | 7261 | void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, |
7260 | const struct net_device_stats *netdev_stats) | 7262 | const struct net_device_stats *netdev_stats) |
7261 | { | 7263 | { |
7262 | #if BITS_PER_LONG == 64 | 7264 | #if BITS_PER_LONG == 64 |
7263 | BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats)); | 7265 | BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats)); |
7264 | memcpy(stats64, netdev_stats, sizeof(*stats64)); | 7266 | memcpy(stats64, netdev_stats, sizeof(*stats64)); |
7267 | /* zero out counters that only exist in rtnl_link_stats64 */ | ||
7268 | memset((char *)stats64 + sizeof(*netdev_stats), 0, | ||
7269 | sizeof(*stats64) - sizeof(*netdev_stats)); | ||
7265 | #else | 7270 | #else |
7266 | size_t i, n = sizeof(*stats64) / sizeof(u64); | 7271 | size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long); |
7267 | const unsigned long *src = (const unsigned long *)netdev_stats; | 7272 | const unsigned long *src = (const unsigned long *)netdev_stats; |
7268 | u64 *dst = (u64 *)stats64; | 7273 | u64 *dst = (u64 *)stats64; |
7269 | 7274 | ||
7270 | BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) != | 7275 | BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64)); |
7271 | sizeof(*stats64) / sizeof(u64)); | ||
7272 | for (i = 0; i < n; i++) | 7276 | for (i = 0; i < n; i++) |
7273 | dst[i] = src[i]; | 7277 | dst[i] = src[i]; |
7278 | /* zero out counters that only exist in rtnl_link_stats64 */ | ||
7279 | memset((char *)stats64 + n * sizeof(u64), 0, | ||
7280 | sizeof(*stats64) - n * sizeof(u64)); | ||
7274 | #endif | 7281 | #endif |
7275 | } | 7282 | } |
7276 | EXPORT_SYMBOL(netdev_stats_to_stats64); | 7283 | EXPORT_SYMBOL(netdev_stats_to_stats64); |