diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-11 23:27:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-11 23:27:54 -0400 |
commit | d0da720f9f16a5023cc084bed8968702400f6e0f (patch) | |
tree | 4bdc0aa45aff71805d2db1bcd89c3c52a272d18f /net | |
parent | d3351b75a7169337877fe6f6f2c019154b6ec1ea (diff) |
ipv4: Pull redirect instantiation out into a helper function.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/route.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 95bfa1ba5b28..a4de87f44c30 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1271,6 +1271,26 @@ static void rt_del(unsigned int hash, struct rtable *rt) | |||
1271 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1271 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | static void ip_do_redirect(struct rtable *rt, __be32 old_gw, __be32 new_gw) | ||
1275 | { | ||
1276 | struct neighbour *n; | ||
1277 | |||
1278 | if (rt->rt_gateway != old_gw) | ||
1279 | return; | ||
1280 | |||
1281 | n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); | ||
1282 | if (n) { | ||
1283 | if (!(n->nud_state & NUD_VALID)) { | ||
1284 | neigh_event_send(n, NULL); | ||
1285 | } else { | ||
1286 | rt->rt_gateway = new_gw; | ||
1287 | rt->rt_flags |= RTCF_REDIRECTED; | ||
1288 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); | ||
1289 | } | ||
1290 | neigh_release(n); | ||
1291 | } | ||
1292 | } | ||
1293 | |||
1274 | /* called in rcu_read_lock() section */ | 1294 | /* called in rcu_read_lock() section */ |
1275 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | 1295 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, |
1276 | __be32 saddr, struct net_device *dev) | 1296 | __be32 saddr, struct net_device *dev) |
@@ -1311,8 +1331,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1311 | rthp = &rt_hash_table[hash].chain; | 1331 | rthp = &rt_hash_table[hash].chain; |
1312 | 1332 | ||
1313 | while ((rt = rcu_dereference(*rthp)) != NULL) { | 1333 | while ((rt = rcu_dereference(*rthp)) != NULL) { |
1314 | struct neighbour *n; | ||
1315 | |||
1316 | rthp = &rt->dst.rt_next; | 1334 | rthp = &rt->dst.rt_next; |
1317 | 1335 | ||
1318 | if (rt->rt_key_dst != daddr || | 1336 | if (rt->rt_key_dst != daddr || |
@@ -1322,21 +1340,10 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1322 | rt_is_expired(rt) || | 1340 | rt_is_expired(rt) || |
1323 | !net_eq(dev_net(rt->dst.dev), net) || | 1341 | !net_eq(dev_net(rt->dst.dev), net) || |
1324 | rt->dst.error || | 1342 | rt->dst.error || |
1325 | rt->dst.dev != dev || | 1343 | rt->dst.dev != dev) |
1326 | rt->rt_gateway != old_gw) | ||
1327 | continue; | 1344 | continue; |
1328 | 1345 | ||
1329 | n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); | 1346 | ip_do_redirect(rt, old_gw, new_gw); |
1330 | if (n) { | ||
1331 | if (!(n->nud_state & NUD_VALID)) { | ||
1332 | neigh_event_send(n, NULL); | ||
1333 | } else { | ||
1334 | rt->rt_gateway = new_gw; | ||
1335 | rt->rt_flags |= RTCF_REDIRECTED; | ||
1336 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); | ||
1337 | } | ||
1338 | neigh_release(n); | ||
1339 | } | ||
1340 | } | 1347 | } |
1341 | } | 1348 | } |
1342 | } | 1349 | } |