aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-06 21:10:05 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-06 21:10:05 -0500
commit959327c7842e8621e28b89acea7d57ff02b60972 (patch)
treeb00de195fa401186228796abdcd16812862fbf4d /net/ipv4/route.c
parentf84ea779c25dabc90956f1c329e5e5c501ea96cc (diff)
parentb835c0f47f725d864bf2545f10c733b754bb6d51 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c47
1 files changed, 19 insertions, 28 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 90402a2a26a9..f30112f7559a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -111,7 +111,7 @@
111#include <net/secure_seq.h> 111#include <net/secure_seq.h>
112 112
113#define RT_FL_TOS(oldflp4) \ 113#define RT_FL_TOS(oldflp4) \
114 ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) 114 ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))
115 115
116#define IP_MAX_MTU 0xFFF0 116#define IP_MAX_MTU 0xFFF0
117 117
@@ -1304,7 +1304,7 @@ static void rt_del(unsigned hash, struct rtable *rt)
1304 spin_unlock_bh(rt_hash_lock_addr(hash)); 1304 spin_unlock_bh(rt_hash_lock_addr(hash));
1305} 1305}
1306 1306
1307static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) 1307static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
1308{ 1308{
1309 struct rtable *rt = (struct rtable *) dst; 1309 struct rtable *rt = (struct rtable *) dst;
1310 __be32 orig_gw = rt->rt_gateway; 1310 __be32 orig_gw = rt->rt_gateway;
@@ -1315,21 +1315,19 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
1315 rt->rt_gateway = peer->redirect_learned.a4; 1315 rt->rt_gateway = peer->redirect_learned.a4;
1316 1316
1317 n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); 1317 n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
1318 if (IS_ERR(n)) 1318 if (IS_ERR(n)) {
1319 return PTR_ERR(n); 1319 rt->rt_gateway = orig_gw;
1320 return;
1321 }
1320 old_n = xchg(&rt->dst._neighbour, n); 1322 old_n = xchg(&rt->dst._neighbour, n);
1321 if (old_n) 1323 if (old_n)
1322 neigh_release(old_n); 1324 neigh_release(old_n);
1323 if (!n || !(n->nud_state & NUD_VALID)) { 1325 if (!(n->nud_state & NUD_VALID)) {
1324 if (n) 1326 neigh_event_send(n, NULL);
1325 neigh_event_send(n, NULL);
1326 rt->rt_gateway = orig_gw;
1327 return -EAGAIN;
1328 } else { 1327 } else {
1329 rt->rt_flags |= RTCF_REDIRECTED; 1328 rt->rt_flags |= RTCF_REDIRECTED;
1330 call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); 1329 call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
1331 } 1330 }
1332 return 0;
1333} 1331}
1334 1332
1335/* called in rcu_read_lock() section */ 1333/* called in rcu_read_lock() section */
@@ -1687,7 +1685,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
1687} 1685}
1688 1686
1689 1687
1690static struct rtable *ipv4_validate_peer(struct rtable *rt) 1688static void ipv4_validate_peer(struct rtable *rt)
1691{ 1689{
1692 if (rt->rt_peer_genid != rt_peer_genid()) { 1690 if (rt->rt_peer_genid != rt_peer_genid()) {
1693 struct inet_peer *peer; 1691 struct inet_peer *peer;
@@ -1702,15 +1700,12 @@ static struct rtable *ipv4_validate_peer(struct rtable *rt)
1702 if (peer->redirect_genid != redirect_genid) 1700 if (peer->redirect_genid != redirect_genid)
1703 peer->redirect_learned.a4 = 0; 1701 peer->redirect_learned.a4 = 0;
1704 if (peer->redirect_learned.a4 && 1702 if (peer->redirect_learned.a4 &&
1705 peer->redirect_learned.a4 != rt->rt_gateway) { 1703 peer->redirect_learned.a4 != rt->rt_gateway)
1706 if (check_peer_redir(&rt->dst, peer)) 1704 check_peer_redir(&rt->dst, peer);
1707 return NULL;
1708 }
1709 } 1705 }
1710 1706
1711 rt->rt_peer_genid = rt_peer_genid(); 1707 rt->rt_peer_genid = rt_peer_genid();
1712 } 1708 }
1713 return rt;
1714} 1709}
1715 1710
1716static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) 1711static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
@@ -1719,7 +1714,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
1719 1714
1720 if (rt_is_expired(rt)) 1715 if (rt_is_expired(rt))
1721 return NULL; 1716 return NULL;
1722 dst = (struct dst_entry *) ipv4_validate_peer(rt); 1717 ipv4_validate_peer(rt);
1723 return dst; 1718 return dst;
1724} 1719}
1725 1720
@@ -2374,9 +2369,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2374 rth->rt_mark == skb->mark && 2369 rth->rt_mark == skb->mark &&
2375 net_eq(dev_net(rth->dst.dev), net) && 2370 net_eq(dev_net(rth->dst.dev), net) &&
2376 !rt_is_expired(rth)) { 2371 !rt_is_expired(rth)) {
2377 rth = ipv4_validate_peer(rth); 2372 ipv4_validate_peer(rth);
2378 if (!rth)
2379 continue;
2380 if (noref) { 2373 if (noref) {
2381 dst_use_noref(&rth->dst, jiffies); 2374 dst_use_noref(&rth->dst, jiffies);
2382 skb_dst_set_noref(skb, &rth->dst); 2375 skb_dst_set_noref(skb, &rth->dst);
@@ -2435,11 +2428,11 @@ EXPORT_SYMBOL(ip_route_input_common);
2435static struct rtable *__mkroute_output(const struct fib_result *res, 2428static struct rtable *__mkroute_output(const struct fib_result *res,
2436 const struct flowi4 *fl4, 2429 const struct flowi4 *fl4,
2437 __be32 orig_daddr, __be32 orig_saddr, 2430 __be32 orig_daddr, __be32 orig_saddr,
2438 int orig_oif, struct net_device *dev_out, 2431 int orig_oif, __u8 orig_rtos,
2432 struct net_device *dev_out,
2439 unsigned int flags) 2433 unsigned int flags)
2440{ 2434{
2441 struct fib_info *fi = res->fi; 2435 struct fib_info *fi = res->fi;
2442 u32 tos = RT_FL_TOS(fl4);
2443 struct in_device *in_dev; 2436 struct in_device *in_dev;
2444 u16 type = res->type; 2437 u16 type = res->type;
2445 struct rtable *rth; 2438 struct rtable *rth;
@@ -2490,7 +2483,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
2490 rth->rt_genid = rt_genid(dev_net(dev_out)); 2483 rth->rt_genid = rt_genid(dev_net(dev_out));
2491 rth->rt_flags = flags; 2484 rth->rt_flags = flags;
2492 rth->rt_type = type; 2485 rth->rt_type = type;
2493 rth->rt_key_tos = tos; 2486 rth->rt_key_tos = orig_rtos;
2494 rth->rt_dst = fl4->daddr; 2487 rth->rt_dst = fl4->daddr;
2495 rth->rt_src = fl4->saddr; 2488 rth->rt_src = fl4->saddr;
2496 rth->rt_route_iif = 0; 2489 rth->rt_route_iif = 0;
@@ -2540,7 +2533,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
2540static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) 2533static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
2541{ 2534{
2542 struct net_device *dev_out = NULL; 2535 struct net_device *dev_out = NULL;
2543 u32 tos = RT_FL_TOS(fl4); 2536 __u8 tos = RT_FL_TOS(fl4);
2544 unsigned int flags = 0; 2537 unsigned int flags = 0;
2545 struct fib_result res; 2538 struct fib_result res;
2546 struct rtable *rth; 2539 struct rtable *rth;
@@ -2716,7 +2709,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
2716 2709
2717make_route: 2710make_route:
2718 rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif, 2711 rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif,
2719 dev_out, flags); 2712 tos, dev_out, flags);
2720 if (!IS_ERR(rth)) { 2713 if (!IS_ERR(rth)) {
2721 unsigned int hash; 2714 unsigned int hash;
2722 2715
@@ -2752,9 +2745,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4)
2752 (IPTOS_RT_MASK | RTO_ONLINK)) && 2745 (IPTOS_RT_MASK | RTO_ONLINK)) &&
2753 net_eq(dev_net(rth->dst.dev), net) && 2746 net_eq(dev_net(rth->dst.dev), net) &&
2754 !rt_is_expired(rth)) { 2747 !rt_is_expired(rth)) {
2755 rth = ipv4_validate_peer(rth); 2748 ipv4_validate_peer(rth);
2756 if (!rth)
2757 continue;
2758 dst_use(&rth->dst, jiffies); 2749 dst_use(&rth->dst, jiffies);
2759 RT_CACHE_STAT_INC(out_hit); 2750 RT_CACHE_STAT_INC(out_hit);
2760 rcu_read_unlock_bh(); 2751 rcu_read_unlock_bh();