aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/veth.c17
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--net/core/dev.c40
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
195tx_drop: 184tx_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 *,
1562extern int dev_hard_start_xmit(struct sk_buff *skb, 1562extern 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);
1565extern int dev_forward_skb(struct net_device *dev,
1566 struct sk_buff *skb);
1565 1567
1566extern int netdev_budget; 1568extern 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 */
1441int 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}
1460EXPORT_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.