diff options
Diffstat (limited to 'net/ipv4/route.c')
| -rw-r--r-- | net/ipv4/route.c | 24 | 
1 files changed, 13 insertions, 11 deletions
| diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1730689f560e..075212e41b83 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -109,6 +109,7 @@  #include <linux/sysctl.h>  #endif  #include <net/atmclip.h> +#include <net/secure_seq.h>  #define RT_FL_TOS(oldflp4) \      ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) @@ -721,7 +722,7 @@ static inline bool compare_hash_inputs(const struct rtable *rt1,  {  	return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) |  		((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | -		(rt1->rt_iif ^ rt2->rt_iif)) == 0); +		(rt1->rt_route_iif ^ rt2->rt_route_iif)) == 0);  }  static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) @@ -730,8 +731,8 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2)  		((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |  		(rt1->rt_mark ^ rt2->rt_mark) |  		(rt1->rt_key_tos ^ rt2->rt_key_tos) | -		(rt1->rt_oif ^ rt2->rt_oif) | -		(rt1->rt_iif ^ rt2->rt_iif)) == 0; +		(rt1->rt_route_iif ^ rt2->rt_route_iif) | +		(rt1->rt_oif ^ rt2->rt_oif)) == 0;  }  static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) @@ -1628,16 +1629,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)  {  	struct rtable *rt = (struct rtable *) dst;  	__be32 orig_gw = rt->rt_gateway; -	struct neighbour *n; +	struct neighbour *n, *old_n;  	dst_confirm(&rt->dst); -	neigh_release(dst_get_neighbour(&rt->dst)); -	dst_set_neighbour(&rt->dst, NULL); -  	rt->rt_gateway = peer->redirect_learned.a4; -	rt_bind_neighbour(rt); -	n = dst_get_neighbour(&rt->dst); + +	n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); +	if (IS_ERR(n)) +		return PTR_ERR(n); +	old_n = xchg(&rt->dst._neighbour, n); +	if (old_n) +		neigh_release(old_n);  	if (!n || !(n->nud_state & NUD_VALID)) {  		if (n)  			neigh_event_send(n, NULL); @@ -2317,8 +2320,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,  	     rth = rcu_dereference(rth->dst.rt_next)) {  		if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) |  		     ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | -		     (rth->rt_iif ^ iif) | -		     rth->rt_oif | +		     (rth->rt_route_iif ^ iif) |  		     (rth->rt_key_tos ^ tos)) == 0 &&  		    rth->rt_mark == skb->mark &&  		    net_eq(dev_net(rth->dst.dev), net) && | 
