]> Git Repo - linux.git/blame - net/ipv6/ip6mr.c
ipmr, ip6mr: Unite vif seq functions
[linux.git] / net / ipv6 / ip6mr.c
CommitLineData
7bc570c8
YH
1/*
2 * Linux IPv6 multicast routing support for BSD pim6sd
3 * Based on net/ipv4/ipmr.c.
4 *
5 * (c) 2004 Mickael Hoerdt, <[email protected]>
6 * LSIIT Laboratory, Strasbourg, France
7 * (c) 2004 Jean-Philippe Andriot, <[email protected]>
8 * 6WIND, Paris, France
9 * Copyright (C)2007,2008 USAGI/WIDE Project
10 * YOSHIFUJI Hideaki <[email protected]>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 *
17 */
18
7c0f6ba6 19#include <linux/uaccess.h>
7bc570c8
YH
20#include <linux/types.h>
21#include <linux/sched.h>
22#include <linux/errno.h>
7bc570c8
YH
23#include <linux/mm.h>
24#include <linux/kernel.h>
25#include <linux/fcntl.h>
26#include <linux/stat.h>
27#include <linux/socket.h>
7bc570c8
YH
28#include <linux/inet.h>
29#include <linux/netdevice.h>
30#include <linux/inetdevice.h>
7bc570c8
YH
31#include <linux/proc_fs.h>
32#include <linux/seq_file.h>
7bc570c8 33#include <linux/init.h>
e2d57766 34#include <linux/compat.h>
7bc570c8
YH
35#include <net/protocol.h>
36#include <linux/skbuff.h>
7bc570c8 37#include <net/raw.h>
7bc570c8
YH
38#include <linux/notifier.h>
39#include <linux/if_arp.h>
7bc570c8
YH
40#include <net/checksum.h>
41#include <net/netlink.h>
d1db275d 42#include <net/fib_rules.h>
7bc570c8
YH
43
44#include <net/ipv6.h>
45#include <net/ip6_route.h>
46#include <linux/mroute6.h>
14fb64e1 47#include <linux/pim.h>
7bc570c8
YH
48#include <net/addrconf.h>
49#include <linux/netfilter_ipv6.h>
bc3b2d7f 50#include <linux/export.h>
5d6e430d 51#include <net/ip6_checksum.h>
d67b8c61 52#include <linux/netconf.h>
7bc570c8 53
d1db275d
PM
54struct ip6mr_rule {
55 struct fib_rule common;
56};
57
58struct ip6mr_result {
b70432f7 59 struct mr_table *mrt;
d1db275d
PM
60};
61
7bc570c8
YH
62/* Big lock, protecting vif table, mrt cache and mroute socket state.
63 Note that the changes are semaphored via rtnl_lock.
64 */
65
66static DEFINE_RWLOCK(mrt_lock);
67
b70432f7 68/* Multicast router control variables */
7bc570c8 69
7bc570c8
YH
70/* Special spinlock for queue of unresolved entries */
71static DEFINE_SPINLOCK(mfc_unres_lock);
72
73/* We return to original Alan's scheme. Hash table of resolved
74 entries is changed only in process context and protected
75 with weak lock mrt_lock. Queue of unresolved entries is protected
76 with strong spinlock mfc_unres_lock.
77
78 In this case data path is free of exclusive locks at all.
79 */
80
81static struct kmem_cache *mrt_cachep __read_mostly;
82
b70432f7
YM
83static struct mr_table *ip6mr_new_table(struct net *net, u32 id);
84static void ip6mr_free_table(struct mr_table *mrt);
d1db275d 85
b70432f7 86static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
2b52c3ad 87 struct sk_buff *skb, struct mfc6_cache *cache);
b70432f7 88static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
8229efda 89 mifi_t mifi, int assert);
b70432f7 90static int __ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
5b285cac 91 struct mfc6_cache *c, struct rtmsg *rtm);
b70432f7 92static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
812e44dd 93 int cmd);
b70432f7 94static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
5b285cac
PM
95static int ip6mr_rtm_dumproute(struct sk_buff *skb,
96 struct netlink_callback *cb);
b70432f7 97static void mroute_clean_tables(struct mr_table *mrt, bool all);
e99e88a9 98static void ipmr_expire_process(struct timer_list *t);
d1db275d
PM
99
100#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
8ffb335e 101#define ip6mr_for_each_table(mrt, net) \
d1db275d
PM
102 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list)
103
b70432f7 104static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
d1db275d 105{
b70432f7 106 struct mr_table *mrt;
d1db275d
PM
107
108 ip6mr_for_each_table(mrt, net) {
109 if (mrt->id == id)
110 return mrt;
111 }
112 return NULL;
113}
114
4c9483b2 115static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
b70432f7 116 struct mr_table **mrt)
d1db275d 117{
d1db275d 118 int err;
95f4a45d
HFS
119 struct ip6mr_result res;
120 struct fib_lookup_arg arg = {
121 .result = &res,
122 .flags = FIB_LOOKUP_NOREF,
123 };
d1db275d 124
4c9483b2
DM
125 err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
126 flowi6_to_flowi(flp6), 0, &arg);
d1db275d
PM
127 if (err < 0)
128 return err;
129 *mrt = res.mrt;
130 return 0;
131}
132
133static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
134 int flags, struct fib_lookup_arg *arg)
135{
136 struct ip6mr_result *res = arg->result;
b70432f7 137 struct mr_table *mrt;
d1db275d
PM
138
139 switch (rule->action) {
140 case FR_ACT_TO_TBL:
141 break;
142 case FR_ACT_UNREACHABLE:
143 return -ENETUNREACH;
144 case FR_ACT_PROHIBIT:
145 return -EACCES;
146 case FR_ACT_BLACKHOLE:
147 default:
148 return -EINVAL;
149 }
150
151 mrt = ip6mr_get_table(rule->fr_net, rule->table);
63159f29 152 if (!mrt)
d1db275d
PM
153 return -EAGAIN;
154 res->mrt = mrt;
155 return 0;
156}
157
158static int ip6mr_rule_match(struct fib_rule *rule, struct flowi *flp, int flags)
159{
160 return 1;
161}
162
163static const struct nla_policy ip6mr_rule_policy[FRA_MAX + 1] = {
164 FRA_GENERIC_POLICY,
165};
166
167static int ip6mr_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
168 struct fib_rule_hdr *frh, struct nlattr **tb)
169{
170 return 0;
171}
172
173static int ip6mr_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
174 struct nlattr **tb)
175{
176 return 1;
177}
178
179static int ip6mr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
180 struct fib_rule_hdr *frh)
181{
182 frh->dst_len = 0;
183 frh->src_len = 0;
184 frh->tos = 0;
185 return 0;
186}
187
04a6f82c 188static const struct fib_rules_ops __net_initconst ip6mr_rules_ops_template = {
d1db275d
PM
189 .family = RTNL_FAMILY_IP6MR,
190 .rule_size = sizeof(struct ip6mr_rule),
191 .addr_size = sizeof(struct in6_addr),
192 .action = ip6mr_rule_action,
193 .match = ip6mr_rule_match,
194 .configure = ip6mr_rule_configure,
195 .compare = ip6mr_rule_compare,
d1db275d
PM
196 .fill = ip6mr_rule_fill,
197 .nlgroup = RTNLGRP_IPV6_RULE,
198 .policy = ip6mr_rule_policy,
199 .owner = THIS_MODULE,
200};
201
202static int __net_init ip6mr_rules_init(struct net *net)
203{
204 struct fib_rules_ops *ops;
b70432f7 205 struct mr_table *mrt;
d1db275d
PM
206 int err;
207
208 ops = fib_rules_register(&ip6mr_rules_ops_template, net);
209 if (IS_ERR(ops))
210 return PTR_ERR(ops);
211
212 INIT_LIST_HEAD(&net->ipv6.mr6_tables);
213
214 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
63159f29 215 if (!mrt) {
d1db275d
PM
216 err = -ENOMEM;
217 goto err1;
218 }
219
220 err = fib_default_rule_add(ops, 0x7fff, RT6_TABLE_DFLT, 0);
221 if (err < 0)
222 goto err2;
223
224 net->ipv6.mr6_rules_ops = ops;
225 return 0;
226
227err2:
f243e5a7 228 ip6mr_free_table(mrt);
d1db275d
PM
229err1:
230 fib_rules_unregister(ops);
231 return err;
232}
233
234static void __net_exit ip6mr_rules_exit(struct net *net)
235{
b70432f7 236 struct mr_table *mrt, *next;
d1db275d 237
905a6f96 238 rtnl_lock();
035320d5
ED
239 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
240 list_del(&mrt->list);
d1db275d 241 ip6mr_free_table(mrt);
035320d5 242 }
d1db275d 243 fib_rules_unregister(net->ipv6.mr6_rules_ops);
419df12f 244 rtnl_unlock();
d1db275d
PM
245}
246#else
247#define ip6mr_for_each_table(mrt, net) \
248 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL)
249
b70432f7 250static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
d1db275d
PM
251{
252 return net->ipv6.mrt6;
253}
254
4c9483b2 255static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
b70432f7 256 struct mr_table **mrt)
d1db275d
PM
257{
258 *mrt = net->ipv6.mrt6;
259 return 0;
260}
261
262static int __net_init ip6mr_rules_init(struct net *net)
263{
264 net->ipv6.mrt6 = ip6mr_new_table(net, RT6_TABLE_DFLT);
265 return net->ipv6.mrt6 ? 0 : -ENOMEM;
266}
267
268static void __net_exit ip6mr_rules_exit(struct net *net)
269{
905a6f96 270 rtnl_lock();
d1db275d 271 ip6mr_free_table(net->ipv6.mrt6);
905a6f96
HFS
272 net->ipv6.mrt6 = NULL;
273 rtnl_unlock();
d1db275d
PM
274}
275#endif
276
87c418bf
YM
277static int ip6mr_hash_cmp(struct rhashtable_compare_arg *arg,
278 const void *ptr)
279{
280 const struct mfc6_cache_cmp_arg *cmparg = arg->key;
281 struct mfc6_cache *c = (struct mfc6_cache *)ptr;
282
283 return !ipv6_addr_equal(&c->mf6c_mcastgrp, &cmparg->mf6c_mcastgrp) ||
284 !ipv6_addr_equal(&c->mf6c_origin, &cmparg->mf6c_origin);
285}
286
287static const struct rhashtable_params ip6mr_rht_params = {
494fff56 288 .head_offset = offsetof(struct mr_mfc, mnode),
87c418bf
YM
289 .key_offset = offsetof(struct mfc6_cache, cmparg),
290 .key_len = sizeof(struct mfc6_cache_cmp_arg),
291 .nelem_hint = 3,
292 .locks_mul = 1,
293 .obj_cmpfn = ip6mr_hash_cmp,
294 .automatic_shrinking = true,
295};
296
0bbbf0e7
YM
297static void ip6mr_new_table_set(struct mr_table *mrt,
298 struct net *net)
299{
300#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
301 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables);
302#endif
303}
304
845c9a7a
YM
305static struct mfc6_cache_cmp_arg ip6mr_mr_table_ops_cmparg_any = {
306 .mf6c_origin = IN6ADDR_ANY_INIT,
307 .mf6c_mcastgrp = IN6ADDR_ANY_INIT,
308};
309
310static struct mr_table_ops ip6mr_mr_table_ops = {
311 .rht_params = &ip6mr_rht_params,
312 .cmparg_any = &ip6mr_mr_table_ops_cmparg_any,
313};
314
b70432f7 315static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
d1db275d 316{
b70432f7 317 struct mr_table *mrt;
d1db275d
PM
318
319 mrt = ip6mr_get_table(net, id);
53b24b8f 320 if (mrt)
d1db275d
PM
321 return mrt;
322
845c9a7a 323 return mr_table_alloc(net, id, &ip6mr_mr_table_ops,
0bbbf0e7 324 ipmr_expire_process, ip6mr_new_table_set);
d1db275d 325}
7bc570c8 326
b70432f7 327static void ip6mr_free_table(struct mr_table *mrt)
d1db275d 328{
7ba0c47c 329 del_timer_sync(&mrt->ipmr_expire_timer);
4c698046 330 mroute_clean_tables(mrt, true);
b70432f7 331 rhltable_destroy(&mrt->mfc_hash);
d1db275d
PM
332 kfree(mrt);
333}
7bc570c8
YH
334
335#ifdef CONFIG_PROC_FS
c8d61968
YM
336/* The /proc interfaces to multicast routing
337 * /proc/ip6_mr_cache /proc/ip6_mr_vif
7bc570c8
YH
338 */
339
7bc570c8
YH
340static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
341 __acquires(mrt_lock)
342{
3feda6b4 343 struct mr_vif_iter *iter = seq->private;
8b90fc7e 344 struct net *net = seq_file_net(seq);
b70432f7 345 struct mr_table *mrt;
d1db275d
PM
346
347 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
63159f29 348 if (!mrt)
d1db275d
PM
349 return ERR_PTR(-ENOENT);
350
351 iter->mrt = mrt;
8b90fc7e 352
7bc570c8 353 read_lock(&mrt_lock);
3feda6b4 354 return mr_vif_seq_start(seq, pos);
7bc570c8
YH
355}
356
357static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
358 __releases(mrt_lock)
359{
360 read_unlock(&mrt_lock);
361}
362
363static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
364{
3feda6b4 365 struct mr_vif_iter *iter = seq->private;
b70432f7 366 struct mr_table *mrt = iter->mrt;
8b90fc7e 367
7bc570c8
YH
368 if (v == SEQ_START_TOKEN) {
369 seq_puts(seq,
370 "Interface BytesIn PktsIn BytesOut PktsOut Flags\n");
371 } else {
6853f21f 372 const struct vif_device *vif = v;
7bc570c8
YH
373 const char *name = vif->dev ? vif->dev->name : "none";
374
375 seq_printf(seq,
d430a227 376 "%2td %-10s %8ld %7ld %8ld %7ld %05X\n",
b70432f7 377 vif - mrt->vif_table,
7bc570c8
YH
378 name, vif->bytes_in, vif->pkt_in,
379 vif->bytes_out, vif->pkt_out,
380 vif->flags);
381 }
382 return 0;
383}
384
98147d52 385static const struct seq_operations ip6mr_vif_seq_ops = {
7bc570c8 386 .start = ip6mr_vif_seq_start,
3feda6b4 387 .next = mr_vif_seq_next,
7bc570c8
YH
388 .stop = ip6mr_vif_seq_stop,
389 .show = ip6mr_vif_seq_show,
390};
391
392static int ip6mr_vif_open(struct inode *inode, struct file *file)
393{
8b90fc7e 394 return seq_open_net(inode, file, &ip6mr_vif_seq_ops,
3feda6b4 395 sizeof(struct mr_vif_iter));
7bc570c8
YH
396}
397
5ca1b998 398static const struct file_operations ip6mr_vif_fops = {
7bc570c8
YH
399 .open = ip6mr_vif_open,
400 .read = seq_read,
401 .llseek = seq_lseek,
8b90fc7e 402 .release = seq_release_net,
7bc570c8
YH
403};
404
405static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
406{
8b90fc7e 407 struct net *net = seq_file_net(seq);
b70432f7 408 struct mr_table *mrt;
8b90fc7e 409
d1db275d 410 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
63159f29 411 if (!mrt)
d1db275d
PM
412 return ERR_PTR(-ENOENT);
413
c8d61968 414 return mr_mfc_seq_start(seq, pos, mrt, &mfc_unres_lock);
7bc570c8
YH
415}
416
417static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
418{
419 int n;
420
421 if (v == SEQ_START_TOKEN) {
422 seq_puts(seq,
423 "Group "
424 "Origin "
425 "Iif Pkts Bytes Wrong Oifs\n");
426 } else {
427 const struct mfc6_cache *mfc = v;
c8d61968 428 const struct mr_mfc_iter *it = seq->private;
b70432f7 429 struct mr_table *mrt = it->mrt;
7bc570c8 430
999890b2 431 seq_printf(seq, "%pI6 %pI6 %-3hd",
0c6ce78a 432 &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
494fff56 433 mfc->_c.mfc_parent);
7bc570c8 434
b70432f7 435 if (it->cache != &mrt->mfc_unres_queue) {
1ea472e2 436 seq_printf(seq, " %8lu %8lu %8lu",
494fff56
YM
437 mfc->_c.mfc_un.res.pkt,
438 mfc->_c.mfc_un.res.bytes,
439 mfc->_c.mfc_un.res.wrong_if);
440 for (n = mfc->_c.mfc_un.res.minvif;
441 n < mfc->_c.mfc_un.res.maxvif; n++) {
b70432f7 442 if (VIF_EXISTS(mrt, n) &&
494fff56 443 mfc->_c.mfc_un.res.ttls[n] < 255)
7bc570c8 444 seq_printf(seq,
494fff56
YM
445 " %2d:%-3d", n,
446 mfc->_c.mfc_un.res.ttls[n]);
7bc570c8 447 }
1ea472e2
BT
448 } else {
449 /* unresolved mfc_caches don't contain
450 * pkt, bytes and wrong_if values
451 */
452 seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul);
7bc570c8
YH
453 }
454 seq_putc(seq, '\n');
455 }
456 return 0;
457}
458
88e9d34c 459static const struct seq_operations ipmr_mfc_seq_ops = {
7bc570c8 460 .start = ipmr_mfc_seq_start,
c8d61968
YM
461 .next = mr_mfc_seq_next,
462 .stop = mr_mfc_seq_stop,
7bc570c8
YH
463 .show = ipmr_mfc_seq_show,
464};
465
466static int ipmr_mfc_open(struct inode *inode, struct file *file)
467{
8b90fc7e 468 return seq_open_net(inode, file, &ipmr_mfc_seq_ops,
c8d61968 469 sizeof(struct mr_mfc_iter));
7bc570c8
YH
470}
471
5ca1b998 472static const struct file_operations ip6mr_mfc_fops = {
7bc570c8
YH
473 .open = ipmr_mfc_open,
474 .read = seq_read,
475 .llseek = seq_lseek,
8b90fc7e 476 .release = seq_release_net,
7bc570c8
YH
477};
478#endif
479
14fb64e1 480#ifdef CONFIG_IPV6_PIMSM_V2
14fb64e1
YH
481
482static int pim6_rcv(struct sk_buff *skb)
483{
484 struct pimreghdr *pim;
485 struct ipv6hdr *encap;
486 struct net_device *reg_dev = NULL;
8229efda 487 struct net *net = dev_net(skb->dev);
b70432f7 488 struct mr_table *mrt;
4c9483b2
DM
489 struct flowi6 fl6 = {
490 .flowi6_iif = skb->dev->ifindex,
491 .flowi6_mark = skb->mark,
d1db275d
PM
492 };
493 int reg_vif_num;
14fb64e1
YH
494
495 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
496 goto drop;
497
498 pim = (struct pimreghdr *)skb_transport_header(skb);
56245cae 499 if (pim->type != ((PIM_VERSION << 4) | PIM_TYPE_REGISTER) ||
14fb64e1 500 (pim->flags & PIM_NULL_REGISTER) ||
1d6e55f1
TG
501 (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
502 sizeof(*pim), IPPROTO_PIM,
503 csum_partial((void *)pim, sizeof(*pim), 0)) &&
ec6b486f 504 csum_fold(skb_checksum(skb, 0, skb->len, 0))))
14fb64e1
YH
505 goto drop;
506
507 /* check if the inner packet is destined to mcast group */
508 encap = (struct ipv6hdr *)(skb_transport_header(skb) +
509 sizeof(*pim));
510
511 if (!ipv6_addr_is_multicast(&encap->daddr) ||
512 encap->payload_len == 0 ||
513 ntohs(encap->payload_len) + sizeof(*pim) > skb->len)
514 goto drop;
515
4c9483b2 516 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
d1db275d
PM
517 goto drop;
518 reg_vif_num = mrt->mroute_reg_vif_num;
519
14fb64e1
YH
520 read_lock(&mrt_lock);
521 if (reg_vif_num >= 0)
b70432f7 522 reg_dev = mrt->vif_table[reg_vif_num].dev;
14fb64e1
YH
523 if (reg_dev)
524 dev_hold(reg_dev);
525 read_unlock(&mrt_lock);
526
63159f29 527 if (!reg_dev)
14fb64e1
YH
528 goto drop;
529
530 skb->mac_header = skb->network_header;
531 skb_pull(skb, (u8 *)encap - skb->data);
532 skb_reset_network_header(skb);
1d6e55f1 533 skb->protocol = htons(ETH_P_IPV6);
3e49e6d5 534 skb->ip_summed = CHECKSUM_NONE;
d19d56dd 535
ea23192e 536 skb_tunnel_rx(skb, reg_dev, dev_net(reg_dev));
d19d56dd 537
caf586e5 538 netif_rx(skb);
8990f468 539
14fb64e1
YH
540 dev_put(reg_dev);
541 return 0;
542 drop:
543 kfree_skb(skb);
544 return 0;
545}
546
41135cc8 547static const struct inet6_protocol pim6_protocol = {
14fb64e1
YH
548 .handler = pim6_rcv,
549};
550
551/* Service routines creating virtual interfaces: PIMREG */
552
6fef4c0c
SH
553static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
554 struct net_device *dev)
14fb64e1 555{
8229efda 556 struct net *net = dev_net(dev);
b70432f7 557 struct mr_table *mrt;
4c9483b2
DM
558 struct flowi6 fl6 = {
559 .flowi6_oif = dev->ifindex,
6a662719 560 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
4c9483b2 561 .flowi6_mark = skb->mark,
d1db275d
PM
562 };
563 int err;
564
4c9483b2 565 err = ip6mr_fib_lookup(net, &fl6, &mrt);
67928c40
BG
566 if (err < 0) {
567 kfree_skb(skb);
d1db275d 568 return err;
67928c40 569 }
8229efda 570
14fb64e1 571 read_lock(&mrt_lock);
dc58c78c
PE
572 dev->stats.tx_bytes += skb->len;
573 dev->stats.tx_packets++;
6bd52143 574 ip6mr_cache_report(mrt, skb, mrt->mroute_reg_vif_num, MRT6MSG_WHOLEPKT);
14fb64e1
YH
575 read_unlock(&mrt_lock);
576 kfree_skb(skb);
6ed10654 577 return NETDEV_TX_OK;
14fb64e1
YH
578}
579
ee9b9596
ND
580static int reg_vif_get_iflink(const struct net_device *dev)
581{
582 return 0;
583}
584
007c3838
SH
585static const struct net_device_ops reg_vif_netdev_ops = {
586 .ndo_start_xmit = reg_vif_xmit,
ee9b9596 587 .ndo_get_iflink = reg_vif_get_iflink,
007c3838
SH
588};
589
14fb64e1
YH
590static void reg_vif_setup(struct net_device *dev)
591{
592 dev->type = ARPHRD_PIMREG;
593 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
594 dev->flags = IFF_NOARP;
007c3838 595 dev->netdev_ops = &reg_vif_netdev_ops;
cf124db5 596 dev->needs_free_netdev = true;
403dbb97 597 dev->features |= NETIF_F_NETNS_LOCAL;
14fb64e1
YH
598}
599
b70432f7 600static struct net_device *ip6mr_reg_vif(struct net *net, struct mr_table *mrt)
14fb64e1
YH
601{
602 struct net_device *dev;
d1db275d
PM
603 char name[IFNAMSIZ];
604
605 if (mrt->id == RT6_TABLE_DFLT)
606 sprintf(name, "pim6reg");
607 else
608 sprintf(name, "pim6reg%u", mrt->id);
14fb64e1 609
c835a677 610 dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup);
63159f29 611 if (!dev)
14fb64e1
YH
612 return NULL;
613
8229efda
BT
614 dev_net_set(dev, net);
615
14fb64e1
YH
616 if (register_netdevice(dev)) {
617 free_netdev(dev);
618 return NULL;
619 }
14fb64e1 620
14fb64e1
YH
621 if (dev_open(dev))
622 goto failure;
623
7af3db78 624 dev_hold(dev);
14fb64e1
YH
625 return dev;
626
627failure:
14fb64e1
YH
628 unregister_netdevice(dev);
629 return NULL;
630}
631#endif
632
7bc570c8
YH
633/*
634 * Delete a VIF entry
635 */
636
b70432f7 637static int mif6_delete(struct mr_table *mrt, int vifi, int notify,
723b929c 638 struct list_head *head)
7bc570c8 639{
6853f21f 640 struct vif_device *v;
7bc570c8 641 struct net_device *dev;
1d6e55f1 642 struct inet6_dev *in6_dev;
6bd52143
PM
643
644 if (vifi < 0 || vifi >= mrt->maxvif)
7bc570c8
YH
645 return -EADDRNOTAVAIL;
646
b70432f7 647 v = &mrt->vif_table[vifi];
7bc570c8
YH
648
649 write_lock_bh(&mrt_lock);
650 dev = v->dev;
651 v->dev = NULL;
652
653 if (!dev) {
654 write_unlock_bh(&mrt_lock);
655 return -EADDRNOTAVAIL;
656 }
657
14fb64e1 658#ifdef CONFIG_IPV6_PIMSM_V2
6bd52143
PM
659 if (vifi == mrt->mroute_reg_vif_num)
660 mrt->mroute_reg_vif_num = -1;
14fb64e1
YH
661#endif
662
6bd52143 663 if (vifi + 1 == mrt->maxvif) {
7bc570c8
YH
664 int tmp;
665 for (tmp = vifi - 1; tmp >= 0; tmp--) {
b70432f7 666 if (VIF_EXISTS(mrt, tmp))
7bc570c8
YH
667 break;
668 }
6bd52143 669 mrt->maxvif = tmp + 1;
7bc570c8
YH
670 }
671
672 write_unlock_bh(&mrt_lock);
673
674 dev_set_allmulti(dev, -1);
675
1d6e55f1 676 in6_dev = __in6_dev_get(dev);
d67b8c61 677 if (in6_dev) {
1d6e55f1 678 in6_dev->cnf.mc_forwarding--;
85b3daad 679 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
d67b8c61
ND
680 NETCONFA_MC_FORWARDING,
681 dev->ifindex, &in6_dev->cnf);
682 }
1d6e55f1 683
723b929c 684 if ((v->flags & MIFF_REGISTER) && !notify)
c871e664 685 unregister_netdevice_queue(dev, head);
7bc570c8
YH
686
687 dev_put(dev);
688 return 0;
689}
690
87c418bf 691static inline void ip6mr_cache_free_rcu(struct rcu_head *head)
58701ad4 692{
494fff56 693 struct mr_mfc *c = container_of(head, struct mr_mfc, rcu);
87c418bf 694
494fff56 695 kmem_cache_free(mrt_cachep, (struct mfc6_cache *)c);
58701ad4
BT
696}
697
87c418bf
YM
698static inline void ip6mr_cache_free(struct mfc6_cache *c)
699{
494fff56 700 call_rcu(&c->_c.rcu, ip6mr_cache_free_rcu);
87c418bf
YM
701}
702
7bc570c8
YH
703/* Destroy an unresolved cache entry, killing queued skbs
704 and reporting error to netlink readers.
705 */
706
b70432f7 707static void ip6mr_destroy_unres(struct mr_table *mrt, struct mfc6_cache *c)
7bc570c8 708{
6bd52143 709 struct net *net = read_pnet(&mrt->net);
7bc570c8
YH
710 struct sk_buff *skb;
711
6bd52143 712 atomic_dec(&mrt->cache_resolve_queue_len);
7bc570c8 713
494fff56 714 while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved)) != NULL) {
7bc570c8 715 if (ipv6_hdr(skb)->version == 0) {
af72868b
JB
716 struct nlmsghdr *nlh = skb_pull(skb,
717 sizeof(struct ipv6hdr));
7bc570c8 718 nlh->nlmsg_type = NLMSG_ERROR;
573ce260 719 nlh->nlmsg_len = nlmsg_msg_size(sizeof(struct nlmsgerr));
7bc570c8 720 skb_trim(skb, nlh->nlmsg_len);
573ce260 721 ((struct nlmsgerr *)nlmsg_data(nlh))->error = -ETIMEDOUT;
15e47304 722 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
7bc570c8
YH
723 } else
724 kfree_skb(skb);
725 }
726
58701ad4 727 ip6mr_cache_free(c);
7bc570c8
YH
728}
729
730
c476efbc 731/* Timer process for all the unresolved queue. */
7bc570c8 732
b70432f7 733static void ipmr_do_expire_process(struct mr_table *mrt)
7bc570c8
YH
734{
735 unsigned long now = jiffies;
736 unsigned long expires = 10 * HZ;
494fff56 737 struct mr_mfc *c, *next;
7bc570c8 738
b70432f7 739 list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) {
7bc570c8
YH
740 if (time_after(c->mfc_un.unres.expires, now)) {
741 /* not yet... */
742 unsigned long interval = c->mfc_un.unres.expires - now;
743 if (interval < expires)
744 expires = interval;
7bc570c8
YH
745 continue;
746 }
747
f30a7784 748 list_del(&c->list);
494fff56
YM
749 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
750 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
7bc570c8
YH
751 }
752
b70432f7 753 if (!list_empty(&mrt->mfc_unres_queue))
6bd52143 754 mod_timer(&mrt->ipmr_expire_timer, jiffies + expires);
7bc570c8
YH
755}
756
e99e88a9 757static void ipmr_expire_process(struct timer_list *t)
7bc570c8 758{
b70432f7 759 struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
c476efbc 760
7bc570c8 761 if (!spin_trylock(&mfc_unres_lock)) {
6bd52143 762 mod_timer(&mrt->ipmr_expire_timer, jiffies + 1);
7bc570c8
YH
763 return;
764 }
765
b70432f7 766 if (!list_empty(&mrt->mfc_unres_queue))
6bd52143 767 ipmr_do_expire_process(mrt);
7bc570c8
YH
768
769 spin_unlock(&mfc_unres_lock);
770}
771
772/* Fill oifs list. It is called under write locked mrt_lock. */
773
b70432f7 774static void ip6mr_update_thresholds(struct mr_table *mrt,
494fff56 775 struct mr_mfc *cache,
b5aa30b1 776 unsigned char *ttls)
7bc570c8
YH
777{
778 int vifi;
779
6ac7eb08 780 cache->mfc_un.res.minvif = MAXMIFS;
7bc570c8 781 cache->mfc_un.res.maxvif = 0;
6ac7eb08 782 memset(cache->mfc_un.res.ttls, 255, MAXMIFS);
7bc570c8 783
6bd52143 784 for (vifi = 0; vifi < mrt->maxvif; vifi++) {
b70432f7 785 if (VIF_EXISTS(mrt, vifi) &&
4e16880c 786 ttls[vifi] && ttls[vifi] < 255) {
7bc570c8
YH
787 cache->mfc_un.res.ttls[vifi] = ttls[vifi];
788 if (cache->mfc_un.res.minvif > vifi)
789 cache->mfc_un.res.minvif = vifi;
790 if (cache->mfc_un.res.maxvif <= vifi)
791 cache->mfc_un.res.maxvif = vifi + 1;
792 }
793 }
90b5ca17 794 cache->mfc_un.res.lastuse = jiffies;
7bc570c8
YH
795}
796
b70432f7 797static int mif6_add(struct net *net, struct mr_table *mrt,
6bd52143 798 struct mif6ctl *vifc, int mrtsock)
7bc570c8
YH
799{
800 int vifi = vifc->mif6c_mifi;
b70432f7 801 struct vif_device *v = &mrt->vif_table[vifi];
7bc570c8 802 struct net_device *dev;
1d6e55f1 803 struct inet6_dev *in6_dev;
5ae7b444 804 int err;
7bc570c8
YH
805
806 /* Is vif busy ? */
b70432f7 807 if (VIF_EXISTS(mrt, vifi))
7bc570c8
YH
808 return -EADDRINUSE;
809
810 switch (vifc->mif6c_flags) {
14fb64e1
YH
811#ifdef CONFIG_IPV6_PIMSM_V2
812 case MIFF_REGISTER:
813 /*
814 * Special Purpose VIF in PIM
815 * All the packets will be sent to the daemon
816 */
6bd52143 817 if (mrt->mroute_reg_vif_num >= 0)
14fb64e1 818 return -EADDRINUSE;
d1db275d 819 dev = ip6mr_reg_vif(net, mrt);
14fb64e1
YH
820 if (!dev)
821 return -ENOBUFS;
5ae7b444
WC
822 err = dev_set_allmulti(dev, 1);
823 if (err) {
824 unregister_netdevice(dev);
7af3db78 825 dev_put(dev);
5ae7b444
WC
826 return err;
827 }
14fb64e1
YH
828 break;
829#endif
7bc570c8 830 case 0:
8229efda 831 dev = dev_get_by_index(net, vifc->mif6c_pifi);
7bc570c8
YH
832 if (!dev)
833 return -EADDRNOTAVAIL;
5ae7b444 834 err = dev_set_allmulti(dev, 1);
7af3db78
WC
835 if (err) {
836 dev_put(dev);
5ae7b444 837 return err;
7af3db78 838 }
7bc570c8
YH
839 break;
840 default:
841 return -EINVAL;
842 }
843
1d6e55f1 844 in6_dev = __in6_dev_get(dev);
d67b8c61 845 if (in6_dev) {
1d6e55f1 846 in6_dev->cnf.mc_forwarding++;
85b3daad 847 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
d67b8c61
ND
848 NETCONFA_MC_FORWARDING,
849 dev->ifindex, &in6_dev->cnf);
850 }
1d6e55f1 851
6853f21f
YM
852 /* Fill in the VIF structures */
853 vif_device_init(v, dev, vifc->vifc_rate_limit, vifc->vifc_threshold,
854 vifc->mif6c_flags | (!mrtsock ? VIFF_STATIC : 0),
855 MIFF_REGISTER);
7bc570c8
YH
856
857 /* And finish update writing critical data */
858 write_lock_bh(&mrt_lock);
7bc570c8 859 v->dev = dev;
14fb64e1
YH
860#ifdef CONFIG_IPV6_PIMSM_V2
861 if (v->flags & MIFF_REGISTER)
6bd52143 862 mrt->mroute_reg_vif_num = vifi;
14fb64e1 863#endif
6bd52143
PM
864 if (vifi + 1 > mrt->maxvif)
865 mrt->maxvif = vifi + 1;
7bc570c8
YH
866 write_unlock_bh(&mrt_lock);
867 return 0;
868}
869
b70432f7 870static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt,
b71d1d42
ED
871 const struct in6_addr *origin,
872 const struct in6_addr *mcastgrp)
7bc570c8 873{
87c418bf
YM
874 struct mfc6_cache_cmp_arg arg = {
875 .mf6c_origin = *origin,
876 .mf6c_mcastgrp = *mcastgrp,
877 };
87c418bf 878
845c9a7a 879 return mr_mfc_find(mrt, &arg);
660b26dc
ND
880}
881
882/* Look for a (*,G) entry */
b70432f7 883static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
660b26dc
ND
884 struct in6_addr *mcastgrp,
885 mifi_t mifi)
886{
87c418bf
YM
887 struct mfc6_cache_cmp_arg arg = {
888 .mf6c_origin = in6addr_any,
889 .mf6c_mcastgrp = *mcastgrp,
890 };
660b26dc
ND
891
892 if (ipv6_addr_any(mcastgrp))
845c9a7a
YM
893 return mr_mfc_find_any_parent(mrt, mifi);
894 return mr_mfc_find_any(mrt, mifi, &arg);
660b26dc
ND
895}
896
87c418bf
YM
897/* Look for a (S,G,iif) entry if parent != -1 */
898static struct mfc6_cache *
b70432f7 899ip6mr_cache_find_parent(struct mr_table *mrt,
87c418bf
YM
900 const struct in6_addr *origin,
901 const struct in6_addr *mcastgrp,
902 int parent)
903{
904 struct mfc6_cache_cmp_arg arg = {
905 .mf6c_origin = *origin,
906 .mf6c_mcastgrp = *mcastgrp,
907 };
87c418bf 908
845c9a7a 909 return mr_mfc_find_parent(mrt, &arg, parent);
87c418bf
YM
910}
911
845c9a7a 912/* Allocate a multicast cache entry */
b5aa30b1 913static struct mfc6_cache *ip6mr_cache_alloc(void)
7bc570c8 914{
36cbac59 915 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
63159f29 916 if (!c)
7bc570c8 917 return NULL;
494fff56
YM
918 c->_c.mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
919 c->_c.mfc_un.res.minvif = MAXMIFS;
7bc570c8
YH
920 return c;
921}
922
b5aa30b1 923static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
7bc570c8 924{
36cbac59 925 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
63159f29 926 if (!c)
7bc570c8 927 return NULL;
494fff56
YM
928 skb_queue_head_init(&c->_c.mfc_un.unres.unresolved);
929 c->_c.mfc_un.unres.expires = jiffies + 10 * HZ;
7bc570c8
YH
930 return c;
931}
932
933/*
934 * A cache entry has gone into a resolved state from queued
935 */
936
b70432f7 937static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
6bd52143 938 struct mfc6_cache *uc, struct mfc6_cache *c)
7bc570c8
YH
939{
940 struct sk_buff *skb;
941
942 /*
943 * Play the pending entries through our router
944 */
945
494fff56 946 while ((skb = __skb_dequeue(&uc->_c.mfc_un.unres.unresolved))) {
7bc570c8 947 if (ipv6_hdr(skb)->version == 0) {
af72868b
JB
948 struct nlmsghdr *nlh = skb_pull(skb,
949 sizeof(struct ipv6hdr));
7bc570c8 950
573ce260 951 if (__ip6mr_fill_mroute(mrt, skb, c, nlmsg_data(nlh)) > 0) {
549e028d 952 nlh->nlmsg_len = skb_tail_pointer(skb) - (u8 *)nlh;
7bc570c8
YH
953 } else {
954 nlh->nlmsg_type = NLMSG_ERROR;
573ce260 955 nlh->nlmsg_len = nlmsg_msg_size(sizeof(struct nlmsgerr));
7bc570c8 956 skb_trim(skb, nlh->nlmsg_len);
573ce260 957 ((struct nlmsgerr *)nlmsg_data(nlh))->error = -EMSGSIZE;
7bc570c8 958 }
15e47304 959 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
7bc570c8 960 } else
6bd52143 961 ip6_mr_forward(net, mrt, skb, c);
7bc570c8
YH
962 }
963}
964
965/*
dd12d15c 966 * Bounce a cache query up to pim6sd and netlink.
7bc570c8
YH
967 *
968 * Called under mrt_lock.
969 */
970
b70432f7 971static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
6bd52143 972 mifi_t mifi, int assert)
7bc570c8 973{
8571ab47 974 struct sock *mroute6_sk;
7bc570c8
YH
975 struct sk_buff *skb;
976 struct mrt6msg *msg;
977 int ret;
978
14fb64e1
YH
979#ifdef CONFIG_IPV6_PIMSM_V2
980 if (assert == MRT6MSG_WHOLEPKT)
981 skb = skb_realloc_headroom(pkt, -skb_network_offset(pkt)
982 +sizeof(*msg));
983 else
984#endif
985 skb = alloc_skb(sizeof(struct ipv6hdr) + sizeof(*msg), GFP_ATOMIC);
7bc570c8
YH
986
987 if (!skb)
988 return -ENOBUFS;
989
990 /* I suppose that internal messages
991 * do not require checksums */
992
993 skb->ip_summed = CHECKSUM_UNNECESSARY;
994
14fb64e1
YH
995#ifdef CONFIG_IPV6_PIMSM_V2
996 if (assert == MRT6MSG_WHOLEPKT) {
997 /* Ugly, but we have no choice with this interface.
998 Duplicate old header, fix length etc.
999 And all this only to mangle msg->im6_msgtype and
1000 to set msg->im6_mbz to "mbz" :-)
1001 */
1002 skb_push(skb, -skb_network_offset(pkt));
1003
1004 skb_push(skb, sizeof(*msg));
1005 skb_reset_transport_header(skb);
1006 msg = (struct mrt6msg *)skb_transport_header(skb);
1007 msg->im6_mbz = 0;
1008 msg->im6_msgtype = MRT6MSG_WHOLEPKT;
6bd52143 1009 msg->im6_mif = mrt->mroute_reg_vif_num;
14fb64e1 1010 msg->im6_pad = 0;
4e3fd7a0
AD
1011 msg->im6_src = ipv6_hdr(pkt)->saddr;
1012 msg->im6_dst = ipv6_hdr(pkt)->daddr;
14fb64e1
YH
1013
1014 skb->ip_summed = CHECKSUM_UNNECESSARY;
1015 } else
1016#endif
1017 {
7bc570c8
YH
1018 /*
1019 * Copy the IP header
1020 */
1021
1022 skb_put(skb, sizeof(struct ipv6hdr));
1023 skb_reset_network_header(skb);
1024 skb_copy_to_linear_data(skb, ipv6_hdr(pkt), sizeof(struct ipv6hdr));
1025
1026 /*
1027 * Add our header
1028 */
1029 skb_put(skb, sizeof(*msg));
1030 skb_reset_transport_header(skb);
1031 msg = (struct mrt6msg *)skb_transport_header(skb);
1032
1033 msg->im6_mbz = 0;
1034 msg->im6_msgtype = assert;
6ac7eb08 1035 msg->im6_mif = mifi;
7bc570c8 1036 msg->im6_pad = 0;
4e3fd7a0
AD
1037 msg->im6_src = ipv6_hdr(pkt)->saddr;
1038 msg->im6_dst = ipv6_hdr(pkt)->daddr;
7bc570c8 1039
adf30907 1040 skb_dst_set(skb, dst_clone(skb_dst(pkt)));
7bc570c8 1041 skb->ip_summed = CHECKSUM_UNNECESSARY;
14fb64e1 1042 }
7bc570c8 1043
8571ab47 1044 rcu_read_lock();
b70432f7 1045 mroute6_sk = rcu_dereference(mrt->mroute_sk);
8571ab47
YM
1046 if (!mroute6_sk) {
1047 rcu_read_unlock();
7bc570c8
YH
1048 kfree_skb(skb);
1049 return -EINVAL;
1050 }
1051
dd12d15c
JG
1052 mrt6msg_netlink_event(mrt, skb);
1053
8571ab47
YM
1054 /* Deliver to user space multicast routing algorithms */
1055 ret = sock_queue_rcv_skb(mroute6_sk, skb);
1056 rcu_read_unlock();
bd91b8bf 1057 if (ret < 0) {
e87cc472 1058 net_warn_ratelimited("mroute6: pending queue full, dropping entries\n");
7bc570c8
YH
1059 kfree_skb(skb);
1060 }
1061
1062 return ret;
1063}
1064
494fff56
YM
1065/* Queue a packet for resolution. It gets locked cache entry! */
1066static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
1067 struct sk_buff *skb)
7bc570c8 1068{
494fff56 1069 struct mfc6_cache *c;
f30a7784 1070 bool found = false;
7bc570c8 1071 int err;
7bc570c8
YH
1072
1073 spin_lock_bh(&mfc_unres_lock);
494fff56 1074 list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
c476efbc 1075 if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&
f30a7784
PM
1076 ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) {
1077 found = true;
7bc570c8 1078 break;
f30a7784 1079 }
7bc570c8
YH
1080 }
1081
f30a7784 1082 if (!found) {
7bc570c8
YH
1083 /*
1084 * Create a new entry if allowable
1085 */
1086
6bd52143 1087 if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 ||
b5aa30b1 1088 (c = ip6mr_cache_alloc_unres()) == NULL) {
7bc570c8
YH
1089 spin_unlock_bh(&mfc_unres_lock);
1090
1091 kfree_skb(skb);
1092 return -ENOBUFS;
1093 }
1094
494fff56
YM
1095 /* Fill in the new cache entry */
1096 c->_c.mfc_parent = -1;
7bc570c8
YH
1097 c->mf6c_origin = ipv6_hdr(skb)->saddr;
1098 c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr;
1099
1100 /*
1101 * Reflect first query at pim6sd
1102 */
6bd52143 1103 err = ip6mr_cache_report(mrt, skb, mifi, MRT6MSG_NOCACHE);
8229efda 1104 if (err < 0) {
7bc570c8
YH
1105 /* If the report failed throw the cache entry
1106 out - Brad Parker
1107 */
1108 spin_unlock_bh(&mfc_unres_lock);
1109
58701ad4 1110 ip6mr_cache_free(c);
7bc570c8
YH
1111 kfree_skb(skb);
1112 return err;
1113 }
1114
6bd52143 1115 atomic_inc(&mrt->cache_resolve_queue_len);
494fff56 1116 list_add(&c->_c.list, &mrt->mfc_unres_queue);
812e44dd 1117 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
7bc570c8 1118
6bd52143 1119 ipmr_do_expire_process(mrt);
7bc570c8
YH
1120 }
1121
494fff56
YM
1122 /* See if we can append the packet */
1123 if (c->_c.mfc_un.unres.unresolved.qlen > 3) {
7bc570c8
YH
1124 kfree_skb(skb);
1125 err = -ENOBUFS;
1126 } else {
494fff56 1127 skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
7bc570c8
YH
1128 err = 0;
1129 }
1130
1131 spin_unlock_bh(&mfc_unres_lock);
1132 return err;
1133}
1134
1135/*
1136 * MFC6 cache manipulation by user space
1137 */
1138
b70432f7 1139static int ip6mr_mfc_delete(struct mr_table *mrt, struct mf6cctl *mfc,
660b26dc 1140 int parent)
7bc570c8 1141{
87c418bf 1142 struct mfc6_cache *c;
7bc570c8 1143
87c418bf
YM
1144 /* The entries are added/deleted only under RTNL */
1145 rcu_read_lock();
1146 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1147 &mfc->mf6cc_mcastgrp.sin6_addr, parent);
1148 rcu_read_unlock();
1149 if (!c)
1150 return -ENOENT;
494fff56
YM
1151 rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params);
1152 list_del_rcu(&c->_c.list);
7bc570c8 1153
87c418bf
YM
1154 mr6_netlink_event(mrt, c, RTM_DELROUTE);
1155 ip6mr_cache_free(c);
1156 return 0;
7bc570c8
YH
1157}
1158
1159static int ip6mr_device_event(struct notifier_block *this,
1160 unsigned long event, void *ptr)
1161{
351638e7 1162 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
8229efda 1163 struct net *net = dev_net(dev);
b70432f7 1164 struct mr_table *mrt;
6853f21f 1165 struct vif_device *v;
7bc570c8
YH
1166 int ct;
1167
7bc570c8
YH
1168 if (event != NETDEV_UNREGISTER)
1169 return NOTIFY_DONE;
1170
d1db275d 1171 ip6mr_for_each_table(mrt, net) {
b70432f7 1172 v = &mrt->vif_table[0];
d1db275d
PM
1173 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1174 if (v->dev == dev)
723b929c 1175 mif6_delete(mrt, ct, 1, NULL);
d1db275d 1176 }
7bc570c8 1177 }
c871e664 1178
7bc570c8
YH
1179 return NOTIFY_DONE;
1180}
1181
1182static struct notifier_block ip6_mr_notifier = {
1183 .notifier_call = ip6mr_device_event
1184};
1185
1186/*
1187 * Setup for IP multicast routing
1188 */
1189
4e16880c
BT
1190static int __net_init ip6mr_net_init(struct net *net)
1191{
d1db275d 1192 int err;
f30a7784 1193
d1db275d
PM
1194 err = ip6mr_rules_init(net);
1195 if (err < 0)
4e16880c 1196 goto fail;
8b90fc7e
BT
1197
1198#ifdef CONFIG_PROC_FS
1199 err = -ENOMEM;
d4beaa66 1200 if (!proc_create("ip6_mr_vif", 0, net->proc_net, &ip6mr_vif_fops))
8b90fc7e 1201 goto proc_vif_fail;
d4beaa66 1202 if (!proc_create("ip6_mr_cache", 0, net->proc_net, &ip6mr_mfc_fops))
8b90fc7e
BT
1203 goto proc_cache_fail;
1204#endif
6bd52143 1205
4a6258a0
BT
1206 return 0;
1207
8b90fc7e
BT
1208#ifdef CONFIG_PROC_FS
1209proc_cache_fail:
ece31ffd 1210 remove_proc_entry("ip6_mr_vif", net->proc_net);
8b90fc7e 1211proc_vif_fail:
d1db275d 1212 ip6mr_rules_exit(net);
8b90fc7e 1213#endif
4e16880c
BT
1214fail:
1215 return err;
1216}
1217
1218static void __net_exit ip6mr_net_exit(struct net *net)
1219{
8b90fc7e 1220#ifdef CONFIG_PROC_FS
ece31ffd
G
1221 remove_proc_entry("ip6_mr_cache", net->proc_net);
1222 remove_proc_entry("ip6_mr_vif", net->proc_net);
8b90fc7e 1223#endif
d1db275d 1224 ip6mr_rules_exit(net);
4e16880c
BT
1225}
1226
1227static struct pernet_operations ip6mr_net_ops = {
1228 .init = ip6mr_net_init,
1229 .exit = ip6mr_net_exit,
b01a59a4 1230 .async = true,
4e16880c
BT
1231};
1232
623d1a1a 1233int __init ip6_mr_init(void)
7bc570c8 1234{
623d1a1a
WC
1235 int err;
1236
7bc570c8
YH
1237 mrt_cachep = kmem_cache_create("ip6_mrt_cache",
1238 sizeof(struct mfc6_cache),
1239 0, SLAB_HWCACHE_ALIGN,
1240 NULL);
1241 if (!mrt_cachep)
623d1a1a 1242 return -ENOMEM;
7bc570c8 1243
4e16880c
BT
1244 err = register_pernet_subsys(&ip6mr_net_ops);
1245 if (err)
1246 goto reg_pernet_fail;
1247
623d1a1a
WC
1248 err = register_netdevice_notifier(&ip6_mr_notifier);
1249 if (err)
1250 goto reg_notif_fail;
403dbb97
TG
1251#ifdef CONFIG_IPV6_PIMSM_V2
1252 if (inet6_add_protocol(&pim6_protocol, IPPROTO_PIM) < 0) {
f3213831 1253 pr_err("%s: can't add PIM protocol\n", __func__);
403dbb97
TG
1254 err = -EAGAIN;
1255 goto add_proto_fail;
1256 }
1257#endif
a3fde2ad
FW
1258 err = rtnl_register_module(THIS_MODULE, RTNL_FAMILY_IP6MR, RTM_GETROUTE,
1259 NULL, ip6mr_rtm_dumproute, 0);
1260 if (err == 0)
1261 return 0;
1262
403dbb97 1263#ifdef CONFIG_IPV6_PIMSM_V2
a3fde2ad 1264 inet6_del_protocol(&pim6_protocol, IPPROTO_PIM);
403dbb97
TG
1265add_proto_fail:
1266 unregister_netdevice_notifier(&ip6_mr_notifier);
1267#endif
87b30a65 1268reg_notif_fail:
4e16880c
BT
1269 unregister_pernet_subsys(&ip6mr_net_ops);
1270reg_pernet_fail:
87b30a65 1271 kmem_cache_destroy(mrt_cachep);
623d1a1a 1272 return err;
7bc570c8
YH
1273}
1274
623d1a1a
WC
1275void ip6_mr_cleanup(void)
1276{
ffb1388a
DJ
1277 rtnl_unregister(RTNL_FAMILY_IP6MR, RTM_GETROUTE);
1278#ifdef CONFIG_IPV6_PIMSM_V2
1279 inet6_del_protocol(&pim6_protocol, IPPROTO_PIM);
1280#endif
623d1a1a 1281 unregister_netdevice_notifier(&ip6_mr_notifier);
4e16880c 1282 unregister_pernet_subsys(&ip6mr_net_ops);
623d1a1a
WC
1283 kmem_cache_destroy(mrt_cachep);
1284}
7bc570c8 1285
b70432f7 1286static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
660b26dc 1287 struct mf6cctl *mfc, int mrtsock, int parent)
7bc570c8 1288{
6ac7eb08 1289 unsigned char ttls[MAXMIFS];
87c418bf 1290 struct mfc6_cache *uc, *c;
494fff56 1291 struct mr_mfc *_uc;
87c418bf
YM
1292 bool found;
1293 int i, err;
7bc570c8 1294
a50436f2
PM
1295 if (mfc->mf6cc_parent >= MAXMIFS)
1296 return -ENFILE;
1297
6ac7eb08
RR
1298 memset(ttls, 255, MAXMIFS);
1299 for (i = 0; i < MAXMIFS; i++) {
7bc570c8
YH
1300 if (IF_ISSET(i, &mfc->mf6cc_ifset))
1301 ttls[i] = 1;
7bc570c8
YH
1302 }
1303
87c418bf
YM
1304 /* The entries are added/deleted only under RTNL */
1305 rcu_read_lock();
1306 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1307 &mfc->mf6cc_mcastgrp.sin6_addr, parent);
1308 rcu_read_unlock();
1309 if (c) {
7bc570c8 1310 write_lock_bh(&mrt_lock);
494fff56
YM
1311 c->_c.mfc_parent = mfc->mf6cc_parent;
1312 ip6mr_update_thresholds(mrt, &c->_c, ttls);
7bc570c8 1313 if (!mrtsock)
494fff56 1314 c->_c.mfc_flags |= MFC_STATIC;
7bc570c8 1315 write_unlock_bh(&mrt_lock);
812e44dd 1316 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
7bc570c8
YH
1317 return 0;
1318 }
1319
660b26dc
ND
1320 if (!ipv6_addr_any(&mfc->mf6cc_mcastgrp.sin6_addr) &&
1321 !ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
7bc570c8
YH
1322 return -EINVAL;
1323
b5aa30b1 1324 c = ip6mr_cache_alloc();
63159f29 1325 if (!c)
7bc570c8
YH
1326 return -ENOMEM;
1327
1328 c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
1329 c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr;
494fff56
YM
1330 c->_c.mfc_parent = mfc->mf6cc_parent;
1331 ip6mr_update_thresholds(mrt, &c->_c, ttls);
7bc570c8 1332 if (!mrtsock)
494fff56 1333 c->_c.mfc_flags |= MFC_STATIC;
7bc570c8 1334
494fff56 1335 err = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
87c418bf
YM
1336 ip6mr_rht_params);
1337 if (err) {
1338 pr_err("ip6mr: rhtable insert error %d\n", err);
1339 ip6mr_cache_free(c);
1340 return err;
1341 }
494fff56 1342 list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
7bc570c8 1343
87c418bf
YM
1344 /* Check to see if we resolved a queued list. If so we
1345 * need to send on the frames and tidy up.
7bc570c8 1346 */
f30a7784 1347 found = false;
7bc570c8 1348 spin_lock_bh(&mfc_unres_lock);
494fff56
YM
1349 list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
1350 uc = (struct mfc6_cache *)_uc;
c476efbc 1351 if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
7bc570c8 1352 ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) {
494fff56 1353 list_del(&_uc->list);
6bd52143 1354 atomic_dec(&mrt->cache_resolve_queue_len);
f30a7784 1355 found = true;
7bc570c8
YH
1356 break;
1357 }
1358 }
b70432f7 1359 if (list_empty(&mrt->mfc_unres_queue))
6bd52143 1360 del_timer(&mrt->ipmr_expire_timer);
7bc570c8
YH
1361 spin_unlock_bh(&mfc_unres_lock);
1362
f30a7784 1363 if (found) {
6bd52143 1364 ip6mr_cache_resolve(net, mrt, uc, c);
58701ad4 1365 ip6mr_cache_free(uc);
7bc570c8 1366 }
812e44dd 1367 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
7bc570c8
YH
1368 return 0;
1369}
1370
1371/*
1372 * Close the multicast socket, and clear the vif tables etc
1373 */
1374
b70432f7 1375static void mroute_clean_tables(struct mr_table *mrt, bool all)
7bc570c8 1376{
494fff56 1377 struct mr_mfc *c, *tmp;
c871e664 1378 LIST_HEAD(list);
87c418bf 1379 int i;
7bc570c8 1380
87c418bf 1381 /* Shut down all active vif entries */
6bd52143 1382 for (i = 0; i < mrt->maxvif; i++) {
b70432f7 1383 if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
4c698046 1384 continue;
723b929c 1385 mif6_delete(mrt, i, 0, &list);
7bc570c8 1386 }
c871e664 1387 unregister_netdevice_many(&list);
7bc570c8 1388
87c418bf 1389 /* Wipe the cache */
b70432f7 1390 list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
87c418bf
YM
1391 if (!all && (c->mfc_flags & MFC_STATIC))
1392 continue;
b70432f7 1393 rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
87c418bf 1394 list_del_rcu(&c->list);
494fff56
YM
1395 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
1396 ip6mr_cache_free((struct mfc6_cache *)c);
7bc570c8
YH
1397 }
1398
6bd52143 1399 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
7bc570c8 1400 spin_lock_bh(&mfc_unres_lock);
b70432f7 1401 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
f30a7784 1402 list_del(&c->list);
494fff56
YM
1403 mr6_netlink_event(mrt, (struct mfc6_cache *)c,
1404 RTM_DELROUTE);
1405 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
7bc570c8
YH
1406 }
1407 spin_unlock_bh(&mfc_unres_lock);
1408 }
1409}
1410
b70432f7 1411static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk)
7bc570c8
YH
1412{
1413 int err = 0;
8229efda 1414 struct net *net = sock_net(sk);
7bc570c8
YH
1415
1416 rtnl_lock();
1417 write_lock_bh(&mrt_lock);
b70432f7 1418 if (rtnl_dereference(mrt->mroute_sk)) {
7bc570c8 1419 err = -EADDRINUSE;
8571ab47 1420 } else {
b70432f7 1421 rcu_assign_pointer(mrt->mroute_sk, sk);
8571ab47 1422 net->ipv6.devconf_all->mc_forwarding++;
927265bc 1423 }
7bc570c8
YH
1424 write_unlock_bh(&mrt_lock);
1425
927265bc 1426 if (!err)
85b3daad
DA
1427 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
1428 NETCONFA_MC_FORWARDING,
927265bc
ED
1429 NETCONFA_IFINDEX_ALL,
1430 net->ipv6.devconf_all);
7bc570c8
YH
1431 rtnl_unlock();
1432
1433 return err;
1434}
1435
1436int ip6mr_sk_done(struct sock *sk)
1437{
d1db275d 1438 int err = -EACCES;
8229efda 1439 struct net *net = sock_net(sk);
b70432f7 1440 struct mr_table *mrt;
7bc570c8 1441
338d182f
FR
1442 if (sk->sk_type != SOCK_RAW ||
1443 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1444 return err;
1445
7bc570c8 1446 rtnl_lock();
d1db275d 1447 ip6mr_for_each_table(mrt, net) {
b70432f7 1448 if (sk == rtnl_dereference(mrt->mroute_sk)) {
d1db275d 1449 write_lock_bh(&mrt_lock);
b70432f7 1450 RCU_INIT_POINTER(mrt->mroute_sk, NULL);
d1db275d 1451 net->ipv6.devconf_all->mc_forwarding--;
927265bc 1452 write_unlock_bh(&mrt_lock);
85b3daad 1453 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
d67b8c61
ND
1454 NETCONFA_MC_FORWARDING,
1455 NETCONFA_IFINDEX_ALL,
1456 net->ipv6.devconf_all);
7bc570c8 1457
4c698046 1458 mroute_clean_tables(mrt, false);
d1db275d
PM
1459 err = 0;
1460 break;
1461 }
1462 }
7bc570c8 1463 rtnl_unlock();
8571ab47 1464 synchronize_rcu();
7bc570c8
YH
1465
1466 return err;
1467}
1468
8571ab47 1469bool mroute6_is_socket(struct net *net, struct sk_buff *skb)
6bd52143 1470{
b70432f7 1471 struct mr_table *mrt;
4c9483b2 1472 struct flowi6 fl6 = {
e374c618 1473 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
4c9483b2
DM
1474 .flowi6_oif = skb->dev->ifindex,
1475 .flowi6_mark = skb->mark,
d1db275d
PM
1476 };
1477
4c9483b2 1478 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
d1db275d 1479 return NULL;
6bd52143 1480
b70432f7 1481 return rcu_access_pointer(mrt->mroute_sk);
6bd52143 1482}
8571ab47 1483EXPORT_SYMBOL(mroute6_is_socket);
6bd52143 1484
7bc570c8
YH
1485/*
1486 * Socket options and virtual interface manipulation. The whole
1487 * virtual interface system is a complete heap, but unfortunately
1488 * that's how BSD mrouted happens to think. Maybe one day with a proper
1489 * MOSPF/PIM router set up we can clean this up.
1490 */
1491
b7058842 1492int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
7bc570c8 1493{
660b26dc 1494 int ret, parent = 0;
7bc570c8
YH
1495 struct mif6ctl vif;
1496 struct mf6cctl mfc;
1497 mifi_t mifi;
8229efda 1498 struct net *net = sock_net(sk);
b70432f7 1499 struct mr_table *mrt;
d1db275d 1500
99253eb7
XL
1501 if (sk->sk_type != SOCK_RAW ||
1502 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1503 return -EOPNOTSUPP;
1504
d1db275d 1505 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
63159f29 1506 if (!mrt)
d1db275d 1507 return -ENOENT;
7bc570c8
YH
1508
1509 if (optname != MRT6_INIT) {
b70432f7 1510 if (sk != rcu_access_pointer(mrt->mroute_sk) &&
8571ab47 1511 !ns_capable(net->user_ns, CAP_NET_ADMIN))
7bc570c8
YH
1512 return -EACCES;
1513 }
1514
1515 switch (optname) {
1516 case MRT6_INIT:
7bc570c8
YH
1517 if (optlen < sizeof(int))
1518 return -EINVAL;
1519
6bd52143 1520 return ip6mr_sk_init(mrt, sk);
7bc570c8
YH
1521
1522 case MRT6_DONE:
1523 return ip6mr_sk_done(sk);
1524
1525 case MRT6_ADD_MIF:
1526 if (optlen < sizeof(vif))
1527 return -EINVAL;
1528 if (copy_from_user(&vif, optval, sizeof(vif)))
1529 return -EFAULT;
6ac7eb08 1530 if (vif.mif6c_mifi >= MAXMIFS)
7bc570c8
YH
1531 return -ENFILE;
1532 rtnl_lock();
8571ab47 1533 ret = mif6_add(net, mrt, &vif,
b70432f7 1534 sk == rtnl_dereference(mrt->mroute_sk));
7bc570c8
YH
1535 rtnl_unlock();
1536 return ret;
1537
1538 case MRT6_DEL_MIF:
1539 if (optlen < sizeof(mifi_t))
1540 return -EINVAL;
1541 if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
1542 return -EFAULT;
1543 rtnl_lock();
723b929c 1544 ret = mif6_delete(mrt, mifi, 0, NULL);
7bc570c8
YH
1545 rtnl_unlock();
1546 return ret;
1547
1548 /*
1549 * Manipulate the forwarding caches. These live
1550 * in a sort of kernel/user symbiosis.
1551 */
1552 case MRT6_ADD_MFC:
1553 case MRT6_DEL_MFC:
660b26dc 1554 parent = -1;
275757e6 1555 /* fall through */
660b26dc
ND
1556 case MRT6_ADD_MFC_PROXY:
1557 case MRT6_DEL_MFC_PROXY:
7bc570c8
YH
1558 if (optlen < sizeof(mfc))
1559 return -EINVAL;
1560 if (copy_from_user(&mfc, optval, sizeof(mfc)))
1561 return -EFAULT;
660b26dc
ND
1562 if (parent == 0)
1563 parent = mfc.mf6cc_parent;
7bc570c8 1564 rtnl_lock();
660b26dc
ND
1565 if (optname == MRT6_DEL_MFC || optname == MRT6_DEL_MFC_PROXY)
1566 ret = ip6mr_mfc_delete(mrt, &mfc, parent);
7bc570c8 1567 else
660b26dc 1568 ret = ip6mr_mfc_add(net, mrt, &mfc,
8571ab47 1569 sk ==
b70432f7 1570 rtnl_dereference(mrt->mroute_sk),
8571ab47 1571 parent);
7bc570c8
YH
1572 rtnl_unlock();
1573 return ret;
1574
14fb64e1
YH
1575 /*
1576 * Control PIM assert (to activate pim will activate assert)
1577 */
1578 case MRT6_ASSERT:
1579 {
1580 int v;
03f52a0a
JP
1581
1582 if (optlen != sizeof(v))
1583 return -EINVAL;
14fb64e1
YH
1584 if (get_user(v, (int __user *)optval))
1585 return -EFAULT;
53d6841d 1586 mrt->mroute_do_assert = v;
14fb64e1
YH
1587 return 0;
1588 }
1589
1590#ifdef CONFIG_IPV6_PIMSM_V2
1591 case MRT6_PIM:
1592 {
a9f83bf3 1593 int v;
03f52a0a
JP
1594
1595 if (optlen != sizeof(v))
1596 return -EINVAL;
14fb64e1
YH
1597 if (get_user(v, (int __user *)optval))
1598 return -EFAULT;
1599 v = !!v;
1600 rtnl_lock();
1601 ret = 0;
6bd52143
PM
1602 if (v != mrt->mroute_do_pim) {
1603 mrt->mroute_do_pim = v;
1604 mrt->mroute_do_assert = v;
14fb64e1
YH
1605 }
1606 rtnl_unlock();
1607 return ret;
1608 }
1609
d1db275d
PM
1610#endif
1611#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
1612 case MRT6_TABLE:
1613 {
1614 u32 v;
1615
1616 if (optlen != sizeof(u32))
1617 return -EINVAL;
1618 if (get_user(v, (u32 __user *)optval))
1619 return -EFAULT;
75356a81
DC
1620 /* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */
1621 if (v != RT_TABLE_DEFAULT && v >= 100000000)
1622 return -EINVAL;
b70432f7 1623 if (sk == rcu_access_pointer(mrt->mroute_sk))
d1db275d
PM
1624 return -EBUSY;
1625
1626 rtnl_lock();
1627 ret = 0;
1628 if (!ip6mr_new_table(net, v))
1629 ret = -ENOMEM;
1630 raw6_sk(sk)->ip6mr_table = v;
1631 rtnl_unlock();
1632 return ret;
1633 }
14fb64e1 1634#endif
7bc570c8 1635 /*
7d120c55 1636 * Spurious command, or MRT6_VERSION which you cannot
7bc570c8
YH
1637 * set.
1638 */
1639 default:
1640 return -ENOPROTOOPT;
1641 }
1642}
1643
1644/*
1645 * Getsock opt support for the multicast routing system.
1646 */
1647
1648int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval,
1649 int __user *optlen)
1650{
1651 int olr;
1652 int val;
8229efda 1653 struct net *net = sock_net(sk);
b70432f7 1654 struct mr_table *mrt;
d1db275d 1655
99253eb7
XL
1656 if (sk->sk_type != SOCK_RAW ||
1657 inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1658 return -EOPNOTSUPP;
1659
d1db275d 1660 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
63159f29 1661 if (!mrt)
d1db275d 1662 return -ENOENT;
7bc570c8
YH
1663
1664 switch (optname) {
1665 case MRT6_VERSION:
1666 val = 0x0305;
1667 break;
14fb64e1
YH
1668#ifdef CONFIG_IPV6_PIMSM_V2
1669 case MRT6_PIM:
6bd52143 1670 val = mrt->mroute_do_pim;
14fb64e1
YH
1671 break;
1672#endif
1673 case MRT6_ASSERT:
6bd52143 1674 val = mrt->mroute_do_assert;
14fb64e1 1675 break;
7bc570c8
YH
1676 default:
1677 return -ENOPROTOOPT;
1678 }
1679
1680 if (get_user(olr, optlen))
1681 return -EFAULT;
1682
1683 olr = min_t(int, olr, sizeof(int));
1684 if (olr < 0)
1685 return -EINVAL;
1686
1687 if (put_user(olr, optlen))
1688 return -EFAULT;
1689 if (copy_to_user(optval, &val, olr))
1690 return -EFAULT;
1691 return 0;
1692}
1693
1694/*
1695 * The IP multicast ioctl support routines.
1696 */
1697
1698int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1699{
1700 struct sioc_sg_req6 sr;
1701 struct sioc_mif_req6 vr;
6853f21f 1702 struct vif_device *vif;
7bc570c8 1703 struct mfc6_cache *c;
8229efda 1704 struct net *net = sock_net(sk);
b70432f7 1705 struct mr_table *mrt;
d1db275d
PM
1706
1707 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
63159f29 1708 if (!mrt)
d1db275d 1709 return -ENOENT;
7bc570c8
YH
1710
1711 switch (cmd) {
1712 case SIOCGETMIFCNT_IN6:
1713 if (copy_from_user(&vr, arg, sizeof(vr)))
1714 return -EFAULT;
6bd52143 1715 if (vr.mifi >= mrt->maxvif)
7bc570c8
YH
1716 return -EINVAL;
1717 read_lock(&mrt_lock);
b70432f7
YM
1718 vif = &mrt->vif_table[vr.mifi];
1719 if (VIF_EXISTS(mrt, vr.mifi)) {
7bc570c8
YH
1720 vr.icount = vif->pkt_in;
1721 vr.ocount = vif->pkt_out;
1722 vr.ibytes = vif->bytes_in;
1723 vr.obytes = vif->bytes_out;
1724 read_unlock(&mrt_lock);
1725
1726 if (copy_to_user(arg, &vr, sizeof(vr)))
1727 return -EFAULT;
1728 return 0;
1729 }
1730 read_unlock(&mrt_lock);
1731 return -EADDRNOTAVAIL;
1732 case SIOCGETSGCNT_IN6:
1733 if (copy_from_user(&sr, arg, sizeof(sr)))
1734 return -EFAULT;
1735
87c418bf 1736 rcu_read_lock();
6bd52143 1737 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
7bc570c8 1738 if (c) {
494fff56
YM
1739 sr.pktcnt = c->_c.mfc_un.res.pkt;
1740 sr.bytecnt = c->_c.mfc_un.res.bytes;
1741 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
87c418bf 1742 rcu_read_unlock();
7bc570c8
YH
1743
1744 if (copy_to_user(arg, &sr, sizeof(sr)))
1745 return -EFAULT;
1746 return 0;
1747 }
87c418bf 1748 rcu_read_unlock();
7bc570c8
YH
1749 return -EADDRNOTAVAIL;
1750 default:
1751 return -ENOIOCTLCMD;
1752 }
1753}
1754
e2d57766
DM
1755#ifdef CONFIG_COMPAT
1756struct compat_sioc_sg_req6 {
1757 struct sockaddr_in6 src;
1758 struct sockaddr_in6 grp;
1759 compat_ulong_t pktcnt;
1760 compat_ulong_t bytecnt;
1761 compat_ulong_t wrong_if;
1762};
1763
1764struct compat_sioc_mif_req6 {
1765 mifi_t mifi;
1766 compat_ulong_t icount;
1767 compat_ulong_t ocount;
1768 compat_ulong_t ibytes;
1769 compat_ulong_t obytes;
1770};
1771
1772int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1773{
1774 struct compat_sioc_sg_req6 sr;
1775 struct compat_sioc_mif_req6 vr;
6853f21f 1776 struct vif_device *vif;
e2d57766
DM
1777 struct mfc6_cache *c;
1778 struct net *net = sock_net(sk);
b70432f7 1779 struct mr_table *mrt;
e2d57766
DM
1780
1781 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
63159f29 1782 if (!mrt)
e2d57766
DM
1783 return -ENOENT;
1784
1785 switch (cmd) {
1786 case SIOCGETMIFCNT_IN6:
1787 if (copy_from_user(&vr, arg, sizeof(vr)))
1788 return -EFAULT;
1789 if (vr.mifi >= mrt->maxvif)
1790 return -EINVAL;
1791 read_lock(&mrt_lock);
b70432f7
YM
1792 vif = &mrt->vif_table[vr.mifi];
1793 if (VIF_EXISTS(mrt, vr.mifi)) {
e2d57766
DM
1794 vr.icount = vif->pkt_in;
1795 vr.ocount = vif->pkt_out;
1796 vr.ibytes = vif->bytes_in;
1797 vr.obytes = vif->bytes_out;
1798 read_unlock(&mrt_lock);
1799
1800 if (copy_to_user(arg, &vr, sizeof(vr)))
1801 return -EFAULT;
1802 return 0;
1803 }
1804 read_unlock(&mrt_lock);
1805 return -EADDRNOTAVAIL;
1806 case SIOCGETSGCNT_IN6:
1807 if (copy_from_user(&sr, arg, sizeof(sr)))
1808 return -EFAULT;
1809
87c418bf 1810 rcu_read_lock();
e2d57766
DM
1811 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
1812 if (c) {
494fff56
YM
1813 sr.pktcnt = c->_c.mfc_un.res.pkt;
1814 sr.bytecnt = c->_c.mfc_un.res.bytes;
1815 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
87c418bf 1816 rcu_read_unlock();
e2d57766
DM
1817
1818 if (copy_to_user(arg, &sr, sizeof(sr)))
1819 return -EFAULT;
1820 return 0;
1821 }
87c418bf 1822 rcu_read_unlock();
e2d57766
DM
1823 return -EADDRNOTAVAIL;
1824 default:
1825 return -ENOIOCTLCMD;
1826 }
1827}
1828#endif
7bc570c8 1829
0c4b51f0 1830static inline int ip6mr_forward2_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
7bc570c8 1831{
1d015503
ED
1832 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
1833 IPSTATS_MIB_OUTFORWDATAGRAMS);
1834 __IP6_ADD_STATS(net, ip6_dst_idev(skb_dst(skb)),
1835 IPSTATS_MIB_OUTOCTETS, skb->len);
13206b6b 1836 return dst_output(net, sk, skb);
7bc570c8
YH
1837}
1838
1839/*
1840 * Processing handlers for ip6mr_forward
1841 */
1842
b70432f7 1843static int ip6mr_forward2(struct net *net, struct mr_table *mrt,
6bd52143 1844 struct sk_buff *skb, struct mfc6_cache *c, int vifi)
7bc570c8
YH
1845{
1846 struct ipv6hdr *ipv6h;
b70432f7 1847 struct vif_device *vif = &mrt->vif_table[vifi];
7bc570c8
YH
1848 struct net_device *dev;
1849 struct dst_entry *dst;
4c9483b2 1850 struct flowi6 fl6;
7bc570c8 1851
63159f29 1852 if (!vif->dev)
7bc570c8
YH
1853 goto out_free;
1854
14fb64e1
YH
1855#ifdef CONFIG_IPV6_PIMSM_V2
1856 if (vif->flags & MIFF_REGISTER) {
1857 vif->pkt_out++;
1858 vif->bytes_out += skb->len;
dc58c78c
PE
1859 vif->dev->stats.tx_bytes += skb->len;
1860 vif->dev->stats.tx_packets++;
6bd52143 1861 ip6mr_cache_report(mrt, skb, vifi, MRT6MSG_WHOLEPKT);
8da73b73 1862 goto out_free;
14fb64e1
YH
1863 }
1864#endif
1865
7bc570c8
YH
1866 ipv6h = ipv6_hdr(skb);
1867
4c9483b2
DM
1868 fl6 = (struct flowi6) {
1869 .flowi6_oif = vif->link,
1870 .daddr = ipv6h->daddr,
7bc570c8
YH
1871 };
1872
4c9483b2 1873 dst = ip6_route_output(net, NULL, &fl6);
5095d64d
RL
1874 if (dst->error) {
1875 dst_release(dst);
7bc570c8 1876 goto out_free;
5095d64d 1877 }
7bc570c8 1878
adf30907
ED
1879 skb_dst_drop(skb);
1880 skb_dst_set(skb, dst);
7bc570c8
YH
1881
1882 /*
1883 * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
1884 * not only before forwarding, but after forwarding on all output
1885 * interfaces. It is clear, if mrouter runs a multicasting
1886 * program, it should receive packets not depending to what interface
1887 * program is joined.
1888 * If we will not make it, the program will have to join on all
1889 * interfaces. On the other hand, multihoming host (or router, but
1890 * not mrouter) cannot join to more than one interface - it will
1891 * result in receiving multiple packets.
1892 */
1893 dev = vif->dev;
1894 skb->dev = dev;
1895 vif->pkt_out++;
1896 vif->bytes_out += skb->len;
1897
1898 /* We are about to write */
1899 /* XXX: extension headers? */
1900 if (skb_cow(skb, sizeof(*ipv6h) + LL_RESERVED_SPACE(dev)))
1901 goto out_free;
1902
1903 ipv6h = ipv6_hdr(skb);
1904 ipv6h->hop_limit--;
1905
1906 IP6CB(skb)->flags |= IP6SKB_FORWARDED;
1907
29a26a56
EB
1908 return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD,
1909 net, NULL, skb, skb->dev, dev,
7bc570c8
YH
1910 ip6mr_forward2_finish);
1911
1912out_free:
1913 kfree_skb(skb);
1914 return 0;
1915}
1916
b70432f7 1917static int ip6mr_find_vif(struct mr_table *mrt, struct net_device *dev)
7bc570c8
YH
1918{
1919 int ct;
6bd52143
PM
1920
1921 for (ct = mrt->maxvif - 1; ct >= 0; ct--) {
b70432f7 1922 if (mrt->vif_table[ct].dev == dev)
7bc570c8
YH
1923 break;
1924 }
1925 return ct;
1926}
1927
b70432f7 1928static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
494fff56 1929 struct sk_buff *skb, struct mfc6_cache *c)
7bc570c8
YH
1930{
1931 int psend = -1;
1932 int vif, ct;
660b26dc 1933 int true_vifi = ip6mr_find_vif(mrt, skb->dev);
7bc570c8 1934
494fff56
YM
1935 vif = c->_c.mfc_parent;
1936 c->_c.mfc_un.res.pkt++;
1937 c->_c.mfc_un.res.bytes += skb->len;
1938 c->_c.mfc_un.res.lastuse = jiffies;
7bc570c8 1939
494fff56 1940 if (ipv6_addr_any(&c->mf6c_origin) && true_vifi >= 0) {
660b26dc
ND
1941 struct mfc6_cache *cache_proxy;
1942
40dc2ca3 1943 /* For an (*,G) entry, we only check that the incoming
660b26dc
ND
1944 * interface is part of the static tree.
1945 */
87c418bf 1946 rcu_read_lock();
845c9a7a 1947 cache_proxy = mr_mfc_find_any_parent(mrt, vif);
660b26dc 1948 if (cache_proxy &&
494fff56 1949 cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255) {
87c418bf 1950 rcu_read_unlock();
660b26dc 1951 goto forward;
87c418bf
YM
1952 }
1953 rcu_read_unlock();
660b26dc
ND
1954 }
1955
14fb64e1
YH
1956 /*
1957 * Wrong interface: drop packet and (maybe) send PIM assert.
1958 */
b70432f7 1959 if (mrt->vif_table[vif].dev != skb->dev) {
494fff56 1960 c->_c.mfc_un.res.wrong_if++;
14fb64e1 1961
6bd52143 1962 if (true_vifi >= 0 && mrt->mroute_do_assert &&
14fb64e1
YH
1963 /* pimsm uses asserts, when switching from RPT to SPT,
1964 so that we cannot check that packet arrived on an oif.
1965 It is bad, but otherwise we would need to move pretty
1966 large chunk of pimd to kernel. Ough... --ANK
1967 */
6bd52143 1968 (mrt->mroute_do_pim ||
494fff56 1969 c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
14fb64e1 1970 time_after(jiffies,
494fff56
YM
1971 c->_c.mfc_un.res.last_assert +
1972 MFC_ASSERT_THRESH)) {
1973 c->_c.mfc_un.res.last_assert = jiffies;
6bd52143 1974 ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
14fb64e1
YH
1975 }
1976 goto dont_forward;
1977 }
1978
660b26dc 1979forward:
b70432f7
YM
1980 mrt->vif_table[vif].pkt_in++;
1981 mrt->vif_table[vif].bytes_in += skb->len;
7bc570c8
YH
1982
1983 /*
1984 * Forward the frame
1985 */
494fff56
YM
1986 if (ipv6_addr_any(&c->mf6c_origin) &&
1987 ipv6_addr_any(&c->mf6c_mcastgrp)) {
660b26dc 1988 if (true_vifi >= 0 &&
494fff56 1989 true_vifi != c->_c.mfc_parent &&
660b26dc 1990 ipv6_hdr(skb)->hop_limit >
494fff56 1991 c->_c.mfc_un.res.ttls[c->_c.mfc_parent]) {
660b26dc
ND
1992 /* It's an (*,*) entry and the packet is not coming from
1993 * the upstream: forward the packet to the upstream
1994 * only.
1995 */
494fff56 1996 psend = c->_c.mfc_parent;
660b26dc
ND
1997 goto last_forward;
1998 }
1999 goto dont_forward;
2000 }
494fff56
YM
2001 for (ct = c->_c.mfc_un.res.maxvif - 1;
2002 ct >= c->_c.mfc_un.res.minvif; ct--) {
660b26dc 2003 /* For (*,G) entry, don't forward to the incoming interface */
494fff56
YM
2004 if ((!ipv6_addr_any(&c->mf6c_origin) || ct != true_vifi) &&
2005 ipv6_hdr(skb)->hop_limit > c->_c.mfc_un.res.ttls[ct]) {
7bc570c8
YH
2006 if (psend != -1) {
2007 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
2008 if (skb2)
494fff56
YM
2009 ip6mr_forward2(net, mrt, skb2,
2010 c, psend);
7bc570c8
YH
2011 }
2012 psend = ct;
2013 }
2014 }
660b26dc 2015last_forward:
7bc570c8 2016 if (psend != -1) {
494fff56 2017 ip6mr_forward2(net, mrt, skb, c, psend);
2b52c3ad 2018 return;
7bc570c8
YH
2019 }
2020
14fb64e1 2021dont_forward:
7bc570c8 2022 kfree_skb(skb);
7bc570c8
YH
2023}
2024
2025
2026/*
2027 * Multicast packets for forwarding arrive here
2028 */
2029
2030int ip6_mr_input(struct sk_buff *skb)
2031{
2032 struct mfc6_cache *cache;
8229efda 2033 struct net *net = dev_net(skb->dev);
b70432f7 2034 struct mr_table *mrt;
4c9483b2
DM
2035 struct flowi6 fl6 = {
2036 .flowi6_iif = skb->dev->ifindex,
2037 .flowi6_mark = skb->mark,
d1db275d
PM
2038 };
2039 int err;
2040
4c9483b2 2041 err = ip6mr_fib_lookup(net, &fl6, &mrt);
2015de5f
BG
2042 if (err < 0) {
2043 kfree_skb(skb);
d1db275d 2044 return err;
2015de5f 2045 }
7bc570c8
YH
2046
2047 read_lock(&mrt_lock);
6bd52143 2048 cache = ip6mr_cache_find(mrt,
8229efda 2049 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
63159f29 2050 if (!cache) {
660b26dc
ND
2051 int vif = ip6mr_find_vif(mrt, skb->dev);
2052
2053 if (vif >= 0)
2054 cache = ip6mr_cache_find_any(mrt,
2055 &ipv6_hdr(skb)->daddr,
2056 vif);
2057 }
7bc570c8
YH
2058
2059 /*
2060 * No usable cache entry
2061 */
63159f29 2062 if (!cache) {
7bc570c8
YH
2063 int vif;
2064
6bd52143 2065 vif = ip6mr_find_vif(mrt, skb->dev);
7bc570c8 2066 if (vif >= 0) {
6bd52143 2067 int err = ip6mr_cache_unresolved(mrt, vif, skb);
7bc570c8
YH
2068 read_unlock(&mrt_lock);
2069
2070 return err;
2071 }
2072 read_unlock(&mrt_lock);
2073 kfree_skb(skb);
2074 return -ENODEV;
2075 }
2076
6bd52143 2077 ip6_mr_forward(net, mrt, skb, cache);
7bc570c8
YH
2078
2079 read_unlock(&mrt_lock);
2080
2081 return 0;
2082}
2083
2084
b70432f7 2085static int __ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
5b285cac 2086 struct mfc6_cache *c, struct rtmsg *rtm)
7bc570c8 2087{
adfa85e4 2088 struct rta_mfc_stats mfcs;
43b9e127
NA
2089 struct nlattr *mp_attr;
2090 struct rtnexthop *nhp;
b5036cd4 2091 unsigned long lastuse;
43b9e127 2092 int ct;
7bc570c8 2093
7438189b 2094 /* If cache is unresolved, don't try to parse IIF and OIF */
494fff56 2095 if (c->_c.mfc_parent >= MAXMIFS) {
1708ebc9 2096 rtm->rtm_flags |= RTNH_F_UNRESOLVED;
7438189b 2097 return -ENOENT;
1708ebc9 2098 }
7438189b 2099
494fff56 2100 if (VIF_EXISTS(mrt, c->_c.mfc_parent) &&
b70432f7 2101 nla_put_u32(skb, RTA_IIF,
494fff56 2102 mrt->vif_table[c->_c.mfc_parent].dev->ifindex) < 0)
74a0bd7d 2103 return -EMSGSIZE;
70b386a0 2104 mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
63159f29 2105 if (!mp_attr)
70b386a0 2106 return -EMSGSIZE;
7bc570c8 2107
494fff56
YM
2108 for (ct = c->_c.mfc_un.res.minvif;
2109 ct < c->_c.mfc_un.res.maxvif; ct++) {
2110 if (VIF_EXISTS(mrt, ct) && c->_c.mfc_un.res.ttls[ct] < 255) {
70b386a0 2111 nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
63159f29 2112 if (!nhp) {
70b386a0
ND
2113 nla_nest_cancel(skb, mp_attr);
2114 return -EMSGSIZE;
2115 }
2116
7bc570c8 2117 nhp->rtnh_flags = 0;
494fff56 2118 nhp->rtnh_hops = c->_c.mfc_un.res.ttls[ct];
b70432f7 2119 nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex;
7bc570c8
YH
2120 nhp->rtnh_len = sizeof(*nhp);
2121 }
2122 }
70b386a0
ND
2123
2124 nla_nest_end(skb, mp_attr);
2125
494fff56 2126 lastuse = READ_ONCE(c->_c.mfc_un.res.lastuse);
b5036cd4
NA
2127 lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
2128
494fff56
YM
2129 mfcs.mfcs_packets = c->_c.mfc_un.res.pkt;
2130 mfcs.mfcs_bytes = c->_c.mfc_un.res.bytes;
2131 mfcs.mfcs_wrong_if = c->_c.mfc_un.res.wrong_if;
43b9e127 2132 if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
b5036cd4 2133 nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
43b9e127 2134 RTA_PAD))
adfa85e4
ND
2135 return -EMSGSIZE;
2136
7bc570c8
YH
2137 rtm->rtm_type = RTN_MULTICAST;
2138 return 1;
7bc570c8
YH
2139}
2140
2cf75070 2141int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
fd61c6ba 2142 u32 portid)
7bc570c8
YH
2143{
2144 int err;
b70432f7 2145 struct mr_table *mrt;
7bc570c8 2146 struct mfc6_cache *cache;
adf30907 2147 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
7bc570c8 2148
d1db275d 2149 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
63159f29 2150 if (!mrt)
d1db275d
PM
2151 return -ENOENT;
2152
7bc570c8 2153 read_lock(&mrt_lock);
6bd52143 2154 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
660b26dc
ND
2155 if (!cache && skb->dev) {
2156 int vif = ip6mr_find_vif(mrt, skb->dev);
2157
2158 if (vif >= 0)
2159 cache = ip6mr_cache_find_any(mrt, &rt->rt6i_dst.addr,
2160 vif);
2161 }
7bc570c8
YH
2162
2163 if (!cache) {
2164 struct sk_buff *skb2;
2165 struct ipv6hdr *iph;
2166 struct net_device *dev;
2167 int vif;
2168
7bc570c8 2169 dev = skb->dev;
63159f29 2170 if (!dev || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
7bc570c8
YH
2171 read_unlock(&mrt_lock);
2172 return -ENODEV;
2173 }
2174
2175 /* really correct? */
2176 skb2 = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
2177 if (!skb2) {
2178 read_unlock(&mrt_lock);
2179 return -ENOMEM;
2180 }
2181
2cf75070 2182 NETLINK_CB(skb2).portid = portid;
7bc570c8
YH
2183 skb_reset_transport_header(skb2);
2184
2185 skb_put(skb2, sizeof(struct ipv6hdr));
2186 skb_reset_network_header(skb2);
2187
2188 iph = ipv6_hdr(skb2);
2189 iph->version = 0;
2190 iph->priority = 0;
2191 iph->flow_lbl[0] = 0;
2192 iph->flow_lbl[1] = 0;
2193 iph->flow_lbl[2] = 0;
2194 iph->payload_len = 0;
2195 iph->nexthdr = IPPROTO_NONE;
2196 iph->hop_limit = 0;
4e3fd7a0
AD
2197 iph->saddr = rt->rt6i_src.addr;
2198 iph->daddr = rt->rt6i_dst.addr;
7bc570c8 2199
6bd52143 2200 err = ip6mr_cache_unresolved(mrt, vif, skb2);
7bc570c8
YH
2201 read_unlock(&mrt_lock);
2202
2203 return err;
2204 }
2205
fd61c6ba 2206 if (rtm->rtm_flags & RTM_F_NOTIFY)
494fff56 2207 cache->_c.mfc_flags |= MFC_NOTIFY;
7bc570c8 2208
5b285cac 2209 err = __ip6mr_fill_mroute(mrt, skb, cache, rtm);
7bc570c8
YH
2210 read_unlock(&mrt_lock);
2211 return err;
2212}
2213
b70432f7 2214static int ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
f518338b
ND
2215 u32 portid, u32 seq, struct mfc6_cache *c, int cmd,
2216 int flags)
5b285cac
PM
2217{
2218 struct nlmsghdr *nlh;
2219 struct rtmsg *rtm;
1eb99af5 2220 int err;
5b285cac 2221
f518338b 2222 nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags);
63159f29 2223 if (!nlh)
5b285cac
PM
2224 return -EMSGSIZE;
2225
2226 rtm = nlmsg_data(nlh);
193c1e47 2227 rtm->rtm_family = RTNL_FAMILY_IP6MR;
5b285cac
PM
2228 rtm->rtm_dst_len = 128;
2229 rtm->rtm_src_len = 128;
2230 rtm->rtm_tos = 0;
2231 rtm->rtm_table = mrt->id;
c78679e8
DM
2232 if (nla_put_u32(skb, RTA_TABLE, mrt->id))
2233 goto nla_put_failure;
1eb99af5 2234 rtm->rtm_type = RTN_MULTICAST;
5b285cac 2235 rtm->rtm_scope = RT_SCOPE_UNIVERSE;
494fff56 2236 if (c->_c.mfc_flags & MFC_STATIC)
9a68ac72
ND
2237 rtm->rtm_protocol = RTPROT_STATIC;
2238 else
2239 rtm->rtm_protocol = RTPROT_MROUTED;
5b285cac
PM
2240 rtm->rtm_flags = 0;
2241
930345ea
JB
2242 if (nla_put_in6_addr(skb, RTA_SRC, &c->mf6c_origin) ||
2243 nla_put_in6_addr(skb, RTA_DST, &c->mf6c_mcastgrp))
c78679e8 2244 goto nla_put_failure;
1eb99af5
ND
2245 err = __ip6mr_fill_mroute(mrt, skb, c, rtm);
2246 /* do not break the dump if cache is unresolved */
2247 if (err < 0 && err != -ENOENT)
5b285cac
PM
2248 goto nla_put_failure;
2249
053c095a
JB
2250 nlmsg_end(skb, nlh);
2251 return 0;
5b285cac
PM
2252
2253nla_put_failure:
2254 nlmsg_cancel(skb, nlh);
2255 return -EMSGSIZE;
2256}
2257
812e44dd
ND
2258static int mr6_msgsize(bool unresolved, int maxvif)
2259{
2260 size_t len =
2261 NLMSG_ALIGN(sizeof(struct rtmsg))
2262 + nla_total_size(4) /* RTA_TABLE */
2263 + nla_total_size(sizeof(struct in6_addr)) /* RTA_SRC */
2264 + nla_total_size(sizeof(struct in6_addr)) /* RTA_DST */
2265 ;
2266
2267 if (!unresolved)
2268 len = len
2269 + nla_total_size(4) /* RTA_IIF */
2270 + nla_total_size(0) /* RTA_MULTIPATH */
2271 + maxvif * NLA_ALIGN(sizeof(struct rtnexthop))
2272 /* RTA_MFC_STATS */
3d6b66c1 2273 + nla_total_size_64bit(sizeof(struct rta_mfc_stats))
812e44dd
ND
2274 ;
2275
2276 return len;
2277}
2278
b70432f7 2279static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
812e44dd
ND
2280 int cmd)
2281{
2282 struct net *net = read_pnet(&mrt->net);
2283 struct sk_buff *skb;
2284 int err = -ENOBUFS;
2285
494fff56 2286 skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS, mrt->maxvif),
812e44dd 2287 GFP_ATOMIC);
63159f29 2288 if (!skb)
812e44dd
ND
2289 goto errout;
2290
f518338b 2291 err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);
812e44dd
ND
2292 if (err < 0)
2293 goto errout;
2294
2295 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_MROUTE, NULL, GFP_ATOMIC);
2296 return;
2297
2298errout:
2299 kfree_skb(skb);
2300 if (err < 0)
2301 rtnl_set_sk_err(net, RTNLGRP_IPV6_MROUTE, err);
2302}
2303
dd12d15c
JG
2304static size_t mrt6msg_netlink_msgsize(size_t payloadlen)
2305{
2306 size_t len =
2307 NLMSG_ALIGN(sizeof(struct rtgenmsg))
2308 + nla_total_size(1) /* IP6MRA_CREPORT_MSGTYPE */
2309 + nla_total_size(4) /* IP6MRA_CREPORT_MIF_ID */
2310 /* IP6MRA_CREPORT_SRC_ADDR */
2311 + nla_total_size(sizeof(struct in6_addr))
2312 /* IP6MRA_CREPORT_DST_ADDR */
2313 + nla_total_size(sizeof(struct in6_addr))
2314 /* IP6MRA_CREPORT_PKT */
2315 + nla_total_size(payloadlen)
2316 ;
2317
2318 return len;
2319}
2320
b70432f7 2321static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt)
dd12d15c
JG
2322{
2323 struct net *net = read_pnet(&mrt->net);
2324 struct nlmsghdr *nlh;
2325 struct rtgenmsg *rtgenm;
2326 struct mrt6msg *msg;
2327 struct sk_buff *skb;
2328 struct nlattr *nla;
2329 int payloadlen;
2330
2331 payloadlen = pkt->len - sizeof(struct mrt6msg);
2332 msg = (struct mrt6msg *)skb_transport_header(pkt);
2333
2334 skb = nlmsg_new(mrt6msg_netlink_msgsize(payloadlen), GFP_ATOMIC);
2335 if (!skb)
2336 goto errout;
2337
2338 nlh = nlmsg_put(skb, 0, 0, RTM_NEWCACHEREPORT,
2339 sizeof(struct rtgenmsg), 0);
2340 if (!nlh)
2341 goto errout;
2342 rtgenm = nlmsg_data(nlh);
2343 rtgenm->rtgen_family = RTNL_FAMILY_IP6MR;
2344 if (nla_put_u8(skb, IP6MRA_CREPORT_MSGTYPE, msg->im6_msgtype) ||
2345 nla_put_u32(skb, IP6MRA_CREPORT_MIF_ID, msg->im6_mif) ||
2346 nla_put_in6_addr(skb, IP6MRA_CREPORT_SRC_ADDR,
2347 &msg->im6_src) ||
2348 nla_put_in6_addr(skb, IP6MRA_CREPORT_DST_ADDR,
2349 &msg->im6_dst))
2350 goto nla_put_failure;
2351
2352 nla = nla_reserve(skb, IP6MRA_CREPORT_PKT, payloadlen);
2353 if (!nla || skb_copy_bits(pkt, sizeof(struct mrt6msg),
2354 nla_data(nla), payloadlen))
2355 goto nla_put_failure;
2356
2357 nlmsg_end(skb, nlh);
2358
2359 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_MROUTE_R, NULL, GFP_ATOMIC);
2360 return;
2361
2362nla_put_failure:
2363 nlmsg_cancel(skb, nlh);
2364errout:
2365 kfree_skb(skb);
2366 rtnl_set_sk_err(net, RTNLGRP_IPV6_MROUTE_R, -ENOBUFS);
2367}
2368
5b285cac
PM
2369static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
2370{
2371 struct net *net = sock_net(skb->sk);
5b285cac 2372 unsigned int t = 0, s_t;
5b285cac 2373 unsigned int e = 0, s_e;
494fff56
YM
2374 struct mr_table *mrt;
2375 struct mr_mfc *mfc;
5b285cac
PM
2376
2377 s_t = cb->args[0];
87c418bf 2378 s_e = cb->args[1];
5b285cac 2379
87c418bf 2380 rcu_read_lock();
5b285cac
PM
2381 ip6mr_for_each_table(mrt, net) {
2382 if (t < s_t)
2383 goto next_table;
b70432f7 2384 list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
87c418bf
YM
2385 if (e < s_e)
2386 goto next_entry;
2387 if (ip6mr_fill_mroute(mrt, skb,
2388 NETLINK_CB(cb->skb).portid,
2389 cb->nlh->nlmsg_seq,
494fff56
YM
2390 (struct mfc6_cache *)mfc,
2391 RTM_NEWROUTE, NLM_F_MULTI) < 0)
87c418bf 2392 goto done;
5b285cac 2393next_entry:
87c418bf 2394 e++;
5b285cac 2395 }
87c418bf
YM
2396 e = 0;
2397 s_e = 0;
2398
1eb99af5 2399 spin_lock_bh(&mfc_unres_lock);
b70432f7 2400 list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
1eb99af5
ND
2401 if (e < s_e)
2402 goto next_entry2;
2403 if (ip6mr_fill_mroute(mrt, skb,
2404 NETLINK_CB(cb->skb).portid,
2405 cb->nlh->nlmsg_seq,
494fff56
YM
2406 (struct mfc6_cache *)mfc,
2407 RTM_NEWROUTE, NLM_F_MULTI) < 0) {
1eb99af5
ND
2408 spin_unlock_bh(&mfc_unres_lock);
2409 goto done;
2410 }
2411next_entry2:
2412 e++;
2413 }
2414 spin_unlock_bh(&mfc_unres_lock);
2415 e = s_e = 0;
5b285cac
PM
2416next_table:
2417 t++;
2418 }
2419done:
87c418bf 2420 rcu_read_unlock();
5b285cac 2421
87c418bf 2422 cb->args[1] = e;
5b285cac
PM
2423 cb->args[0] = t;
2424
2425 return skb->len;
2426}
This page took 1.172059 seconds and 4 git commands to generate.