Commit b94f1c09 authored by David S. Miller's avatar David S. Miller

ipv6: Use icmpv6_notify() to propagate redirect, instead of rt6_redirect().

And delete rt6_redirect(), since it is no longer used.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ec18d9a2
...@@ -133,8 +133,6 @@ extern int rt6_route_rcv(struct net_device *dev, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)
......
...@@ -1633,92 +1633,6 @@ static int ip6_route_del(struct fib6_config *cfg) ...@@ -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) ...@@ -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
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment