aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/loopback.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/loopback.c')
-rw-r--r--drivers/net/loopback.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index b7d438a367f3..da472c687481 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -62,6 +62,7 @@
62struct pcpu_lstats { 62struct pcpu_lstats {
63 unsigned long packets; 63 unsigned long packets;
64 unsigned long bytes; 64 unsigned long bytes;
65 unsigned long drops;
65}; 66};
66 67
67/* 68/*
@@ -71,18 +72,22 @@ struct pcpu_lstats {
71static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) 72static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
72{ 73{
73 struct pcpu_lstats *pcpu_lstats, *lb_stats; 74 struct pcpu_lstats *pcpu_lstats, *lb_stats;
75 int len;
74 76
75 skb_orphan(skb); 77 skb_orphan(skb);
76 78
77 skb->protocol = eth_type_trans(skb,dev); 79 skb->protocol = eth_type_trans(skb, dev);
78 80
79 /* it's OK to use per_cpu_ptr() because BHs are off */ 81 /* it's OK to use per_cpu_ptr() because BHs are off */
80 pcpu_lstats = dev->ml_priv; 82 pcpu_lstats = dev->ml_priv;
81 lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id()); 83 lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
82 lb_stats->bytes += skb->len;
83 lb_stats->packets++;
84 84
85 netif_rx(skb); 85 len = skb->len;
86 if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
87 lb_stats->bytes += len;
88 lb_stats->packets++;
89 } else
90 lb_stats->drops++;
86 91
87 return 0; 92 return 0;
88} 93}
@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
93 struct net_device_stats *stats = &dev->stats; 98 struct net_device_stats *stats = &dev->stats;
94 unsigned long bytes = 0; 99 unsigned long bytes = 0;
95 unsigned long packets = 0; 100 unsigned long packets = 0;
101 unsigned long drops = 0;
96 int i; 102 int i;
97 103
98 pcpu_lstats = dev->ml_priv; 104 pcpu_lstats = dev->ml_priv;
@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
102 lb_stats = per_cpu_ptr(pcpu_lstats, i); 108 lb_stats = per_cpu_ptr(pcpu_lstats, i);
103 bytes += lb_stats->bytes; 109 bytes += lb_stats->bytes;
104 packets += lb_stats->packets; 110 packets += lb_stats->packets;
111 drops += lb_stats->drops;
105 } 112 }
106 stats->rx_packets = packets; 113 stats->rx_packets = packets;
107 stats->tx_packets = packets; 114 stats->tx_packets = packets;
108 stats->rx_bytes = bytes; 115 stats->rx_dropped = drops;
109 stats->tx_bytes = bytes; 116 stats->rx_errors = drops;
117 stats->rx_bytes = bytes;
118 stats->tx_bytes = bytes;
110 return stats; 119 return stats;
111} 120}
112 121
@@ -161,6 +170,7 @@ static void loopback_setup(struct net_device *dev)
161 dev->tx_queue_len = 0; 170 dev->tx_queue_len = 0;
162 dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ 171 dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
163 dev->flags = IFF_LOOPBACK; 172 dev->flags = IFF_LOOPBACK;
173 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
164 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST 174 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
165 | NETIF_F_TSO 175 | NETIF_F_TSO
166 | NETIF_F_NO_CSUM 176 | NETIF_F_NO_CSUM