The hook in my testcase is at NF_BR_FORWARD, and priority is -2. And at this hook point both the entry->out and entry->in are not bridge device. But the dst was set to the bridge's fake_rtable. Rundong Ge <rdong.ge@xxxxxxxxx> 于2019年4月22日周一 下午5:51写道: > > skb->dev is munged in setup_prerouting() to be bridge or vlan device on > top of bridge. > --Yes, but br_nf_pre_routing_finish will set the skb->dev back to the phyindev. > > Florian Westphal <fw@xxxxxxxxx> 于2019年4月22日周一 下午5:35写道: > > > > Rundong Ge <rdong.ge@xxxxxxxxx> wrote: > > > br_nf_pre_routing will call the NF_INET_PRE_ROUTING hooks, at this > > > time both entry->state.in and entry->state.out are not bridge device. > > > > > > NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->net, state->sk, skb, > > > skb->dev, NULL, > > > br_nf_pre_routing_finish); > > > > skb->dev is munged in setup_prerouting() to be bridge or vlan device on > > top of bridge. > > > > That being said, I think we need this fix at least: > > > > diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c > > --- a/net/netfilter/nf_queue.c > > +++ b/net/netfilter/nf_queue.c > > @@ -197,8 +197,15 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, > > .size = sizeof(*entry) + route_key_size, > > }; > > > > + if (skb_dst(skb)) { > > + skb_dst_force(skb); > > + if (!skb_dst(skb)) { > > + status = -EHOSTUNREACH; > > + goto err; > > + } > > + } > > + > > nf_queue_entry_get_refs(entry); > > - skb_dst_force(skb); > > > > switch (entry->state.pf) { > > case AF_INET: > > > > > > Then, why not add, in dev_cmp: > > > > dst = skb_dst(skb); > > if (dst && dst->dev->index == index ... > > > > ?