diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-09-30 17:06:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-05 17:47:55 -0400 |
commit | caf586e5f23cebb2a68cbaf288d59dbbf2d74052 (patch) | |
tree | 5c0dfcf5a14c55501f9225835c83abddb8d1876e /net/core | |
parent | a00eac0c459abecb539fb2a2abd3122dd7ca5d4a (diff) |
net: add a core netdev->rx_dropped counter
In various situations, a device provides a packet to our stack and we
drop it before it enters protocol stack :
- softnet backlog full (accounted in /proc/net/softnet_stat)
- bad vlan tag (not accounted)
- unknown/unregistered protocol (not accounted)
We can handle a per-device counter of such dropped frames at core level,
and automatically adds it to the device provided stats (rx_dropped), so
that standard tools can be used (ifconfig, ip link, cat /proc/net/dev)
This is a generalization of commit 8990f468a (net: rx_dropped
accounting), thus reverting it.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ce6ad88c980..7d149550e8d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1483,8 +1483,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
1483 | skb_orphan(skb); | 1483 | skb_orphan(skb); |
1484 | nf_reset(skb); | 1484 | nf_reset(skb); |
1485 | 1485 | ||
1486 | if (!(dev->flags & IFF_UP) || | 1486 | if (unlikely(!(dev->flags & IFF_UP) || |
1487 | (skb->len > (dev->mtu + dev->hard_header_len))) { | 1487 | (skb->len > (dev->mtu + dev->hard_header_len)))) { |
1488 | atomic_long_inc(&dev->rx_dropped); | ||
1488 | kfree_skb(skb); | 1489 | kfree_skb(skb); |
1489 | return NET_RX_DROP; | 1490 | return NET_RX_DROP; |
1490 | } | 1491 | } |
@@ -2548,6 +2549,7 @@ enqueue: | |||
2548 | 2549 | ||
2549 | local_irq_restore(flags); | 2550 | local_irq_restore(flags); |
2550 | 2551 | ||
2552 | atomic_long_inc(&skb->dev->rx_dropped); | ||
2551 | kfree_skb(skb); | 2553 | kfree_skb(skb); |
2552 | return NET_RX_DROP; | 2554 | return NET_RX_DROP; |
2553 | } | 2555 | } |
@@ -2995,6 +2997,7 @@ ncls: | |||
2995 | if (pt_prev) { | 2997 | if (pt_prev) { |
2996 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 2998 | ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
2997 | } else { | 2999 | } else { |
3000 | atomic_long_inc(&skb->dev->rx_dropped); | ||
2998 | kfree_skb(skb); | 3001 | kfree_skb(skb); |
2999 | /* Jamal, now you will not able to escape explaining | 3002 | /* Jamal, now you will not able to escape explaining |
3000 | * me how you were going to use this. :-) | 3003 | * me how you were going to use this. :-) |
@@ -5429,14 +5432,14 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, | |||
5429 | 5432 | ||
5430 | if (ops->ndo_get_stats64) { | 5433 | if (ops->ndo_get_stats64) { |
5431 | memset(storage, 0, sizeof(*storage)); | 5434 | memset(storage, 0, sizeof(*storage)); |
5432 | return ops->ndo_get_stats64(dev, storage); | 5435 | ops->ndo_get_stats64(dev, storage); |
5433 | } | 5436 | } else if (ops->ndo_get_stats) { |
5434 | if (ops->ndo_get_stats) { | ||
5435 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); | 5437 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); |
5436 | return storage; | 5438 | } else { |
5439 | netdev_stats_to_stats64(storage, &dev->stats); | ||
5440 | dev_txq_stats_fold(dev, storage); | ||
5437 | } | 5441 | } |
5438 | netdev_stats_to_stats64(storage, &dev->stats); | 5442 | storage->rx_dropped += atomic_long_read(&dev->rx_dropped); |
5439 | dev_txq_stats_fold(dev, storage); | ||
5440 | return storage; | 5443 | return storage; |
5441 | } | 5444 | } |
5442 | EXPORT_SYMBOL(dev_get_stats); | 5445 | EXPORT_SYMBOL(dev_get_stats); |