netfilter: nf_tables: add packet duplication to the netdev family
[sfrench/cifs-2.6.git] / net / netfilter / nf_dup_netdev.c
diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c
new file mode 100644 (file)
index 0000000..8414ee1
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables.h>
+
+void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif)
+{
+       struct net_device *dev;
+       struct sk_buff *skb;
+
+       dev = dev_get_by_index_rcu(pkt->net, oif);
+       if (dev == NULL)
+               return;
+
+       skb = skb_clone(pkt->skb, GFP_ATOMIC);
+       if (skb == NULL)
+               return;
+
+       if (skb_mac_header_was_set(skb))
+               skb_push(skb, skb->mac_len);
+
+       skb->dev = dev;
+       skb_sender_cpu_clear(skb);
+       dev_queue_xmit(skb);
+}
+EXPORT_SYMBOL_GPL(nf_dup_netdev_egress);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");