diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 63 |
1 files changed, 24 insertions, 39 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d6fe7646a8ff..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) { |
@@ -1471,9 +1470,10 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, | |||
1471 | }, | 1470 | }, |
1472 | }, | 1471 | }, |
1473 | }, | 1472 | }, |
1474 | .gateway = *gateway, | ||
1475 | }; | 1473 | }; |
1476 | 1474 | ||
1475 | ipv6_addr_copy(&rdfl.gateway, gateway); | ||
1476 | |||
1477 | if (rt6_need_strict(dest)) | 1477 | if (rt6_need_strict(dest)) |
1478 | flags |= RT6_LOOKUP_F_IFACE; | 1478 | flags |= RT6_LOOKUP_F_IFACE; |
1479 | 1479 | ||
@@ -1872,7 +1872,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) | |||
1872 | switch (ipstats_mib_noroutes) { | 1872 | switch (ipstats_mib_noroutes) { |
1873 | case IPSTATS_MIB_INNOROUTES: | 1873 | case IPSTATS_MIB_INNOROUTES: |
1874 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); | 1874 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); |
1875 | if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { | 1875 | if (type == IPV6_ADDR_ANY) { |
1876 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), | 1876 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), |
1877 | IPSTATS_MIB_INADDRERRORS); | 1877 | IPSTATS_MIB_INADDRERRORS); |
1878 | break; | 1878 | break; |
@@ -1883,7 +1883,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) | |||
1883 | ipstats_mib_noroutes); | 1883 | ipstats_mib_noroutes); |
1884 | break; | 1884 | break; |
1885 | } | 1885 | } |
1886 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); | 1886 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0); |
1887 | kfree_skb(skb); | 1887 | kfree_skb(skb); |
1888 | return 0; | 1888 | return 0; |
1889 | } | 1889 | } |
@@ -2546,7 +2546,6 @@ ctl_table ipv6_route_table_template[] = { | |||
2546 | .proc_handler = ipv6_sysctl_rtcache_flush | 2546 | .proc_handler = ipv6_sysctl_rtcache_flush |
2547 | }, | 2547 | }, |
2548 | { | 2548 | { |
2549 | .ctl_name = NET_IPV6_ROUTE_GC_THRESH, | ||
2550 | .procname = "gc_thresh", | 2549 | .procname = "gc_thresh", |
2551 | .data = &ip6_dst_ops_template.gc_thresh, | 2550 | .data = &ip6_dst_ops_template.gc_thresh, |
2552 | .maxlen = sizeof(int), | 2551 | .maxlen = sizeof(int), |
@@ -2554,7 +2553,6 @@ ctl_table ipv6_route_table_template[] = { | |||
2554 | .proc_handler = proc_dointvec, | 2553 | .proc_handler = proc_dointvec, |
2555 | }, | 2554 | }, |
2556 | { | 2555 | { |
2557 | .ctl_name = NET_IPV6_ROUTE_MAX_SIZE, | ||
2558 | .procname = "max_size", | 2556 | .procname = "max_size", |
2559 | .data = &init_net.ipv6.sysctl.ip6_rt_max_size, | 2557 | .data = &init_net.ipv6.sysctl.ip6_rt_max_size, |
2560 | .maxlen = sizeof(int), | 2558 | .maxlen = sizeof(int), |
@@ -2562,72 +2560,58 @@ ctl_table ipv6_route_table_template[] = { | |||
2562 | .proc_handler = proc_dointvec, | 2560 | .proc_handler = proc_dointvec, |
2563 | }, | 2561 | }, |
2564 | { | 2562 | { |
2565 | .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL, | ||
2566 | .procname = "gc_min_interval", | 2563 | .procname = "gc_min_interval", |
2567 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, | 2564 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, |
2568 | .maxlen = sizeof(int), | 2565 | .maxlen = sizeof(int), |
2569 | .mode = 0644, | 2566 | .mode = 0644, |
2570 | .proc_handler = proc_dointvec_jiffies, | 2567 | .proc_handler = proc_dointvec_jiffies, |
2571 | .strategy = sysctl_jiffies, | ||
2572 | }, | 2568 | }, |
2573 | { | 2569 | { |
2574 | .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT, | ||
2575 | .procname = "gc_timeout", | 2570 | .procname = "gc_timeout", |
2576 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout, | 2571 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout, |
2577 | .maxlen = sizeof(int), | 2572 | .maxlen = sizeof(int), |
2578 | .mode = 0644, | 2573 | .mode = 0644, |
2579 | .proc_handler = proc_dointvec_jiffies, | 2574 | .proc_handler = proc_dointvec_jiffies, |
2580 | .strategy = sysctl_jiffies, | ||
2581 | }, | 2575 | }, |
2582 | { | 2576 | { |
2583 | .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL, | ||
2584 | .procname = "gc_interval", | 2577 | .procname = "gc_interval", |
2585 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval, | 2578 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval, |
2586 | .maxlen = sizeof(int), | 2579 | .maxlen = sizeof(int), |
2587 | .mode = 0644, | 2580 | .mode = 0644, |
2588 | .proc_handler = proc_dointvec_jiffies, | 2581 | .proc_handler = proc_dointvec_jiffies, |
2589 | .strategy = sysctl_jiffies, | ||
2590 | }, | 2582 | }, |
2591 | { | 2583 | { |
2592 | .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY, | ||
2593 | .procname = "gc_elasticity", | 2584 | .procname = "gc_elasticity", |
2594 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity, | 2585 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity, |
2595 | .maxlen = sizeof(int), | 2586 | .maxlen = sizeof(int), |
2596 | .mode = 0644, | 2587 | .mode = 0644, |
2597 | .proc_handler = proc_dointvec_jiffies, | 2588 | .proc_handler = proc_dointvec_jiffies, |
2598 | .strategy = sysctl_jiffies, | ||
2599 | }, | 2589 | }, |
2600 | { | 2590 | { |
2601 | .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES, | ||
2602 | .procname = "mtu_expires", | 2591 | .procname = "mtu_expires", |
2603 | .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires, | 2592 | .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires, |
2604 | .maxlen = sizeof(int), | 2593 | .maxlen = sizeof(int), |
2605 | .mode = 0644, | 2594 | .mode = 0644, |
2606 | .proc_handler = proc_dointvec_jiffies, | 2595 | .proc_handler = proc_dointvec_jiffies, |
2607 | .strategy = sysctl_jiffies, | ||
2608 | }, | 2596 | }, |
2609 | { | 2597 | { |
2610 | .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS, | ||
2611 | .procname = "min_adv_mss", | 2598 | .procname = "min_adv_mss", |
2612 | .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss, | 2599 | .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss, |
2613 | .maxlen = sizeof(int), | 2600 | .maxlen = sizeof(int), |
2614 | .mode = 0644, | 2601 | .mode = 0644, |
2615 | .proc_handler = proc_dointvec_jiffies, | 2602 | .proc_handler = proc_dointvec_jiffies, |
2616 | .strategy = sysctl_jiffies, | ||
2617 | }, | 2603 | }, |
2618 | { | 2604 | { |
2619 | .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, | ||
2620 | .procname = "gc_min_interval_ms", | 2605 | .procname = "gc_min_interval_ms", |
2621 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, | 2606 | .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval, |
2622 | .maxlen = sizeof(int), | 2607 | .maxlen = sizeof(int), |
2623 | .mode = 0644, | 2608 | .mode = 0644, |
2624 | .proc_handler = proc_dointvec_ms_jiffies, | 2609 | .proc_handler = proc_dointvec_ms_jiffies, |
2625 | .strategy = sysctl_ms_jiffies, | ||
2626 | }, | 2610 | }, |
2627 | { .ctl_name = 0 } | 2611 | { } |
2628 | }; | 2612 | }; |
2629 | 2613 | ||
2630 | struct ctl_table *ipv6_route_sysctl_init(struct net *net) | 2614 | struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net) |
2631 | { | 2615 | { |
2632 | struct ctl_table *table; | 2616 | struct ctl_table *table; |
2633 | 2617 | ||
@@ -2645,13 +2629,14 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) | |||
2645 | table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity; | 2629 | table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity; |
2646 | table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires; | 2630 | table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires; |
2647 | table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss; | 2631 | table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss; |
2632 | table[9].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; | ||
2648 | } | 2633 | } |
2649 | 2634 | ||
2650 | return table; | 2635 | return table; |
2651 | } | 2636 | } |
2652 | #endif | 2637 | #endif |
2653 | 2638 | ||
2654 | static int ip6_route_net_init(struct net *net) | 2639 | static int __net_init ip6_route_net_init(struct net *net) |
2655 | { | 2640 | { |
2656 | int ret = -ENOMEM; | 2641 | int ret = -ENOMEM; |
2657 | 2642 | ||
@@ -2716,7 +2701,7 @@ out_ip6_dst_ops: | |||
2716 | goto out; | 2701 | goto out; |
2717 | } | 2702 | } |
2718 | 2703 | ||
2719 | static void ip6_route_net_exit(struct net *net) | 2704 | static void __net_exit ip6_route_net_exit(struct net *net) |
2720 | { | 2705 | { |
2721 | #ifdef CONFIG_PROC_FS | 2706 | #ifdef CONFIG_PROC_FS |
2722 | proc_net_remove(net, "ipv6_route"); | 2707 | proc_net_remove(net, "ipv6_route"); |