aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig14
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ip6mr.c428
3 files changed, 377 insertions, 67 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index a578096152ab..36d7437ac054 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -229,6 +229,20 @@ config IPV6_MROUTE
229 Experimental support for IPv6 multicast forwarding. 229 Experimental support for IPv6 multicast forwarding.
230 If unsure, say N. 230 If unsure, say N.
231 231
232config IPV6_MROUTE_MULTIPLE_TABLES
233 bool "IPv6: multicast policy routing"
234 depends on IPV6_MROUTE
235 select FIB_RULES
236 help
237 Normally, a multicast router runs a userspace daemon and decides
238 what to do with a multicast packet based on the source and
239 destination addresses. If you say Y here, the multicast router
240 will also be able to take interfaces and packet marks into
241 account and run multiple instances of userspace daemons
242 simultaneously, each one handling a single table.
243
244 If unsure, say N.
245
232config IPV6_PIMSM_V2 246config IPV6_PIMSM_V2
233 bool "IPv6: PIM-SM version 2 support (EXPERIMENTAL)" 247 bool "IPv6: PIM-SM version 2 support (EXPERIMENTAL)"
234 depends on IPV6_MROUTE 248 depends on IPV6_MROUTE
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5173acaeb501..cd963f64e27c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -108,7 +108,7 @@ static int ip6_finish_output2(struct sk_buff *skb)
108 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); 108 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
109 109
110 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) && 110 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) &&
111 ((mroute6_socket(dev_net(dev)) && 111 ((mroute6_socket(dev_net(dev), skb) &&
112 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || 112 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
113 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, 113 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
114 &ipv6_hdr(skb)->saddr))) { 114 &ipv6_hdr(skb)->saddr))) {
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 9419fceeed41..c2920a1a6db3 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -42,6 +42,7 @@
42#include <linux/if_arp.h> 42#include <linux/if_arp.h>
43#include <net/checksum.h> 43#include <net/checksum.h>
44#include <net/netlink.h> 44#include <net/netlink.h>
45#include <net/fib_rules.h>
45 46
46#include <net/ipv6.h> 47#include <net/ipv6.h>
47#include <net/ip6_route.h> 48#include <net/ip6_route.h>
@@ -52,9 +53,11 @@
52#include <net/ip6_checksum.h> 53#include <net/ip6_checksum.h>
53 54
54struct mr6_table { 55struct mr6_table {
56 struct list_head list;
55#ifdef CONFIG_NET_NS 57#ifdef CONFIG_NET_NS
56 struct net *net; 58 struct net *net;
57#endif 59#endif
60 u32 id;
58 struct sock *mroute6_sk; 61 struct sock *mroute6_sk;
59 struct timer_list ipmr_expire_timer; 62 struct timer_list ipmr_expire_timer;
60 struct list_head mfc6_unres_queue; 63 struct list_head mfc6_unres_queue;
@@ -69,6 +72,14 @@ struct mr6_table {
69#endif 72#endif
70}; 73};
71 74
75struct ip6mr_rule {
76 struct fib_rule common;
77};
78
79struct ip6mr_result {
80 struct mr6_table *mrt;
81};
82
72/* Big lock, protecting vif table, mrt cache and mroute socket state. 83/* Big lock, protecting vif table, mrt cache and mroute socket state.
73 Note that the changes are semaphored via rtnl_lock. 84 Note that the changes are semaphored via rtnl_lock.
74 */ 85 */
@@ -94,6 +105,9 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
94 105
95static struct kmem_cache *mrt_cachep __read_mostly; 106static struct kmem_cache *mrt_cachep __read_mostly;
96 107
108static struct mr6_table *ip6mr_new_table(struct net *net, u32 id);
109static void ip6mr_free_table(struct mr6_table *mrt);
110
97static int ip6_mr_forward(struct net *net, struct mr6_table *mrt, 111static int ip6_mr_forward(struct net *net, struct mr6_table *mrt,
98 struct sk_buff *skb, struct mfc6_cache *cache); 112 struct sk_buff *skb, struct mfc6_cache *cache);
99static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt, 113static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
@@ -101,12 +115,220 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
101static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, 115static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
102 struct mfc6_cache *c, struct rtmsg *rtm); 116 struct mfc6_cache *c, struct rtmsg *rtm);
103static void mroute_clean_tables(struct mr6_table *mrt); 117static void mroute_clean_tables(struct mr6_table *mrt);
118static void ipmr_expire_process(unsigned long arg);
119
120#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
121#define ip6mr_for_each_table(mrt, met) \
122 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list)
123
124static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
125{
126 struct mr6_table *mrt;
104 127
128 ip6mr_for_each_table(mrt, net) {
129 if (mrt->id == id)
130 return mrt;
131 }
132 return NULL;
133}
134
135static int ip6mr_fib_lookup(struct net *net, struct flowi *flp,
136 struct mr6_table **mrt)
137{
138 struct ip6mr_result res;
139 struct fib_lookup_arg arg = { .result = &res, };
140 int err;
141
142 err = fib_rules_lookup(net->ipv6.mr6_rules_ops, flp, 0, &arg);
143 if (err < 0)
144 return err;
145 *mrt = res.mrt;
146 return 0;
147}
148
149static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
150 int flags, struct fib_lookup_arg *arg)
151{
152 struct ip6mr_result *res = arg->result;
153 struct mr6_table *mrt;
154
155 switch (rule->action) {
156 case FR_ACT_TO_TBL:
157 break;
158 case FR_ACT_UNREACHABLE:
159 return -ENETUNREACH;
160 case FR_ACT_PROHIBIT:
161 return -EACCES;
162 case FR_ACT_BLACKHOLE:
163 default:
164 return -EINVAL;
165 }
166
167 mrt = ip6mr_get_table(rule->fr_net, rule->table);
168 if (mrt == NULL)
169 return -EAGAIN;
170 res->mrt = mrt;
171 return 0;
172}
173
174static int ip6mr_rule_match(struct fib_rule *rule, struct flowi *flp, int flags)
175{
176 return 1;
177}
178
179static const struct nla_policy ip6mr_rule_policy[FRA_MAX + 1] = {
180 FRA_GENERIC_POLICY,
181};
182
183static int ip6mr_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
184 struct fib_rule_hdr *frh, struct nlattr **tb)
185{
186 return 0;
187}
188
189static int ip6mr_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
190 struct nlattr **tb)
191{
192 return 1;
193}
194
195static int ip6mr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
196 struct fib_rule_hdr *frh)
197{
198 frh->dst_len = 0;
199 frh->src_len = 0;
200 frh->tos = 0;
201 return 0;
202}
203
204static const struct fib_rules_ops __net_initdata ip6mr_rules_ops_template = {
205 .family = RTNL_FAMILY_IP6MR,
206 .rule_size = sizeof(struct ip6mr_rule),
207 .addr_size = sizeof(struct in6_addr),
208 .action = ip6mr_rule_action,
209 .match = ip6mr_rule_match,
210 .configure = ip6mr_rule_configure,
211 .compare = ip6mr_rule_compare,
212 .default_pref = fib_default_rule_pref,
213 .fill = ip6mr_rule_fill,
214 .nlgroup = RTNLGRP_IPV6_RULE,
215 .policy = ip6mr_rule_policy,
216 .owner = THIS_MODULE,
217};
218
219static int __net_init ip6mr_rules_init(struct net *net)
220{
221 struct fib_rules_ops *ops;
222 struct mr6_table *mrt;
223 int err;
224
225 ops = fib_rules_register(&ip6mr_rules_ops_template, net);
226 if (IS_ERR(ops))
227 return PTR_ERR(ops);
228
229 INIT_LIST_HEAD(&net->ipv6.mr6_tables);
230
231 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
232 if (mrt == NULL) {
233 err = -ENOMEM;
234 goto err1;
235 }
236
237 err = fib_default_rule_add(ops, 0x7fff, RT6_TABLE_DFLT, 0);
238 if (err < 0)
239 goto err2;
240
241 net->ipv6.mr6_rules_ops = ops;
242 return 0;
243
244err2:
245 kfree(mrt);
246err1:
247 fib_rules_unregister(ops);
248 return err;
249}
250
251static void __net_exit ip6mr_rules_exit(struct net *net)
252{
253 struct mr6_table *mrt, *next;
254
255 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list)
256 ip6mr_free_table(mrt);
257 fib_rules_unregister(net->ipv6.mr6_rules_ops);
258}
259#else
260#define ip6mr_for_each_table(mrt, net) \
261 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL)
262
263static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
264{
265 return net->ipv6.mrt6;
266}
267
268static int ip6mr_fib_lookup(struct net *net, struct flowi *flp,
269 struct mr6_table **mrt)
270{
271 *mrt = net->ipv6.mrt6;
272 return 0;
273}
274
275static int __net_init ip6mr_rules_init(struct net *net)
276{
277 net->ipv6.mrt6 = ip6mr_new_table(net, RT6_TABLE_DFLT);
278 return net->ipv6.mrt6 ? 0 : -ENOMEM;
279}
280
281static void __net_exit ip6mr_rules_exit(struct net *net)
282{
283 ip6mr_free_table(net->ipv6.mrt6);
284}
285#endif
286
287static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
288{
289 struct mr6_table *mrt;
290 unsigned int i;
291
292 mrt = ip6mr_get_table(net, id);
293 if (mrt != NULL)
294 return mrt;
295
296 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
297 if (mrt == NULL)
298 return NULL;
299 mrt->id = id;
300 write_pnet(&mrt->net, net);
301
302 /* Forwarding cache */
303 for (i = 0; i < MFC6_LINES; i++)
304 INIT_LIST_HEAD(&mrt->mfc6_cache_array[i]);
305
306 INIT_LIST_HEAD(&mrt->mfc6_unres_queue);
307
308 setup_timer(&mrt->ipmr_expire_timer, ipmr_expire_process,
309 (unsigned long)mrt);
310
311#ifdef CONFIG_IPV6_PIMSM_V2
312 mrt->mroute_reg_vif_num = -1;
313#endif
314#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
315 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables);
316#endif
317 return mrt;
318}
319
320static void ip6mr_free_table(struct mr6_table *mrt)
321{
322 del_timer(&mrt->ipmr_expire_timer);
323 mroute_clean_tables(mrt);
324 kfree(mrt);
325}
105 326
106#ifdef CONFIG_PROC_FS 327#ifdef CONFIG_PROC_FS
107 328
108struct ipmr_mfc_iter { 329struct ipmr_mfc_iter {
109 struct seq_net_private p; 330 struct seq_net_private p;
331 struct mr6_table *mrt;
110 struct list_head *cache; 332 struct list_head *cache;
111 int ct; 333 int ct;
112}; 334};
@@ -115,7 +337,7 @@ struct ipmr_mfc_iter {
115static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net, 337static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
116 struct ipmr_mfc_iter *it, loff_t pos) 338 struct ipmr_mfc_iter *it, loff_t pos)
117{ 339{
118 struct mr6_table *mrt = net->ipv6.mrt6; 340 struct mr6_table *mrt = it->mrt;
119 struct mfc6_cache *mfc; 341 struct mfc6_cache *mfc;
120 342
121 read_lock(&mrt_lock); 343 read_lock(&mrt_lock);
@@ -144,6 +366,7 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
144 366
145struct ipmr_vif_iter { 367struct ipmr_vif_iter {
146 struct seq_net_private p; 368 struct seq_net_private p;
369 struct mr6_table *mrt;
147 int ct; 370 int ct;
148}; 371};
149 372
@@ -151,7 +374,7 @@ static struct mif_device *ip6mr_vif_seq_idx(struct net *net,
151 struct ipmr_vif_iter *iter, 374 struct ipmr_vif_iter *iter,
152 loff_t pos) 375 loff_t pos)
153{ 376{
154 struct mr6_table *mrt = net->ipv6.mrt6; 377 struct mr6_table *mrt = iter->mrt;
155 378
156 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) { 379 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) {
157 if (!MIF_EXISTS(mrt, iter->ct)) 380 if (!MIF_EXISTS(mrt, iter->ct))
@@ -165,7 +388,15 @@ static struct mif_device *ip6mr_vif_seq_idx(struct net *net,
165static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 388static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
166 __acquires(mrt_lock) 389 __acquires(mrt_lock)
167{ 390{
391 struct ipmr_vif_iter *iter = seq->private;
168 struct net *net = seq_file_net(seq); 392 struct net *net = seq_file_net(seq);
393 struct mr6_table *mrt;
394
395 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
396 if (mrt == NULL)
397 return ERR_PTR(-ENOENT);
398
399 iter->mrt = mrt;
169 400
170 read_lock(&mrt_lock); 401 read_lock(&mrt_lock);
171 return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1) 402 return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1)
@@ -176,7 +407,7 @@ static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
176{ 407{
177 struct ipmr_vif_iter *iter = seq->private; 408 struct ipmr_vif_iter *iter = seq->private;
178 struct net *net = seq_file_net(seq); 409 struct net *net = seq_file_net(seq);
179 struct mr6_table *mrt = net->ipv6.mrt6; 410 struct mr6_table *mrt = iter->mrt;
180 411
181 ++*pos; 412 ++*pos;
182 if (v == SEQ_START_TOKEN) 413 if (v == SEQ_START_TOKEN)
@@ -198,8 +429,8 @@ static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
198 429
199static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) 430static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
200{ 431{
201 struct net *net = seq_file_net(seq); 432 struct ipmr_vif_iter *iter = seq->private;
202 struct mr6_table *mrt = net->ipv6.mrt6; 433 struct mr6_table *mrt = iter->mrt;
203 434
204 if (v == SEQ_START_TOKEN) { 435 if (v == SEQ_START_TOKEN) {
205 seq_puts(seq, 436 seq_puts(seq,
@@ -241,8 +472,15 @@ static const struct file_operations ip6mr_vif_fops = {
241 472
242static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) 473static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
243{ 474{
475 struct ipmr_mfc_iter *it = seq->private;
244 struct net *net = seq_file_net(seq); 476 struct net *net = seq_file_net(seq);
477 struct mr6_table *mrt;
478
479 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
480 if (mrt == NULL)
481 return ERR_PTR(-ENOENT);
245 482
483 it->mrt = mrt;
246 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1) 484 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
247 : SEQ_START_TOKEN; 485 : SEQ_START_TOKEN;
248} 486}
@@ -252,7 +490,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
252 struct mfc6_cache *mfc = v; 490 struct mfc6_cache *mfc = v;
253 struct ipmr_mfc_iter *it = seq->private; 491 struct ipmr_mfc_iter *it = seq->private;
254 struct net *net = seq_file_net(seq); 492 struct net *net = seq_file_net(seq);
255 struct mr6_table *mrt = net->ipv6.mrt6; 493 struct mr6_table *mrt = it->mrt;
256 494
257 ++*pos; 495 ++*pos;
258 496
@@ -293,8 +531,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
293static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) 531static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
294{ 532{
295 struct ipmr_mfc_iter *it = seq->private; 533 struct ipmr_mfc_iter *it = seq->private;
296 struct net *net = seq_file_net(seq); 534 struct mr6_table *mrt = it->mrt;
297 struct mr6_table *mrt = net->ipv6.mrt6;
298 535
299 if (it->cache == &mrt->mfc6_unres_queue) 536 if (it->cache == &mrt->mfc6_unres_queue)
300 spin_unlock_bh(&mfc_unres_lock); 537 spin_unlock_bh(&mfc_unres_lock);
@@ -305,8 +542,6 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
305static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) 542static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
306{ 543{
307 int n; 544 int n;
308 struct net *net = seq_file_net(seq);
309 struct mr6_table *mrt = net->ipv6.mrt6;
310 545
311 if (v == SEQ_START_TOKEN) { 546 if (v == SEQ_START_TOKEN) {
312 seq_puts(seq, 547 seq_puts(seq,
@@ -316,6 +551,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
316 } else { 551 } else {
317 const struct mfc6_cache *mfc = v; 552 const struct mfc6_cache *mfc = v;
318 const struct ipmr_mfc_iter *it = seq->private; 553 const struct ipmr_mfc_iter *it = seq->private;
554 struct mr6_table *mrt = it->mrt;
319 555
320 seq_printf(seq, "%pI6 %pI6 %-3hd", 556 seq_printf(seq, "%pI6 %pI6 %-3hd",
321 &mfc->mf6c_mcastgrp, &mfc->mf6c_origin, 557 &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
@@ -375,8 +611,12 @@ static int pim6_rcv(struct sk_buff *skb)
375 struct ipv6hdr *encap; 611 struct ipv6hdr *encap;
376 struct net_device *reg_dev = NULL; 612 struct net_device *reg_dev = NULL;
377 struct net *net = dev_net(skb->dev); 613 struct net *net = dev_net(skb->dev);
378 struct mr6_table *mrt = net->ipv6.mrt6; 614 struct mr6_table *mrt;
379 int reg_vif_num = mrt->mroute_reg_vif_num; 615 struct flowi fl = {
616 .iif = skb->dev->ifindex,
617 .mark = skb->mark,
618 };
619 int reg_vif_num;
380 620
381 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) 621 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
382 goto drop; 622 goto drop;
@@ -399,6 +639,10 @@ static int pim6_rcv(struct sk_buff *skb)
399 ntohs(encap->payload_len) + sizeof(*pim) > skb->len) 639 ntohs(encap->payload_len) + sizeof(*pim) > skb->len)
400 goto drop; 640 goto drop;
401 641
642 if (ip6mr_fib_lookup(net, &fl, &mrt) < 0)
643 goto drop;
644 reg_vif_num = mrt->mroute_reg_vif_num;
645
402 read_lock(&mrt_lock); 646 read_lock(&mrt_lock);
403 if (reg_vif_num >= 0) 647 if (reg_vif_num >= 0)
404 reg_dev = mrt->vif6_table[reg_vif_num].dev; 648 reg_dev = mrt->vif6_table[reg_vif_num].dev;
@@ -438,7 +682,17 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
438 struct net_device *dev) 682 struct net_device *dev)
439{ 683{
440 struct net *net = dev_net(dev); 684 struct net *net = dev_net(dev);
441 struct mr6_table *mrt = net->ipv6.mrt6; 685 struct mr6_table *mrt;
686 struct flowi fl = {
687 .oif = dev->ifindex,
688 .iif = skb->skb_iif,
689 .mark = skb->mark,
690 };
691 int err;
692
693 err = ip6mr_fib_lookup(net, &fl, &mrt);
694 if (err < 0)
695 return err;
442 696
443 read_lock(&mrt_lock); 697 read_lock(&mrt_lock);
444 dev->stats.tx_bytes += skb->len; 698 dev->stats.tx_bytes += skb->len;
@@ -463,11 +717,17 @@ static void reg_vif_setup(struct net_device *dev)
463 dev->features |= NETIF_F_NETNS_LOCAL; 717 dev->features |= NETIF_F_NETNS_LOCAL;
464} 718}
465 719
466static struct net_device *ip6mr_reg_vif(struct net *net) 720static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
467{ 721{
468 struct net_device *dev; 722 struct net_device *dev;
723 char name[IFNAMSIZ];
724
725 if (mrt->id == RT6_TABLE_DFLT)
726 sprintf(name, "pim6reg");
727 else
728 sprintf(name, "pim6reg%u", mrt->id);
469 729
470 dev = alloc_netdev(0, "pim6reg", reg_vif_setup); 730 dev = alloc_netdev(0, name, reg_vif_setup);
471 if (dev == NULL) 731 if (dev == NULL)
472 return NULL; 732 return NULL;
473 733
@@ -665,7 +925,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
665 */ 925 */
666 if (mrt->mroute_reg_vif_num >= 0) 926 if (mrt->mroute_reg_vif_num >= 0)
667 return -EADDRINUSE; 927 return -EADDRINUSE;
668 dev = ip6mr_reg_vif(net); 928 dev = ip6mr_reg_vif(net, mrt);
669 if (!dev) 929 if (!dev)
670 return -ENOBUFS; 930 return -ENOBUFS;
671 err = dev_set_allmulti(dev, 1); 931 err = dev_set_allmulti(dev, 1);
@@ -995,7 +1255,7 @@ static int ip6mr_device_event(struct notifier_block *this,
995{ 1255{
996 struct net_device *dev = ptr; 1256 struct net_device *dev = ptr;
997 struct net *net = dev_net(dev); 1257 struct net *net = dev_net(dev);
998 struct mr6_table *mrt = net->ipv6.mrt6; 1258 struct mr6_table *mrt;
999 struct mif_device *v; 1259 struct mif_device *v;
1000 int ct; 1260 int ct;
1001 LIST_HEAD(list); 1261 LIST_HEAD(list);
@@ -1003,10 +1263,12 @@ static int ip6mr_device_event(struct notifier_block *this,
1003 if (event != NETDEV_UNREGISTER) 1263 if (event != NETDEV_UNREGISTER)
1004 return NOTIFY_DONE; 1264 return NOTIFY_DONE;
1005 1265
1006 v = &mrt->vif6_table[0]; 1266 ip6mr_for_each_table(mrt, net) {
1007 for (ct = 0; ct < mrt->maxvif; ct++, v++) { 1267 v = &mrt->vif6_table[0];
1008 if (v->dev == dev) 1268 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1009 mif6_delete(mrt, ct, &list); 1269 if (v->dev == dev)
1270 mif6_delete(mrt, ct, &list);
1271 }
1010 } 1272 }
1011 unregister_netdevice_many(&list); 1273 unregister_netdevice_many(&list);
1012 1274
@@ -1023,29 +1285,11 @@ static struct notifier_block ip6_mr_notifier = {
1023 1285
1024static int __net_init ip6mr_net_init(struct net *net) 1286static int __net_init ip6mr_net_init(struct net *net)
1025{ 1287{
1026 struct mr6_table *mrt; 1288 int err;
1027 unsigned int i;
1028 int err = 0;
1029 1289
1030 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL); 1290 err = ip6mr_rules_init(net);
1031 if (mrt == NULL) { 1291 if (err < 0)
1032 err = -ENOMEM;
1033 goto fail; 1292 goto fail;
1034 }
1035
1036 write_pnet(&mrt->net, net);
1037
1038 for (i = 0; i < MFC6_LINES; i++)
1039 INIT_LIST_HEAD(&mrt->mfc6_cache_array[i]);
1040
1041 INIT_LIST_HEAD(&mrt->mfc6_unres_queue);
1042
1043 setup_timer(&mrt->ipmr_expire_timer, ipmr_expire_process,
1044 (unsigned long)mrt);
1045
1046#ifdef CONFIG_IPV6_PIMSM_V2
1047 mrt->mroute_reg_vif_num = -1;
1048#endif
1049 1293
1050#ifdef CONFIG_PROC_FS 1294#ifdef CONFIG_PROC_FS
1051 err = -ENOMEM; 1295 err = -ENOMEM;
@@ -1055,14 +1299,13 @@ static int __net_init ip6mr_net_init(struct net *net)
1055 goto proc_cache_fail; 1299 goto proc_cache_fail;
1056#endif 1300#endif
1057 1301
1058 net->ipv6.mrt6 = mrt;
1059 return 0; 1302 return 0;
1060 1303
1061#ifdef CONFIG_PROC_FS 1304#ifdef CONFIG_PROC_FS
1062proc_cache_fail: 1305proc_cache_fail:
1063 proc_net_remove(net, "ip6_mr_vif"); 1306 proc_net_remove(net, "ip6_mr_vif");
1064proc_vif_fail: 1307proc_vif_fail:
1065 kfree(mrt); 1308 ip6mr_rules_exit(net);
1066#endif 1309#endif
1067fail: 1310fail:
1068 return err; 1311 return err;
@@ -1070,15 +1313,11 @@ fail:
1070 1313
1071static void __net_exit ip6mr_net_exit(struct net *net) 1314static void __net_exit ip6mr_net_exit(struct net *net)
1072{ 1315{
1073 struct mr6_table *mrt = net->ipv6.mrt6;
1074
1075#ifdef CONFIG_PROC_FS 1316#ifdef CONFIG_PROC_FS
1076 proc_net_remove(net, "ip6_mr_cache"); 1317 proc_net_remove(net, "ip6_mr_cache");
1077 proc_net_remove(net, "ip6_mr_vif"); 1318 proc_net_remove(net, "ip6_mr_vif");
1078#endif 1319#endif
1079 del_timer(&mrt->ipmr_expire_timer); 1320 ip6mr_rules_exit(net);
1080 mroute_clean_tables(mrt);
1081 kfree(mrt);
1082} 1321}
1083 1322
1084static struct pernet_operations ip6mr_net_ops = { 1323static struct pernet_operations ip6mr_net_ops = {
@@ -1279,28 +1518,39 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
1279 1518
1280int ip6mr_sk_done(struct sock *sk) 1519int ip6mr_sk_done(struct sock *sk)
1281{ 1520{
1282 int err = 0; 1521 int err = -EACCES;
1283 struct net *net = sock_net(sk); 1522 struct net *net = sock_net(sk);
1284 struct mr6_table *mrt = net->ipv6.mrt6; 1523 struct mr6_table *mrt;
1285 1524
1286 rtnl_lock(); 1525 rtnl_lock();
1287 if (sk == mrt->mroute6_sk) { 1526 ip6mr_for_each_table(mrt, net) {
1288 write_lock_bh(&mrt_lock); 1527 if (sk == mrt->mroute6_sk) {
1289 mrt->mroute6_sk = NULL; 1528 write_lock_bh(&mrt_lock);
1290 net->ipv6.devconf_all->mc_forwarding--; 1529 mrt->mroute6_sk = NULL;
1291 write_unlock_bh(&mrt_lock); 1530 net->ipv6.devconf_all->mc_forwarding--;
1531 write_unlock_bh(&mrt_lock);
1292 1532
1293 mroute_clean_tables(mrt); 1533 mroute_clean_tables(mrt);
1294 } else 1534 err = 0;
1295 err = -EACCES; 1535 break;
1536 }
1537 }
1296 rtnl_unlock(); 1538 rtnl_unlock();
1297 1539
1298 return err; 1540 return err;
1299} 1541}
1300 1542
1301struct sock *mroute6_socket(struct net *net) 1543struct sock *mroute6_socket(struct net *net, struct sk_buff *skb)
1302{ 1544{
1303 struct mr6_table *mrt = net->ipv6.mrt6; 1545 struct mr6_table *mrt;
1546 struct flowi fl = {
1547 .iif = skb->skb_iif,
1548 .oif = skb->dev->ifindex,
1549 .mark = skb->mark,
1550 };
1551
1552 if (ip6mr_fib_lookup(net, &fl, &mrt) < 0)
1553 return NULL;
1304 1554
1305 return mrt->mroute6_sk; 1555 return mrt->mroute6_sk;
1306} 1556}
@@ -1319,7 +1569,11 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1319 struct mf6cctl mfc; 1569 struct mf6cctl mfc;
1320 mifi_t mifi; 1570 mifi_t mifi;
1321 struct net *net = sock_net(sk); 1571 struct net *net = sock_net(sk);
1322 struct mr6_table *mrt = net->ipv6.mrt6; 1572 struct mr6_table *mrt;
1573
1574 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1575 if (mrt == NULL)
1576 return -ENOENT;
1323 1577
1324 if (optname != MRT6_INIT) { 1578 if (optname != MRT6_INIT) {
1325 if (sk != mrt->mroute6_sk && !capable(CAP_NET_ADMIN)) 1579 if (sk != mrt->mroute6_sk && !capable(CAP_NET_ADMIN))
@@ -1409,6 +1663,27 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1409 } 1663 }
1410 1664
1411#endif 1665#endif
1666#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
1667 case MRT6_TABLE:
1668 {
1669 u32 v;
1670
1671 if (optlen != sizeof(u32))
1672 return -EINVAL;
1673 if (get_user(v, (u32 __user *)optval))
1674 return -EFAULT;
1675 if (sk == mrt->mroute6_sk)
1676 return -EBUSY;
1677
1678 rtnl_lock();
1679 ret = 0;
1680 if (!ip6mr_new_table(net, v))
1681 ret = -ENOMEM;
1682 raw6_sk(sk)->ip6mr_table = v;
1683 rtnl_unlock();
1684 return ret;
1685 }
1686#endif
1412 /* 1687 /*
1413 * Spurious command, or MRT6_VERSION which you cannot 1688 * Spurious command, or MRT6_VERSION which you cannot
1414 * set. 1689 * set.
@@ -1428,7 +1703,11 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval,
1428 int olr; 1703 int olr;
1429 int val; 1704 int val;
1430 struct net *net = sock_net(sk); 1705 struct net *net = sock_net(sk);
1431 struct mr6_table *mrt = net->ipv6.mrt6; 1706 struct mr6_table *mrt;
1707
1708 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1709 if (mrt == NULL)
1710 return -ENOENT;
1432 1711
1433 switch (optname) { 1712 switch (optname) {
1434 case MRT6_VERSION: 1713 case MRT6_VERSION:
@@ -1471,7 +1750,11 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1471 struct mif_device *vif; 1750 struct mif_device *vif;
1472 struct mfc6_cache *c; 1751 struct mfc6_cache *c;
1473 struct net *net = sock_net(sk); 1752 struct net *net = sock_net(sk);
1474 struct mr6_table *mrt = net->ipv6.mrt6; 1753 struct mr6_table *mrt;
1754
1755 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1756 if (mrt == NULL)
1757 return -ENOENT;
1475 1758
1476 switch (cmd) { 1759 switch (cmd) {
1477 case SIOCGETMIFCNT_IN6: 1760 case SIOCGETMIFCNT_IN6:
@@ -1683,7 +1966,16 @@ int ip6_mr_input(struct sk_buff *skb)
1683{ 1966{
1684 struct mfc6_cache *cache; 1967 struct mfc6_cache *cache;
1685 struct net *net = dev_net(skb->dev); 1968 struct net *net = dev_net(skb->dev);
1686 struct mr6_table *mrt = net->ipv6.mrt6; 1969 struct mr6_table *mrt;
1970 struct flowi fl = {
1971 .iif = skb->dev->ifindex,
1972 .mark = skb->mark,
1973 };
1974 int err;
1975
1976 err = ip6mr_fib_lookup(net, &fl, &mrt);
1977 if (err < 0)
1978 return err;
1687 1979
1688 read_lock(&mrt_lock); 1980 read_lock(&mrt_lock);
1689 cache = ip6mr_cache_find(mrt, 1981 cache = ip6mr_cache_find(mrt,
@@ -1758,10 +2050,14 @@ int ip6mr_get_route(struct net *net,
1758 struct sk_buff *skb, struct rtmsg *rtm, int nowait) 2050 struct sk_buff *skb, struct rtmsg *rtm, int nowait)
1759{ 2051{
1760 int err; 2052 int err;
1761 struct mr6_table *mrt = net->ipv6.mrt6; 2053 struct mr6_table *mrt;
1762 struct mfc6_cache *cache; 2054 struct mfc6_cache *cache;
1763 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); 2055 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
1764 2056
2057 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
2058 if (mrt == NULL)
2059 return -ENOENT;
2060
1765 read_lock(&mrt_lock); 2061 read_lock(&mrt_lock);
1766 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr); 2062 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
1767 2063