+ struct net_device *dev;
+ int ret;
+
-+ dev = alloc_netdev_mq(0, "imq%d", imq_setup, numqueues);
++ dev = alloc_netdev_mq(0, "imq%d", NET_NAME_UNKNOWN, imq_setup, numqueues);
+ if (!dev)
+ return -ENOMEM;
+
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+ struct nf_queue_entry *nf_queue_entry;
+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
struct nf_bridge_info *nf_bridge;
#endif
-@@ -490,6 +499,9 @@ struct sk_buff {
- */
- __u8 encapsulation:1;
- /* 6/8 bit hole (depending on ndisc_nodetype presence) */
+@@ -490,6 +490,9 @@ struct sk_buff {
+ __u16 tc_verd; /* traffic control verdict */
+ #endif
+ #endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+ __u8 imq_flags:IMQ_F_BITS;
+#endif
- kmemcheck_bitfield_end(flags2);
- #if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL
+ union {
+ __wsum csum;
@@ -625,6 +637,12 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
return (struct rtable *)skb_dst(skb);
}
void kfree_skb(struct sk_buff *skb);
void kfree_skb_list(struct sk_buff *segs);
void skb_tx_error(struct sk_buff *skb);
+@@ -2435,6 +2453,10 @@ static inline void nf_reset(struct sk_buff *skb)
+ nf_conntrack_put(skb->nfct);
+ skb->nfct = NULL;
+ #endif
++#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
++ skb->imq_flags = 0;
++ skb->nf_queue_entry = NULL;
++#endif
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+ nf_bridge_put(skb->nf_bridge);
+ skb->nf_bridge = NULL;
@@ -2635,6 +2653,10 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
- nf_conntrack_get(src->nfct);
- dst->nfctinfo = src->nfctinfo;
+ if (copy)
+ dst->nfctinfo = src->nfctinfo;
#endif
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+ dst->imq_flags = src->imq_flags;
+ dst->nf_queue_entry = src->nf_queue_entry;
+#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
dst->nf_bridge = src->nf_bridge;
nf_bridge_get(src->nf_bridge);
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -131,6 +131,9 @@
- #include <linux/hashtable.h>
- #include <linux/vmalloc.h>
#include <linux/if_macvlan.h>
+ #include <linux/errqueue.h>
+ #include <linux/hrtimer.h>
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+#include <linux/imq.h>
+#endif
#include "net-sysfs.h"
-@@ -2595,7 +2598,12 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
- }
- }
+@@ -2618,7 +2618,11 @@ static int xmit_one(struct sk_buff *skb,
+ unsigned int len;
+ int rc;
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
-+ if (!list_empty(&ptype_all) &&
-+ !(skb->imq_flags & IMQ_F_ENQUEUE))
++ if ((!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) && !(skb->imq_flags & IMQ_F_ENQUEUE))
+#else
- if (!list_empty(&ptype_all))
+ if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
+#endif
- dev_queue_xmit_nit(skb, dev);
+ dev_queue_xmit_nit(skb, dev);
- skb_len = skb->len;
+ len = skb->len;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index c28c7fe..a5f1888 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
-@@ -73,6 +73,9 @@
+@@ -73,6 +73,84 @@
struct kmem_cache *skbuff_head_cache __read_mostly;
static struct kmem_cache *skbuff_fclone_cache __read_mostly;
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+static struct kmem_cache *skbuff_cb_store_cache __read_mostly;
-+#endif
-
- static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
-@@ -92,6 +95,82 @@ static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
- return 1;
- }
-
-+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
++
+/* Control buffer save/restore for IMQ devices */
+struct skb_cb_table {
+ char cb[48] __aligned(8);
+}
+#endif
- /* Pipe buffer operations for a socket. */
- static const struct pipe_buf_operations sock_pipe_buf_ops = {
+ /**
+ * skb_panic - private function for out-of-line support
@@ -577,6 +656,28 @@ static void skb_release_head_state(struct sk_buff *skb)
WARN_ON(in_irq());
skb->destructor(skb);
nf_conntrack_put(skb->nfct);
#endif
@@ -709,6 +810,10 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
+ #ifdef CONFIG_XFRM
new->sp = secpath_get(old->sp);
#endif
- memcpy(new->cb, old->cb, sizeof(old->cb));
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+ new->cb_next = NULL;
+ /*skb_copy_stored_cb(new, old);*/
+#endif
- new->csum = old->csum;
- new->local_df = old->local_df;
- new->pkt_type = old->pkt_type;
+ __nf_copy(new, old, false);
+
+ /* Note : this field could be in headers_start/headers_end section
@@ -3112,6 +3217,13 @@ void __init skb_init(void)
0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC,