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.c555
1 files changed, 356 insertions, 199 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e8b241cb60bc..a4b5aee0f68a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -40,6 +40,7 @@
40#include <linux/if_arp.h> 40#include <linux/if_arp.h>
41#include <linux/proc_fs.h> 41#include <linux/proc_fs.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/nsproxy.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>
@@ -87,14 +88,16 @@ static void ip6_link_failure(struct sk_buff *skb);
87static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu); 88static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
88 89
89#ifdef CONFIG_IPV6_ROUTE_INFO 90#ifdef CONFIG_IPV6_ROUTE_INFO
90static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixlen, 91static struct rt6_info *rt6_add_route_info(struct net *net,
92 struct in6_addr *prefix, int prefixlen,
91 struct in6_addr *gwaddr, int ifindex, 93 struct in6_addr *gwaddr, int ifindex,
92 unsigned pref); 94 unsigned pref);
93static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixlen, 95static struct rt6_info *rt6_get_route_info(struct net *net,
96 struct in6_addr *prefix, int prefixlen,
94 struct in6_addr *gwaddr, int ifindex); 97 struct in6_addr *gwaddr, int ifindex);
95#endif 98#endif
96 99
97static struct dst_ops ip6_dst_ops = { 100static struct dst_ops ip6_dst_ops_template = {
98 .family = AF_INET6, 101 .family = AF_INET6,
99 .protocol = __constant_htons(ETH_P_IPV6), 102 .protocol = __constant_htons(ETH_P_IPV6),
100 .gc = ip6_dst_gc, 103 .gc = ip6_dst_gc,
@@ -124,7 +127,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
124 .entries = ATOMIC_INIT(0), 127 .entries = ATOMIC_INIT(0),
125}; 128};
126 129
127struct rt6_info ip6_null_entry = { 130static struct rt6_info ip6_null_entry_template = {
128 .u = { 131 .u = {
129 .dst = { 132 .dst = {
130 .__refcnt = ATOMIC_INIT(1), 133 .__refcnt = ATOMIC_INIT(1),
@@ -134,8 +137,6 @@ struct rt6_info ip6_null_entry = {
134 .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, 137 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
135 .input = ip6_pkt_discard, 138 .input = ip6_pkt_discard,
136 .output = ip6_pkt_discard_out, 139 .output = ip6_pkt_discard_out,
137 .ops = &ip6_dst_ops,
138 .path = (struct dst_entry*)&ip6_null_entry,
139 } 140 }
140 }, 141 },
141 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), 142 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -148,7 +149,7 @@ struct rt6_info ip6_null_entry = {
148static int ip6_pkt_prohibit(struct sk_buff *skb); 149static int ip6_pkt_prohibit(struct sk_buff *skb);
149static int ip6_pkt_prohibit_out(struct sk_buff *skb); 150static int ip6_pkt_prohibit_out(struct sk_buff *skb);
150 151
151struct rt6_info ip6_prohibit_entry = { 152struct rt6_info ip6_prohibit_entry_template = {
152 .u = { 153 .u = {
153 .dst = { 154 .dst = {
154 .__refcnt = ATOMIC_INIT(1), 155 .__refcnt = ATOMIC_INIT(1),
@@ -158,8 +159,6 @@ struct rt6_info ip6_prohibit_entry = {
158 .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, 159 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
159 .input = ip6_pkt_prohibit, 160 .input = ip6_pkt_prohibit,
160 .output = ip6_pkt_prohibit_out, 161 .output = ip6_pkt_prohibit_out,
161 .ops = &ip6_dst_ops,
162 .path = (struct dst_entry*)&ip6_prohibit_entry,
163 } 162 }
164 }, 163 },
165 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), 164 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -167,7 +166,7 @@ struct rt6_info ip6_prohibit_entry = {
167 .rt6i_ref = ATOMIC_INIT(1), 166 .rt6i_ref = ATOMIC_INIT(1),
168}; 167};
169 168
170struct rt6_info ip6_blk_hole_entry = { 169static struct rt6_info ip6_blk_hole_entry_template = {
171 .u = { 170 .u = {
172 .dst = { 171 .dst = {
173 .__refcnt = ATOMIC_INIT(1), 172 .__refcnt = ATOMIC_INIT(1),
@@ -177,8 +176,6 @@ struct rt6_info ip6_blk_hole_entry = {
177 .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, 176 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
178 .input = dst_discard, 177 .input = dst_discard,
179 .output = dst_discard, 178 .output = dst_discard,
180 .ops = &ip6_dst_ops,
181 .path = (struct dst_entry*)&ip6_blk_hole_entry,
182 } 179 }
183 }, 180 },
184 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), 181 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
@@ -189,9 +186,9 @@ struct rt6_info ip6_blk_hole_entry = {
189#endif 186#endif
190 187
191/* allocate dst with ip6_dst_ops */ 188/* allocate dst with ip6_dst_ops */
192static __inline__ struct rt6_info *ip6_dst_alloc(void) 189static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops)
193{ 190{
194 return (struct rt6_info *)dst_alloc(&ip6_dst_ops); 191 return (struct rt6_info *)dst_alloc(ops);
195} 192}
196 193
197static void ip6_dst_destroy(struct dst_entry *dst) 194static void ip6_dst_destroy(struct dst_entry *dst)
@@ -239,7 +236,8 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
239 * Route lookup. Any table->tb6_lock is implied. 236 * Route lookup. Any table->tb6_lock is implied.
240 */ 237 */
241 238
242static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, 239static inline struct rt6_info *rt6_device_match(struct net *net,
240 struct rt6_info *rt,
243 int oif, 241 int oif,
244 int strict) 242 int strict)
245{ 243{
@@ -268,7 +266,7 @@ static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt,
268 return local; 266 return local;
269 267
270 if (strict) 268 if (strict)
271 return &ip6_null_entry; 269 return net->ipv6.ip6_null_entry;
272 } 270 }
273 return rt; 271 return rt;
274} 272}
@@ -409,9 +407,10 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
409static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) 407static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
410{ 408{
411 struct rt6_info *match, *rt0; 409 struct rt6_info *match, *rt0;
410 struct net *net;
412 411
413 RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n", 412 RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n",
414 __FUNCTION__, fn->leaf, oif); 413 __func__, fn->leaf, oif);
415 414
416 rt0 = fn->rr_ptr; 415 rt0 = fn->rr_ptr;
417 if (!rt0) 416 if (!rt0)
@@ -432,15 +431,17 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
432 } 431 }
433 432
434 RT6_TRACE("%s() => %p\n", 433 RT6_TRACE("%s() => %p\n",
435 __FUNCTION__, match); 434 __func__, match);
436 435
437 return (match ? match : &ip6_null_entry); 436 net = rt0->rt6i_dev->nd_net;
437 return (match ? match : net->ipv6.ip6_null_entry);
438} 438}
439 439
440#ifdef CONFIG_IPV6_ROUTE_INFO 440#ifdef CONFIG_IPV6_ROUTE_INFO
441int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, 441int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
442 struct in6_addr *gwaddr) 442 struct in6_addr *gwaddr)
443{ 443{
444 struct net *net = dev->nd_net;
444 struct route_info *rinfo = (struct route_info *) opt; 445 struct route_info *rinfo = (struct route_info *) opt;
445 struct in6_addr prefix_buf, *prefix; 446 struct in6_addr prefix_buf, *prefix;
446 unsigned int pref; 447 unsigned int pref;
@@ -488,7 +489,8 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
488 prefix = &prefix_buf; 489 prefix = &prefix_buf;
489 } 490 }
490 491
491 rt = rt6_get_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex); 492 rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
493 dev->ifindex);
492 494
493 if (rt && !lifetime) { 495 if (rt && !lifetime) {
494 ip6_del_rt(rt); 496 ip6_del_rt(rt);
@@ -496,7 +498,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
496 } 498 }
497 499
498 if (!rt && lifetime) 500 if (!rt && lifetime)
499 rt = rt6_add_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex, 501 rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr, dev->ifindex,
500 pref); 502 pref);
501 else if (rt) 503 else if (rt)
502 rt->rt6i_flags = RTF_ROUTEINFO | 504 rt->rt6i_flags = RTF_ROUTEINFO |
@@ -515,9 +517,9 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
515} 517}
516#endif 518#endif
517 519
518#define BACKTRACK(saddr) \ 520#define BACKTRACK(__net, saddr) \
519do { \ 521do { \
520 if (rt == &ip6_null_entry) { \ 522 if (rt == __net->ipv6.ip6_null_entry) { \
521 struct fib6_node *pn; \ 523 struct fib6_node *pn; \
522 while (1) { \ 524 while (1) { \
523 if (fn->fn_flags & RTN_TL_ROOT) \ 525 if (fn->fn_flags & RTN_TL_ROOT) \
@@ -533,7 +535,8 @@ do { \
533 } \ 535 } \
534} while(0) 536} while(0)
535 537
536static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table, 538static struct rt6_info *ip6_pol_route_lookup(struct net *net,
539 struct fib6_table *table,
537 struct flowi *fl, int flags) 540 struct flowi *fl, int flags)
538{ 541{
539 struct fib6_node *fn; 542 struct fib6_node *fn;
@@ -543,8 +546,8 @@ static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table,
543 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 546 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
544restart: 547restart:
545 rt = fn->leaf; 548 rt = fn->leaf;
546 rt = rt6_device_match(rt, fl->oif, flags); 549 rt = rt6_device_match(net, rt, fl->oif, flags);
547 BACKTRACK(&fl->fl6_src); 550 BACKTRACK(net, &fl->fl6_src);
548out: 551out:
549 dst_use(&rt->u.dst, jiffies); 552 dst_use(&rt->u.dst, jiffies);
550 read_unlock_bh(&table->tb6_lock); 553 read_unlock_bh(&table->tb6_lock);
@@ -552,8 +555,8 @@ out:
552 555
553} 556}
554 557
555struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, 558struct rt6_info *rt6_lookup(struct net *net, struct in6_addr *daddr,
556 int oif, int strict) 559 struct in6_addr *saddr, int oif, int strict)
557{ 560{
558 struct flowi fl = { 561 struct flowi fl = {
559 .oif = oif, 562 .oif = oif,
@@ -571,7 +574,7 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
571 flags |= RT6_LOOKUP_F_HAS_SADDR; 574 flags |= RT6_LOOKUP_F_HAS_SADDR;
572 } 575 }
573 576
574 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); 577 dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_lookup);
575 if (dst->error == 0) 578 if (dst->error == 0)
576 return (struct rt6_info *) dst; 579 return (struct rt6_info *) dst;
577 580
@@ -604,7 +607,7 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
604int ip6_ins_rt(struct rt6_info *rt) 607int ip6_ins_rt(struct rt6_info *rt)
605{ 608{
606 struct nl_info info = { 609 struct nl_info info = {
607 .nl_net = &init_net, 610 .nl_net = rt->rt6i_dev->nd_net,
608 }; 611 };
609 return __ip6_ins_rt(rt, &info); 612 return __ip6_ins_rt(rt, &info);
610} 613}
@@ -660,8 +663,8 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
660 return rt; 663 return rt;
661} 664}
662 665
663static struct rt6_info *ip6_pol_route(struct fib6_table *table, int oif, 666static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
664 struct flowi *fl, int flags) 667 struct flowi *fl, int flags)
665{ 668{
666 struct fib6_node *fn; 669 struct fib6_node *fn;
667 struct rt6_info *rt, *nrt; 670 struct rt6_info *rt, *nrt;
@@ -680,8 +683,9 @@ restart_2:
680 683
681restart: 684restart:
682 rt = rt6_select(fn, oif, strict | reachable); 685 rt = rt6_select(fn, oif, strict | reachable);
683 BACKTRACK(&fl->fl6_src); 686
684 if (rt == &ip6_null_entry || 687 BACKTRACK(net, &fl->fl6_src);
688 if (rt == net->ipv6.ip6_null_entry ||
685 rt->rt6i_flags & RTF_CACHE) 689 rt->rt6i_flags & RTF_CACHE)
686 goto out; 690 goto out;
687 691
@@ -699,7 +703,7 @@ restart:
699 } 703 }
700 704
701 dst_release(&rt->u.dst); 705 dst_release(&rt->u.dst);
702 rt = nrt ? : &ip6_null_entry; 706 rt = nrt ? : net->ipv6.ip6_null_entry;
703 707
704 dst_hold(&rt->u.dst); 708 dst_hold(&rt->u.dst);
705 if (nrt) { 709 if (nrt) {
@@ -732,15 +736,16 @@ out2:
732 return rt; 736 return rt;
733} 737}
734 738
735static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, 739static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
736 struct flowi *fl, int flags) 740 struct flowi *fl, int flags)
737{ 741{
738 return ip6_pol_route(table, fl->iif, fl, flags); 742 return ip6_pol_route(net, table, fl->iif, fl, flags);
739} 743}
740 744
741void ip6_route_input(struct sk_buff *skb) 745void ip6_route_input(struct sk_buff *skb)
742{ 746{
743 struct ipv6hdr *iph = ipv6_hdr(skb); 747 struct ipv6hdr *iph = ipv6_hdr(skb);
748 struct net *net = skb->dev->nd_net;
744 int flags = RT6_LOOKUP_F_HAS_SADDR; 749 int flags = RT6_LOOKUP_F_HAS_SADDR;
745 struct flowi fl = { 750 struct flowi fl = {
746 .iif = skb->dev->ifindex, 751 .iif = skb->dev->ifindex,
@@ -758,16 +763,17 @@ void ip6_route_input(struct sk_buff *skb)
758 if (rt6_need_strict(&iph->daddr)) 763 if (rt6_need_strict(&iph->daddr))
759 flags |= RT6_LOOKUP_F_IFACE; 764 flags |= RT6_LOOKUP_F_IFACE;
760 765
761 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); 766 skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input);
762} 767}
763 768
764static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, 769static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
765 struct flowi *fl, int flags) 770 struct flowi *fl, int flags)
766{ 771{
767 return ip6_pol_route(table, fl->oif, fl, flags); 772 return ip6_pol_route(net, table, fl->oif, fl, flags);
768} 773}
769 774
770struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) 775struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
776 struct flowi *fl)
771{ 777{
772 int flags = 0; 778 int flags = 0;
773 779
@@ -777,7 +783,7 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
777 if (!ipv6_addr_any(&fl->fl6_src)) 783 if (!ipv6_addr_any(&fl->fl6_src))
778 flags |= RT6_LOOKUP_F_HAS_SADDR; 784 flags |= RT6_LOOKUP_F_HAS_SADDR;
779 785
780 return fib6_rule_lookup(fl, flags, ip6_pol_route_output); 786 return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
781} 787}
782 788
783EXPORT_SYMBOL(ip6_route_output); 789EXPORT_SYMBOL(ip6_route_output);
@@ -886,12 +892,12 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
886 892
887static int ipv6_get_mtu(struct net_device *dev); 893static int ipv6_get_mtu(struct net_device *dev);
888 894
889static inline unsigned int ipv6_advmss(unsigned int mtu) 895static inline unsigned int ipv6_advmss(struct net *net, unsigned int mtu)
890{ 896{
891 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); 897 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
892 898
893 if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss) 899 if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
894 mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss; 900 mtu = net->ipv6.sysctl.ip6_rt_min_advmss;
895 901
896 /* 902 /*
897 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and 903 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
@@ -904,21 +910,21 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
904 return mtu; 910 return mtu;
905} 911}
906 912
907static struct dst_entry *ndisc_dst_gc_list; 913static struct dst_entry *icmp6_dst_gc_list;
908static DEFINE_SPINLOCK(ndisc_lock); 914static DEFINE_SPINLOCK(icmp6_dst_lock);
909 915
910struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 916struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
911 struct neighbour *neigh, 917 struct neighbour *neigh,
912 struct in6_addr *addr, 918 struct in6_addr *addr)
913 int (*output)(struct sk_buff *))
914{ 919{
915 struct rt6_info *rt; 920 struct rt6_info *rt;
916 struct inet6_dev *idev = in6_dev_get(dev); 921 struct inet6_dev *idev = in6_dev_get(dev);
922 struct net *net = dev->nd_net;
917 923
918 if (unlikely(idev == NULL)) 924 if (unlikely(idev == NULL))
919 return NULL; 925 return NULL;
920 926
921 rt = ip6_dst_alloc(); 927 rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
922 if (unlikely(rt == NULL)) { 928 if (unlikely(rt == NULL)) {
923 in6_dev_put(idev); 929 in6_dev_put(idev);
924 goto out; 930 goto out;
@@ -936,8 +942,8 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
936 atomic_set(&rt->u.dst.__refcnt, 1); 942 atomic_set(&rt->u.dst.__refcnt, 1);
937 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255; 943 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
938 rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); 944 rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
939 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); 945 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));
940 rt->u.dst.output = output; 946 rt->u.dst.output = ip6_output;
941 947
942#if 0 /* there's no chance to use these for ndisc */ 948#if 0 /* there's no chance to use these for ndisc */
943 rt->u.dst.flags = ipv6_addr_type(addr) & IPV6_ADDR_UNICAST 949 rt->u.dst.flags = ipv6_addr_type(addr) & IPV6_ADDR_UNICAST
@@ -947,18 +953,18 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
947 rt->rt6i_dst.plen = 128; 953 rt->rt6i_dst.plen = 128;
948#endif 954#endif
949 955
950 spin_lock_bh(&ndisc_lock); 956 spin_lock_bh(&icmp6_dst_lock);
951 rt->u.dst.next = ndisc_dst_gc_list; 957 rt->u.dst.next = icmp6_dst_gc_list;
952 ndisc_dst_gc_list = &rt->u.dst; 958 icmp6_dst_gc_list = &rt->u.dst;
953 spin_unlock_bh(&ndisc_lock); 959 spin_unlock_bh(&icmp6_dst_lock);
954 960
955 fib6_force_start_gc(); 961 fib6_force_start_gc(net);
956 962
957out: 963out:
958 return &rt->u.dst; 964 return &rt->u.dst;
959} 965}
960 966
961int ndisc_dst_gc(int *more) 967int icmp6_dst_gc(int *more)
962{ 968{
963 struct dst_entry *dst, *next, **pprev; 969 struct dst_entry *dst, *next, **pprev;
964 int freed; 970 int freed;
@@ -966,8 +972,8 @@ int ndisc_dst_gc(int *more)
966 next = NULL; 972 next = NULL;
967 freed = 0; 973 freed = 0;
968 974
969 spin_lock_bh(&ndisc_lock); 975 spin_lock_bh(&icmp6_dst_lock);
970 pprev = &ndisc_dst_gc_list; 976 pprev = &icmp6_dst_gc_list;
971 977
972 while ((dst = *pprev) != NULL) { 978 while ((dst = *pprev) != NULL) {
973 if (!atomic_read(&dst->__refcnt)) { 979 if (!atomic_read(&dst->__refcnt)) {
@@ -980,30 +986,33 @@ int ndisc_dst_gc(int *more)
980 } 986 }
981 } 987 }
982 988
983 spin_unlock_bh(&ndisc_lock); 989 spin_unlock_bh(&icmp6_dst_lock);
984 990
985 return freed; 991 return freed;
986} 992}
987 993
988static int ip6_dst_gc(struct dst_ops *ops) 994static int ip6_dst_gc(struct dst_ops *ops)
989{ 995{
990 static unsigned expire = 30*HZ;
991 static unsigned long last_gc;
992 unsigned long now = jiffies; 996 unsigned long now = jiffies;
993 997 struct net *net = ops->dst_net;
994 if (time_after(last_gc + init_net.ipv6.sysctl.ip6_rt_gc_min_interval, now) && 998 int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval;
995 atomic_read(&ip6_dst_ops.entries) <= init_net.ipv6.sysctl.ip6_rt_max_size) 999 int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size;
1000 int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
1001 int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout;
1002 unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc;
1003
1004 if (time_after(rt_last_gc + rt_min_interval, now) &&
1005 atomic_read(&ops->entries) <= rt_max_size)
996 goto out; 1006 goto out;
997 1007
998 expire++; 1008 net->ipv6.ip6_rt_gc_expire++;
999 fib6_run_gc(expire); 1009 fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net);
1000 last_gc = now; 1010 net->ipv6.ip6_rt_last_gc = now;
1001 if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh) 1011 if (atomic_read(&ops->entries) < ops->gc_thresh)
1002 expire = init_net.ipv6.sysctl.ip6_rt_gc_timeout>>1; 1012 net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1;
1003
1004out: 1013out:
1005 expire -= expire>>init_net.ipv6.sysctl.ip6_rt_gc_elasticity; 1014 net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity;
1006 return (atomic_read(&ip6_dst_ops.entries) > init_net.ipv6.sysctl.ip6_rt_max_size); 1015 return (atomic_read(&ops->entries) > rt_max_size);
1007} 1016}
1008 1017
1009/* Clean host part of a prefix. Not necessary in radix tree, 1018/* Clean host part of a prefix. Not necessary in radix tree,
@@ -1045,6 +1054,7 @@ int ipv6_get_hoplimit(struct net_device *dev)
1045int ip6_route_add(struct fib6_config *cfg) 1054int ip6_route_add(struct fib6_config *cfg)
1046{ 1055{
1047 int err; 1056 int err;
1057 struct net *net = cfg->fc_nlinfo.nl_net;
1048 struct rt6_info *rt = NULL; 1058 struct rt6_info *rt = NULL;
1049 struct net_device *dev = NULL; 1059 struct net_device *dev = NULL;
1050 struct inet6_dev *idev = NULL; 1060 struct inet6_dev *idev = NULL;
@@ -1059,7 +1069,7 @@ int ip6_route_add(struct fib6_config *cfg)
1059#endif 1069#endif
1060 if (cfg->fc_ifindex) { 1070 if (cfg->fc_ifindex) {
1061 err = -ENODEV; 1071 err = -ENODEV;
1062 dev = dev_get_by_index(&init_net, cfg->fc_ifindex); 1072 dev = dev_get_by_index(net, cfg->fc_ifindex);
1063 if (!dev) 1073 if (!dev)
1064 goto out; 1074 goto out;
1065 idev = in6_dev_get(dev); 1075 idev = in6_dev_get(dev);
@@ -1070,13 +1080,13 @@ int ip6_route_add(struct fib6_config *cfg)
1070 if (cfg->fc_metric == 0) 1080 if (cfg->fc_metric == 0)
1071 cfg->fc_metric = IP6_RT_PRIO_USER; 1081 cfg->fc_metric = IP6_RT_PRIO_USER;
1072 1082
1073 table = fib6_new_table(cfg->fc_table); 1083 table = fib6_new_table(net, cfg->fc_table);
1074 if (table == NULL) { 1084 if (table == NULL) {
1075 err = -ENOBUFS; 1085 err = -ENOBUFS;
1076 goto out; 1086 goto out;
1077 } 1087 }
1078 1088
1079 rt = ip6_dst_alloc(); 1089 rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
1080 1090
1081 if (rt == NULL) { 1091 if (rt == NULL) {
1082 err = -ENOMEM; 1092 err = -ENOMEM;
@@ -1117,12 +1127,12 @@ int ip6_route_add(struct fib6_config *cfg)
1117 if ((cfg->fc_flags & RTF_REJECT) || 1127 if ((cfg->fc_flags & RTF_REJECT) ||
1118 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { 1128 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
1119 /* hold loopback dev/idev if we haven't done so. */ 1129 /* hold loopback dev/idev if we haven't done so. */
1120 if (dev != init_net.loopback_dev) { 1130 if (dev != net->loopback_dev) {
1121 if (dev) { 1131 if (dev) {
1122 dev_put(dev); 1132 dev_put(dev);
1123 in6_dev_put(idev); 1133 in6_dev_put(idev);
1124 } 1134 }
1125 dev = init_net.loopback_dev; 1135 dev = net->loopback_dev;
1126 dev_hold(dev); 1136 dev_hold(dev);
1127 idev = in6_dev_get(dev); 1137 idev = in6_dev_get(dev);
1128 if (!idev) { 1138 if (!idev) {
@@ -1159,7 +1169,7 @@ int ip6_route_add(struct fib6_config *cfg)
1159 if (!(gwa_type&IPV6_ADDR_UNICAST)) 1169 if (!(gwa_type&IPV6_ADDR_UNICAST))
1160 goto out; 1170 goto out;
1161 1171
1162 grt = rt6_lookup(gw_addr, NULL, cfg->fc_ifindex, 1); 1172 grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1);
1163 1173
1164 err = -EHOSTUNREACH; 1174 err = -EHOSTUNREACH;
1165 if (grt == NULL) 1175 if (grt == NULL)
@@ -1226,10 +1236,13 @@ install_route:
1226 if (!rt->u.dst.metrics[RTAX_MTU-1]) 1236 if (!rt->u.dst.metrics[RTAX_MTU-1])
1227 rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); 1237 rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev);
1228 if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) 1238 if (!rt->u.dst.metrics[RTAX_ADVMSS-1])
1229 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); 1239 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));
1230 rt->u.dst.dev = dev; 1240 rt->u.dst.dev = dev;
1231 rt->rt6i_idev = idev; 1241 rt->rt6i_idev = idev;
1232 rt->rt6i_table = table; 1242 rt->rt6i_table = table;
1243
1244 cfg->fc_nlinfo.nl_net = dev->nd_net;
1245
1233 return __ip6_ins_rt(rt, &cfg->fc_nlinfo); 1246 return __ip6_ins_rt(rt, &cfg->fc_nlinfo);
1234 1247
1235out: 1248out:
@@ -1246,8 +1259,9 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
1246{ 1259{
1247 int err; 1260 int err;
1248 struct fib6_table *table; 1261 struct fib6_table *table;
1262 struct net *net = rt->rt6i_dev->nd_net;
1249 1263
1250 if (rt == &ip6_null_entry) 1264 if (rt == net->ipv6.ip6_null_entry)
1251 return -ENOENT; 1265 return -ENOENT;
1252 1266
1253 table = rt->rt6i_table; 1267 table = rt->rt6i_table;
@@ -1264,7 +1278,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
1264int ip6_del_rt(struct rt6_info *rt) 1278int ip6_del_rt(struct rt6_info *rt)
1265{ 1279{
1266 struct nl_info info = { 1280 struct nl_info info = {
1267 .nl_net = &init_net, 1281 .nl_net = rt->rt6i_dev->nd_net,
1268 }; 1282 };
1269 return __ip6_del_rt(rt, &info); 1283 return __ip6_del_rt(rt, &info);
1270} 1284}
@@ -1276,7 +1290,7 @@ static int ip6_route_del(struct fib6_config *cfg)
1276 struct rt6_info *rt; 1290 struct rt6_info *rt;
1277 int err = -ESRCH; 1291 int err = -ESRCH;
1278 1292
1279 table = fib6_get_table(cfg->fc_table); 1293 table = fib6_get_table(cfg->fc_nlinfo.nl_net, cfg->fc_table);
1280 if (table == NULL) 1294 if (table == NULL)
1281 return err; 1295 return err;
1282 1296
@@ -1316,7 +1330,8 @@ struct ip6rd_flowi {
1316 struct in6_addr gateway; 1330 struct in6_addr gateway;
1317}; 1331};
1318 1332
1319static struct rt6_info *__ip6_route_redirect(struct fib6_table *table, 1333static struct rt6_info *__ip6_route_redirect(struct net *net,
1334 struct fib6_table *table,
1320 struct flowi *fl, 1335 struct flowi *fl,
1321 int flags) 1336 int flags)
1322{ 1337{
@@ -1359,8 +1374,8 @@ restart:
1359 } 1374 }
1360 1375
1361 if (!rt) 1376 if (!rt)
1362 rt = &ip6_null_entry; 1377 rt = net->ipv6.ip6_null_entry;
1363 BACKTRACK(&fl->fl6_src); 1378 BACKTRACK(net, &fl->fl6_src);
1364out: 1379out:
1365 dst_hold(&rt->u.dst); 1380 dst_hold(&rt->u.dst);
1366 1381
@@ -1375,6 +1390,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1375 struct net_device *dev) 1390 struct net_device *dev)
1376{ 1391{
1377 int flags = RT6_LOOKUP_F_HAS_SADDR; 1392 int flags = RT6_LOOKUP_F_HAS_SADDR;
1393 struct net *net = dev->nd_net;
1378 struct ip6rd_flowi rdfl = { 1394 struct ip6rd_flowi rdfl = {
1379 .fl = { 1395 .fl = {
1380 .oif = dev->ifindex, 1396 .oif = dev->ifindex,
@@ -1391,7 +1407,8 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1391 if (rt6_need_strict(dest)) 1407 if (rt6_need_strict(dest))
1392 flags |= RT6_LOOKUP_F_IFACE; 1408 flags |= RT6_LOOKUP_F_IFACE;
1393 1409
1394 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); 1410 return (struct rt6_info *)fib6_rule_lookup(net, (struct flowi *)&rdfl,
1411 flags, __ip6_route_redirect);
1395} 1412}
1396 1413
1397void rt6_redirect(struct in6_addr *dest, struct in6_addr *src, 1414void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
@@ -1400,10 +1417,11 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1400{ 1417{
1401 struct rt6_info *rt, *nrt = NULL; 1418 struct rt6_info *rt, *nrt = NULL;
1402 struct netevent_redirect netevent; 1419 struct netevent_redirect netevent;
1420 struct net *net = neigh->dev->nd_net;
1403 1421
1404 rt = ip6_route_redirect(dest, src, saddr, neigh->dev); 1422 rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
1405 1423
1406 if (rt == &ip6_null_entry) { 1424 if (rt == net->ipv6.ip6_null_entry) {
1407 if (net_ratelimit()) 1425 if (net_ratelimit())
1408 printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " 1426 printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
1409 "for redirect target\n"); 1427 "for redirect target\n");
@@ -1448,7 +1466,8 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1448 nrt->rt6i_nexthop = neigh_clone(neigh); 1466 nrt->rt6i_nexthop = neigh_clone(neigh);
1449 /* Reset pmtu, it may be better */ 1467 /* Reset pmtu, it may be better */
1450 nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); 1468 nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
1451 nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); 1469 nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(neigh->dev->nd_net,
1470 dst_mtu(&nrt->u.dst));
1452 1471
1453 if (ip6_ins_rt(nrt)) 1472 if (ip6_ins_rt(nrt))
1454 goto out; 1473 goto out;
@@ -1476,9 +1495,10 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1476 struct net_device *dev, u32 pmtu) 1495 struct net_device *dev, u32 pmtu)
1477{ 1496{
1478 struct rt6_info *rt, *nrt; 1497 struct rt6_info *rt, *nrt;
1498 struct net *net = dev->nd_net;
1479 int allfrag = 0; 1499 int allfrag = 0;
1480 1500
1481 rt = rt6_lookup(daddr, saddr, dev->ifindex, 0); 1501 rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0);
1482 if (rt == NULL) 1502 if (rt == NULL)
1483 return; 1503 return;
1484 1504
@@ -1511,7 +1531,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1511 rt->u.dst.metrics[RTAX_MTU-1] = pmtu; 1531 rt->u.dst.metrics[RTAX_MTU-1] = pmtu;
1512 if (allfrag) 1532 if (allfrag)
1513 rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; 1533 rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
1514 dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires); 1534 dst_set_expires(&rt->u.dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
1515 rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; 1535 rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
1516 goto out; 1536 goto out;
1517 } 1537 }
@@ -1537,7 +1557,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1537 * which is 10 mins. After 10 mins the decreased pmtu is expired 1557 * which is 10 mins. After 10 mins the decreased pmtu is expired
1538 * and detecting PMTU increase will be automatically happened. 1558 * and detecting PMTU increase will be automatically happened.
1539 */ 1559 */
1540 dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires); 1560 dst_set_expires(&nrt->u.dst, net->ipv6.sysctl.ip6_rt_mtu_expires);
1541 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; 1561 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
1542 1562
1543 ip6_ins_rt(nrt); 1563 ip6_ins_rt(nrt);
@@ -1552,7 +1572,8 @@ out:
1552 1572
1553static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) 1573static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1554{ 1574{
1555 struct rt6_info *rt = ip6_dst_alloc(); 1575 struct net *net = ort->rt6i_dev->nd_net;
1576 struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
1556 1577
1557 if (rt) { 1578 if (rt) {
1558 rt->u.dst.input = ort->u.dst.input; 1579 rt->u.dst.input = ort->u.dst.input;
@@ -1583,14 +1604,15 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1583} 1604}
1584 1605
1585#ifdef CONFIG_IPV6_ROUTE_INFO 1606#ifdef CONFIG_IPV6_ROUTE_INFO
1586static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixlen, 1607static struct rt6_info *rt6_get_route_info(struct net *net,
1608 struct in6_addr *prefix, int prefixlen,
1587 struct in6_addr *gwaddr, int ifindex) 1609 struct in6_addr *gwaddr, int ifindex)
1588{ 1610{
1589 struct fib6_node *fn; 1611 struct fib6_node *fn;
1590 struct rt6_info *rt = NULL; 1612 struct rt6_info *rt = NULL;
1591 struct fib6_table *table; 1613 struct fib6_table *table;
1592 1614
1593 table = fib6_get_table(RT6_TABLE_INFO); 1615 table = fib6_get_table(net, RT6_TABLE_INFO);
1594 if (table == NULL) 1616 if (table == NULL)
1595 return NULL; 1617 return NULL;
1596 1618
@@ -1614,7 +1636,8 @@ out:
1614 return rt; 1636 return rt;
1615} 1637}
1616 1638
1617static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixlen, 1639static struct rt6_info *rt6_add_route_info(struct net *net,
1640 struct in6_addr *prefix, int prefixlen,
1618 struct in6_addr *gwaddr, int ifindex, 1641 struct in6_addr *gwaddr, int ifindex,
1619 unsigned pref) 1642 unsigned pref)
1620{ 1643{
@@ -1625,6 +1648,9 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
1625 .fc_dst_len = prefixlen, 1648 .fc_dst_len = prefixlen,
1626 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | 1649 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
1627 RTF_UP | RTF_PREF(pref), 1650 RTF_UP | RTF_PREF(pref),
1651 .fc_nlinfo.pid = 0,
1652 .fc_nlinfo.nlh = NULL,
1653 .fc_nlinfo.nl_net = net,
1628 }; 1654 };
1629 1655
1630 ipv6_addr_copy(&cfg.fc_dst, prefix); 1656 ipv6_addr_copy(&cfg.fc_dst, prefix);
@@ -1636,7 +1662,7 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
1636 1662
1637 ip6_route_add(&cfg); 1663 ip6_route_add(&cfg);
1638 1664
1639 return rt6_get_route_info(prefix, prefixlen, gwaddr, ifindex); 1665 return rt6_get_route_info(net, prefix, prefixlen, gwaddr, ifindex);
1640} 1666}
1641#endif 1667#endif
1642 1668
@@ -1645,7 +1671,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
1645 struct rt6_info *rt; 1671 struct rt6_info *rt;
1646 struct fib6_table *table; 1672 struct fib6_table *table;
1647 1673
1648 table = fib6_get_table(RT6_TABLE_DFLT); 1674 table = fib6_get_table(dev->nd_net, RT6_TABLE_DFLT);
1649 if (table == NULL) 1675 if (table == NULL)
1650 return NULL; 1676 return NULL;
1651 1677
@@ -1674,6 +1700,9 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
1674 .fc_ifindex = dev->ifindex, 1700 .fc_ifindex = dev->ifindex,
1675 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | 1701 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
1676 RTF_UP | RTF_EXPIRES | RTF_PREF(pref), 1702 RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
1703 .fc_nlinfo.pid = 0,
1704 .fc_nlinfo.nlh = NULL,
1705 .fc_nlinfo.nl_net = dev->nd_net,
1677 }; 1706 };
1678 1707
1679 ipv6_addr_copy(&cfg.fc_gateway, gwaddr); 1708 ipv6_addr_copy(&cfg.fc_gateway, gwaddr);
@@ -1683,13 +1712,13 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
1683 return rt6_get_dflt_router(gwaddr, dev); 1712 return rt6_get_dflt_router(gwaddr, dev);
1684} 1713}
1685 1714
1686void rt6_purge_dflt_routers(void) 1715void rt6_purge_dflt_routers(struct net *net)
1687{ 1716{
1688 struct rt6_info *rt; 1717 struct rt6_info *rt;
1689 struct fib6_table *table; 1718 struct fib6_table *table;
1690 1719
1691 /* NOTE: Keep consistent with rt6_get_dflt_router */ 1720 /* NOTE: Keep consistent with rt6_get_dflt_router */
1692 table = fib6_get_table(RT6_TABLE_DFLT); 1721 table = fib6_get_table(net, RT6_TABLE_DFLT);
1693 if (table == NULL) 1722 if (table == NULL)
1694 return; 1723 return;
1695 1724
@@ -1706,7 +1735,8 @@ restart:
1706 read_unlock_bh(&table->tb6_lock); 1735 read_unlock_bh(&table->tb6_lock);
1707} 1736}
1708 1737
1709static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg, 1738static void rtmsg_to_fib6_config(struct net *net,
1739 struct in6_rtmsg *rtmsg,
1710 struct fib6_config *cfg) 1740 struct fib6_config *cfg)
1711{ 1741{
1712 memset(cfg, 0, sizeof(*cfg)); 1742 memset(cfg, 0, sizeof(*cfg));
@@ -1719,14 +1749,14 @@ static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg,
1719 cfg->fc_src_len = rtmsg->rtmsg_src_len; 1749 cfg->fc_src_len = rtmsg->rtmsg_src_len;
1720 cfg->fc_flags = rtmsg->rtmsg_flags; 1750 cfg->fc_flags = rtmsg->rtmsg_flags;
1721 1751
1722 cfg->fc_nlinfo.nl_net = &init_net; 1752 cfg->fc_nlinfo.nl_net = net;
1723 1753
1724 ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); 1754 ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst);
1725 ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); 1755 ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src);
1726 ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); 1756 ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway);
1727} 1757}
1728 1758
1729int ipv6_route_ioctl(unsigned int cmd, void __user *arg) 1759int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
1730{ 1760{
1731 struct fib6_config cfg; 1761 struct fib6_config cfg;
1732 struct in6_rtmsg rtmsg; 1762 struct in6_rtmsg rtmsg;
@@ -1742,7 +1772,7 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1742 if (err) 1772 if (err)
1743 return -EFAULT; 1773 return -EFAULT;
1744 1774
1745 rtmsg_to_fib6_config(&rtmsg, &cfg); 1775 rtmsg_to_fib6_config(net, &rtmsg, &cfg);
1746 1776
1747 rtnl_lock(); 1777 rtnl_lock();
1748 switch (cmd) { 1778 switch (cmd) {
@@ -1821,21 +1851,22 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1821 const struct in6_addr *addr, 1851 const struct in6_addr *addr,
1822 int anycast) 1852 int anycast)
1823{ 1853{
1824 struct rt6_info *rt = ip6_dst_alloc(); 1854 struct net *net = idev->dev->nd_net;
1855 struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
1825 1856
1826 if (rt == NULL) 1857 if (rt == NULL)
1827 return ERR_PTR(-ENOMEM); 1858 return ERR_PTR(-ENOMEM);
1828 1859
1829 dev_hold(init_net.loopback_dev); 1860 dev_hold(net->loopback_dev);
1830 in6_dev_hold(idev); 1861 in6_dev_hold(idev);
1831 1862
1832 rt->u.dst.flags = DST_HOST; 1863 rt->u.dst.flags = DST_HOST;
1833 rt->u.dst.input = ip6_input; 1864 rt->u.dst.input = ip6_input;
1834 rt->u.dst.output = ip6_output; 1865 rt->u.dst.output = ip6_output;
1835 rt->rt6i_dev = init_net.loopback_dev; 1866 rt->rt6i_dev = net->loopback_dev;
1836 rt->rt6i_idev = idev; 1867 rt->rt6i_idev = idev;
1837 rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); 1868 rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
1838 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); 1869 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));
1839 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; 1870 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1;
1840 rt->u.dst.obsolete = -1; 1871 rt->u.dst.obsolete = -1;
1841 1872
@@ -1852,26 +1883,39 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1852 1883
1853 ipv6_addr_copy(&rt->rt6i_dst.addr, addr); 1884 ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
1854 rt->rt6i_dst.plen = 128; 1885 rt->rt6i_dst.plen = 128;
1855 rt->rt6i_table = fib6_get_table(RT6_TABLE_LOCAL); 1886 rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL);
1856 1887
1857 atomic_set(&rt->u.dst.__refcnt, 1); 1888 atomic_set(&rt->u.dst.__refcnt, 1);
1858 1889
1859 return rt; 1890 return rt;
1860} 1891}
1861 1892
1893struct arg_dev_net {
1894 struct net_device *dev;
1895 struct net *net;
1896};
1897
1862static int fib6_ifdown(struct rt6_info *rt, void *arg) 1898static int fib6_ifdown(struct rt6_info *rt, void *arg)
1863{ 1899{
1864 if (((void*)rt->rt6i_dev == arg || arg == NULL) && 1900 struct net_device *dev = ((struct arg_dev_net *)arg)->dev;
1865 rt != &ip6_null_entry) { 1901 struct net *net = ((struct arg_dev_net *)arg)->net;
1902
1903 if (((void *)rt->rt6i_dev == dev || dev == NULL) &&
1904 rt != net->ipv6.ip6_null_entry) {
1866 RT6_TRACE("deleted by ifdown %p\n", rt); 1905 RT6_TRACE("deleted by ifdown %p\n", rt);
1867 return -1; 1906 return -1;
1868 } 1907 }
1869 return 0; 1908 return 0;
1870} 1909}
1871 1910
1872void rt6_ifdown(struct net_device *dev) 1911void rt6_ifdown(struct net *net, struct net_device *dev)
1873{ 1912{
1874 fib6_clean_all(fib6_ifdown, 0, dev); 1913 struct arg_dev_net adn = {
1914 .dev = dev,
1915 .net = net,
1916 };
1917
1918 fib6_clean_all(net, fib6_ifdown, 0, &adn);
1875} 1919}
1876 1920
1877struct rt6_mtu_change_arg 1921struct rt6_mtu_change_arg
@@ -1884,6 +1928,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
1884{ 1928{
1885 struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg; 1929 struct rt6_mtu_change_arg *arg = (struct rt6_mtu_change_arg *) p_arg;
1886 struct inet6_dev *idev; 1930 struct inet6_dev *idev;
1931 struct net *net = arg->dev->nd_net;
1887 1932
1888 /* In IPv6 pmtu discovery is not optional, 1933 /* In IPv6 pmtu discovery is not optional,
1889 so that RTAX_MTU lock cannot disable it. 1934 so that RTAX_MTU lock cannot disable it.
@@ -1915,7 +1960,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
1915 (dst_mtu(&rt->u.dst) < arg->mtu && 1960 (dst_mtu(&rt->u.dst) < arg->mtu &&
1916 dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) { 1961 dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) {
1917 rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu; 1962 rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu;
1918 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu); 1963 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, arg->mtu);
1919 } 1964 }
1920 return 0; 1965 return 0;
1921} 1966}
@@ -1927,7 +1972,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu)
1927 .mtu = mtu, 1972 .mtu = mtu,
1928 }; 1973 };
1929 1974
1930 fib6_clean_all(rt6_mtu_change_route, 0, &arg); 1975 fib6_clean_all(dev->nd_net, rt6_mtu_change_route, 0, &arg);
1931} 1976}
1932 1977
1933static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { 1978static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
@@ -2010,13 +2055,9 @@ errout:
2010 2055
2011static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2056static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
2012{ 2057{
2013 struct net *net = skb->sk->sk_net;
2014 struct fib6_config cfg; 2058 struct fib6_config cfg;
2015 int err; 2059 int err;
2016 2060
2017 if (net != &init_net)
2018 return -EINVAL;
2019
2020 err = rtm_to_fib6_config(skb, nlh, &cfg); 2061 err = rtm_to_fib6_config(skb, nlh, &cfg);
2021 if (err < 0) 2062 if (err < 0)
2022 return err; 2063 return err;
@@ -2026,13 +2067,9 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
2026 2067
2027static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2068static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
2028{ 2069{
2029 struct net *net = skb->sk->sk_net;
2030 struct fib6_config cfg; 2070 struct fib6_config cfg;
2031 int err; 2071 int err;
2032 2072
2033 if (net != &init_net)
2034 return -EINVAL;
2035
2036 err = rtm_to_fib6_config(skb, nlh, &cfg); 2073 err = rtm_to_fib6_config(skb, nlh, &cfg);
2037 if (err < 0) 2074 if (err < 0)
2038 return err; 2075 return err;
@@ -2122,7 +2159,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2122 NLA_PUT_U32(skb, RTA_IIF, iif); 2159 NLA_PUT_U32(skb, RTA_IIF, iif);
2123 else if (dst) { 2160 else if (dst) {
2124 struct in6_addr saddr_buf; 2161 struct in6_addr saddr_buf;
2125 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0) 2162 if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
2163 dst, &saddr_buf) == 0)
2126 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2164 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
2127 } 2165 }
2128 2166
@@ -2175,9 +2213,6 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2175 struct flowi fl; 2213 struct flowi fl;
2176 int err, iif = 0; 2214 int err, iif = 0;
2177 2215
2178 if (net != &init_net)
2179 return -EINVAL;
2180
2181 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); 2216 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
2182 if (err < 0) 2217 if (err < 0)
2183 goto errout; 2218 goto errout;
@@ -2207,7 +2242,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2207 2242
2208 if (iif) { 2243 if (iif) {
2209 struct net_device *dev; 2244 struct net_device *dev;
2210 dev = __dev_get_by_index(&init_net, iif); 2245 dev = __dev_get_by_index(net, iif);
2211 if (!dev) { 2246 if (!dev) {
2212 err = -ENODEV; 2247 err = -ENODEV;
2213 goto errout; 2248 goto errout;
@@ -2226,7 +2261,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2226 skb_reset_mac_header(skb); 2261 skb_reset_mac_header(skb);
2227 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); 2262 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
2228 2263
2229 rt = (struct rt6_info*) ip6_route_output(NULL, &fl); 2264 rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
2230 skb->dst = &rt->u.dst; 2265 skb->dst = &rt->u.dst;
2231 2266
2232 err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, 2267 err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
@@ -2237,7 +2272,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2237 goto errout; 2272 goto errout;
2238 } 2273 }
2239 2274
2240 err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); 2275 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
2241errout: 2276errout:
2242 return err; 2277 return err;
2243} 2278}
@@ -2245,6 +2280,7 @@ errout:
2245void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) 2280void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2246{ 2281{
2247 struct sk_buff *skb; 2282 struct sk_buff *skb;
2283 struct net *net = info->nl_net;
2248 u32 seq; 2284 u32 seq;
2249 int err; 2285 int err;
2250 2286
@@ -2263,11 +2299,31 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2263 kfree_skb(skb); 2299 kfree_skb(skb);
2264 goto errout; 2300 goto errout;
2265 } 2301 }
2266 err = rtnl_notify(skb, &init_net, info->pid, 2302 err = rtnl_notify(skb, net, info->pid, RTNLGRP_IPV6_ROUTE,
2267 RTNLGRP_IPV6_ROUTE, info->nlh, gfp_any()); 2303 info->nlh, gfp_any());
2268errout: 2304errout:
2269 if (err < 0) 2305 if (err < 0)
2270 rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_ROUTE, err); 2306 rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err);
2307}
2308
2309static int ip6_route_dev_notify(struct notifier_block *this,
2310 unsigned long event, void *data)
2311{
2312 struct net_device *dev = (struct net_device *)data;
2313 struct net *net = dev->nd_net;
2314
2315 if (event == NETDEV_REGISTER && (dev->flags & IFF_LOOPBACK)) {
2316 net->ipv6.ip6_null_entry->u.dst.dev = dev;
2317 net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev);
2318#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2319 net->ipv6.ip6_prohibit_entry->u.dst.dev = dev;
2320 net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
2321 net->ipv6.ip6_blk_hole_entry->u.dst.dev = dev;
2322 net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
2323#endif
2324 }
2325
2326 return NOTIFY_OK;
2271} 2327}
2272 2328
2273/* 2329/*
@@ -2316,13 +2372,25 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2316 2372
2317static int ipv6_route_show(struct seq_file *m, void *v) 2373static int ipv6_route_show(struct seq_file *m, void *v)
2318{ 2374{
2319 fib6_clean_all(rt6_info_route, 0, m); 2375 struct net *net = (struct net *)m->private;
2376 fib6_clean_all(net, rt6_info_route, 0, m);
2320 return 0; 2377 return 0;
2321} 2378}
2322 2379
2323static int ipv6_route_open(struct inode *inode, struct file *file) 2380static int ipv6_route_open(struct inode *inode, struct file *file)
2324{ 2381{
2325 return single_open(file, ipv6_route_show, NULL); 2382 struct net *net = get_proc_net(inode);
2383 if (!net)
2384 return -ENXIO;
2385 return single_open(file, ipv6_route_show, net);
2386}
2387
2388static int ipv6_route_release(struct inode *inode, struct file *file)
2389{
2390 struct seq_file *seq = file->private_data;
2391 struct net *net = seq->private;
2392 put_net(net);
2393 return single_release(inode, file);
2326} 2394}
2327 2395
2328static const struct file_operations ipv6_route_proc_fops = { 2396static const struct file_operations ipv6_route_proc_fops = {
@@ -2330,24 +2398,36 @@ static const struct file_operations ipv6_route_proc_fops = {
2330 .open = ipv6_route_open, 2398 .open = ipv6_route_open,
2331 .read = seq_read, 2399 .read = seq_read,
2332 .llseek = seq_lseek, 2400 .llseek = seq_lseek,
2333 .release = single_release, 2401 .release = ipv6_route_release,
2334}; 2402};
2335 2403
2336static int rt6_stats_seq_show(struct seq_file *seq, void *v) 2404static int rt6_stats_seq_show(struct seq_file *seq, void *v)
2337{ 2405{
2406 struct net *net = (struct net *)seq->private;
2338 seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n", 2407 seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
2339 rt6_stats.fib_nodes, rt6_stats.fib_route_nodes, 2408 net->ipv6.rt6_stats->fib_nodes,
2340 rt6_stats.fib_rt_alloc, rt6_stats.fib_rt_entries, 2409 net->ipv6.rt6_stats->fib_route_nodes,
2341 rt6_stats.fib_rt_cache, 2410 net->ipv6.rt6_stats->fib_rt_alloc,
2342 atomic_read(&ip6_dst_ops.entries), 2411 net->ipv6.rt6_stats->fib_rt_entries,
2343 rt6_stats.fib_discarded_routes); 2412 net->ipv6.rt6_stats->fib_rt_cache,
2413 atomic_read(&net->ipv6.ip6_dst_ops->entries),
2414 net->ipv6.rt6_stats->fib_discarded_routes);
2344 2415
2345 return 0; 2416 return 0;
2346} 2417}
2347 2418
2348static int rt6_stats_seq_open(struct inode *inode, struct file *file) 2419static int rt6_stats_seq_open(struct inode *inode, struct file *file)
2349{ 2420{
2350 return single_open(file, rt6_stats_seq_show, NULL); 2421 struct net *net = get_proc_net(inode);
2422 return single_open(file, rt6_stats_seq_show, net);
2423}
2424
2425static int rt6_stats_seq_release(struct inode *inode, struct file *file)
2426{
2427 struct seq_file *seq = file->private_data;
2428 struct net *net = (struct net *)seq->private;
2429 put_net(net);
2430 return single_release(inode, file);
2351} 2431}
2352 2432
2353static const struct file_operations rt6_stats_seq_fops = { 2433static const struct file_operations rt6_stats_seq_fops = {
@@ -2355,42 +2435,8 @@ static const struct file_operations rt6_stats_seq_fops = {
2355 .open = rt6_stats_seq_open, 2435 .open = rt6_stats_seq_open,
2356 .read = seq_read, 2436 .read = seq_read,
2357 .llseek = seq_lseek, 2437 .llseek = seq_lseek,
2358 .release = single_release, 2438 .release = rt6_stats_seq_release,
2359}; 2439};
2360
2361static int ipv6_route_proc_init(struct net *net)
2362{
2363 int ret = -ENOMEM;
2364 if (!proc_net_fops_create(net, "ipv6_route",
2365 0, &ipv6_route_proc_fops))
2366 goto out;
2367
2368 if (!proc_net_fops_create(net, "rt6_stats",
2369 S_IRUGO, &rt6_stats_seq_fops))
2370 goto out_ipv6_route;
2371
2372 ret = 0;
2373out:
2374 return ret;
2375out_ipv6_route:
2376 proc_net_remove(net, "ipv6_route");
2377 goto out;
2378}
2379
2380static void ipv6_route_proc_fini(struct net *net)
2381{
2382 proc_net_remove(net, "ipv6_route");
2383 proc_net_remove(net, "rt6_stats");
2384}
2385#else
2386static inline int ipv6_route_proc_init(struct net *net)
2387{
2388 return 0;
2389}
2390static inline void ipv6_route_proc_fini(struct net *net)
2391{
2392 return ;
2393}
2394#endif /* CONFIG_PROC_FS */ 2440#endif /* CONFIG_PROC_FS */
2395 2441
2396#ifdef CONFIG_SYSCTL 2442#ifdef CONFIG_SYSCTL
@@ -2399,10 +2445,11 @@ static
2399int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, 2445int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
2400 void __user *buffer, size_t *lenp, loff_t *ppos) 2446 void __user *buffer, size_t *lenp, loff_t *ppos)
2401{ 2447{
2402 int delay = init_net.ipv6.sysctl.flush_delay; 2448 struct net *net = current->nsproxy->net_ns;
2449 int delay = net->ipv6.sysctl.flush_delay;
2403 if (write) { 2450 if (write) {
2404 proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 2451 proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
2405 fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay); 2452 fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net);
2406 return 0; 2453 return 0;
2407 } else 2454 } else
2408 return -EINVAL; 2455 return -EINVAL;
@@ -2419,7 +2466,7 @@ ctl_table ipv6_route_table_template[] = {
2419 { 2466 {
2420 .ctl_name = NET_IPV6_ROUTE_GC_THRESH, 2467 .ctl_name = NET_IPV6_ROUTE_GC_THRESH,
2421 .procname = "gc_thresh", 2468 .procname = "gc_thresh",
2422 .data = &ip6_dst_ops.gc_thresh, 2469 .data = &ip6_dst_ops_template.gc_thresh,
2423 .maxlen = sizeof(int), 2470 .maxlen = sizeof(int),
2424 .mode = 0644, 2471 .mode = 0644,
2425 .proc_handler = &proc_dointvec, 2472 .proc_handler = &proc_dointvec,
@@ -2505,33 +2552,141 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
2505 table = kmemdup(ipv6_route_table_template, 2552 table = kmemdup(ipv6_route_table_template,
2506 sizeof(ipv6_route_table_template), 2553 sizeof(ipv6_route_table_template),
2507 GFP_KERNEL); 2554 GFP_KERNEL);
2555
2556 if (table) {
2557 table[0].data = &net->ipv6.sysctl.flush_delay;
2558 table[1].data = &net->ipv6.ip6_dst_ops->gc_thresh;
2559 table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
2560 table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
2561 table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
2562 table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval;
2563 table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
2564 table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
2565 table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
2566 }
2567
2508 return table; 2568 return table;
2509} 2569}
2510#endif 2570#endif
2511 2571
2572static int ip6_route_net_init(struct net *net)
2573{
2574 int ret = 0;
2575
2576 ret = -ENOMEM;
2577 net->ipv6.ip6_dst_ops = kmemdup(&ip6_dst_ops_template,
2578 sizeof(*net->ipv6.ip6_dst_ops),
2579 GFP_KERNEL);
2580 if (!net->ipv6.ip6_dst_ops)
2581 goto out;
2582 net->ipv6.ip6_dst_ops->dst_net = net;
2583
2584 net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
2585 sizeof(*net->ipv6.ip6_null_entry),
2586 GFP_KERNEL);
2587 if (!net->ipv6.ip6_null_entry)
2588 goto out_ip6_dst_ops;
2589 net->ipv6.ip6_null_entry->u.dst.path =
2590 (struct dst_entry *)net->ipv6.ip6_null_entry;
2591 net->ipv6.ip6_null_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
2592
2593#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2594 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
2595 sizeof(*net->ipv6.ip6_prohibit_entry),
2596 GFP_KERNEL);
2597 if (!net->ipv6.ip6_prohibit_entry) {
2598 kfree(net->ipv6.ip6_null_entry);
2599 goto out;
2600 }
2601 net->ipv6.ip6_prohibit_entry->u.dst.path =
2602 (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
2603 net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
2604
2605 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
2606 sizeof(*net->ipv6.ip6_blk_hole_entry),
2607 GFP_KERNEL);
2608 if (!net->ipv6.ip6_blk_hole_entry) {
2609 kfree(net->ipv6.ip6_null_entry);
2610 kfree(net->ipv6.ip6_prohibit_entry);
2611 goto out;
2612 }
2613 net->ipv6.ip6_blk_hole_entry->u.dst.path =
2614 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
2615 net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
2616#endif
2617
2618#ifdef CONFIG_PROC_FS
2619 proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
2620 proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
2621#endif
2622 net->ipv6.ip6_rt_gc_expire = 30*HZ;
2623
2624 ret = 0;
2625out:
2626 return ret;
2627
2628out_ip6_dst_ops:
2629 kfree(net->ipv6.ip6_dst_ops);
2630 goto out;
2631}
2632
2633static void ip6_route_net_exit(struct net *net)
2634{
2635#ifdef CONFIG_PROC_FS
2636 proc_net_remove(net, "ipv6_route");
2637 proc_net_remove(net, "rt6_stats");
2638#endif
2639 kfree(net->ipv6.ip6_null_entry);
2640#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2641 kfree(net->ipv6.ip6_prohibit_entry);
2642 kfree(net->ipv6.ip6_blk_hole_entry);
2643#endif
2644 kfree(net->ipv6.ip6_dst_ops);
2645}
2646
2647static struct pernet_operations ip6_route_net_ops = {
2648 .init = ip6_route_net_init,
2649 .exit = ip6_route_net_exit,
2650};
2651
2652static struct notifier_block ip6_route_dev_notifier = {
2653 .notifier_call = ip6_route_dev_notify,
2654 .priority = 0,
2655};
2656
2512int __init ip6_route_init(void) 2657int __init ip6_route_init(void)
2513{ 2658{
2514 int ret; 2659 int ret;
2515 2660
2516 ip6_dst_ops.kmem_cachep = 2661 ret = -ENOMEM;
2662 ip6_dst_ops_template.kmem_cachep =
2517 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, 2663 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
2518 SLAB_HWCACHE_ALIGN, NULL); 2664 SLAB_HWCACHE_ALIGN, NULL);
2519 if (!ip6_dst_ops.kmem_cachep) 2665 if (!ip6_dst_ops_template.kmem_cachep)
2520 return -ENOMEM; 2666 goto out;;
2521 2667
2522 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep; 2668 ret = register_pernet_subsys(&ip6_route_net_ops);
2523
2524 ret = fib6_init();
2525 if (ret) 2669 if (ret)
2526 goto out_kmem_cache; 2670 goto out_kmem_cache;
2527 2671
2528 ret = ipv6_route_proc_init(&init_net); 2672 /* Registering of the loopback is done before this portion of code,
2673 * the loopback reference in rt6_info will not be taken, do it
2674 * manually for init_net */
2675 init_net.ipv6.ip6_null_entry->u.dst.dev = init_net.loopback_dev;
2676 init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
2677 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
2678 init_net.ipv6.ip6_prohibit_entry->u.dst.dev = init_net.loopback_dev;
2679 init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
2680 init_net.ipv6.ip6_blk_hole_entry->u.dst.dev = init_net.loopback_dev;
2681 init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
2682 #endif
2683 ret = fib6_init();
2529 if (ret) 2684 if (ret)
2530 goto out_fib6_init; 2685 goto out_register_subsys;
2531 2686
2532 ret = xfrm6_init(); 2687 ret = xfrm6_init();
2533 if (ret) 2688 if (ret)
2534 goto out_proc_init; 2689 goto out_fib6_init;
2535 2690
2536 ret = fib6_rules_init(); 2691 ret = fib6_rules_init();
2537 if (ret) 2692 if (ret)
@@ -2543,7 +2698,10 @@ int __init ip6_route_init(void)
2543 __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL)) 2698 __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL))
2544 goto fib6_rules_init; 2699 goto fib6_rules_init;
2545 2700
2546 ret = 0; 2701 ret = register_netdevice_notifier(&ip6_route_dev_notifier);
2702 if (ret)
2703 goto fib6_rules_init;
2704
2547out: 2705out:
2548 return ret; 2706 return ret;
2549 2707
@@ -2551,22 +2709,21 @@ fib6_rules_init:
2551 fib6_rules_cleanup(); 2709 fib6_rules_cleanup();
2552xfrm6_init: 2710xfrm6_init:
2553 xfrm6_fini(); 2711 xfrm6_fini();
2554out_proc_init:
2555 ipv6_route_proc_fini(&init_net);
2556out_fib6_init: 2712out_fib6_init:
2557 rt6_ifdown(NULL);
2558 fib6_gc_cleanup(); 2713 fib6_gc_cleanup();
2714out_register_subsys:
2715 unregister_pernet_subsys(&ip6_route_net_ops);
2559out_kmem_cache: 2716out_kmem_cache:
2560 kmem_cache_destroy(ip6_dst_ops.kmem_cachep); 2717 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
2561 goto out; 2718 goto out;
2562} 2719}
2563 2720
2564void ip6_route_cleanup(void) 2721void ip6_route_cleanup(void)
2565{ 2722{
2723 unregister_netdevice_notifier(&ip6_route_dev_notifier);
2566 fib6_rules_cleanup(); 2724 fib6_rules_cleanup();
2567 ipv6_route_proc_fini(&init_net);
2568 xfrm6_fini(); 2725 xfrm6_fini();
2569 rt6_ifdown(NULL);
2570 fib6_gc_cleanup(); 2726 fib6_gc_cleanup();
2571 kmem_cache_destroy(ip6_dst_ops.kmem_cachep); 2727 unregister_pernet_subsys(&ip6_route_net_ops);
2728 kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
2572} 2729}