git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
netns xfrm: fix "ip xfrm state|policy count" misreport
[safe/jmp/linux-2.6]
/
drivers
/
net
/
veth.c
diff --git
a/drivers/net/veth.c
b/drivers/net/veth.c
index
0c4a811
..
3a15de5
100644
(file)
--- 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)
struct veth_net_stats *stats, *rcv_stats;
int length;
struct veth_net_stats *stats, *rcv_stats;
int length;
- skb_orphan(skb);
-
priv = netdev_priv(dev);
rcv = priv->peer;
rcv_priv = netdev_priv(rcv);
priv = netdev_priv(dev);
rcv = priv->peer;
rcv_priv = netdev_priv(rcv);
@@
-167,20
+165,12
@@
static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
if (!(rcv->flags & IFF_UP))
goto tx_drop;
if (!(rcv->flags & IFF_UP))
goto tx_drop;
- if (skb->len > (rcv->mtu + MTU_PAD))
- goto rx_drop;
-
- skb->tstamp.tv64 = 0;
- skb->pkt_type = PACKET_HOST;
- skb->protocol = eth_type_trans(skb, rcv);
if (dev->features & NETIF_F_NO_CSUM)
skb->ip_summed = rcv_priv->ip_summed;
if (dev->features & NETIF_F_NO_CSUM)
skb->ip_summed = rcv_priv->ip_summed;
- skb->mark = 0;
- secpath_reset(skb);
- nf_reset(skb);
-
- length = skb->len;
+ length = skb->len + ETH_HLEN;
+ if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
+ goto rx_drop;
stats->tx_bytes += length;
stats->tx_packets++;
stats->tx_bytes += length;
stats->tx_packets++;
@@
-188,7
+178,6
@@
static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
rcv_stats->rx_bytes += length;
rcv_stats->rx_packets++;
rcv_stats->rx_bytes += length;
rcv_stats->rx_packets++;
- netif_rx(skb);
return NETDEV_TX_OK;
tx_drop:
return NETDEV_TX_OK;
tx_drop:
@@
-209,32
+198,29
@@
rx_drop:
static struct net_device_stats *veth_get_stats(struct net_device *dev)
{
struct veth_priv *priv;
static struct net_device_stats *veth_get_stats(struct net_device *dev)
{
struct veth_priv *priv;
- struct net_device_stats *dev_stats;
int cpu;
int cpu;
- struct veth_net_stats *stats;
+ struct veth_net_stats *stats
, total = {0}
;
priv = netdev_priv(dev);
priv = netdev_priv(dev);
- dev_stats = &dev->stats;
- dev_stats->rx_packets = 0;
- dev_stats->tx_packets = 0;
- dev_stats->rx_bytes = 0;
- dev_stats->tx_bytes = 0;
- dev_stats->tx_dropped = 0;
- dev_stats->rx_dropped = 0;
-
- for_each_online_cpu(cpu) {
+ for_each_possible_cpu(cpu) {
stats = per_cpu_ptr(priv->stats, cpu);
stats = per_cpu_ptr(priv->stats, cpu);
-
dev_stats->
rx_packets += stats->rx_packets;
-
dev_stats->
tx_packets += stats->tx_packets;
-
dev_stats->rx_bytes
+= stats->rx_bytes;
-
dev_stats->tx_bytes
+= stats->tx_bytes;
-
dev_stats->
tx_dropped += stats->tx_dropped;
-
dev_stats->
rx_dropped += stats->rx_dropped;
+
total.
rx_packets += stats->rx_packets;
+
total.
tx_packets += stats->tx_packets;
+
total.rx_bytes
+= stats->rx_bytes;
+
total.tx_bytes
+= stats->tx_bytes;
+
total.
tx_dropped += stats->tx_dropped;
+
total.
rx_dropped += stats->rx_dropped;
}
}
-
- return dev_stats;
+ dev->stats.rx_packets = total.rx_packets;
+ dev->stats.tx_packets = total.tx_packets;
+ dev->stats.rx_bytes = total.rx_bytes;
+ dev->stats.tx_bytes = total.tx_bytes;
+ dev->stats.tx_dropped = total.tx_dropped;
+ dev->stats.rx_dropped = total.rx_dropped;
+
+ return &dev->stats;
}
static int veth_open(struct net_device *dev)
}
static int veth_open(struct net_device *dev)
@@
-339,7
+325,7
@@
static int veth_validate(struct nlattr *tb[], struct nlattr *data[])
static struct rtnl_link_ops veth_link_ops;
static struct rtnl_link_ops veth_link_ops;
-static int veth_newlink(struct net_device *dev,
+static int veth_newlink(struct net
*src_net, struct net
_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
int err;
struct nlattr *tb[], struct nlattr *data[])
{
int err;
@@
-347,6
+333,7
@@
static int veth_newlink(struct net_device *dev,
struct veth_priv *priv;
char ifname[IFNAMSIZ];
struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
struct veth_priv *priv;
char ifname[IFNAMSIZ];
struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
+ struct net *net;
/*
* create and register peer first
/*
* create and register peer first
@@
-379,14
+366,22
@@
static int veth_newlink(struct net_device *dev,
else
snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
else
snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
- peer = rtnl_create_link(dev_net(dev), ifname, &veth_link_ops, tbp);
- if (IS_ERR(peer))
+ net = rtnl_link_get_net(src_net, tbp);
+ if (IS_ERR(net))
+ return PTR_ERR(net);
+
+ peer = rtnl_create_link(src_net, net, ifname, &veth_link_ops, tbp);
+ if (IS_ERR(peer)) {
+ put_net(net);
return PTR_ERR(peer);
return PTR_ERR(peer);
+ }
if (tbp[IFLA_ADDRESS] == NULL)
random_ether_addr(peer->dev_addr);
err = register_netdevice(peer);
if (tbp[IFLA_ADDRESS] == NULL)
random_ether_addr(peer->dev_addr);
err = register_netdevice(peer);
+ put_net(net);
+ net = NULL;
if (err < 0)
goto err_register_peer;
if (err < 0)
goto err_register_peer;
@@
-441,7
+436,7
@@
err_register_peer:
return err;
}
return err;
}
-static void veth_dellink(struct net_device *dev)
+static void veth_dellink(struct net_device *dev
, struct list_head *head
)
{
struct veth_priv *priv;
struct net_device *peer;
{
struct veth_priv *priv;
struct net_device *peer;
@@
-449,8
+444,8
@@
static void veth_dellink(struct net_device *dev)
priv = netdev_priv(dev);
peer = priv->peer;
priv = netdev_priv(dev);
peer = priv->peer;
- unregister_netdevice
(dev
);
- unregister_netdevice
(peer
);
+ unregister_netdevice
_queue(dev, head
);
+ unregister_netdevice
_queue(peer, head
);
}
static const struct nla_policy veth_policy[VETH_INFO_MAX + 1];
}
static const struct nla_policy veth_policy[VETH_INFO_MAX + 1];