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