|
@@ -105,6 +105,7 @@
|
|
|
#include <net/dst.h>
|
|
|
#include <net/pkt_sched.h>
|
|
|
#include <net/checksum.h>
|
|
|
+#include <net/xfrm.h>
|
|
|
#include <linux/highmem.h>
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/kmod.h>
|
|
@@ -1419,6 +1420,45 @@ static inline void net_timestamp(struct sk_buff *skb)
|
|
|
skb->tstamp.tv64 = 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * dev_forward_skb - loopback an skb to another netif
|
|
|
+ *
|
|
|
+ * @dev: destination network device
|
|
|
+ * @skb: buffer to forward
|
|
|
+ *
|
|
|
+ * return values:
|
|
|
+ * NET_RX_SUCCESS (no congestion)
|
|
|
+ * NET_RX_DROP (packet was dropped)
|
|
|
+ *
|
|
|
+ * dev_forward_skb can be used for injecting an skb from the
|
|
|
+ * start_xmit function of one device into the receive queue
|
|
|
+ * of another device.
|
|
|
+ *
|
|
|
+ * The receiving device may be in another namespace, so
|
|
|
+ * we have to clear all information in the skb that could
|
|
|
+ * impact namespace isolation.
|
|
|
+ */
|
|
|
+int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ skb_orphan(skb);
|
|
|
+
|
|
|
+ if (!(dev->flags & IFF_UP))
|
|
|
+ return NET_RX_DROP;
|
|
|
+
|
|
|
+ if (skb->len > (dev->mtu + dev->hard_header_len))
|
|
|
+ return NET_RX_DROP;
|
|
|
+
|
|
|
+ skb_dst_drop(skb);
|
|
|
+ skb->tstamp.tv64 = 0;
|
|
|
+ skb->pkt_type = PACKET_HOST;
|
|
|
+ skb->protocol = eth_type_trans(skb, dev);
|
|
|
+ skb->mark = 0;
|
|
|
+ secpath_reset(skb);
|
|
|
+ nf_reset(skb);
|
|
|
+ return netif_rx(skb);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(dev_forward_skb);
|
|
|
+
|
|
|
/*
|
|
|
* Support routine. Sends outgoing frames to any network
|
|
|
* taps currently in use.
|