diff options
author | David S. Miller <davem@davemloft.net> | 2011-12-06 21:10:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-06 21:10:05 -0500 |
commit | 959327c7842e8621e28b89acea7d57ff02b60972 (patch) | |
tree | b00de195fa401186228796abdcd16812862fbf4d /net/ipv4/route.c | |
parent | f84ea779c25dabc90956f1c329e5e5c501ea96cc (diff) | |
parent | b835c0f47f725d864bf2545f10c733b754bb6d51 (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.c | 47 |
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 | ||
1307 | static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | 1307 | static 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 | ||
1690 | static struct rtable *ipv4_validate_peer(struct rtable *rt) | 1688 | static 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 | ||
1716 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | 1711 | static 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); | |||
2435 | static struct rtable *__mkroute_output(const struct fib_result *res, | 2428 | static 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, | |||
2540 | static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) | 2533 | static 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 | ||
2717 | make_route: | 2710 | make_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(); |