diff options
author | David S. Miller <davem@davemloft.net> | 2011-10-24 18:18:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-24 18:18:09 -0400 |
commit | 1805b2f04855f07afe3a71d620a68f483b0ed74f (patch) | |
tree | b823b90f37f5404fcaef70f785c70112ca74a329 /net/ipv4/route.c | |
parent | 78d81d15b74246c7cedf84894434890b33da3907 (diff) | |
parent | f42af6c486aa5ca6ee62800cb45c5b252020509d (diff) |
Merge branch 'master' of ra.kernel.org:/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 26c77e14395f..1082460daca7 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1308,7 +1308,12 @@ static void rt_del(unsigned hash, struct rtable *rt) | |||
1308 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | 1308 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, |
1309 | __be32 saddr, struct net_device *dev) | 1309 | __be32 saddr, struct net_device *dev) |
1310 | { | 1310 | { |
1311 | int s, i; | ||
1311 | struct in_device *in_dev = __in_dev_get_rcu(dev); | 1312 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
1313 | struct rtable *rt; | ||
1314 | __be32 skeys[2] = { saddr, 0 }; | ||
1315 | int ikeys[2] = { dev->ifindex, 0 }; | ||
1316 | struct flowi4 fl4; | ||
1312 | struct inet_peer *peer; | 1317 | struct inet_peer *peer; |
1313 | struct net *net; | 1318 | struct net *net; |
1314 | 1319 | ||
@@ -1331,13 +1336,34 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1331 | goto reject_redirect; | 1336 | goto reject_redirect; |
1332 | } | 1337 | } |
1333 | 1338 | ||
1334 | peer = inet_getpeer_v4(daddr, 1); | 1339 | memset(&fl4, 0, sizeof(fl4)); |
1335 | if (peer) { | 1340 | fl4.daddr = daddr; |
1336 | peer->redirect_learned.a4 = new_gw; | 1341 | for (s = 0; s < 2; s++) { |
1342 | for (i = 0; i < 2; i++) { | ||
1343 | fl4.flowi4_oif = ikeys[i]; | ||
1344 | fl4.saddr = skeys[s]; | ||
1345 | rt = __ip_route_output_key(net, &fl4); | ||
1346 | if (IS_ERR(rt)) | ||
1347 | continue; | ||
1337 | 1348 | ||
1338 | inet_putpeer(peer); | 1349 | if (rt->dst.error || rt->dst.dev != dev || |
1350 | rt->rt_gateway != old_gw) { | ||
1351 | ip_rt_put(rt); | ||
1352 | continue; | ||
1353 | } | ||
1339 | 1354 | ||
1340 | atomic_inc(&__rt_peer_genid); | 1355 | if (!rt->peer) |
1356 | rt_bind_peer(rt, rt->rt_dst, 1); | ||
1357 | |||
1358 | peer = rt->peer; | ||
1359 | if (peer) { | ||
1360 | peer->redirect_learned.a4 = new_gw; | ||
1361 | atomic_inc(&__rt_peer_genid); | ||
1362 | } | ||
1363 | |||
1364 | ip_rt_put(rt); | ||
1365 | return; | ||
1366 | } | ||
1341 | } | 1367 | } |
1342 | return; | 1368 | return; |
1343 | 1369 | ||