From bdb8182b12a3b51b3ebacb3759b1f8cec6630e2d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 11 Jul 2012 20:27:54 -0700 Subject: [PATCH] --- yaml --- r: 315124 b: refs/heads/master c: d0da720f9f16a5023cc084bed8968702400f6e0f h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/net/ipv4/route.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/[refs] b/[refs] index d5252ace0538..43dafb8623ae 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d3351b75a7169337877fe6f6f2c019154b6ec1ea +refs/heads/master: d0da720f9f16a5023cc084bed8968702400f6e0f diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 95bfa1ba5b28..a4de87f44c30 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1271,6 +1271,26 @@ static void rt_del(unsigned int hash, struct rtable *rt) spin_unlock_bh(rt_hash_lock_addr(hash)); } +static void ip_do_redirect(struct rtable *rt, __be32 old_gw, __be32 new_gw) +{ + struct neighbour *n; + + if (rt->rt_gateway != old_gw) + return; + + n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); + if (n) { + if (!(n->nud_state & NUD_VALID)) { + neigh_event_send(n, NULL); + } else { + rt->rt_gateway = new_gw; + rt->rt_flags |= RTCF_REDIRECTED; + call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); + } + neigh_release(n); + } +} + /* called in rcu_read_lock() section */ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, __be32 saddr, struct net_device *dev) @@ -1311,8 +1331,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rthp = &rt_hash_table[hash].chain; while ((rt = rcu_dereference(*rthp)) != NULL) { - struct neighbour *n; - rthp = &rt->dst.rt_next; if (rt->rt_key_dst != daddr || @@ -1322,21 +1340,10 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rt_is_expired(rt) || !net_eq(dev_net(rt->dst.dev), net) || rt->dst.error || - rt->dst.dev != dev || - rt->rt_gateway != old_gw) + rt->dst.dev != dev) continue; - n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); - if (n) { - if (!(n->nud_state & NUD_VALID)) { - neigh_event_send(n, NULL); - } else { - rt->rt_gateway = new_gw; - rt->rt_flags |= RTCF_REDIRECTED; - call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); - } - neigh_release(n); - } + ip_do_redirect(rt, old_gw, new_gw); } } }