aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c2bd74c5f8d9..05ebd7833043 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -40,6 +40,7 @@
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h> 41#include <linux/seq_file.h>
42#include <linux/nsproxy.h> 42#include <linux/nsproxy.h>
43#include <linux/slab.h>
43#include <net/net_namespace.h> 44#include <net/net_namespace.h>
44#include <net/snmp.h> 45#include <net/snmp.h>
45#include <net/ipv6.h> 46#include <net/ipv6.h>
@@ -814,20 +815,13 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
814{ 815{
815 int flags = 0; 816 int flags = 0;
816 817
817 if (rt6_need_strict(&fl->fl6_dst)) 818 if (fl->oif || rt6_need_strict(&fl->fl6_dst))
818 flags |= RT6_LOOKUP_F_IFACE; 819 flags |= RT6_LOOKUP_F_IFACE;
819 820
820 if (!ipv6_addr_any(&fl->fl6_src)) 821 if (!ipv6_addr_any(&fl->fl6_src))
821 flags |= RT6_LOOKUP_F_HAS_SADDR; 822 flags |= RT6_LOOKUP_F_HAS_SADDR;
822 else if (sk) { 823 else if (sk)
823 unsigned int prefs = inet6_sk(sk)->srcprefs; 824 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
824 if (prefs & IPV6_PREFER_SRC_TMP)
825 flags |= RT6_LOOKUP_F_SRCPREF_TMP;
826 if (prefs & IPV6_PREFER_SRC_PUBLIC)
827 flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC;
828 if (prefs & IPV6_PREFER_SRC_COA)
829 flags |= RT6_LOOKUP_F_SRCPREF_COA;
830 }
831 825
832 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); 826 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
833} 827}
@@ -886,7 +880,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
886 880
887 rt = (struct rt6_info *) dst; 881 rt = (struct rt6_info *) dst;
888 882
889 if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) 883 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
890 return dst; 884 return dst;
891 885
892 return NULL; 886 return NULL;
@@ -897,19 +891,24 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
897 struct rt6_info *rt = (struct rt6_info *) dst; 891 struct rt6_info *rt = (struct rt6_info *) dst;
898 892
899 if (rt) { 893 if (rt) {
900 if (rt->rt6i_flags & RTF_CACHE) 894 if (rt->rt6i_flags & RTF_CACHE) {
901 ip6_del_rt(rt); 895 if (rt6_check_expired(rt)) {
902 else 896 ip6_del_rt(rt);
897 dst = NULL;
898 }
899 } else {
903 dst_release(dst); 900 dst_release(dst);
901 dst = NULL;
902 }
904 } 903 }
905 return NULL; 904 return dst;
906} 905}
907 906
908static void ip6_link_failure(struct sk_buff *skb) 907static void ip6_link_failure(struct sk_buff *skb)
909{ 908{
910 struct rt6_info *rt; 909 struct rt6_info *rt;
911 910
912 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); 911 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
913 912
914 rt = (struct rt6_info *) skb_dst(skb); 913 rt = (struct rt6_info *) skb_dst(skb);
915 if (rt) { 914 if (rt) {
@@ -1873,7 +1872,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
1873 switch (ipstats_mib_noroutes) { 1872 switch (ipstats_mib_noroutes) {
1874 case IPSTATS_MIB_INNOROUTES: 1873 case IPSTATS_MIB_INNOROUTES:
1875 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); 1874 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
1876 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { 1875 if (type == IPV6_ADDR_ANY) {
1877 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), 1876 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
1878 IPSTATS_MIB_INADDRERRORS); 1877 IPSTATS_MIB_INADDRERRORS);
1879 break; 1878 break;
@@ -1884,7 +1883,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
1884 ipstats_mib_noroutes); 1883 ipstats_mib_noroutes);
1885 break; 1884 break;
1886 } 1885 }
1887 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1886 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0);
1888 kfree_skb(skb); 1887 kfree_skb(skb);
1889 return 0; 1888 return 0;
1890} 1889}
@@ -2612,7 +2611,7 @@ ctl_table ipv6_route_table_template[] = {
2612 { } 2611 { }
2613}; 2612};
2614 2613
2615struct ctl_table *ipv6_route_sysctl_init(struct net *net) 2614struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
2616{ 2615{
2617 struct ctl_table *table; 2616 struct ctl_table *table;
2618 2617
@@ -2637,7 +2636,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
2637} 2636}
2638#endif 2637#endif
2639 2638
2640static int ip6_route_net_init(struct net *net) 2639static int __net_init ip6_route_net_init(struct net *net)
2641{ 2640{
2642 int ret = -ENOMEM; 2641 int ret = -ENOMEM;
2643 2642
@@ -2702,7 +2701,7 @@ out_ip6_dst_ops:
2702 goto out; 2701 goto out;
2703} 2702}
2704 2703
2705static void ip6_route_net_exit(struct net *net) 2704static void __net_exit ip6_route_net_exit(struct net *net)
2706{ 2705{
2707#ifdef CONFIG_PROC_FS 2706#ifdef CONFIG_PROC_FS
2708 proc_net_remove(net, "ipv6_route"); 2707 proc_net_remove(net, "ipv6_route");