diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 41 |
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 | ||
908 | static void ip6_link_failure(struct sk_buff *skb) | 907 | static 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 | ||
2615 | struct ctl_table *ipv6_route_sysctl_init(struct net *net) | 2614 | struct 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 | ||
2640 | static int ip6_route_net_init(struct net *net) | 2639 | static 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 | ||
2705 | static void ip6_route_net_exit(struct net *net) | 2704 | static 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"); |