diff options
-rw-r--r-- | drivers/net/veth.c | 17 | ||||
-rw-r--r-- | include/linux/netdevice.h | 2 | ||||
-rw-r--r-- | net/core/dev.c | 40 |
3 files changed, 45 insertions, 14 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 2d657f2314cb..6c4b5a2d7877 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 | ||
195 | tx_drop: | 184 | tx_drop: |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 97873e31661c..9428793775a0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1562,6 +1562,8 @@ extern int dev_set_mac_address(struct net_device *, | |||
1562 | extern int dev_hard_start_xmit(struct sk_buff *skb, | 1562 | extern int dev_hard_start_xmit(struct sk_buff *skb, |
1563 | struct net_device *dev, | 1563 | struct net_device *dev, |
1564 | struct netdev_queue *txq); | 1564 | struct netdev_queue *txq); |
1565 | extern int dev_forward_skb(struct net_device *dev, | ||
1566 | struct sk_buff *skb); | ||
1565 | 1567 | ||
1566 | extern int netdev_budget; | 1568 | extern int netdev_budget; |
1567 | 1569 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index e65af6041415..7775e8b48deb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -105,6 +105,7 @@ | |||
105 | #include <net/dst.h> | 105 | #include <net/dst.h> |
106 | #include <net/pkt_sched.h> | 106 | #include <net/pkt_sched.h> |
107 | #include <net/checksum.h> | 107 | #include <net/checksum.h> |
108 | #include <net/xfrm.h> | ||
108 | #include <linux/highmem.h> | 109 | #include <linux/highmem.h> |
109 | #include <linux/init.h> | 110 | #include <linux/init.h> |
110 | #include <linux/kmod.h> | 111 | #include <linux/kmod.h> |
@@ -1419,6 +1420,45 @@ static inline void net_timestamp(struct sk_buff *skb) | |||
1419 | skb->tstamp.tv64 = 0; | 1420 | skb->tstamp.tv64 = 0; |
1420 | } | 1421 | } |
1421 | 1422 | ||
1423 | /** | ||
1424 | * dev_forward_skb - loopback an skb to another netif | ||
1425 | * | ||
1426 | * @dev: destination network device | ||
1427 | * @skb: buffer to forward | ||
1428 | * | ||
1429 | * return values: | ||
1430 | * NET_RX_SUCCESS (no congestion) | ||
1431 | * NET_RX_DROP (packet was dropped) | ||
1432 | * | ||
1433 | * dev_forward_skb can be used for injecting an skb from the | ||
1434 | * start_xmit function of one device into the receive queue | ||
1435 | * of another device. | ||
1436 | * | ||
1437 | * The receiving device may be in another namespace, so | ||
1438 | * we have to clear all information in the skb that could | ||
1439 | * impact namespace isolation. | ||
1440 | */ | ||
1441 | int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | ||
1442 | { | ||
1443 | skb_orphan(skb); | ||
1444 | |||
1445 | if (!(dev->flags & IFF_UP)) | ||
1446 | return NET_RX_DROP; | ||
1447 | |||
1448 | if (skb->len > (dev->mtu + dev->hard_header_len)) | ||
1449 | return NET_RX_DROP; | ||
1450 | |||
1451 | skb_dst_drop(skb); | ||
1452 | skb->tstamp.tv64 = 0; | ||
1453 | skb->pkt_type = PACKET_HOST; | ||
1454 | skb->protocol = eth_type_trans(skb, dev); | ||
1455 | skb->mark = 0; | ||
1456 | secpath_reset(skb); | ||
1457 | nf_reset(skb); | ||
1458 | return netif_rx(skb); | ||
1459 | } | ||
1460 | EXPORT_SYMBOL_GPL(dev_forward_skb); | ||
1461 | |||
1422 | /* | 1462 | /* |
1423 | * Support routine. Sends outgoing frames to any network | 1463 | * Support routine. Sends outgoing frames to any network |
1424 | * taps currently in use. | 1464 | * taps currently in use. |