diff options
Diffstat (limited to 'net/ipv6/route.c')
| -rw-r--r-- | net/ipv6/route.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c2bd74c5f8d9..0d7713c5c206 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, | |||
| 819 | 819 | ||
| 820 | if (!ipv6_addr_any(&fl->fl6_src)) | 820 | if (!ipv6_addr_any(&fl->fl6_src)) |
| 821 | flags |= RT6_LOOKUP_F_HAS_SADDR; | 821 | flags |= RT6_LOOKUP_F_HAS_SADDR; |
| 822 | else if (sk) { | 822 | else if (sk) |
| 823 | unsigned int prefs = inet6_sk(sk)->srcprefs; | 823 | 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 | 824 | ||
| 832 | return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); | 825 | return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); |
| 833 | } | 826 | } |
| @@ -886,7 +879,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
| 886 | 879 | ||
| 887 | rt = (struct rt6_info *) dst; | 880 | rt = (struct rt6_info *) dst; |
| 888 | 881 | ||
| 889 | if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) | 882 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
| 890 | return dst; | 883 | return dst; |
| 891 | 884 | ||
| 892 | return NULL; | 885 | return NULL; |
| @@ -897,19 +890,24 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) | |||
| 897 | struct rt6_info *rt = (struct rt6_info *) dst; | 890 | struct rt6_info *rt = (struct rt6_info *) dst; |
| 898 | 891 | ||
| 899 | if (rt) { | 892 | if (rt) { |
| 900 | if (rt->rt6i_flags & RTF_CACHE) | 893 | if (rt->rt6i_flags & RTF_CACHE) { |
| 901 | ip6_del_rt(rt); | 894 | if (rt6_check_expired(rt)) { |
| 902 | else | 895 | ip6_del_rt(rt); |
| 896 | dst = NULL; | ||
| 897 | } | ||
| 898 | } else { | ||
| 903 | dst_release(dst); | 899 | dst_release(dst); |
| 900 | dst = NULL; | ||
| 901 | } | ||
| 904 | } | 902 | } |
| 905 | return NULL; | 903 | return dst; |
| 906 | } | 904 | } |
| 907 | 905 | ||
| 908 | static void ip6_link_failure(struct sk_buff *skb) | 906 | static void ip6_link_failure(struct sk_buff *skb) |
| 909 | { | 907 | { |
| 910 | struct rt6_info *rt; | 908 | struct rt6_info *rt; |
| 911 | 909 | ||
| 912 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); | 910 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); |
| 913 | 911 | ||
| 914 | rt = (struct rt6_info *) skb_dst(skb); | 912 | rt = (struct rt6_info *) skb_dst(skb); |
| 915 | if (rt) { | 913 | if (rt) { |
| @@ -1873,7 +1871,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) | |||
| 1873 | switch (ipstats_mib_noroutes) { | 1871 | switch (ipstats_mib_noroutes) { |
| 1874 | case IPSTATS_MIB_INNOROUTES: | 1872 | case IPSTATS_MIB_INNOROUTES: |
| 1875 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); | 1873 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); |
| 1876 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { | 1874 | if (type == IPV6_ADDR_ANY) { |
| 1877 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), | 1875 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), |
| 1878 | IPSTATS_MIB_INADDRERRORS); | 1876 | IPSTATS_MIB_INADDRERRORS); |
| 1879 | break; | 1877 | break; |
| @@ -1884,7 +1882,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) | |||
| 1884 | ipstats_mib_noroutes); | 1882 | ipstats_mib_noroutes); |
| 1885 | break; | 1883 | break; |
| 1886 | } | 1884 | } |
| 1887 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); | 1885 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0); |
| 1888 | kfree_skb(skb); | 1886 | kfree_skb(skb); |
| 1889 | return 0; | 1887 | return 0; |
| 1890 | } | 1888 | } |
| @@ -2612,7 +2610,7 @@ ctl_table ipv6_route_table_template[] = { | |||
| 2612 | { } | 2610 | { } |
| 2613 | }; | 2611 | }; |
| 2614 | 2612 | ||
| 2615 | struct ctl_table *ipv6_route_sysctl_init(struct net *net) | 2613 | struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net) |
| 2616 | { | 2614 | { |
| 2617 | struct ctl_table *table; | 2615 | struct ctl_table *table; |
| 2618 | 2616 | ||
| @@ -2637,7 +2635,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) | |||
| 2637 | } | 2635 | } |
| 2638 | #endif | 2636 | #endif |
| 2639 | 2637 | ||
| 2640 | static int ip6_route_net_init(struct net *net) | 2638 | static int __net_init ip6_route_net_init(struct net *net) |
| 2641 | { | 2639 | { |
| 2642 | int ret = -ENOMEM; | 2640 | int ret = -ENOMEM; |
| 2643 | 2641 | ||
| @@ -2702,7 +2700,7 @@ out_ip6_dst_ops: | |||
| 2702 | goto out; | 2700 | goto out; |
| 2703 | } | 2701 | } |
| 2704 | 2702 | ||
| 2705 | static void ip6_route_net_exit(struct net *net) | 2703 | static void __net_exit ip6_route_net_exit(struct net *net) |
| 2706 | { | 2704 | { |
| 2707 | #ifdef CONFIG_PROC_FS | 2705 | #ifdef CONFIG_PROC_FS |
| 2708 | proc_net_remove(net, "ipv6_route"); | 2706 | proc_net_remove(net, "ipv6_route"); |
