From 72bf35da507dd85e497fec10deef9fe653f2890f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 2 Jul 2012 22:15:37 -0700 Subject: [PATCH] --- yaml --- r: 314973 b: refs/heads/master c: 13a43d94ab026c423dc8902170ef27c2bd36aa87 h: refs/heads/master i: 314971: c0e43de9a3dbec16a062ab026e2007c387990641 v: v3 --- [refs] | 2 +- trunk/net/core/neighbour.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index b38f2c9a2a5f..8188a6d504dc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f9d751667fd60788fe3641738938e0968e99cece +refs/heads/master: 13a43d94ab026c423dc8902170ef27c2bd36aa87 diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index a793af9af150..117afaf51268 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -1201,10 +1201,23 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, write_unlock_bh(&neigh->lock); rcu_read_lock(); - /* On shaper/eql skb->dst->neighbour != neigh :( */ - if (dst && (n2 = dst_get_neighbour_noref(dst)) != NULL) - n1 = n2; + + /* Why not just use 'neigh' as-is? The problem is that + * things such as shaper, eql, and sch_teql can end up + * using alternative, different, neigh objects to output + * the packet in the output path. So what we need to do + * here is re-lookup the top-level neigh in the path so + * we can reinject the packet there. + */ + n2 = NULL; + if (dst) { + n2 = dst_neigh_lookup_skb(dst, skb); + if (n2) + n1 = n2; + } n1->output(n1, skb); + if (n2) + neigh_release(n2); rcu_read_unlock(); write_lock_bh(&neigh->lock);