diff options
Diffstat (limited to 'drivers/net/veth.c')
-rw-r--r-- | drivers/net/veth.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 87197dd9c788..190f784c9cfe 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -171,6 +171,7 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
171 | if (skb->len > (rcv->mtu + MTU_PAD)) | 171 | if (skb->len > (rcv->mtu + MTU_PAD)) |
172 | goto rx_drop; | 172 | goto rx_drop; |
173 | 173 | ||
174 | skb->tstamp.tv64 = 0; | ||
174 | skb->pkt_type = PACKET_HOST; | 175 | skb->pkt_type = PACKET_HOST; |
175 | skb->protocol = eth_type_trans(skb, rcv); | 176 | skb->protocol = eth_type_trans(skb, rcv); |
176 | if (dev->features & NETIF_F_NO_CSUM) | 177 | if (dev->features & NETIF_F_NO_CSUM) |
@@ -189,17 +190,17 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
189 | rcv_stats->rx_packets++; | 190 | rcv_stats->rx_packets++; |
190 | 191 | ||
191 | netif_rx(skb); | 192 | netif_rx(skb); |
192 | return 0; | 193 | return NETDEV_TX_OK; |
193 | 194 | ||
194 | tx_drop: | 195 | tx_drop: |
195 | kfree_skb(skb); | 196 | kfree_skb(skb); |
196 | stats->tx_dropped++; | 197 | stats->tx_dropped++; |
197 | return 0; | 198 | return NETDEV_TX_OK; |
198 | 199 | ||
199 | rx_drop: | 200 | rx_drop: |
200 | kfree_skb(skb); | 201 | kfree_skb(skb); |
201 | rcv_stats->rx_dropped++; | 202 | rcv_stats->rx_dropped++; |
202 | return 0; | 203 | return NETDEV_TX_OK; |
203 | } | 204 | } |
204 | 205 | ||
205 | /* | 206 | /* |
@@ -208,11 +209,14 @@ rx_drop: | |||
208 | 209 | ||
209 | static struct net_device_stats *veth_get_stats(struct net_device *dev) | 210 | static struct net_device_stats *veth_get_stats(struct net_device *dev) |
210 | { | 211 | { |
211 | struct veth_priv *priv = netdev_priv(dev); | 212 | struct veth_priv *priv; |
212 | struct net_device_stats *dev_stats = &dev->stats; | 213 | struct net_device_stats *dev_stats; |
213 | unsigned int cpu; | 214 | int cpu; |
214 | struct veth_net_stats *stats; | 215 | struct veth_net_stats *stats; |
215 | 216 | ||
217 | priv = netdev_priv(dev); | ||
218 | dev_stats = &dev->stats; | ||
219 | |||
216 | dev_stats->rx_packets = 0; | 220 | dev_stats->rx_packets = 0; |
217 | dev_stats->tx_packets = 0; | 221 | dev_stats->tx_packets = 0; |
218 | dev_stats->rx_bytes = 0; | 222 | dev_stats->rx_bytes = 0; |
@@ -220,17 +224,16 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev) | |||
220 | dev_stats->tx_dropped = 0; | 224 | dev_stats->tx_dropped = 0; |
221 | dev_stats->rx_dropped = 0; | 225 | dev_stats->rx_dropped = 0; |
222 | 226 | ||
223 | if (priv->stats) | 227 | for_each_online_cpu(cpu) { |
224 | for_each_online_cpu(cpu) { | 228 | stats = per_cpu_ptr(priv->stats, cpu); |
225 | stats = per_cpu_ptr(priv->stats, cpu); | ||
226 | 229 | ||
227 | dev_stats->rx_packets += stats->rx_packets; | 230 | dev_stats->rx_packets += stats->rx_packets; |
228 | dev_stats->tx_packets += stats->tx_packets; | 231 | dev_stats->tx_packets += stats->tx_packets; |
229 | dev_stats->rx_bytes += stats->rx_bytes; | 232 | dev_stats->rx_bytes += stats->rx_bytes; |
230 | dev_stats->tx_bytes += stats->tx_bytes; | 233 | dev_stats->tx_bytes += stats->tx_bytes; |
231 | dev_stats->tx_dropped += stats->tx_dropped; | 234 | dev_stats->tx_dropped += stats->tx_dropped; |
232 | dev_stats->rx_dropped += stats->rx_dropped; | 235 | dev_stats->rx_dropped += stats->rx_dropped; |
233 | } | 236 | } |
234 | 237 | ||
235 | return dev_stats; | 238 | return dev_stats; |
236 | } | 239 | } |
@@ -257,8 +260,6 @@ static int veth_close(struct net_device *dev) | |||
257 | netif_carrier_off(dev); | 260 | netif_carrier_off(dev); |
258 | netif_carrier_off(priv->peer); | 261 | netif_carrier_off(priv->peer); |
259 | 262 | ||
260 | free_percpu(priv->stats); | ||
261 | priv->stats = NULL; | ||
262 | return 0; | 263 | return 0; |
263 | } | 264 | } |
264 | 265 | ||
@@ -289,6 +290,15 @@ static int veth_dev_init(struct net_device *dev) | |||
289 | return 0; | 290 | return 0; |
290 | } | 291 | } |
291 | 292 | ||
293 | static void veth_dev_free(struct net_device *dev) | ||
294 | { | ||
295 | struct veth_priv *priv; | ||
296 | |||
297 | priv = netdev_priv(dev); | ||
298 | free_percpu(priv->stats); | ||
299 | free_netdev(dev); | ||
300 | } | ||
301 | |||
292 | static const struct net_device_ops veth_netdev_ops = { | 302 | static const struct net_device_ops veth_netdev_ops = { |
293 | .ndo_init = veth_dev_init, | 303 | .ndo_init = veth_dev_init, |
294 | .ndo_open = veth_open, | 304 | .ndo_open = veth_open, |
@@ -306,7 +316,7 @@ static void veth_setup(struct net_device *dev) | |||
306 | dev->netdev_ops = &veth_netdev_ops; | 316 | dev->netdev_ops = &veth_netdev_ops; |
307 | dev->ethtool_ops = &veth_ethtool_ops; | 317 | dev->ethtool_ops = &veth_ethtool_ops; |
308 | dev->features |= NETIF_F_LLTX; | 318 | dev->features |= NETIF_F_LLTX; |
309 | dev->destructor = free_netdev; | 319 | dev->destructor = veth_dev_free; |
310 | } | 320 | } |
311 | 321 | ||
312 | /* | 322 | /* |