aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-03 01:15:37 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-05 04:12:00 -0400
commit13a43d94ab026c423dc8902170ef27c2bd36aa87 (patch)
tree3dce5cdca10a4f21b5e7c9815c7aee295b4123a2 /net/core
parentf9d751667fd60788fe3641738938e0968e99cece (diff)
neigh: Convert over to dst_neigh_lookup_skb().
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/neighbour.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index a793af9af150..117afaf51268 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1201,10 +1201,23 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
1201 write_unlock_bh(&neigh->lock); 1201 write_unlock_bh(&neigh->lock);
1202 1202
1203 rcu_read_lock(); 1203 rcu_read_lock();
1204 /* On shaper/eql skb->dst->neighbour != neigh :( */ 1204
1205 if (dst && (n2 = dst_get_neighbour_noref(dst)) != NULL) 1205 /* Why not just use 'neigh' as-is? The problem is that
1206 n1 = n2; 1206 * things such as shaper, eql, and sch_teql can end up
1207 * using alternative, different, neigh objects to output
1208 * the packet in the output path. So what we need to do
1209 * here is re-lookup the top-level neigh in the path so
1210 * we can reinject the packet there.
1211 */
1212 n2 = NULL;
1213 if (dst) {
1214 n2 = dst_neigh_lookup_skb(dst, skb);
1215 if (n2)
1216 n1 = n2;
1217 }
1207 n1->output(n1, skb); 1218 n1->output(n1, skb);
1219 if (n2)
1220 neigh_release(n2);
1208 rcu_read_unlock(); 1221 rcu_read_unlock();
1209 1222
1210 write_lock_bh(&neigh->lock); 1223 write_lock_bh(&neigh->lock);