aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-12 03:33:37 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-12 03:33:37 -0400
commitb94f1c0904da9b8bf031667afc48080ba7c3e8c9 (patch)
treeebf088c677a9b930d43e4961e14722e2ca1adbe6 /net/ipv6
parentec18d9a2691d69cd14b48f9b919fddcef28b7f5c (diff)
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>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/ipv6/route.c107
3 files changed, 2 insertions, 109 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index a113f7d7e938..24d69dbca4d6 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -598,7 +598,7 @@ out:
598 icmpv6_xmit_unlock(sk); 598 icmpv6_xmit_unlock(sk);
599} 599}
600 600
601static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) 601void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
602{ 602{
603 const struct inet6_protocol *ipprot; 603 const struct inet6_protocol *ipprot;
604 int inner_offset; 604 int inner_offset;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index b8d53e186a78..ff36194a71aa 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1350,7 +1350,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
1350 return; 1350 return;
1351 } 1351 }
1352 1352
1353 rt6_redirect(skb); 1353 icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
1354} 1354}
1355 1355
1356void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) 1356void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f52cf83bb1e0..7296af144d6c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1633,92 +1633,6 @@ static int ip6_route_del(struct fib6_config *cfg)
1633 return err; 1633 return err;
1634} 1634}
1635 1635
1636/*
1637 * Handle redirects
1638 */
1639struct ip6rd_flowi {
1640 struct flowi6 fl6;
1641 struct in6_addr gateway;
1642};
1643
1644static struct rt6_info *__ip6_route_redirect(struct net *net,
1645 struct fib6_table *table,
1646 struct flowi6 *fl6,
1647 int flags)
1648{
1649 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
1650 struct rt6_info *rt;
1651 struct fib6_node *fn;
1652
1653 /*
1654 * Get the "current" route for this destination and
1655 * check if the redirect has come from approriate router.
1656 *
1657 * RFC 2461 specifies that redirects should only be
1658 * accepted if they come from the nexthop to the target.
1659 * Due to the way the routes are chosen, this notion
1660 * is a bit fuzzy and one might need to check all possible
1661 * routes.
1662 */
1663
1664 read_lock_bh(&table->tb6_lock);
1665 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
1666restart:
1667 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
1668 /*
1669 * Current route is on-link; redirect is always invalid.
1670 *
1671 * Seems, previous statement is not true. It could
1672 * be node, which looks for us as on-link (f.e. proxy ndisc)
1673 * But then router serving it might decide, that we should
1674 * know truth 8)8) --ANK (980726).
1675 */
1676 if (rt6_check_expired(rt))
1677 continue;
1678 if (!(rt->rt6i_flags & RTF_GATEWAY))
1679 continue;
1680 if (fl6->flowi6_oif != rt->dst.dev->ifindex)
1681 continue;
1682 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
1683 continue;
1684 break;
1685 }
1686
1687 if (!rt)
1688 rt = net->ipv6.ip6_null_entry;
1689 BACKTRACK(net, &fl6->saddr);
1690out:
1691 dst_hold(&rt->dst);
1692
1693 read_unlock_bh(&table->tb6_lock);
1694
1695 return rt;
1696};
1697
1698static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest,
1699 const struct in6_addr *src,
1700 const struct in6_addr *gateway,
1701 struct net_device *dev)
1702{
1703 int flags = RT6_LOOKUP_F_HAS_SADDR;
1704 struct net *net = dev_net(dev);
1705 struct ip6rd_flowi rdfl = {
1706 .fl6 = {
1707 .flowi6_oif = dev->ifindex,
1708 .daddr = *dest,
1709 .saddr = *src,
1710 },
1711 };
1712
1713 rdfl.gateway = *gateway;
1714
1715 if (rt6_need_strict(dest))
1716 flags |= RT6_LOOKUP_F_IFACE;
1717
1718 return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6,
1719 flags, __ip6_route_redirect);
1720}
1721
1722static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb) 1636static void rt6_do_redirect(struct dst_entry *dst, struct sk_buff *skb)
1723{ 1637{
1724 struct net *net = dev_net(skb->dev); 1638 struct net *net = dev_net(skb->dev);
@@ -1848,27 +1762,6 @@ out:
1848 neigh_release(neigh); 1762 neigh_release(neigh);
1849} 1763}
1850 1764
1851void rt6_redirect(struct sk_buff *skb)
1852{
1853 const struct in6_addr *target;
1854 const struct in6_addr *dest;
1855 const struct in6_addr *src;
1856 const struct in6_addr *saddr;
1857 struct icmp6hdr *icmph;
1858 struct rt6_info *rt;
1859
1860 icmph = icmp6_hdr(skb);
1861 target = (const struct in6_addr *) (icmph + 1);
1862 dest = target + 1;
1863
1864 src = &ipv6_hdr(skb)->daddr;
1865 saddr = &ipv6_hdr(skb)->saddr;
1866
1867 rt = ip6_route_redirect(dest, src, saddr, skb->dev);
1868 rt6_do_redirect(&rt->dst, skb);
1869 dst_release(&rt->dst);
1870}
1871
1872/* 1765/*
1873 * Misc support functions 1766 * Misc support functions
1874 */ 1767 */