aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-11 23:27:54 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-11 23:27:54 -0400
commitd0da720f9f16a5023cc084bed8968702400f6e0f (patch)
tree4bdc0aa45aff71805d2db1bcd89c3c52a272d18f /net/ipv4
parentd3351b75a7169337877fe6f6f2c019154b6ec1ea (diff)
ipv4: Pull redirect instantiation out into a helper function.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/route.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 95bfa1ba5b2..a4de87f44c3 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
1274static 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 */
1275void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, 1295void 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 }