aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/veth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/veth.c')
-rw-r--r--drivers/net/veth.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index ade5b344f75d..63099c58a6dd 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -155,8 +155,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
155 struct veth_net_stats *stats, *rcv_stats; 155 struct veth_net_stats *stats, *rcv_stats;
156 int length, cpu; 156 int length, cpu;
157 157
158 skb_orphan(skb);
159
160 priv = netdev_priv(dev); 158 priv = netdev_priv(dev);
161 rcv = priv->peer; 159 rcv = priv->peer;
162 rcv_priv = netdev_priv(rcv); 160 rcv_priv = netdev_priv(rcv);
@@ -168,20 +166,12 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
168 if (!(rcv->flags & IFF_UP)) 166 if (!(rcv->flags & IFF_UP))
169 goto tx_drop; 167 goto tx_drop;
170 168
171 if (skb->len > (rcv->mtu + MTU_PAD))
172 goto rx_drop;
173
174 skb->tstamp.tv64 = 0;
175 skb->pkt_type = PACKET_HOST;
176 skb->protocol = eth_type_trans(skb, rcv);
177 if (dev->features & NETIF_F_NO_CSUM) 169 if (dev->features & NETIF_F_NO_CSUM)
178 skb->ip_summed = rcv_priv->ip_summed; 170 skb->ip_summed = rcv_priv->ip_summed;
179 171
180 skb->mark = 0; 172 length = skb->len + ETH_HLEN;
181 secpath_reset(skb); 173 if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
182 nf_reset(skb); 174 goto rx_drop;
183
184 length = skb->len;
185 175
186 stats->tx_bytes += length; 176 stats->tx_bytes += length;
187 stats->tx_packets++; 177 stats->tx_packets++;
@@ -189,7 +179,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
189 rcv_stats->rx_bytes += length; 179 rcv_stats->rx_bytes += length;
190 rcv_stats->rx_packets++; 180 rcv_stats->rx_packets++;
191 181
192 netif_rx(skb);
193 return NETDEV_TX_OK; 182 return NETDEV_TX_OK;
194 183
195tx_drop: 184tx_drop:
@@ -210,32 +199,29 @@ rx_drop:
210static struct net_device_stats *veth_get_stats(struct net_device *dev) 199static struct net_device_stats *veth_get_stats(struct net_device *dev)
211{ 200{
212 struct veth_priv *priv; 201 struct veth_priv *priv;
213 struct net_device_stats *dev_stats;
214 int cpu; 202 int cpu;
215 struct veth_net_stats *stats; 203 struct veth_net_stats *stats, total = {0};
216 204
217 priv = netdev_priv(dev); 205 priv = netdev_priv(dev);
218 dev_stats = &dev->stats;
219 206
220 dev_stats->rx_packets = 0; 207 for_each_possible_cpu(cpu) {
221 dev_stats->tx_packets = 0;
222 dev_stats->rx_bytes = 0;
223 dev_stats->tx_bytes = 0;
224 dev_stats->tx_dropped = 0;
225 dev_stats->rx_dropped = 0;
226
227 for_each_online_cpu(cpu) {
228 stats = per_cpu_ptr(priv->stats, cpu); 208 stats = per_cpu_ptr(priv->stats, cpu);
229 209
230 dev_stats->rx_packets += stats->rx_packets; 210 total.rx_packets += stats->rx_packets;
231 dev_stats->tx_packets += stats->tx_packets; 211 total.tx_packets += stats->tx_packets;
232 dev_stats->rx_bytes += stats->rx_bytes; 212 total.rx_bytes += stats->rx_bytes;
233 dev_stats->tx_bytes += stats->tx_bytes; 213 total.tx_bytes += stats->tx_bytes;
234 dev_stats->tx_dropped += stats->tx_dropped; 214 total.tx_dropped += stats->tx_dropped;
235 dev_stats->rx_dropped += stats->rx_dropped; 215 total.rx_dropped += stats->rx_dropped;
236 } 216 }
237 217 dev->stats.rx_packets = total.rx_packets;
238 return dev_stats; 218 dev->stats.tx_packets = total.tx_packets;
219 dev->stats.rx_bytes = total.rx_bytes;
220 dev->stats.tx_bytes = total.tx_bytes;
221 dev->stats.tx_dropped = total.tx_dropped;
222 dev->stats.rx_dropped = total.rx_dropped;
223
224 return &dev->stats;
239} 225}
240 226
241static int veth_open(struct net_device *dev) 227static int veth_open(struct net_device *dev)
@@ -340,7 +326,7 @@ static int veth_validate(struct nlattr *tb[], struct nlattr *data[])
340 326
341static struct rtnl_link_ops veth_link_ops; 327static struct rtnl_link_ops veth_link_ops;
342 328
343static int veth_newlink(struct net_device *dev, 329static int veth_newlink(struct net *src_net, struct net_device *dev,
344 struct nlattr *tb[], struct nlattr *data[]) 330 struct nlattr *tb[], struct nlattr *data[])
345{ 331{
346 int err; 332 int err;
@@ -348,6 +334,7 @@ static int veth_newlink(struct net_device *dev,
348 struct veth_priv *priv; 334 struct veth_priv *priv;
349 char ifname[IFNAMSIZ]; 335 char ifname[IFNAMSIZ];
350 struct nlattr *peer_tb[IFLA_MAX + 1], **tbp; 336 struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
337 struct net *net;
351 338
352 /* 339 /*
353 * create and register peer first 340 * create and register peer first
@@ -380,14 +367,22 @@ static int veth_newlink(struct net_device *dev,
380 else 367 else
381 snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d"); 368 snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
382 369
383 peer = rtnl_create_link(dev_net(dev), ifname, &veth_link_ops, tbp); 370 net = rtnl_link_get_net(src_net, tbp);
384 if (IS_ERR(peer)) 371 if (IS_ERR(net))
372 return PTR_ERR(net);
373
374 peer = rtnl_create_link(src_net, net, ifname, &veth_link_ops, tbp);
375 if (IS_ERR(peer)) {
376 put_net(net);
385 return PTR_ERR(peer); 377 return PTR_ERR(peer);
378 }
386 379
387 if (tbp[IFLA_ADDRESS] == NULL) 380 if (tbp[IFLA_ADDRESS] == NULL)
388 random_ether_addr(peer->dev_addr); 381 random_ether_addr(peer->dev_addr);
389 382
390 err = register_netdevice(peer); 383 err = register_netdevice(peer);
384 put_net(net);
385 net = NULL;
391 if (err < 0) 386 if (err < 0)
392 goto err_register_peer; 387 goto err_register_peer;
393 388
@@ -442,7 +437,7 @@ err_register_peer:
442 return err; 437 return err;
443} 438}
444 439
445static void veth_dellink(struct net_device *dev) 440static void veth_dellink(struct net_device *dev, struct list_head *head)
446{ 441{
447 struct veth_priv *priv; 442 struct veth_priv *priv;
448 struct net_device *peer; 443 struct net_device *peer;
@@ -450,8 +445,8 @@ static void veth_dellink(struct net_device *dev)
450 priv = netdev_priv(dev); 445 priv = netdev_priv(dev);
451 peer = priv->peer; 446 peer = priv->peer;
452 447
453 unregister_netdevice(dev); 448 unregister_netdevice_queue(dev, head);
454 unregister_netdevice(peer); 449 unregister_netdevice_queue(peer, head);
455} 450}
456 451
457static const struct nla_policy veth_policy[VETH_INFO_MAX + 1]; 452static const struct nla_policy veth_policy[VETH_INFO_MAX + 1];