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.c367
1 files changed, 242 insertions, 125 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a998db6e7895..de2b1decd786 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -89,14 +89,44 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
89 89
90#ifdef CONFIG_IPV6_ROUTE_INFO 90#ifdef CONFIG_IPV6_ROUTE_INFO
91static struct rt6_info *rt6_add_route_info(struct net *net, 91static struct rt6_info *rt6_add_route_info(struct net *net,
92 struct in6_addr *prefix, int prefixlen, 92 const struct in6_addr *prefix, int prefixlen,
93 struct in6_addr *gwaddr, int ifindex, 93 const struct in6_addr *gwaddr, int ifindex,
94 unsigned pref); 94 unsigned pref);
95static struct rt6_info *rt6_get_route_info(struct net *net, 95static struct rt6_info *rt6_get_route_info(struct net *net,
96 struct in6_addr *prefix, int prefixlen, 96 const struct in6_addr *prefix, int prefixlen,
97 struct in6_addr *gwaddr, int ifindex); 97 const struct in6_addr *gwaddr, int ifindex);
98#endif 98#endif
99 99
100static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
101{
102 struct rt6_info *rt = (struct rt6_info *) dst;
103 struct inet_peer *peer;
104 u32 *p = NULL;
105
106 if (!rt->rt6i_peer)
107 rt6_bind_peer(rt, 1);
108
109 peer = rt->rt6i_peer;
110 if (peer) {
111 u32 *old_p = __DST_METRICS_PTR(old);
112 unsigned long prev, new;
113
114 p = peer->metrics;
115 if (inet_metrics_new(peer))
116 memcpy(p, old_p, sizeof(u32) * RTAX_MAX);
117
118 new = (unsigned long) p;
119 prev = cmpxchg(&dst->_metrics, old, new);
120
121 if (prev != old) {
122 p = __DST_METRICS_PTR(prev);
123 if (prev & DST_METRICS_READ_ONLY)
124 p = NULL;
125 }
126 }
127 return p;
128}
129
100static struct dst_ops ip6_dst_ops_template = { 130static struct dst_ops ip6_dst_ops_template = {
101 .family = AF_INET6, 131 .family = AF_INET6,
102 .protocol = cpu_to_be16(ETH_P_IPV6), 132 .protocol = cpu_to_be16(ETH_P_IPV6),
@@ -105,6 +135,7 @@ static struct dst_ops ip6_dst_ops_template = {
105 .check = ip6_dst_check, 135 .check = ip6_dst_check,
106 .default_advmss = ip6_default_advmss, 136 .default_advmss = ip6_default_advmss,
107 .default_mtu = ip6_default_mtu, 137 .default_mtu = ip6_default_mtu,
138 .cow_metrics = ipv6_cow_metrics,
108 .destroy = ip6_dst_destroy, 139 .destroy = ip6_dst_destroy,
109 .ifdown = ip6_dst_ifdown, 140 .ifdown = ip6_dst_ifdown,
110 .negative_advice = ip6_negative_advice, 141 .negative_advice = ip6_negative_advice,
@@ -122,6 +153,12 @@ static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
122{ 153{
123} 154}
124 155
156static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
157 unsigned long old)
158{
159 return NULL;
160}
161
125static struct dst_ops ip6_dst_blackhole_ops = { 162static struct dst_ops ip6_dst_blackhole_ops = {
126 .family = AF_INET6, 163 .family = AF_INET6,
127 .protocol = cpu_to_be16(ETH_P_IPV6), 164 .protocol = cpu_to_be16(ETH_P_IPV6),
@@ -130,6 +167,11 @@ static struct dst_ops ip6_dst_blackhole_ops = {
130 .default_mtu = ip6_blackhole_default_mtu, 167 .default_mtu = ip6_blackhole_default_mtu,
131 .default_advmss = ip6_default_advmss, 168 .default_advmss = ip6_default_advmss,
132 .update_pmtu = ip6_rt_blackhole_update_pmtu, 169 .update_pmtu = ip6_rt_blackhole_update_pmtu,
170 .cow_metrics = ip6_rt_blackhole_cow_metrics,
171};
172
173static const u32 ip6_template_metrics[RTAX_MAX] = {
174 [RTAX_HOPLIMIT - 1] = 255,
133}; 175};
134 176
135static struct rt6_info ip6_null_entry_template = { 177static struct rt6_info ip6_null_entry_template = {
@@ -185,9 +227,14 @@ static struct rt6_info ip6_blk_hole_entry_template = {
185#endif 227#endif
186 228
187/* allocate dst with ip6_dst_ops */ 229/* allocate dst with ip6_dst_ops */
188static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops) 230static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
231 struct net_device *dev)
189{ 232{
190 return (struct rt6_info *)dst_alloc(ops); 233 struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0);
234
235 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
236
237 return rt;
191} 238}
192 239
193static void ip6_dst_destroy(struct dst_entry *dst) 240static void ip6_dst_destroy(struct dst_entry *dst)
@@ -206,6 +253,13 @@ static void ip6_dst_destroy(struct dst_entry *dst)
206 } 253 }
207} 254}
208 255
256static atomic_t __rt6_peer_genid = ATOMIC_INIT(0);
257
258static u32 rt6_peer_genid(void)
259{
260 return atomic_read(&__rt6_peer_genid);
261}
262
209void rt6_bind_peer(struct rt6_info *rt, int create) 263void rt6_bind_peer(struct rt6_info *rt, int create)
210{ 264{
211 struct inet_peer *peer; 265 struct inet_peer *peer;
@@ -213,6 +267,8 @@ void rt6_bind_peer(struct rt6_info *rt, int create)
213 peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); 267 peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create);
214 if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) 268 if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL)
215 inet_putpeer(peer); 269 inet_putpeer(peer);
270 else
271 rt->rt6i_peer_genid = rt6_peer_genid();
216} 272}
217 273
218static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, 274static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@ -239,7 +295,7 @@ static __inline__ int rt6_check_expired(const struct rt6_info *rt)
239 time_after(jiffies, rt->rt6i_expires); 295 time_after(jiffies, rt->rt6i_expires);
240} 296}
241 297
242static inline int rt6_need_strict(struct in6_addr *daddr) 298static inline int rt6_need_strict(const struct in6_addr *daddr)
243{ 299{
244 return ipv6_addr_type(daddr) & 300 return ipv6_addr_type(daddr) &
245 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); 301 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
@@ -251,7 +307,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
251 307
252static inline struct rt6_info *rt6_device_match(struct net *net, 308static inline struct rt6_info *rt6_device_match(struct net *net,
253 struct rt6_info *rt, 309 struct rt6_info *rt,
254 struct in6_addr *saddr, 310 const struct in6_addr *saddr,
255 int oif, 311 int oif,
256 int flags) 312 int flags)
257{ 313{
@@ -463,7 +519,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
463 519
464#ifdef CONFIG_IPV6_ROUTE_INFO 520#ifdef CONFIG_IPV6_ROUTE_INFO
465int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, 521int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
466 struct in6_addr *gwaddr) 522 const struct in6_addr *gwaddr)
467{ 523{
468 struct net *net = dev_net(dev); 524 struct net *net = dev_net(dev);
469 struct route_info *rinfo = (struct route_info *) opt; 525 struct route_info *rinfo = (struct route_info *) opt;
@@ -555,17 +611,17 @@ do { \
555 611
556static struct rt6_info *ip6_pol_route_lookup(struct net *net, 612static struct rt6_info *ip6_pol_route_lookup(struct net *net,
557 struct fib6_table *table, 613 struct fib6_table *table,
558 struct flowi *fl, int flags) 614 struct flowi6 *fl6, int flags)
559{ 615{
560 struct fib6_node *fn; 616 struct fib6_node *fn;
561 struct rt6_info *rt; 617 struct rt6_info *rt;
562 618
563 read_lock_bh(&table->tb6_lock); 619 read_lock_bh(&table->tb6_lock);
564 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 620 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
565restart: 621restart:
566 rt = fn->leaf; 622 rt = fn->leaf;
567 rt = rt6_device_match(net, rt, &fl->fl6_src, fl->oif, flags); 623 rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
568 BACKTRACK(net, &fl->fl6_src); 624 BACKTRACK(net, &fl6->saddr);
569out: 625out:
570 dst_use(&rt->dst, jiffies); 626 dst_use(&rt->dst, jiffies);
571 read_unlock_bh(&table->tb6_lock); 627 read_unlock_bh(&table->tb6_lock);
@@ -576,19 +632,19 @@ out:
576struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, 632struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
577 const struct in6_addr *saddr, int oif, int strict) 633 const struct in6_addr *saddr, int oif, int strict)
578{ 634{
579 struct flowi fl = { 635 struct flowi6 fl6 = {
580 .oif = oif, 636 .flowi6_oif = oif,
581 .fl6_dst = *daddr, 637 .daddr = *daddr,
582 }; 638 };
583 struct dst_entry *dst; 639 struct dst_entry *dst;
584 int flags = strict ? RT6_LOOKUP_F_IFACE : 0; 640 int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
585 641
586 if (saddr) { 642 if (saddr) {
587 memcpy(&fl.fl6_src, saddr, sizeof(*saddr)); 643 memcpy(&fl6.saddr, saddr, sizeof(*saddr));
588 flags |= RT6_LOOKUP_F_HAS_SADDR; 644 flags |= RT6_LOOKUP_F_HAS_SADDR;
589 } 645 }
590 646
591 dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_lookup); 647 dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup);
592 if (dst->error == 0) 648 if (dst->error == 0)
593 return (struct rt6_info *) dst; 649 return (struct rt6_info *) dst;
594 650
@@ -626,8 +682,8 @@ int ip6_ins_rt(struct rt6_info *rt)
626 return __ip6_ins_rt(rt, &info); 682 return __ip6_ins_rt(rt, &info);
627} 683}
628 684
629static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr, 685static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_addr *daddr,
630 struct in6_addr *saddr) 686 const struct in6_addr *saddr)
631{ 687{
632 struct rt6_info *rt; 688 struct rt6_info *rt;
633 689
@@ -695,7 +751,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
695 return rt; 751 return rt;
696} 752}
697 753
698static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *daddr) 754static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr)
699{ 755{
700 struct rt6_info *rt = ip6_rt_copy(ort); 756 struct rt6_info *rt = ip6_rt_copy(ort);
701 if (rt) { 757 if (rt) {
@@ -709,7 +765,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
709} 765}
710 766
711static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, 767static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
712 struct flowi *fl, int flags) 768 struct flowi6 *fl6, int flags)
713{ 769{
714 struct fib6_node *fn; 770 struct fib6_node *fn;
715 struct rt6_info *rt, *nrt; 771 struct rt6_info *rt, *nrt;
@@ -724,12 +780,12 @@ relookup:
724 read_lock_bh(&table->tb6_lock); 780 read_lock_bh(&table->tb6_lock);
725 781
726restart_2: 782restart_2:
727 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 783 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
728 784
729restart: 785restart:
730 rt = rt6_select(fn, oif, strict | reachable); 786 rt = rt6_select(fn, oif, strict | reachable);
731 787
732 BACKTRACK(net, &fl->fl6_src); 788 BACKTRACK(net, &fl6->saddr);
733 if (rt == net->ipv6.ip6_null_entry || 789 if (rt == net->ipv6.ip6_null_entry ||
734 rt->rt6i_flags & RTF_CACHE) 790 rt->rt6i_flags & RTF_CACHE)
735 goto out; 791 goto out;
@@ -738,9 +794,11 @@ restart:
738 read_unlock_bh(&table->tb6_lock); 794 read_unlock_bh(&table->tb6_lock);
739 795
740 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 796 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
741 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); 797 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
798 else if (!(rt->dst.flags & DST_HOST))
799 nrt = rt6_alloc_clone(rt, &fl6->daddr);
742 else 800 else
743 nrt = rt6_alloc_clone(rt, &fl->fl6_dst); 801 goto out2;
744 802
745 dst_release(&rt->dst); 803 dst_release(&rt->dst);
746 rt = nrt ? : net->ipv6.ip6_null_entry; 804 rt = nrt ? : net->ipv6.ip6_null_entry;
@@ -777,74 +835,71 @@ out2:
777} 835}
778 836
779static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, 837static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
780 struct flowi *fl, int flags) 838 struct flowi6 *fl6, int flags)
781{ 839{
782 return ip6_pol_route(net, table, fl->iif, fl, flags); 840 return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
783} 841}
784 842
785void ip6_route_input(struct sk_buff *skb) 843void ip6_route_input(struct sk_buff *skb)
786{ 844{
787 struct ipv6hdr *iph = ipv6_hdr(skb); 845 const struct ipv6hdr *iph = ipv6_hdr(skb);
788 struct net *net = dev_net(skb->dev); 846 struct net *net = dev_net(skb->dev);
789 int flags = RT6_LOOKUP_F_HAS_SADDR; 847 int flags = RT6_LOOKUP_F_HAS_SADDR;
790 struct flowi fl = { 848 struct flowi6 fl6 = {
791 .iif = skb->dev->ifindex, 849 .flowi6_iif = skb->dev->ifindex,
792 .fl6_dst = iph->daddr, 850 .daddr = iph->daddr,
793 .fl6_src = iph->saddr, 851 .saddr = iph->saddr,
794 .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, 852 .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
795 .mark = skb->mark, 853 .flowi6_mark = skb->mark,
796 .proto = iph->nexthdr, 854 .flowi6_proto = iph->nexthdr,
797 }; 855 };
798 856
799 if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) 857 if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
800 flags |= RT6_LOOKUP_F_IFACE; 858 flags |= RT6_LOOKUP_F_IFACE;
801 859
802 skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input)); 860 skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input));
803} 861}
804 862
805static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, 863static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
806 struct flowi *fl, int flags) 864 struct flowi6 *fl6, int flags)
807{ 865{
808 return ip6_pol_route(net, table, fl->oif, fl, flags); 866 return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
809} 867}
810 868
811struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, 869struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,
812 struct flowi *fl) 870 struct flowi6 *fl6)
813{ 871{
814 int flags = 0; 872 int flags = 0;
815 873
816 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst)) 874 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr))
817 flags |= RT6_LOOKUP_F_IFACE; 875 flags |= RT6_LOOKUP_F_IFACE;
818 876
819 if (!ipv6_addr_any(&fl->fl6_src)) 877 if (!ipv6_addr_any(&fl6->saddr))
820 flags |= RT6_LOOKUP_F_HAS_SADDR; 878 flags |= RT6_LOOKUP_F_HAS_SADDR;
821 else if (sk) 879 else if (sk)
822 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); 880 flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
823 881
824 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); 882 return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
825} 883}
826 884
827EXPORT_SYMBOL(ip6_route_output); 885EXPORT_SYMBOL(ip6_route_output);
828 886
829int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl) 887struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
830{ 888{
831 struct rt6_info *ort = (struct rt6_info *) *dstp; 889 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
832 struct rt6_info *rt = (struct rt6_info *)
833 dst_alloc(&ip6_dst_blackhole_ops);
834 struct dst_entry *new = NULL; 890 struct dst_entry *new = NULL;
835 891
892 rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
836 if (rt) { 893 if (rt) {
894 memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
895
837 new = &rt->dst; 896 new = &rt->dst;
838 897
839 atomic_set(&new->__refcnt, 1);
840 new->__use = 1; 898 new->__use = 1;
841 new->input = dst_discard; 899 new->input = dst_discard;
842 new->output = dst_discard; 900 new->output = dst_discard;
843 901
844 dst_copy_metrics(new, &ort->dst); 902 dst_copy_metrics(new, &ort->dst);
845 new->dev = ort->dst.dev;
846 if (new->dev)
847 dev_hold(new->dev);
848 rt->rt6i_idev = ort->rt6i_idev; 903 rt->rt6i_idev = ort->rt6i_idev;
849 if (rt->rt6i_idev) 904 if (rt->rt6i_idev)
850 in6_dev_hold(rt->rt6i_idev); 905 in6_dev_hold(rt->rt6i_idev);
@@ -862,11 +917,9 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
862 dst_free(new); 917 dst_free(new);
863 } 918 }
864 919
865 dst_release(*dstp); 920 dst_release(dst_orig);
866 *dstp = new; 921 return new ? new : ERR_PTR(-ENOMEM);
867 return new ? 0 : -ENOMEM;
868} 922}
869EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
870 923
871/* 924/*
872 * Destination cache support functions 925 * Destination cache support functions
@@ -878,9 +931,14 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
878 931
879 rt = (struct rt6_info *) dst; 932 rt = (struct rt6_info *) dst;
880 933
881 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) 934 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
935 if (rt->rt6i_peer_genid != rt6_peer_genid()) {
936 if (!rt->rt6i_peer)
937 rt6_bind_peer(rt, 0);
938 rt->rt6i_peer_genid = rt6_peer_genid();
939 }
882 return dst; 940 return dst;
883 941 }
884 return NULL; 942 return NULL;
885} 943}
886 944
@@ -931,7 +989,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
931 dst_metric_set(dst, RTAX_FEATURES, features); 989 dst_metric_set(dst, RTAX_FEATURES, features);
932 } 990 }
933 dst_metric_set(dst, RTAX_MTU, mtu); 991 dst_metric_set(dst, RTAX_MTU, mtu);
934 call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
935 } 992 }
936} 993}
937 994
@@ -985,13 +1042,12 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
985 if (unlikely(idev == NULL)) 1042 if (unlikely(idev == NULL))
986 return NULL; 1043 return NULL;
987 1044
988 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1045 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev);
989 if (unlikely(rt == NULL)) { 1046 if (unlikely(rt == NULL)) {
990 in6_dev_put(idev); 1047 in6_dev_put(idev);
991 goto out; 1048 goto out;
992 } 1049 }
993 1050
994 dev_hold(dev);
995 if (neigh) 1051 if (neigh)
996 neigh_hold(neigh); 1052 neigh_hold(neigh);
997 else { 1053 else {
@@ -1000,7 +1056,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1000 neigh = NULL; 1056 neigh = NULL;
1001 } 1057 }
1002 1058
1003 rt->rt6i_dev = dev;
1004 rt->rt6i_idev = idev; 1059 rt->rt6i_idev = idev;
1005 rt->rt6i_nexthop = neigh; 1060 rt->rt6i_nexthop = neigh;
1006 atomic_set(&rt->dst.__refcnt, 1); 1061 atomic_set(&rt->dst.__refcnt, 1);
@@ -1028,11 +1083,9 @@ out:
1028 1083
1029int icmp6_dst_gc(void) 1084int icmp6_dst_gc(void)
1030{ 1085{
1031 struct dst_entry *dst, *next, **pprev; 1086 struct dst_entry *dst, **pprev;
1032 int more = 0; 1087 int more = 0;
1033 1088
1034 next = NULL;
1035
1036 spin_lock_bh(&icmp6_dst_lock); 1089 spin_lock_bh(&icmp6_dst_lock);
1037 pprev = &icmp6_dst_gc_list; 1090 pprev = &icmp6_dst_gc_list;
1038 1091
@@ -1161,7 +1214,7 @@ int ip6_route_add(struct fib6_config *cfg)
1161 goto out; 1214 goto out;
1162 } 1215 }
1163 1216
1164 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1217 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL);
1165 1218
1166 if (rt == NULL) { 1219 if (rt == NULL) {
1167 err = -ENOMEM; 1220 err = -ENOMEM;
@@ -1228,7 +1281,7 @@ int ip6_route_add(struct fib6_config *cfg)
1228 } 1281 }
1229 1282
1230 if (cfg->fc_flags & RTF_GATEWAY) { 1283 if (cfg->fc_flags & RTF_GATEWAY) {
1231 struct in6_addr *gw_addr; 1284 const struct in6_addr *gw_addr;
1232 int gwa_type; 1285 int gwa_type;
1233 1286
1234 gw_addr = &cfg->fc_gateway; 1287 gw_addr = &cfg->fc_gateway;
@@ -1281,6 +1334,16 @@ int ip6_route_add(struct fib6_config *cfg)
1281 if (dev == NULL) 1334 if (dev == NULL)
1282 goto out; 1335 goto out;
1283 1336
1337 if (!ipv6_addr_any(&cfg->fc_prefsrc)) {
1338 if (!ipv6_chk_addr(net, &cfg->fc_prefsrc, dev, 0)) {
1339 err = -EINVAL;
1340 goto out;
1341 }
1342 ipv6_addr_copy(&rt->rt6i_prefsrc.addr, &cfg->fc_prefsrc);
1343 rt->rt6i_prefsrc.plen = 128;
1344 } else
1345 rt->rt6i_prefsrc.plen = 0;
1346
1284 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) { 1347 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
1285 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); 1348 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
1286 if (IS_ERR(rt->rt6i_nexthop)) { 1349 if (IS_ERR(rt->rt6i_nexthop)) {
@@ -1400,16 +1463,16 @@ static int ip6_route_del(struct fib6_config *cfg)
1400 * Handle redirects 1463 * Handle redirects
1401 */ 1464 */
1402struct ip6rd_flowi { 1465struct ip6rd_flowi {
1403 struct flowi fl; 1466 struct flowi6 fl6;
1404 struct in6_addr gateway; 1467 struct in6_addr gateway;
1405}; 1468};
1406 1469
1407static struct rt6_info *__ip6_route_redirect(struct net *net, 1470static struct rt6_info *__ip6_route_redirect(struct net *net,
1408 struct fib6_table *table, 1471 struct fib6_table *table,
1409 struct flowi *fl, 1472 struct flowi6 *fl6,
1410 int flags) 1473 int flags)
1411{ 1474{
1412 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl; 1475 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
1413 struct rt6_info *rt; 1476 struct rt6_info *rt;
1414 struct fib6_node *fn; 1477 struct fib6_node *fn;
1415 1478
@@ -1425,7 +1488,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
1425 */ 1488 */
1426 1489
1427 read_lock_bh(&table->tb6_lock); 1490 read_lock_bh(&table->tb6_lock);
1428 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 1491 fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
1429restart: 1492restart:
1430 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { 1493 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
1431 /* 1494 /*
@@ -1440,7 +1503,7 @@ restart:
1440 continue; 1503 continue;
1441 if (!(rt->rt6i_flags & RTF_GATEWAY)) 1504 if (!(rt->rt6i_flags & RTF_GATEWAY))
1442 continue; 1505 continue;
1443 if (fl->oif != rt->rt6i_dev->ifindex) 1506 if (fl6->flowi6_oif != rt->rt6i_dev->ifindex)
1444 continue; 1507 continue;
1445 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway)) 1508 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
1446 continue; 1509 continue;
@@ -1449,7 +1512,7 @@ restart:
1449 1512
1450 if (!rt) 1513 if (!rt)
1451 rt = net->ipv6.ip6_null_entry; 1514 rt = net->ipv6.ip6_null_entry;
1452 BACKTRACK(net, &fl->fl6_src); 1515 BACKTRACK(net, &fl6->saddr);
1453out: 1516out:
1454 dst_hold(&rt->dst); 1517 dst_hold(&rt->dst);
1455 1518
@@ -1458,18 +1521,18 @@ out:
1458 return rt; 1521 return rt;
1459}; 1522};
1460 1523
1461static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, 1524static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest,
1462 struct in6_addr *src, 1525 const struct in6_addr *src,
1463 struct in6_addr *gateway, 1526 const struct in6_addr *gateway,
1464 struct net_device *dev) 1527 struct net_device *dev)
1465{ 1528{
1466 int flags = RT6_LOOKUP_F_HAS_SADDR; 1529 int flags = RT6_LOOKUP_F_HAS_SADDR;
1467 struct net *net = dev_net(dev); 1530 struct net *net = dev_net(dev);
1468 struct ip6rd_flowi rdfl = { 1531 struct ip6rd_flowi rdfl = {
1469 .fl = { 1532 .fl6 = {
1470 .oif = dev->ifindex, 1533 .flowi6_oif = dev->ifindex,
1471 .fl6_dst = *dest, 1534 .daddr = *dest,
1472 .fl6_src = *src, 1535 .saddr = *src,
1473 }, 1536 },
1474 }; 1537 };
1475 1538
@@ -1478,12 +1541,12 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1478 if (rt6_need_strict(dest)) 1541 if (rt6_need_strict(dest))
1479 flags |= RT6_LOOKUP_F_IFACE; 1542 flags |= RT6_LOOKUP_F_IFACE;
1480 1543
1481 return (struct rt6_info *)fib6_rule_lookup(net, (struct flowi *)&rdfl, 1544 return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6,
1482 flags, __ip6_route_redirect); 1545 flags, __ip6_route_redirect);
1483} 1546}
1484 1547
1485void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, 1548void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1486 struct in6_addr *saddr, 1549 const struct in6_addr *saddr,
1487 struct neighbour *neigh, u8 *lladdr, int on_link) 1550 struct neighbour *neigh, u8 *lladdr, int on_link)
1488{ 1551{
1489 struct rt6_info *rt, *nrt = NULL; 1552 struct rt6_info *rt, *nrt = NULL;
@@ -1557,7 +1620,7 @@ out:
1557 * i.e. Path MTU discovery 1620 * i.e. Path MTU discovery
1558 */ 1621 */
1559 1622
1560static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, 1623static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr *saddr,
1561 struct net *net, u32 pmtu, int ifindex) 1624 struct net *net, u32 pmtu, int ifindex)
1562{ 1625{
1563 struct rt6_info *rt, *nrt; 1626 struct rt6_info *rt, *nrt;
@@ -1642,7 +1705,7 @@ out:
1642 dst_release(&rt->dst); 1705 dst_release(&rt->dst);
1643} 1706}
1644 1707
1645void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, 1708void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *saddr,
1646 struct net_device *dev, u32 pmtu) 1709 struct net_device *dev, u32 pmtu)
1647{ 1710{
1648 struct net *net = dev_net(dev); 1711 struct net *net = dev_net(dev);
@@ -1670,7 +1733,8 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1670static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) 1733static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1671{ 1734{
1672 struct net *net = dev_net(ort->rt6i_dev); 1735 struct net *net = dev_net(ort->rt6i_dev);
1673 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1736 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
1737 ort->dst.dev);
1674 1738
1675 if (rt) { 1739 if (rt) {
1676 rt->dst.input = ort->dst.input; 1740 rt->dst.input = ort->dst.input;
@@ -1678,9 +1742,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1678 1742
1679 dst_copy_metrics(&rt->dst, &ort->dst); 1743 dst_copy_metrics(&rt->dst, &ort->dst);
1680 rt->dst.error = ort->dst.error; 1744 rt->dst.error = ort->dst.error;
1681 rt->dst.dev = ort->dst.dev;
1682 if (rt->dst.dev)
1683 dev_hold(rt->dst.dev);
1684 rt->rt6i_idev = ort->rt6i_idev; 1745 rt->rt6i_idev = ort->rt6i_idev;
1685 if (rt->rt6i_idev) 1746 if (rt->rt6i_idev)
1686 in6_dev_hold(rt->rt6i_idev); 1747 in6_dev_hold(rt->rt6i_idev);
@@ -1695,6 +1756,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1695#ifdef CONFIG_IPV6_SUBTREES 1756#ifdef CONFIG_IPV6_SUBTREES
1696 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); 1757 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
1697#endif 1758#endif
1759 memcpy(&rt->rt6i_prefsrc, &ort->rt6i_prefsrc, sizeof(struct rt6key));
1698 rt->rt6i_table = ort->rt6i_table; 1760 rt->rt6i_table = ort->rt6i_table;
1699 } 1761 }
1700 return rt; 1762 return rt;
@@ -1702,8 +1764,8 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1702 1764
1703#ifdef CONFIG_IPV6_ROUTE_INFO 1765#ifdef CONFIG_IPV6_ROUTE_INFO
1704static struct rt6_info *rt6_get_route_info(struct net *net, 1766static struct rt6_info *rt6_get_route_info(struct net *net,
1705 struct in6_addr *prefix, int prefixlen, 1767 const struct in6_addr *prefix, int prefixlen,
1706 struct in6_addr *gwaddr, int ifindex) 1768 const struct in6_addr *gwaddr, int ifindex)
1707{ 1769{
1708 struct fib6_node *fn; 1770 struct fib6_node *fn;
1709 struct rt6_info *rt = NULL; 1771 struct rt6_info *rt = NULL;
@@ -1734,8 +1796,8 @@ out:
1734} 1796}
1735 1797
1736static struct rt6_info *rt6_add_route_info(struct net *net, 1798static struct rt6_info *rt6_add_route_info(struct net *net,
1737 struct in6_addr *prefix, int prefixlen, 1799 const struct in6_addr *prefix, int prefixlen,
1738 struct in6_addr *gwaddr, int ifindex, 1800 const struct in6_addr *gwaddr, int ifindex,
1739 unsigned pref) 1801 unsigned pref)
1740{ 1802{
1741 struct fib6_config cfg = { 1803 struct fib6_config cfg = {
@@ -1763,7 +1825,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
1763} 1825}
1764#endif 1826#endif
1765 1827
1766struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev) 1828struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev)
1767{ 1829{
1768 struct rt6_info *rt; 1830 struct rt6_info *rt;
1769 struct fib6_table *table; 1831 struct fib6_table *table;
@@ -1785,7 +1847,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
1785 return rt; 1847 return rt;
1786} 1848}
1787 1849
1788struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr, 1850struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
1789 struct net_device *dev, 1851 struct net_device *dev,
1790 unsigned int pref) 1852 unsigned int pref)
1791{ 1853{
@@ -1950,7 +2012,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1950 int anycast) 2012 int anycast)
1951{ 2013{
1952 struct net *net = dev_net(idev->dev); 2014 struct net *net = dev_net(idev->dev);
1953 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 2015 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
2016 net->loopback_dev);
1954 struct neighbour *neigh; 2017 struct neighbour *neigh;
1955 2018
1956 if (rt == NULL) { 2019 if (rt == NULL) {
@@ -1960,15 +2023,12 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1960 return ERR_PTR(-ENOMEM); 2023 return ERR_PTR(-ENOMEM);
1961 } 2024 }
1962 2025
1963 dev_hold(net->loopback_dev);
1964 in6_dev_hold(idev); 2026 in6_dev_hold(idev);
1965 2027
1966 rt->dst.flags = DST_HOST; 2028 rt->dst.flags = DST_HOST;
1967 rt->dst.input = ip6_input; 2029 rt->dst.input = ip6_input;
1968 rt->dst.output = ip6_output; 2030 rt->dst.output = ip6_output;
1969 rt->rt6i_dev = net->loopback_dev;
1970 rt->rt6i_idev = idev; 2031 rt->rt6i_idev = idev;
1971 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1);
1972 rt->dst.obsolete = -1; 2032 rt->dst.obsolete = -1;
1973 2033
1974 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; 2034 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
@@ -1980,12 +2040,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1980 if (IS_ERR(neigh)) { 2040 if (IS_ERR(neigh)) {
1981 dst_free(&rt->dst); 2041 dst_free(&rt->dst);
1982 2042
1983 /* We are casting this because that is the return 2043 return ERR_CAST(neigh);
1984 * value type. But an errno encoded pointer is the
1985 * same regardless of the underlying pointer type,
1986 * and that's what we are returning. So this is OK.
1987 */
1988 return (struct rt6_info *) neigh;
1989 } 2044 }
1990 rt->rt6i_nexthop = neigh; 2045 rt->rt6i_nexthop = neigh;
1991 2046
@@ -1998,6 +2053,55 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1998 return rt; 2053 return rt;
1999} 2054}
2000 2055
2056int ip6_route_get_saddr(struct net *net,
2057 struct rt6_info *rt,
2058 const struct in6_addr *daddr,
2059 unsigned int prefs,
2060 struct in6_addr *saddr)
2061{
2062 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt);
2063 int err = 0;
2064 if (rt->rt6i_prefsrc.plen)
2065 ipv6_addr_copy(saddr, &rt->rt6i_prefsrc.addr);
2066 else
2067 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
2068 daddr, prefs, saddr);
2069 return err;
2070}
2071
2072/* remove deleted ip from prefsrc entries */
2073struct arg_dev_net_ip {
2074 struct net_device *dev;
2075 struct net *net;
2076 struct in6_addr *addr;
2077};
2078
2079static int fib6_remove_prefsrc(struct rt6_info *rt, void *arg)
2080{
2081 struct net_device *dev = ((struct arg_dev_net_ip *)arg)->dev;
2082 struct net *net = ((struct arg_dev_net_ip *)arg)->net;
2083 struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr;
2084
2085 if (((void *)rt->rt6i_dev == dev || dev == NULL) &&
2086 rt != net->ipv6.ip6_null_entry &&
2087 ipv6_addr_equal(addr, &rt->rt6i_prefsrc.addr)) {
2088 /* remove prefsrc entry */
2089 rt->rt6i_prefsrc.plen = 0;
2090 }
2091 return 0;
2092}
2093
2094void rt6_remove_prefsrc(struct inet6_ifaddr *ifp)
2095{
2096 struct net *net = dev_net(ifp->idev->dev);
2097 struct arg_dev_net_ip adni = {
2098 .dev = ifp->idev->dev,
2099 .net = net,
2100 .addr = &ifp->addr,
2101 };
2102 fib6_clean_all(net, fib6_remove_prefsrc, 0, &adni);
2103}
2104
2001struct arg_dev_net { 2105struct arg_dev_net {
2002 struct net_device *dev; 2106 struct net_device *dev;
2003 struct net *net; 2107 struct net *net;
@@ -2144,6 +2248,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
2144 nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen); 2248 nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen);
2145 } 2249 }
2146 2250
2251 if (tb[RTA_PREFSRC])
2252 nla_memcpy(&cfg->fc_prefsrc, tb[RTA_PREFSRC], 16);
2253
2147 if (tb[RTA_OIF]) 2254 if (tb[RTA_OIF])
2148 cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]); 2255 cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]);
2149 2256
@@ -2286,13 +2393,17 @@ static int rt6_fill_node(struct net *net,
2286#endif 2393#endif
2287 NLA_PUT_U32(skb, RTA_IIF, iif); 2394 NLA_PUT_U32(skb, RTA_IIF, iif);
2288 } else if (dst) { 2395 } else if (dst) {
2289 struct inet6_dev *idev = ip6_dst_idev(&rt->dst);
2290 struct in6_addr saddr_buf; 2396 struct in6_addr saddr_buf;
2291 if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, 2397 if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0)
2292 dst, 0, &saddr_buf) == 0)
2293 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2398 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2294 } 2399 }
2295 2400
2401 if (rt->rt6i_prefsrc.plen) {
2402 struct in6_addr saddr_buf;
2403 ipv6_addr_copy(&saddr_buf, &rt->rt6i_prefsrc.addr);
2404 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2405 }
2406
2296 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 2407 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
2297 goto nla_put_failure; 2408 goto nla_put_failure;
2298 2409
@@ -2346,7 +2457,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2346 struct rt6_info *rt; 2457 struct rt6_info *rt;
2347 struct sk_buff *skb; 2458 struct sk_buff *skb;
2348 struct rtmsg *rtm; 2459 struct rtmsg *rtm;
2349 struct flowi fl; 2460 struct flowi6 fl6;
2350 int err, iif = 0; 2461 int err, iif = 0;
2351 2462
2352 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); 2463 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
@@ -2354,27 +2465,27 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2354 goto errout; 2465 goto errout;
2355 2466
2356 err = -EINVAL; 2467 err = -EINVAL;
2357 memset(&fl, 0, sizeof(fl)); 2468 memset(&fl6, 0, sizeof(fl6));
2358 2469
2359 if (tb[RTA_SRC]) { 2470 if (tb[RTA_SRC]) {
2360 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) 2471 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
2361 goto errout; 2472 goto errout;
2362 2473
2363 ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC])); 2474 ipv6_addr_copy(&fl6.saddr, nla_data(tb[RTA_SRC]));
2364 } 2475 }
2365 2476
2366 if (tb[RTA_DST]) { 2477 if (tb[RTA_DST]) {
2367 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) 2478 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
2368 goto errout; 2479 goto errout;
2369 2480
2370 ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST])); 2481 ipv6_addr_copy(&fl6.daddr, nla_data(tb[RTA_DST]));
2371 } 2482 }
2372 2483
2373 if (tb[RTA_IIF]) 2484 if (tb[RTA_IIF])
2374 iif = nla_get_u32(tb[RTA_IIF]); 2485 iif = nla_get_u32(tb[RTA_IIF]);
2375 2486
2376 if (tb[RTA_OIF]) 2487 if (tb[RTA_OIF])
2377 fl.oif = nla_get_u32(tb[RTA_OIF]); 2488 fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]);
2378 2489
2379 if (iif) { 2490 if (iif) {
2380 struct net_device *dev; 2491 struct net_device *dev;
@@ -2397,10 +2508,10 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2397 skb_reset_mac_header(skb); 2508 skb_reset_mac_header(skb);
2398 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); 2509 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
2399 2510
2400 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); 2511 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6);
2401 skb_dst_set(skb, &rt->dst); 2512 skb_dst_set(skb, &rt->dst);
2402 2513
2403 err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, 2514 err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
2404 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2515 RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
2405 nlh->nlmsg_seq, 0, 0, 0); 2516 nlh->nlmsg_seq, 0, 0, 0);
2406 if (err < 0) { 2517 if (err < 0) {
@@ -2557,14 +2668,16 @@ static
2557int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, 2668int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write,
2558 void __user *buffer, size_t *lenp, loff_t *ppos) 2669 void __user *buffer, size_t *lenp, loff_t *ppos)
2559{ 2670{
2560 struct net *net = current->nsproxy->net_ns; 2671 struct net *net;
2561 int delay = net->ipv6.sysctl.flush_delay; 2672 int delay;
2562 if (write) { 2673 if (!write)
2563 proc_dointvec(ctl, write, buffer, lenp, ppos);
2564 fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net);
2565 return 0;
2566 } else
2567 return -EINVAL; 2674 return -EINVAL;
2675
2676 net = (struct net *)ctl->extra1;
2677 delay = net->ipv6.sysctl.flush_delay;
2678 proc_dointvec(ctl, write, buffer, lenp, ppos);
2679 fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net);
2680 return 0;
2568} 2681}
2569 2682
2570ctl_table ipv6_route_table_template[] = { 2683ctl_table ipv6_route_table_template[] = {
@@ -2651,6 +2764,7 @@ struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
2651 2764
2652 if (table) { 2765 if (table) {
2653 table[0].data = &net->ipv6.sysctl.flush_delay; 2766 table[0].data = &net->ipv6.sysctl.flush_delay;
2767 table[0].extra1 = net;
2654 table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh; 2768 table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh;
2655 table[2].data = &net->ipv6.sysctl.ip6_rt_max_size; 2769 table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
2656 table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; 2770 table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
@@ -2684,7 +2798,8 @@ static int __net_init ip6_route_net_init(struct net *net)
2684 net->ipv6.ip6_null_entry->dst.path = 2798 net->ipv6.ip6_null_entry->dst.path =
2685 (struct dst_entry *)net->ipv6.ip6_null_entry; 2799 (struct dst_entry *)net->ipv6.ip6_null_entry;
2686 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2800 net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2687 dst_metric_set(&net->ipv6.ip6_null_entry->dst, RTAX_HOPLIMIT, 255); 2801 dst_init_metrics(&net->ipv6.ip6_null_entry->dst,
2802 ip6_template_metrics, true);
2688 2803
2689#ifdef CONFIG_IPV6_MULTIPLE_TABLES 2804#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2690 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, 2805 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
@@ -2695,7 +2810,8 @@ static int __net_init ip6_route_net_init(struct net *net)
2695 net->ipv6.ip6_prohibit_entry->dst.path = 2810 net->ipv6.ip6_prohibit_entry->dst.path =
2696 (struct dst_entry *)net->ipv6.ip6_prohibit_entry; 2811 (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
2697 net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2812 net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2698 dst_metric_set(&net->ipv6.ip6_prohibit_entry->dst, RTAX_HOPLIMIT, 255); 2813 dst_init_metrics(&net->ipv6.ip6_prohibit_entry->dst,
2814 ip6_template_metrics, true);
2699 2815
2700 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, 2816 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
2701 sizeof(*net->ipv6.ip6_blk_hole_entry), 2817 sizeof(*net->ipv6.ip6_blk_hole_entry),
@@ -2705,7 +2821,8 @@ static int __net_init ip6_route_net_init(struct net *net)
2705 net->ipv6.ip6_blk_hole_entry->dst.path = 2821 net->ipv6.ip6_blk_hole_entry->dst.path =
2706 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; 2822 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
2707 net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; 2823 net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
2708 dst_metric_set(&net->ipv6.ip6_blk_hole_entry->dst, RTAX_HOPLIMIT, 255); 2824 dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
2825 ip6_template_metrics, true);
2709#endif 2826#endif
2710 2827
2711 net->ipv6.sysctl.flush_delay = 0; 2828 net->ipv6.sysctl.flush_delay = 0;