forked from mirrors/linux
		
	ipv6: Use icmpv6_notify() to propagate redirect, instead of rt6_redirect().
And delete rt6_redirect(), since it is no longer used. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									ec18d9a269
								
							
						
					
					
						commit
						b94f1c0904
					
				
					 5 changed files with 4 additions and 111 deletions
				
			
		| 
						 | 
					@ -133,8 +133,6 @@ extern int			rt6_route_rcv(struct net_device *dev,
 | 
				
			||||||
					      u8 *opt, int len,
 | 
										      u8 *opt, int len,
 | 
				
			||||||
					      const struct in6_addr *gwaddr);
 | 
										      const struct in6_addr *gwaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void			rt6_redirect(struct sk_buff *skb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
 | 
					extern void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
 | 
				
			||||||
			    int oif, u32 mark);
 | 
								    int oif, u32 mark);
 | 
				
			||||||
extern void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk,
 | 
					extern void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,6 +251,8 @@ static inline void fl6_sock_release(struct ip6_flowlabel *fl)
 | 
				
			||||||
		atomic_dec(&fl->users);
 | 
							atomic_dec(&fl->users);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int 			ip6_ra_control(struct sock *sk, int sel);
 | 
					extern int 			ip6_ra_control(struct sock *sk, int sel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int			ipv6_parse_hopopts(struct sk_buff *skb);
 | 
					extern int			ipv6_parse_hopopts(struct sk_buff *skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -598,7 +598,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 | 
				
			||||||
	icmpv6_xmit_unlock(sk);
 | 
						icmpv6_xmit_unlock(sk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
 | 
					void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct inet6_protocol *ipprot;
 | 
						const struct inet6_protocol *ipprot;
 | 
				
			||||||
	int inner_offset;
 | 
						int inner_offset;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1350,7 +1350,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt6_redirect(skb);
 | 
						icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 | 
					void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										107
									
								
								net/ipv6/route.c
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								net/ipv6/route.c
									
									
									
									
									
								
							| 
						 | 
					@ -1633,92 +1633,6 @@ static int ip6_route_del(struct fib6_config *cfg)
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *	Handle redirects
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct ip6rd_flowi {
 | 
					 | 
				
			||||||
	struct flowi6 fl6;
 | 
					 | 
				
			||||||
	struct in6_addr gateway;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct rt6_info *__ip6_route_redirect(struct net *net,
 | 
					 | 
				
			||||||
					     struct fib6_table *table,
 | 
					 | 
				
			||||||
					     struct flowi6 *fl6,
 | 
					 | 
				
			||||||
					     int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
 | 
					 | 
				
			||||||
	struct rt6_info *rt;
 | 
					 | 
				
			||||||
	struct fib6_node *fn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Get the "current" route for this destination and
 | 
					 | 
				
			||||||
	 * check if the redirect has come from approriate router.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * RFC 2461 specifies that redirects should only be
 | 
					 | 
				
			||||||
	 * accepted if they come from the nexthop to the target.
 | 
					 | 
				
			||||||
	 * Due to the way the routes are chosen, this notion
 | 
					 | 
				
			||||||
	 * is a bit fuzzy and one might need to check all possible
 | 
					 | 
				
			||||||
	 * routes.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	read_lock_bh(&table->tb6_lock);
 | 
					 | 
				
			||||||
	fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
 | 
					 | 
				
			||||||
restart:
 | 
					 | 
				
			||||||
	for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Current route is on-link; redirect is always invalid.
 | 
					 | 
				
			||||||
		 *
 | 
					 | 
				
			||||||
		 * Seems, previous statement is not true. It could
 | 
					 | 
				
			||||||
		 * be node, which looks for us as on-link (f.e. proxy ndisc)
 | 
					 | 
				
			||||||
		 * But then router serving it might decide, that we should
 | 
					 | 
				
			||||||
		 * know truth 8)8) --ANK (980726).
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (rt6_check_expired(rt))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (!(rt->rt6i_flags & RTF_GATEWAY))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (fl6->flowi6_oif != rt->dst.dev->ifindex)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!rt)
 | 
					 | 
				
			||||||
		rt = net->ipv6.ip6_null_entry;
 | 
					 | 
				
			||||||
	BACKTRACK(net, &fl6->saddr);
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	dst_hold(&rt->dst);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	read_unlock_bh(&table->tb6_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rt;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest,
 | 
					 | 
				
			||||||
					   const struct in6_addr *src,
 | 
					 | 
				
			||||||
					   const struct in6_addr *gateway,
 | 
					 | 
				
			||||||
					   struct net_device *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int flags = RT6_LOOKUP_F_HAS_SADDR;
 | 
					 | 
				
			||||||
	struct net *net = dev_net(dev);
 | 
					 | 
				
			||||||
	struct ip6rd_flowi rdfl = {
 | 
					 | 
				
			||||||
		.fl6 = {
 | 
					 | 
				
			||||||
			.flowi6_oif = dev->ifindex,
 | 
					 | 
				
			||||||
			.daddr = *dest,
 | 
					 | 
				
			||||||
			.saddr = *src,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rdfl.gateway = *gateway;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (rt6_need_strict(dest))
 | 
					 | 
				
			||||||
		flags |= RT6_LOOKUP_F_IFACE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6,
 | 
					 | 
				
			||||||
						   flags, __ip6_route_redirect);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb)
 | 
					static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net *net = dev_net(skb->dev);
 | 
						struct net *net = dev_net(skb->dev);
 | 
				
			||||||
| 
						 | 
					@ -1848,27 +1762,6 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb)
 | 
				
			||||||
	neigh_release(neigh);
 | 
						neigh_release(neigh);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void rt6_redirect(struct sk_buff *skb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const struct in6_addr *target;
 | 
					 | 
				
			||||||
	const struct in6_addr *dest;
 | 
					 | 
				
			||||||
	const struct in6_addr *src;
 | 
					 | 
				
			||||||
	const struct in6_addr *saddr;
 | 
					 | 
				
			||||||
	struct icmp6hdr *icmph;
 | 
					 | 
				
			||||||
	struct rt6_info *rt;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	icmph = icmp6_hdr(skb);
 | 
					 | 
				
			||||||
	target = (const struct in6_addr *) (icmph + 1);
 | 
					 | 
				
			||||||
	dest = target + 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	src = &ipv6_hdr(skb)->daddr;
 | 
					 | 
				
			||||||
	saddr = &ipv6_hdr(skb)->saddr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rt = ip6_route_redirect(dest, src, saddr, skb->dev);
 | 
					 | 
				
			||||||
	rt6_do_redirect(&rt->dst, skb);
 | 
					 | 
				
			||||||
	dst_release(&rt->dst);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *	Misc support functions
 | 
					 *	Misc support functions
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue