We see a packet with skb->dev already freed, which should have passed
this place in br_nf_pre_routing_finish as it has nf_bridge->neigh_header
set to src mac which can be set only later in this stack in
br_nf_pre_routing_finish_bridge. So I try to print all information I can
imagine to help understanding this problem.

We see this skb taken from neigh->arp_queue and then crash on it, and
here:

  +-> br_nf_pre_routing
    +-> br_nf_pre_routing_finish
      +-> skb->dev = nf_bridge->physindev #1
      +-> br_nf_pre_routing_finish_bridge #2
        +-> nf_bridge->bridged_dnat = 1 #1
        +-> neighbour->output #2
          +-> neigh_resolve_output
            +-> neigh_event_send
              +-> __neigh_event_send
                +-> __skb_queue_tail(&neigh->arp_queue, skb)

skb can acutually get to arp_queue. This is the second confirmation that
something wrong likely happened on this stack.

https://virtuozzo.atlassian.net/browse/PSBM-151735
Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com>
---
 net/bridge/br_netfilter_hooks.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index eb8ad039c343f..6258fe55a04eb 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -386,6 +386,17 @@ static int br_nf_pre_routing_finish(struct sock *sk, 
struct sk_buff *skb)
                } else {
                        if (skb_dst(skb)->dev == dev) {
 bridged_dnat:
+                               /*
+                                * Debug for PSBM-151735, I'm really curious 
how we can get here.
+                                */
+                               WARN_ONCE(1, "br_nf_pre_routing_finish: 
saddr=%pI4 daddr=%pI4 nf_bridge_daddr=%pI4 "
+                                            "dev=%s skb->dev=%s 
nf_bridge->indev=%s "
+                                            "skb->dst->dev=%s "
+                                            "err=%d indev_forward=%d\n",
+                                         &iph->saddr, &iph->daddr, 
&nf_bridge->ipv4_daddr,
+                                         dev->name, skb->dev->name, 
nf_bridge->physindev ? nf_bridge->physindev->name : "<none>",
+                                         skb_dst(skb) && skb_dst(skb)->dev ? 
skb_dst(skb)->dev->name : "<none>",
+                                         err, 
IN_DEV_FORWARD(__in_dev_get_rcu(dev)));
                                skb->dev = nf_bridge->physindev;
                                nf_bridge_update_protocol(skb);
                                nf_bridge_push_encap_header(skb);
-- 
2.43.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to