diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h index b1d43894296a6ac35b9e69e90efa13f32ba9143e..6b4de68a762e338fb8a17d85b6f7f42786f9b598 100644 --- a/include/net/netfilter/nf_queue.h +++ b/include/net/netfilter/nf_queue.h @@ -12,6 +12,7 @@ struct nf_queue_entry { struct list_head list; struct sk_buff *skb; + struct net_device *skb_dev; unsigned int id; unsigned int hook_index; /* index in hook_entries->hook[] */ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index bb8607ff94bc7a46751724d530efc58d325cdde0..3e21edbd60630eb90cf51574c95687ca9472e4f5 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -60,10 +60,9 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry) struct nf_hook_state *state = &entry->state; /* Release those devices we held, or Alexey will kill me. */ - if (state->in) - dev_put(state->in); - if (state->out) - dev_put(state->out); + dev_put(entry->skb_dev); + dev_put(state->in); + dev_put(state->out); if (state->sk) nf_queue_sock_put(state->sk); @@ -107,10 +106,9 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry) if (state->sk && !refcount_inc_not_zero(&state->sk->sk_refcnt)) return false; - if (state->in) - dev_hold(state->in); - if (state->out) - dev_hold(state->out); + dev_hold(entry->skb_dev); + dev_hold(state->in); + dev_hold(state->out); #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) if (entry->physin) @@ -212,11 +210,11 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, *entry = (struct nf_queue_entry) { .skb = skb, + .skb_dev = skb->dev, .state = *state, .hook_index = index, .size = sizeof(*entry) + route_key_size, }; - __nf_queue_entry_init_physdevs(entry); if (!nf_queue_entry_get_refs(entry)) { diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 72d30922ed290a4eeb3022d318e323db502eea97..44f58e1b534e9cda6b67c6a2a7fcfde1d6255467 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -913,6 +913,8 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex) if (physinif == ifindex || physoutif == ifindex) return 1; #endif + if (entry->skb_dev && entry->skb_dev->ifindex == ifindex) + return 1; if (entry->state.in) if (entry->state.in->ifindex == ifindex) return 1;