blob: d19a84b7950348519741440ed0376579f0e30767 [file] [log] [blame]
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001/*
2 * Linux IPv6 multicast routing support for BSD pim6sd
3 * Based on net/ipv4/ipmr.c.
4 *
5 * (c) 2004 Mickael Hoerdt, <hoerdt@clarinet.u-strasbg.fr>
6 * LSIIT Laboratory, Strasbourg, France
7 * (c) 2004 Jean-Philippe Andriot, <jean-philippe.andriot@6WIND.com>
8 * 6WIND, Paris, France
9 * Copyright (C)2007,2008 USAGI/WIDE Project
10 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
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
19#include <asm/system.h>
20#include <asm/uaccess.h>
21#include <linux/types.h>
22#include <linux/sched.h>
23#include <linux/errno.h>
24#include <linux/timer.h>
25#include <linux/mm.h>
26#include <linux/kernel.h>
27#include <linux/fcntl.h>
28#include <linux/stat.h>
29#include <linux/socket.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090030#include <linux/inet.h>
31#include <linux/netdevice.h>
32#include <linux/inetdevice.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090033#include <linux/proc_fs.h>
34#include <linux/seq_file.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090035#include <linux/init.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090036#include <net/protocol.h>
37#include <linux/skbuff.h>
38#include <net/sock.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090039#include <net/raw.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090040#include <linux/notifier.h>
41#include <linux/if_arp.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090042#include <net/checksum.h>
43#include <net/netlink.h>
44
45#include <net/ipv6.h>
46#include <net/ip6_route.h>
47#include <linux/mroute6.h>
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +090048#include <linux/pim.h>
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090049#include <net/addrconf.h>
50#include <linux/netfilter_ipv6.h>
51
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090052/* Big lock, protecting vif table, mrt cache and mroute socket state.
53 Note that the changes are semaphored via rtnl_lock.
54 */
55
56static DEFINE_RWLOCK(mrt_lock);
57
58/*
59 * Multicast router control variables
60 */
61
Benjamin Thery4e168802008-12-10 16:15:08 -080062#define MIF_EXISTS(_net, _idx) ((_net)->ipv6.vif6_table[_idx].dev != NULL)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090063
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090064static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090065
66/* Special spinlock for queue of unresolved entries */
67static DEFINE_SPINLOCK(mfc_unres_lock);
68
69/* We return to original Alan's scheme. Hash table of resolved
70 entries is changed only in process context and protected
71 with weak lock mrt_lock. Queue of unresolved entries is protected
72 with strong spinlock mfc_unres_lock.
73
74 In this case data path is free of exclusive locks at all.
75 */
76
77static struct kmem_cache *mrt_cachep __read_mostly;
78
79static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache);
Benjamin Thery8229efd2008-12-10 16:30:15 -080080static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt,
81 mifi_t mifi, int assert);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090082static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm);
Benjamin Thery8229efd2008-12-10 16:30:15 -080083static void mroute_clean_tables(struct net *net);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090084
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +090085#ifdef CONFIG_IPV6_PIMSM_V2
86static struct inet6_protocol pim6_protocol;
87#endif
88
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090089static struct timer_list ipmr_expire_timer;
90
91
92#ifdef CONFIG_PROC_FS
93
94struct ipmr_mfc_iter {
Benjamin Thery8b90fc72008-12-10 16:29:48 -080095 struct seq_net_private p;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +090096 struct mfc6_cache **cache;
97 int ct;
98};
99
100
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800101static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
102 struct ipmr_mfc_iter *it, loff_t pos)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900103{
104 struct mfc6_cache *mfc;
105
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800106 it->cache = net->ipv6.mfc6_cache_array;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900107 read_lock(&mrt_lock);
Benjamin Thery4a6258a2008-12-10 16:24:07 -0800108 for (it->ct = 0; it->ct < MFC6_LINES; it->ct++)
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800109 for (mfc = net->ipv6.mfc6_cache_array[it->ct];
Benjamin Thery4a6258a2008-12-10 16:24:07 -0800110 mfc; mfc = mfc->next)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900111 if (pos-- == 0)
112 return mfc;
113 read_unlock(&mrt_lock);
114
115 it->cache = &mfc_unres_queue;
116 spin_lock_bh(&mfc_unres_lock);
117 for (mfc = mfc_unres_queue; mfc; mfc = mfc->next)
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800118 if (net_eq(mfc6_net(mfc), net) &&
119 pos-- == 0)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900120 return mfc;
121 spin_unlock_bh(&mfc_unres_lock);
122
123 it->cache = NULL;
124 return NULL;
125}
126
127
128
129
130/*
131 * The /proc interfaces to multicast routing /proc/ip6_mr_cache /proc/ip6_mr_vif
132 */
133
134struct ipmr_vif_iter {
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800135 struct seq_net_private p;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900136 int ct;
137};
138
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800139static struct mif_device *ip6mr_vif_seq_idx(struct net *net,
140 struct ipmr_vif_iter *iter,
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900141 loff_t pos)
142{
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800143 for (iter->ct = 0; iter->ct < net->ipv6.maxvif; ++iter->ct) {
144 if (!MIF_EXISTS(net, iter->ct))
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900145 continue;
146 if (pos-- == 0)
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800147 return &net->ipv6.vif6_table[iter->ct];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900148 }
149 return NULL;
150}
151
152static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
153 __acquires(mrt_lock)
154{
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800155 struct net *net = seq_file_net(seq);
156
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900157 read_lock(&mrt_lock);
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800158 return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1)
159 : SEQ_START_TOKEN;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900160}
161
162static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
163{
164 struct ipmr_vif_iter *iter = seq->private;
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800165 struct net *net = seq_file_net(seq);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900166
167 ++*pos;
168 if (v == SEQ_START_TOKEN)
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800169 return ip6mr_vif_seq_idx(net, iter, 0);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900170
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800171 while (++iter->ct < net->ipv6.maxvif) {
172 if (!MIF_EXISTS(net, iter->ct))
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900173 continue;
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800174 return &net->ipv6.vif6_table[iter->ct];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900175 }
176 return NULL;
177}
178
179static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
180 __releases(mrt_lock)
181{
182 read_unlock(&mrt_lock);
183}
184
185static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
186{
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800187 struct net *net = seq_file_net(seq);
188
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900189 if (v == SEQ_START_TOKEN) {
190 seq_puts(seq,
191 "Interface BytesIn PktsIn BytesOut PktsOut Flags\n");
192 } else {
193 const struct mif_device *vif = v;
194 const char *name = vif->dev ? vif->dev->name : "none";
195
196 seq_printf(seq,
Al Virod430a222008-06-02 10:59:02 +0100197 "%2td %-10s %8ld %7ld %8ld %7ld %05X\n",
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800198 vif - net->ipv6.vif6_table,
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900199 name, vif->bytes_in, vif->pkt_in,
200 vif->bytes_out, vif->pkt_out,
201 vif->flags);
202 }
203 return 0;
204}
205
206static struct seq_operations ip6mr_vif_seq_ops = {
207 .start = ip6mr_vif_seq_start,
208 .next = ip6mr_vif_seq_next,
209 .stop = ip6mr_vif_seq_stop,
210 .show = ip6mr_vif_seq_show,
211};
212
213static int ip6mr_vif_open(struct inode *inode, struct file *file)
214{
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800215 return seq_open_net(inode, file, &ip6mr_vif_seq_ops,
216 sizeof(struct ipmr_vif_iter));
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900217}
218
219static struct file_operations ip6mr_vif_fops = {
220 .owner = THIS_MODULE,
221 .open = ip6mr_vif_open,
222 .read = seq_read,
223 .llseek = seq_lseek,
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800224 .release = seq_release_net,
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900225};
226
227static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
228{
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800229 struct net *net = seq_file_net(seq);
230
231 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
232 : SEQ_START_TOKEN;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900233}
234
235static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
236{
237 struct mfc6_cache *mfc = v;
238 struct ipmr_mfc_iter *it = seq->private;
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800239 struct net *net = seq_file_net(seq);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900240
241 ++*pos;
242
243 if (v == SEQ_START_TOKEN)
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800244 return ipmr_mfc_seq_idx(net, seq->private, 0);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900245
246 if (mfc->next)
247 return mfc->next;
248
249 if (it->cache == &mfc_unres_queue)
250 goto end_of_list;
251
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800252 BUG_ON(it->cache != net->ipv6.mfc6_cache_array);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900253
Benjamin Thery4a6258a2008-12-10 16:24:07 -0800254 while (++it->ct < MFC6_LINES) {
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800255 mfc = net->ipv6.mfc6_cache_array[it->ct];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900256 if (mfc)
257 return mfc;
258 }
259
260 /* exhausted cache_array, show unresolved */
261 read_unlock(&mrt_lock);
262 it->cache = &mfc_unres_queue;
263 it->ct = 0;
264
265 spin_lock_bh(&mfc_unres_lock);
266 mfc = mfc_unres_queue;
267 if (mfc)
268 return mfc;
269
270 end_of_list:
271 spin_unlock_bh(&mfc_unres_lock);
272 it->cache = NULL;
273
274 return NULL;
275}
276
277static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
278{
279 struct ipmr_mfc_iter *it = seq->private;
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800280 struct net *net = seq_file_net(seq);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900281
282 if (it->cache == &mfc_unres_queue)
283 spin_unlock_bh(&mfc_unres_lock);
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800284 else if (it->cache == net->ipv6.mfc6_cache_array)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900285 read_unlock(&mrt_lock);
286}
287
288static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
289{
290 int n;
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800291 struct net *net = seq_file_net(seq);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900292
293 if (v == SEQ_START_TOKEN) {
294 seq_puts(seq,
295 "Group "
296 "Origin "
297 "Iif Pkts Bytes Wrong Oifs\n");
298 } else {
299 const struct mfc6_cache *mfc = v;
300 const struct ipmr_mfc_iter *it = seq->private;
301
Benjamin Thery999890b2008-12-03 22:22:16 -0800302 seq_printf(seq, "%pI6 %pI6 %-3hd",
Harvey Harrison0c6ce782008-10-28 16:09:23 -0700303 &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
Benjamin Thery1ea472e2008-12-03 22:21:47 -0800304 mfc->mf6c_parent);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900305
306 if (it->cache != &mfc_unres_queue) {
Benjamin Thery1ea472e2008-12-03 22:21:47 -0800307 seq_printf(seq, " %8lu %8lu %8lu",
308 mfc->mfc_un.res.pkt,
309 mfc->mfc_un.res.bytes,
310 mfc->mfc_un.res.wrong_if);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900311 for (n = mfc->mfc_un.res.minvif;
312 n < mfc->mfc_un.res.maxvif; n++) {
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800313 if (MIF_EXISTS(net, n) &&
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900314 mfc->mfc_un.res.ttls[n] < 255)
315 seq_printf(seq,
316 " %2d:%-3d",
317 n, mfc->mfc_un.res.ttls[n]);
318 }
Benjamin Thery1ea472e2008-12-03 22:21:47 -0800319 } else {
320 /* unresolved mfc_caches don't contain
321 * pkt, bytes and wrong_if values
322 */
323 seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900324 }
325 seq_putc(seq, '\n');
326 }
327 return 0;
328}
329
330static struct seq_operations ipmr_mfc_seq_ops = {
331 .start = ipmr_mfc_seq_start,
332 .next = ipmr_mfc_seq_next,
333 .stop = ipmr_mfc_seq_stop,
334 .show = ipmr_mfc_seq_show,
335};
336
337static int ipmr_mfc_open(struct inode *inode, struct file *file)
338{
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800339 return seq_open_net(inode, file, &ipmr_mfc_seq_ops,
340 sizeof(struct ipmr_mfc_iter));
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900341}
342
343static struct file_operations ip6mr_mfc_fops = {
344 .owner = THIS_MODULE,
345 .open = ipmr_mfc_open,
346 .read = seq_read,
347 .llseek = seq_lseek,
Benjamin Thery8b90fc72008-12-10 16:29:48 -0800348 .release = seq_release_net,
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900349};
350#endif
351
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900352#ifdef CONFIG_IPV6_PIMSM_V2
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900353
354static int pim6_rcv(struct sk_buff *skb)
355{
356 struct pimreghdr *pim;
357 struct ipv6hdr *encap;
358 struct net_device *reg_dev = NULL;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800359 struct net *net = dev_net(skb->dev);
360 int reg_vif_num = net->ipv6.mroute_reg_vif_num;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900361
362 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
363 goto drop;
364
365 pim = (struct pimreghdr *)skb_transport_header(skb);
366 if (pim->type != ((PIM_VERSION << 4) | PIM_REGISTER) ||
367 (pim->flags & PIM_NULL_REGISTER) ||
Thomas Goff1d6e55f2009-01-27 22:39:59 -0800368 (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
369 sizeof(*pim), IPPROTO_PIM,
370 csum_partial((void *)pim, sizeof(*pim), 0)) &&
Al Viroec6b4862008-04-26 22:28:58 -0700371 csum_fold(skb_checksum(skb, 0, skb->len, 0))))
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900372 goto drop;
373
374 /* check if the inner packet is destined to mcast group */
375 encap = (struct ipv6hdr *)(skb_transport_header(skb) +
376 sizeof(*pim));
377
378 if (!ipv6_addr_is_multicast(&encap->daddr) ||
379 encap->payload_len == 0 ||
380 ntohs(encap->payload_len) + sizeof(*pim) > skb->len)
381 goto drop;
382
383 read_lock(&mrt_lock);
384 if (reg_vif_num >= 0)
Benjamin Thery8229efd2008-12-10 16:30:15 -0800385 reg_dev = net->ipv6.vif6_table[reg_vif_num].dev;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900386 if (reg_dev)
387 dev_hold(reg_dev);
388 read_unlock(&mrt_lock);
389
390 if (reg_dev == NULL)
391 goto drop;
392
393 skb->mac_header = skb->network_header;
394 skb_pull(skb, (u8 *)encap - skb->data);
395 skb_reset_network_header(skb);
396 skb->dev = reg_dev;
Thomas Goff1d6e55f2009-01-27 22:39:59 -0800397 skb->protocol = htons(ETH_P_IPV6);
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900398 skb->ip_summed = 0;
399 skb->pkt_type = PACKET_HOST;
400 dst_release(skb->dst);
Pavel Emelyanovdc58c782008-05-21 14:17:54 -0700401 reg_dev->stats.rx_bytes += skb->len;
402 reg_dev->stats.rx_packets++;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900403 skb->dst = NULL;
404 nf_reset(skb);
405 netif_rx(skb);
406 dev_put(reg_dev);
407 return 0;
408 drop:
409 kfree_skb(skb);
410 return 0;
411}
412
413static struct inet6_protocol pim6_protocol = {
414 .handler = pim6_rcv,
415};
416
417/* Service routines creating virtual interfaces: PIMREG */
418
419static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
420{
Benjamin Thery8229efd2008-12-10 16:30:15 -0800421 struct net *net = dev_net(dev);
422
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900423 read_lock(&mrt_lock);
Pavel Emelyanovdc58c782008-05-21 14:17:54 -0700424 dev->stats.tx_bytes += skb->len;
425 dev->stats.tx_packets++;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800426 ip6mr_cache_report(net, skb, net->ipv6.mroute_reg_vif_num,
427 MRT6MSG_WHOLEPKT);
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900428 read_unlock(&mrt_lock);
429 kfree_skb(skb);
430 return 0;
431}
432
Stephen Hemminger007c3832008-11-20 20:28:35 -0800433static const struct net_device_ops reg_vif_netdev_ops = {
434 .ndo_start_xmit = reg_vif_xmit,
435};
436
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900437static void reg_vif_setup(struct net_device *dev)
438{
439 dev->type = ARPHRD_PIMREG;
440 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
441 dev->flags = IFF_NOARP;
Stephen Hemminger007c3832008-11-20 20:28:35 -0800442 dev->netdev_ops = &reg_vif_netdev_ops;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900443 dev->destructor = free_netdev;
444}
445
Benjamin Thery8229efd2008-12-10 16:30:15 -0800446static struct net_device *ip6mr_reg_vif(struct net *net)
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900447{
448 struct net_device *dev;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900449
Pavel Emelyanovdc58c782008-05-21 14:17:54 -0700450 dev = alloc_netdev(0, "pim6reg", reg_vif_setup);
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900451 if (dev == NULL)
452 return NULL;
453
Benjamin Thery8229efd2008-12-10 16:30:15 -0800454 dev_net_set(dev, net);
455
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900456 if (register_netdevice(dev)) {
457 free_netdev(dev);
458 return NULL;
459 }
460 dev->iflink = 0;
461
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900462 if (dev_open(dev))
463 goto failure;
464
Wang Chen7af3db72008-07-14 20:54:54 -0700465 dev_hold(dev);
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900466 return dev;
467
468failure:
469 /* allow the register to be completed before unregistering. */
470 rtnl_unlock();
471 rtnl_lock();
472
473 unregister_netdevice(dev);
474 return NULL;
475}
476#endif
477
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900478/*
479 * Delete a VIF entry
480 */
481
Benjamin Thery8229efd2008-12-10 16:30:15 -0800482static int mif6_delete(struct net *net, int vifi)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900483{
484 struct mif_device *v;
485 struct net_device *dev;
Thomas Goff1d6e55f2009-01-27 22:39:59 -0800486 struct inet6_dev *in6_dev;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800487 if (vifi < 0 || vifi >= net->ipv6.maxvif)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900488 return -EADDRNOTAVAIL;
489
Benjamin Thery8229efd2008-12-10 16:30:15 -0800490 v = &net->ipv6.vif6_table[vifi];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900491
492 write_lock_bh(&mrt_lock);
493 dev = v->dev;
494 v->dev = NULL;
495
496 if (!dev) {
497 write_unlock_bh(&mrt_lock);
498 return -EADDRNOTAVAIL;
499 }
500
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900501#ifdef CONFIG_IPV6_PIMSM_V2
Benjamin Thery8229efd2008-12-10 16:30:15 -0800502 if (vifi == net->ipv6.mroute_reg_vif_num)
503 net->ipv6.mroute_reg_vif_num = -1;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900504#endif
505
Benjamin Thery8229efd2008-12-10 16:30:15 -0800506 if (vifi + 1 == net->ipv6.maxvif) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900507 int tmp;
508 for (tmp = vifi - 1; tmp >= 0; tmp--) {
Benjamin Thery8229efd2008-12-10 16:30:15 -0800509 if (MIF_EXISTS(net, tmp))
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900510 break;
511 }
Benjamin Thery8229efd2008-12-10 16:30:15 -0800512 net->ipv6.maxvif = tmp + 1;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900513 }
514
515 write_unlock_bh(&mrt_lock);
516
517 dev_set_allmulti(dev, -1);
518
Thomas Goff1d6e55f2009-01-27 22:39:59 -0800519 in6_dev = __in6_dev_get(dev);
520 if (in6_dev)
521 in6_dev->cnf.mc_forwarding--;
522
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900523 if (v->flags & MIFF_REGISTER)
524 unregister_netdevice(dev);
525
526 dev_put(dev);
527 return 0;
528}
529
Benjamin Thery58701ad2008-12-10 16:22:34 -0800530static inline void ip6mr_cache_free(struct mfc6_cache *c)
531{
532 release_net(mfc6_net(c));
533 kmem_cache_free(mrt_cachep, c);
534}
535
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900536/* Destroy an unresolved cache entry, killing queued skbs
537 and reporting error to netlink readers.
538 */
539
540static void ip6mr_destroy_unres(struct mfc6_cache *c)
541{
542 struct sk_buff *skb;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800543 struct net *net = mfc6_net(c);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900544
Benjamin Thery8229efd2008-12-10 16:30:15 -0800545 atomic_dec(&net->ipv6.cache_resolve_queue_len);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900546
547 while((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) {
548 if (ipv6_hdr(skb)->version == 0) {
549 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
550 nlh->nlmsg_type = NLMSG_ERROR;
551 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
552 skb_trim(skb, nlh->nlmsg_len);
553 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800554 rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900555 } else
556 kfree_skb(skb);
557 }
558
Benjamin Thery58701ad2008-12-10 16:22:34 -0800559 ip6mr_cache_free(c);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900560}
561
562
563/* Single timer process for all the unresolved queue. */
564
565static void ipmr_do_expire_process(unsigned long dummy)
566{
567 unsigned long now = jiffies;
568 unsigned long expires = 10 * HZ;
569 struct mfc6_cache *c, **cp;
570
571 cp = &mfc_unres_queue;
572
573 while ((c = *cp) != NULL) {
574 if (time_after(c->mfc_un.unres.expires, now)) {
575 /* not yet... */
576 unsigned long interval = c->mfc_un.unres.expires - now;
577 if (interval < expires)
578 expires = interval;
579 cp = &c->next;
580 continue;
581 }
582
583 *cp = c->next;
584 ip6mr_destroy_unres(c);
585 }
586
Benjamin Thery4045e572008-12-10 16:27:21 -0800587 if (mfc_unres_queue != NULL)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900588 mod_timer(&ipmr_expire_timer, jiffies + expires);
589}
590
591static void ipmr_expire_process(unsigned long dummy)
592{
593 if (!spin_trylock(&mfc_unres_lock)) {
594 mod_timer(&ipmr_expire_timer, jiffies + 1);
595 return;
596 }
597
Benjamin Thery4045e572008-12-10 16:27:21 -0800598 if (mfc_unres_queue != NULL)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900599 ipmr_do_expire_process(dummy);
600
601 spin_unlock(&mfc_unres_lock);
602}
603
604/* Fill oifs list. It is called under write locked mrt_lock. */
605
606static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttls)
607{
608 int vifi;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800609 struct net *net = mfc6_net(cache);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900610
Rami Rosen6ac7eb02008-04-10 12:40:10 +0300611 cache->mfc_un.res.minvif = MAXMIFS;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900612 cache->mfc_un.res.maxvif = 0;
Rami Rosen6ac7eb02008-04-10 12:40:10 +0300613 memset(cache->mfc_un.res.ttls, 255, MAXMIFS);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900614
Benjamin Thery8229efd2008-12-10 16:30:15 -0800615 for (vifi = 0; vifi < net->ipv6.maxvif; vifi++) {
616 if (MIF_EXISTS(net, vifi) &&
Benjamin Thery4e168802008-12-10 16:15:08 -0800617 ttls[vifi] && ttls[vifi] < 255) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900618 cache->mfc_un.res.ttls[vifi] = ttls[vifi];
619 if (cache->mfc_un.res.minvif > vifi)
620 cache->mfc_un.res.minvif = vifi;
621 if (cache->mfc_un.res.maxvif <= vifi)
622 cache->mfc_un.res.maxvif = vifi + 1;
623 }
624 }
625}
626
Benjamin Thery8229efd2008-12-10 16:30:15 -0800627static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900628{
629 int vifi = vifc->mif6c_mifi;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800630 struct mif_device *v = &net->ipv6.vif6_table[vifi];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900631 struct net_device *dev;
Thomas Goff1d6e55f2009-01-27 22:39:59 -0800632 struct inet6_dev *in6_dev;
Wang Chen5ae7b442008-07-14 20:54:23 -0700633 int err;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900634
635 /* Is vif busy ? */
Benjamin Thery8229efd2008-12-10 16:30:15 -0800636 if (MIF_EXISTS(net, vifi))
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900637 return -EADDRINUSE;
638
639 switch (vifc->mif6c_flags) {
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900640#ifdef CONFIG_IPV6_PIMSM_V2
641 case MIFF_REGISTER:
642 /*
643 * Special Purpose VIF in PIM
644 * All the packets will be sent to the daemon
645 */
Benjamin Thery8229efd2008-12-10 16:30:15 -0800646 if (net->ipv6.mroute_reg_vif_num >= 0)
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900647 return -EADDRINUSE;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800648 dev = ip6mr_reg_vif(net);
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900649 if (!dev)
650 return -ENOBUFS;
Wang Chen5ae7b442008-07-14 20:54:23 -0700651 err = dev_set_allmulti(dev, 1);
652 if (err) {
653 unregister_netdevice(dev);
Wang Chen7af3db72008-07-14 20:54:54 -0700654 dev_put(dev);
Wang Chen5ae7b442008-07-14 20:54:23 -0700655 return err;
656 }
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900657 break;
658#endif
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900659 case 0:
Benjamin Thery8229efd2008-12-10 16:30:15 -0800660 dev = dev_get_by_index(net, vifc->mif6c_pifi);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900661 if (!dev)
662 return -EADDRNOTAVAIL;
Wang Chen5ae7b442008-07-14 20:54:23 -0700663 err = dev_set_allmulti(dev, 1);
Wang Chen7af3db72008-07-14 20:54:54 -0700664 if (err) {
665 dev_put(dev);
Wang Chen5ae7b442008-07-14 20:54:23 -0700666 return err;
Wang Chen7af3db72008-07-14 20:54:54 -0700667 }
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900668 break;
669 default:
670 return -EINVAL;
671 }
672
Thomas Goff1d6e55f2009-01-27 22:39:59 -0800673 in6_dev = __in6_dev_get(dev);
674 if (in6_dev)
675 in6_dev->cnf.mc_forwarding++;
676
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900677 /*
678 * Fill in the VIF structures
679 */
680 v->rate_limit = vifc->vifc_rate_limit;
681 v->flags = vifc->mif6c_flags;
682 if (!mrtsock)
683 v->flags |= VIFF_STATIC;
684 v->threshold = vifc->vifc_threshold;
685 v->bytes_in = 0;
686 v->bytes_out = 0;
687 v->pkt_in = 0;
688 v->pkt_out = 0;
689 v->link = dev->ifindex;
690 if (v->flags & MIFF_REGISTER)
691 v->link = dev->iflink;
692
693 /* And finish update writing critical data */
694 write_lock_bh(&mrt_lock);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900695 v->dev = dev;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900696#ifdef CONFIG_IPV6_PIMSM_V2
697 if (v->flags & MIFF_REGISTER)
Benjamin Thery8229efd2008-12-10 16:30:15 -0800698 net->ipv6.mroute_reg_vif_num = vifi;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900699#endif
Benjamin Thery8229efd2008-12-10 16:30:15 -0800700 if (vifi + 1 > net->ipv6.maxvif)
701 net->ipv6.maxvif = vifi + 1;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900702 write_unlock_bh(&mrt_lock);
703 return 0;
704}
705
Benjamin Thery8229efd2008-12-10 16:30:15 -0800706static struct mfc6_cache *ip6mr_cache_find(struct net *net,
707 struct in6_addr *origin,
708 struct in6_addr *mcastgrp)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900709{
710 int line = MFC6_HASH(mcastgrp, origin);
711 struct mfc6_cache *c;
712
Benjamin Thery8229efd2008-12-10 16:30:15 -0800713 for (c = net->ipv6.mfc6_cache_array[line]; c; c = c->next) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900714 if (ipv6_addr_equal(&c->mf6c_origin, origin) &&
715 ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp))
716 break;
717 }
718 return c;
719}
720
721/*
722 * Allocate a multicast cache entry
723 */
Benjamin Thery58701ad2008-12-10 16:22:34 -0800724static struct mfc6_cache *ip6mr_cache_alloc(struct net *net)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900725{
Joe Perches36cbac52008-12-03 22:27:25 -0800726 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900727 if (c == NULL)
728 return NULL;
Rami Rosen6ac7eb02008-04-10 12:40:10 +0300729 c->mfc_un.res.minvif = MAXMIFS;
Benjamin Thery58701ad2008-12-10 16:22:34 -0800730 mfc6_net_set(c, net);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900731 return c;
732}
733
Benjamin Thery58701ad2008-12-10 16:22:34 -0800734static struct mfc6_cache *ip6mr_cache_alloc_unres(struct net *net)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900735{
Joe Perches36cbac52008-12-03 22:27:25 -0800736 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900737 if (c == NULL)
738 return NULL;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900739 skb_queue_head_init(&c->mfc_un.unres.unresolved);
740 c->mfc_un.unres.expires = jiffies + 10 * HZ;
Benjamin Thery58701ad2008-12-10 16:22:34 -0800741 mfc6_net_set(c, net);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900742 return c;
743}
744
745/*
746 * A cache entry has gone into a resolved state from queued
747 */
748
749static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c)
750{
751 struct sk_buff *skb;
752
753 /*
754 * Play the pending entries through our router
755 */
756
757 while((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
758 if (ipv6_hdr(skb)->version == 0) {
759 int err;
760 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
761
762 if (ip6mr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) {
YOSHIFUJI Hideaki549e0282008-04-05 22:17:39 +0900763 nlh->nlmsg_len = skb_tail_pointer(skb) - (u8 *)nlh;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900764 } else {
765 nlh->nlmsg_type = NLMSG_ERROR;
766 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
767 skb_trim(skb, nlh->nlmsg_len);
768 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE;
769 }
Benjamin Thery8229efd2008-12-10 16:30:15 -0800770 err = rtnl_unicast(skb, mfc6_net(uc), NETLINK_CB(skb).pid);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900771 } else
772 ip6_mr_forward(skb, c);
773 }
774}
775
776/*
777 * Bounce a cache query up to pim6sd. We could use netlink for this but pim6sd
778 * expects the following bizarre scheme.
779 *
780 * Called under mrt_lock.
781 */
782
Benjamin Thery8229efd2008-12-10 16:30:15 -0800783static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi,
784 int assert)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900785{
786 struct sk_buff *skb;
787 struct mrt6msg *msg;
788 int ret;
789
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900790#ifdef CONFIG_IPV6_PIMSM_V2
791 if (assert == MRT6MSG_WHOLEPKT)
792 skb = skb_realloc_headroom(pkt, -skb_network_offset(pkt)
793 +sizeof(*msg));
794 else
795#endif
796 skb = alloc_skb(sizeof(struct ipv6hdr) + sizeof(*msg), GFP_ATOMIC);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900797
798 if (!skb)
799 return -ENOBUFS;
800
801 /* I suppose that internal messages
802 * do not require checksums */
803
804 skb->ip_summed = CHECKSUM_UNNECESSARY;
805
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900806#ifdef CONFIG_IPV6_PIMSM_V2
807 if (assert == MRT6MSG_WHOLEPKT) {
808 /* Ugly, but we have no choice with this interface.
809 Duplicate old header, fix length etc.
810 And all this only to mangle msg->im6_msgtype and
811 to set msg->im6_mbz to "mbz" :-)
812 */
813 skb_push(skb, -skb_network_offset(pkt));
814
815 skb_push(skb, sizeof(*msg));
816 skb_reset_transport_header(skb);
817 msg = (struct mrt6msg *)skb_transport_header(skb);
818 msg->im6_mbz = 0;
819 msg->im6_msgtype = MRT6MSG_WHOLEPKT;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800820 msg->im6_mif = net->ipv6.mroute_reg_vif_num;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900821 msg->im6_pad = 0;
822 ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr);
823 ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr);
824
825 skb->ip_summed = CHECKSUM_UNNECESSARY;
826 } else
827#endif
828 {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900829 /*
830 * Copy the IP header
831 */
832
833 skb_put(skb, sizeof(struct ipv6hdr));
834 skb_reset_network_header(skb);
835 skb_copy_to_linear_data(skb, ipv6_hdr(pkt), sizeof(struct ipv6hdr));
836
837 /*
838 * Add our header
839 */
840 skb_put(skb, sizeof(*msg));
841 skb_reset_transport_header(skb);
842 msg = (struct mrt6msg *)skb_transport_header(skb);
843
844 msg->im6_mbz = 0;
845 msg->im6_msgtype = assert;
Rami Rosen6ac7eb02008-04-10 12:40:10 +0300846 msg->im6_mif = mifi;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900847 msg->im6_pad = 0;
848 ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr);
849 ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr);
850
851 skb->dst = dst_clone(pkt->dst);
852 skb->ip_summed = CHECKSUM_UNNECESSARY;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +0900853 }
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900854
Benjamin Thery8229efd2008-12-10 16:30:15 -0800855 if (net->ipv6.mroute6_sk == NULL) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900856 kfree_skb(skb);
857 return -EINVAL;
858 }
859
860 /*
861 * Deliver to user space multicast routing algorithms
862 */
Benjamin Thery8229efd2008-12-10 16:30:15 -0800863 ret = sock_queue_rcv_skb(net->ipv6.mroute6_sk, skb);
Benjamin Therybd91b8b2008-12-10 16:07:08 -0800864 if (ret < 0) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900865 if (net_ratelimit())
866 printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n");
867 kfree_skb(skb);
868 }
869
870 return ret;
871}
872
873/*
874 * Queue a packet for resolution. It gets locked cache entry!
875 */
876
877static int
Benjamin Thery8229efd2008-12-10 16:30:15 -0800878ip6mr_cache_unresolved(struct net *net, mifi_t mifi, struct sk_buff *skb)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900879{
880 int err;
881 struct mfc6_cache *c;
882
883 spin_lock_bh(&mfc_unres_lock);
884 for (c = mfc_unres_queue; c; c = c->next) {
Benjamin Thery8229efd2008-12-10 16:30:15 -0800885 if (net_eq(mfc6_net(c), net) &&
Benjamin Thery4045e572008-12-10 16:27:21 -0800886 ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900887 ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr))
888 break;
889 }
890
891 if (c == NULL) {
892 /*
893 * Create a new entry if allowable
894 */
895
Benjamin Thery8229efd2008-12-10 16:30:15 -0800896 if (atomic_read(&net->ipv6.cache_resolve_queue_len) >= 10 ||
897 (c = ip6mr_cache_alloc_unres(net)) == NULL) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900898 spin_unlock_bh(&mfc_unres_lock);
899
900 kfree_skb(skb);
901 return -ENOBUFS;
902 }
903
904 /*
905 * Fill in the new cache entry
906 */
907 c->mf6c_parent = -1;
908 c->mf6c_origin = ipv6_hdr(skb)->saddr;
909 c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr;
910
911 /*
912 * Reflect first query at pim6sd
913 */
Benjamin Thery8229efd2008-12-10 16:30:15 -0800914 err = ip6mr_cache_report(net, skb, mifi, MRT6MSG_NOCACHE);
915 if (err < 0) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900916 /* If the report failed throw the cache entry
917 out - Brad Parker
918 */
919 spin_unlock_bh(&mfc_unres_lock);
920
Benjamin Thery58701ad2008-12-10 16:22:34 -0800921 ip6mr_cache_free(c);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900922 kfree_skb(skb);
923 return err;
924 }
925
Benjamin Thery8229efd2008-12-10 16:30:15 -0800926 atomic_inc(&net->ipv6.cache_resolve_queue_len);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900927 c->next = mfc_unres_queue;
928 mfc_unres_queue = c;
929
930 ipmr_do_expire_process(1);
931 }
932
933 /*
934 * See if we can append the packet
935 */
936 if (c->mfc_un.unres.unresolved.qlen > 3) {
937 kfree_skb(skb);
938 err = -ENOBUFS;
939 } else {
940 skb_queue_tail(&c->mfc_un.unres.unresolved, skb);
941 err = 0;
942 }
943
944 spin_unlock_bh(&mfc_unres_lock);
945 return err;
946}
947
948/*
949 * MFC6 cache manipulation by user space
950 */
951
Benjamin Thery8229efd2008-12-10 16:30:15 -0800952static int ip6mr_mfc_delete(struct net *net, struct mf6cctl *mfc)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900953{
954 int line;
955 struct mfc6_cache *c, **cp;
956
957 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
958
Benjamin Thery8229efd2008-12-10 16:30:15 -0800959 for (cp = &net->ipv6.mfc6_cache_array[line];
Benjamin Thery4a6258a2008-12-10 16:24:07 -0800960 (c = *cp) != NULL; cp = &c->next) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900961 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
962 ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) {
963 write_lock_bh(&mrt_lock);
964 *cp = c->next;
965 write_unlock_bh(&mrt_lock);
966
Benjamin Thery58701ad2008-12-10 16:22:34 -0800967 ip6mr_cache_free(c);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900968 return 0;
969 }
970 }
971 return -ENOENT;
972}
973
974static int ip6mr_device_event(struct notifier_block *this,
975 unsigned long event, void *ptr)
976{
977 struct net_device *dev = ptr;
Benjamin Thery8229efd2008-12-10 16:30:15 -0800978 struct net *net = dev_net(dev);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900979 struct mif_device *v;
980 int ct;
981
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900982 if (event != NETDEV_UNREGISTER)
983 return NOTIFY_DONE;
984
Benjamin Thery8229efd2008-12-10 16:30:15 -0800985 v = &net->ipv6.vif6_table[0];
986 for (ct = 0; ct < net->ipv6.maxvif; ct++, v++) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900987 if (v->dev == dev)
Benjamin Thery8229efd2008-12-10 16:30:15 -0800988 mif6_delete(net, ct);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +0900989 }
990 return NOTIFY_DONE;
991}
992
993static struct notifier_block ip6_mr_notifier = {
994 .notifier_call = ip6mr_device_event
995};
996
997/*
998 * Setup for IP multicast routing
999 */
1000
Benjamin Thery4e168802008-12-10 16:15:08 -08001001static int __net_init ip6mr_net_init(struct net *net)
1002{
1003 int err = 0;
Benjamin Thery4e168802008-12-10 16:15:08 -08001004 net->ipv6.vif6_table = kcalloc(MAXMIFS, sizeof(struct mif_device),
1005 GFP_KERNEL);
1006 if (!net->ipv6.vif6_table) {
1007 err = -ENOMEM;
1008 goto fail;
1009 }
Benjamin Thery4a6258a2008-12-10 16:24:07 -08001010
1011 /* Forwarding cache */
1012 net->ipv6.mfc6_cache_array = kcalloc(MFC6_LINES,
1013 sizeof(struct mfc6_cache *),
1014 GFP_KERNEL);
1015 if (!net->ipv6.mfc6_cache_array) {
1016 err = -ENOMEM;
1017 goto fail_mfc6_cache;
1018 }
Benjamin Thery950d5702008-12-10 16:29:24 -08001019
1020#ifdef CONFIG_IPV6_PIMSM_V2
1021 net->ipv6.mroute_reg_vif_num = -1;
1022#endif
Benjamin Thery8b90fc72008-12-10 16:29:48 -08001023
1024#ifdef CONFIG_PROC_FS
1025 err = -ENOMEM;
1026 if (!proc_net_fops_create(net, "ip6_mr_vif", 0, &ip6mr_vif_fops))
1027 goto proc_vif_fail;
1028 if (!proc_net_fops_create(net, "ip6_mr_cache", 0, &ip6mr_mfc_fops))
1029 goto proc_cache_fail;
1030#endif
Benjamin Thery4a6258a2008-12-10 16:24:07 -08001031 return 0;
1032
Benjamin Thery8b90fc72008-12-10 16:29:48 -08001033#ifdef CONFIG_PROC_FS
1034proc_cache_fail:
1035 proc_net_remove(net, "ip6_mr_vif");
1036proc_vif_fail:
1037 kfree(net->ipv6.mfc6_cache_array);
1038#endif
Benjamin Thery4a6258a2008-12-10 16:24:07 -08001039fail_mfc6_cache:
1040 kfree(net->ipv6.vif6_table);
Benjamin Thery4e168802008-12-10 16:15:08 -08001041fail:
1042 return err;
1043}
1044
1045static void __net_exit ip6mr_net_exit(struct net *net)
1046{
Benjamin Thery8b90fc72008-12-10 16:29:48 -08001047#ifdef CONFIG_PROC_FS
1048 proc_net_remove(net, "ip6_mr_cache");
1049 proc_net_remove(net, "ip6_mr_vif");
1050#endif
Benjamin Thery8229efd2008-12-10 16:30:15 -08001051 mroute_clean_tables(net);
Benjamin Thery4a6258a2008-12-10 16:24:07 -08001052 kfree(net->ipv6.mfc6_cache_array);
Benjamin Thery4e168802008-12-10 16:15:08 -08001053 kfree(net->ipv6.vif6_table);
1054}
1055
1056static struct pernet_operations ip6mr_net_ops = {
1057 .init = ip6mr_net_init,
1058 .exit = ip6mr_net_exit,
1059};
1060
Wang Chen623d1a12008-07-03 12:13:30 +08001061int __init ip6_mr_init(void)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001062{
Wang Chen623d1a12008-07-03 12:13:30 +08001063 int err;
1064
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001065 mrt_cachep = kmem_cache_create("ip6_mrt_cache",
1066 sizeof(struct mfc6_cache),
1067 0, SLAB_HWCACHE_ALIGN,
1068 NULL);
1069 if (!mrt_cachep)
Wang Chen623d1a12008-07-03 12:13:30 +08001070 return -ENOMEM;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001071
Benjamin Thery4e168802008-12-10 16:15:08 -08001072 err = register_pernet_subsys(&ip6mr_net_ops);
1073 if (err)
1074 goto reg_pernet_fail;
1075
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001076 setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
Wang Chen623d1a12008-07-03 12:13:30 +08001077 err = register_netdevice_notifier(&ip6_mr_notifier);
1078 if (err)
1079 goto reg_notif_fail;
Wang Chen623d1a12008-07-03 12:13:30 +08001080 return 0;
Benjamin Thery87b30a62008-11-10 16:34:11 -08001081reg_notif_fail:
1082 del_timer(&ipmr_expire_timer);
Benjamin Thery4e168802008-12-10 16:15:08 -08001083 unregister_pernet_subsys(&ip6mr_net_ops);
1084reg_pernet_fail:
Benjamin Thery87b30a62008-11-10 16:34:11 -08001085 kmem_cache_destroy(mrt_cachep);
Wang Chen623d1a12008-07-03 12:13:30 +08001086 return err;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001087}
1088
Wang Chen623d1a12008-07-03 12:13:30 +08001089void ip6_mr_cleanup(void)
1090{
Wang Chen623d1a12008-07-03 12:13:30 +08001091 unregister_netdevice_notifier(&ip6_mr_notifier);
1092 del_timer(&ipmr_expire_timer);
Benjamin Thery4e168802008-12-10 16:15:08 -08001093 unregister_pernet_subsys(&ip6mr_net_ops);
Wang Chen623d1a12008-07-03 12:13:30 +08001094 kmem_cache_destroy(mrt_cachep);
1095}
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001096
Benjamin Thery8229efd2008-12-10 16:30:15 -08001097static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001098{
1099 int line;
1100 struct mfc6_cache *uc, *c, **cp;
Rami Rosen6ac7eb02008-04-10 12:40:10 +03001101 unsigned char ttls[MAXMIFS];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001102 int i;
1103
Rami Rosen6ac7eb02008-04-10 12:40:10 +03001104 memset(ttls, 255, MAXMIFS);
1105 for (i = 0; i < MAXMIFS; i++) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001106 if (IF_ISSET(i, &mfc->mf6cc_ifset))
1107 ttls[i] = 1;
1108
1109 }
1110
1111 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
1112
Benjamin Thery8229efd2008-12-10 16:30:15 -08001113 for (cp = &net->ipv6.mfc6_cache_array[line];
Benjamin Thery4a6258a2008-12-10 16:24:07 -08001114 (c = *cp) != NULL; cp = &c->next) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001115 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
1116 ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr))
1117 break;
1118 }
1119
1120 if (c != NULL) {
1121 write_lock_bh(&mrt_lock);
1122 c->mf6c_parent = mfc->mf6cc_parent;
1123 ip6mr_update_thresholds(c, ttls);
1124 if (!mrtsock)
1125 c->mfc_flags |= MFC_STATIC;
1126 write_unlock_bh(&mrt_lock);
1127 return 0;
1128 }
1129
1130 if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
1131 return -EINVAL;
1132
Benjamin Thery8229efd2008-12-10 16:30:15 -08001133 c = ip6mr_cache_alloc(net);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001134 if (c == NULL)
1135 return -ENOMEM;
1136
1137 c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
1138 c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr;
1139 c->mf6c_parent = mfc->mf6cc_parent;
1140 ip6mr_update_thresholds(c, ttls);
1141 if (!mrtsock)
1142 c->mfc_flags |= MFC_STATIC;
1143
1144 write_lock_bh(&mrt_lock);
Benjamin Thery8229efd2008-12-10 16:30:15 -08001145 c->next = net->ipv6.mfc6_cache_array[line];
1146 net->ipv6.mfc6_cache_array[line] = c;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001147 write_unlock_bh(&mrt_lock);
1148
1149 /*
1150 * Check to see if we resolved a queued list. If so we
1151 * need to send on the frames and tidy up.
1152 */
1153 spin_lock_bh(&mfc_unres_lock);
1154 for (cp = &mfc_unres_queue; (uc = *cp) != NULL;
1155 cp = &uc->next) {
Benjamin Thery8229efd2008-12-10 16:30:15 -08001156 if (net_eq(mfc6_net(uc), net) &&
Benjamin Thery4045e572008-12-10 16:27:21 -08001157 ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001158 ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) {
1159 *cp = uc->next;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001160 atomic_dec(&net->ipv6.cache_resolve_queue_len);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001161 break;
1162 }
1163 }
Benjamin Thery4045e572008-12-10 16:27:21 -08001164 if (mfc_unres_queue == NULL)
1165 del_timer(&ipmr_expire_timer);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001166 spin_unlock_bh(&mfc_unres_lock);
1167
1168 if (uc) {
1169 ip6mr_cache_resolve(uc, c);
Benjamin Thery58701ad2008-12-10 16:22:34 -08001170 ip6mr_cache_free(uc);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001171 }
1172 return 0;
1173}
1174
1175/*
1176 * Close the multicast socket, and clear the vif tables etc
1177 */
1178
Benjamin Thery8229efd2008-12-10 16:30:15 -08001179static void mroute_clean_tables(struct net *net)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001180{
1181 int i;
1182
1183 /*
1184 * Shut down all active vif entries
1185 */
Benjamin Thery8229efd2008-12-10 16:30:15 -08001186 for (i = 0; i < net->ipv6.maxvif; i++) {
1187 if (!(net->ipv6.vif6_table[i].flags & VIFF_STATIC))
1188 mif6_delete(net, i);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001189 }
1190
1191 /*
1192 * Wipe the cache
1193 */
Benjamin Thery4a6258a2008-12-10 16:24:07 -08001194 for (i = 0; i < MFC6_LINES; i++) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001195 struct mfc6_cache *c, **cp;
1196
Benjamin Thery8229efd2008-12-10 16:30:15 -08001197 cp = &net->ipv6.mfc6_cache_array[i];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001198 while ((c = *cp) != NULL) {
1199 if (c->mfc_flags & MFC_STATIC) {
1200 cp = &c->next;
1201 continue;
1202 }
1203 write_lock_bh(&mrt_lock);
1204 *cp = c->next;
1205 write_unlock_bh(&mrt_lock);
1206
Benjamin Thery58701ad2008-12-10 16:22:34 -08001207 ip6mr_cache_free(c);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001208 }
1209 }
1210
Benjamin Thery8229efd2008-12-10 16:30:15 -08001211 if (atomic_read(&net->ipv6.cache_resolve_queue_len) != 0) {
Benjamin Thery4045e572008-12-10 16:27:21 -08001212 struct mfc6_cache *c, **cp;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001213
1214 spin_lock_bh(&mfc_unres_lock);
Benjamin Thery4045e572008-12-10 16:27:21 -08001215 cp = &mfc_unres_queue;
1216 while ((c = *cp) != NULL) {
Benjamin Thery8229efd2008-12-10 16:30:15 -08001217 if (!net_eq(mfc6_net(c), net)) {
Benjamin Thery4045e572008-12-10 16:27:21 -08001218 cp = &c->next;
1219 continue;
1220 }
1221 *cp = c->next;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001222 ip6mr_destroy_unres(c);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001223 }
1224 spin_unlock_bh(&mfc_unres_lock);
1225 }
1226}
1227
1228static int ip6mr_sk_init(struct sock *sk)
1229{
1230 int err = 0;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001231 struct net *net = sock_net(sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001232
1233 rtnl_lock();
1234 write_lock_bh(&mrt_lock);
Thomas Goff1d6e55f2009-01-27 22:39:59 -08001235 if (likely(net->ipv6.mroute6_sk == NULL)) {
Benjamin Thery8229efd2008-12-10 16:30:15 -08001236 net->ipv6.mroute6_sk = sk;
Thomas Goff1d6e55f2009-01-27 22:39:59 -08001237 net->ipv6.devconf_all->mc_forwarding++;
1238 }
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001239 else
1240 err = -EADDRINUSE;
1241 write_unlock_bh(&mrt_lock);
1242
1243 rtnl_unlock();
1244
1245 return err;
1246}
1247
1248int ip6mr_sk_done(struct sock *sk)
1249{
1250 int err = 0;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001251 struct net *net = sock_net(sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001252
1253 rtnl_lock();
Benjamin Thery8229efd2008-12-10 16:30:15 -08001254 if (sk == net->ipv6.mroute6_sk) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001255 write_lock_bh(&mrt_lock);
Benjamin Thery8229efd2008-12-10 16:30:15 -08001256 net->ipv6.mroute6_sk = NULL;
Thomas Goff1d6e55f2009-01-27 22:39:59 -08001257 net->ipv6.devconf_all->mc_forwarding--;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001258 write_unlock_bh(&mrt_lock);
1259
Benjamin Thery8229efd2008-12-10 16:30:15 -08001260 mroute_clean_tables(net);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001261 } else
1262 err = -EACCES;
1263 rtnl_unlock();
1264
1265 return err;
1266}
1267
1268/*
1269 * Socket options and virtual interface manipulation. The whole
1270 * virtual interface system is a complete heap, but unfortunately
1271 * that's how BSD mrouted happens to think. Maybe one day with a proper
1272 * MOSPF/PIM router set up we can clean this up.
1273 */
1274
1275int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
1276{
1277 int ret;
1278 struct mif6ctl vif;
1279 struct mf6cctl mfc;
1280 mifi_t mifi;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001281 struct net *net = sock_net(sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001282
1283 if (optname != MRT6_INIT) {
Benjamin Thery8229efd2008-12-10 16:30:15 -08001284 if (sk != net->ipv6.mroute6_sk && !capable(CAP_NET_ADMIN))
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001285 return -EACCES;
1286 }
1287
1288 switch (optname) {
1289 case MRT6_INIT:
1290 if (sk->sk_type != SOCK_RAW ||
1291 inet_sk(sk)->num != IPPROTO_ICMPV6)
1292 return -EOPNOTSUPP;
1293 if (optlen < sizeof(int))
1294 return -EINVAL;
1295
1296 return ip6mr_sk_init(sk);
1297
1298 case MRT6_DONE:
1299 return ip6mr_sk_done(sk);
1300
1301 case MRT6_ADD_MIF:
1302 if (optlen < sizeof(vif))
1303 return -EINVAL;
1304 if (copy_from_user(&vif, optval, sizeof(vif)))
1305 return -EFAULT;
Rami Rosen6ac7eb02008-04-10 12:40:10 +03001306 if (vif.mif6c_mifi >= MAXMIFS)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001307 return -ENFILE;
1308 rtnl_lock();
Benjamin Thery8229efd2008-12-10 16:30:15 -08001309 ret = mif6_add(net, &vif, sk == net->ipv6.mroute6_sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001310 rtnl_unlock();
1311 return ret;
1312
1313 case MRT6_DEL_MIF:
1314 if (optlen < sizeof(mifi_t))
1315 return -EINVAL;
1316 if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
1317 return -EFAULT;
1318 rtnl_lock();
Benjamin Thery8229efd2008-12-10 16:30:15 -08001319 ret = mif6_delete(net, mifi);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001320 rtnl_unlock();
1321 return ret;
1322
1323 /*
1324 * Manipulate the forwarding caches. These live
1325 * in a sort of kernel/user symbiosis.
1326 */
1327 case MRT6_ADD_MFC:
1328 case MRT6_DEL_MFC:
1329 if (optlen < sizeof(mfc))
1330 return -EINVAL;
1331 if (copy_from_user(&mfc, optval, sizeof(mfc)))
1332 return -EFAULT;
1333 rtnl_lock();
1334 if (optname == MRT6_DEL_MFC)
Benjamin Thery8229efd2008-12-10 16:30:15 -08001335 ret = ip6mr_mfc_delete(net, &mfc);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001336 else
Benjamin Thery8229efd2008-12-10 16:30:15 -08001337 ret = ip6mr_mfc_add(net, &mfc,
1338 sk == net->ipv6.mroute6_sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001339 rtnl_unlock();
1340 return ret;
1341
1342 /*
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001343 * Control PIM assert (to activate pim will activate assert)
1344 */
1345 case MRT6_ASSERT:
1346 {
1347 int v;
1348 if (get_user(v, (int __user *)optval))
1349 return -EFAULT;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001350 net->ipv6.mroute_do_assert = !!v;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001351 return 0;
1352 }
1353
1354#ifdef CONFIG_IPV6_PIMSM_V2
1355 case MRT6_PIM:
1356 {
YOSHIFUJI Hideakia9f83bf2008-04-10 15:41:28 +09001357 int v;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001358 if (get_user(v, (int __user *)optval))
1359 return -EFAULT;
1360 v = !!v;
1361 rtnl_lock();
1362 ret = 0;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001363 if (v != net->ipv6.mroute_do_pim) {
1364 net->ipv6.mroute_do_pim = v;
1365 net->ipv6.mroute_do_assert = v;
1366 if (net->ipv6.mroute_do_pim)
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001367 ret = inet6_add_protocol(&pim6_protocol,
1368 IPPROTO_PIM);
1369 else
1370 ret = inet6_del_protocol(&pim6_protocol,
1371 IPPROTO_PIM);
1372 if (ret < 0)
1373 ret = -EAGAIN;
1374 }
1375 rtnl_unlock();
1376 return ret;
1377 }
1378
1379#endif
1380 /*
Rami Rosen7d120c52008-04-23 14:35:13 +03001381 * Spurious command, or MRT6_VERSION which you cannot
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001382 * set.
1383 */
1384 default:
1385 return -ENOPROTOOPT;
1386 }
1387}
1388
1389/*
1390 * Getsock opt support for the multicast routing system.
1391 */
1392
1393int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval,
1394 int __user *optlen)
1395{
1396 int olr;
1397 int val;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001398 struct net *net = sock_net(sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001399
1400 switch (optname) {
1401 case MRT6_VERSION:
1402 val = 0x0305;
1403 break;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001404#ifdef CONFIG_IPV6_PIMSM_V2
1405 case MRT6_PIM:
Benjamin Thery8229efd2008-12-10 16:30:15 -08001406 val = net->ipv6.mroute_do_pim;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001407 break;
1408#endif
1409 case MRT6_ASSERT:
Benjamin Thery8229efd2008-12-10 16:30:15 -08001410 val = net->ipv6.mroute_do_assert;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001411 break;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001412 default:
1413 return -ENOPROTOOPT;
1414 }
1415
1416 if (get_user(olr, optlen))
1417 return -EFAULT;
1418
1419 olr = min_t(int, olr, sizeof(int));
1420 if (olr < 0)
1421 return -EINVAL;
1422
1423 if (put_user(olr, optlen))
1424 return -EFAULT;
1425 if (copy_to_user(optval, &val, olr))
1426 return -EFAULT;
1427 return 0;
1428}
1429
1430/*
1431 * The IP multicast ioctl support routines.
1432 */
1433
1434int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1435{
1436 struct sioc_sg_req6 sr;
1437 struct sioc_mif_req6 vr;
1438 struct mif_device *vif;
1439 struct mfc6_cache *c;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001440 struct net *net = sock_net(sk);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001441
1442 switch (cmd) {
1443 case SIOCGETMIFCNT_IN6:
1444 if (copy_from_user(&vr, arg, sizeof(vr)))
1445 return -EFAULT;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001446 if (vr.mifi >= net->ipv6.maxvif)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001447 return -EINVAL;
1448 read_lock(&mrt_lock);
Benjamin Thery8229efd2008-12-10 16:30:15 -08001449 vif = &net->ipv6.vif6_table[vr.mifi];
1450 if (MIF_EXISTS(net, vr.mifi)) {
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001451 vr.icount = vif->pkt_in;
1452 vr.ocount = vif->pkt_out;
1453 vr.ibytes = vif->bytes_in;
1454 vr.obytes = vif->bytes_out;
1455 read_unlock(&mrt_lock);
1456
1457 if (copy_to_user(arg, &vr, sizeof(vr)))
1458 return -EFAULT;
1459 return 0;
1460 }
1461 read_unlock(&mrt_lock);
1462 return -EADDRNOTAVAIL;
1463 case SIOCGETSGCNT_IN6:
1464 if (copy_from_user(&sr, arg, sizeof(sr)))
1465 return -EFAULT;
1466
1467 read_lock(&mrt_lock);
Benjamin Thery8229efd2008-12-10 16:30:15 -08001468 c = ip6mr_cache_find(net, &sr.src.sin6_addr, &sr.grp.sin6_addr);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001469 if (c) {
1470 sr.pktcnt = c->mfc_un.res.pkt;
1471 sr.bytecnt = c->mfc_un.res.bytes;
1472 sr.wrong_if = c->mfc_un.res.wrong_if;
1473 read_unlock(&mrt_lock);
1474
1475 if (copy_to_user(arg, &sr, sizeof(sr)))
1476 return -EFAULT;
1477 return 0;
1478 }
1479 read_unlock(&mrt_lock);
1480 return -EADDRNOTAVAIL;
1481 default:
1482 return -ENOIOCTLCMD;
1483 }
1484}
1485
1486
1487static inline int ip6mr_forward2_finish(struct sk_buff *skb)
1488{
Denis V. Lunev483a47d2008-10-08 11:09:27 -07001489 IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst),
1490 IPSTATS_MIB_OUTFORWDATAGRAMS);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001491 return dst_output(skb);
1492}
1493
1494/*
1495 * Processing handlers for ip6mr_forward
1496 */
1497
1498static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
1499{
1500 struct ipv6hdr *ipv6h;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001501 struct net *net = mfc6_net(c);
1502 struct mif_device *vif = &net->ipv6.vif6_table[vifi];
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001503 struct net_device *dev;
1504 struct dst_entry *dst;
1505 struct flowi fl;
1506
1507 if (vif->dev == NULL)
1508 goto out_free;
1509
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001510#ifdef CONFIG_IPV6_PIMSM_V2
1511 if (vif->flags & MIFF_REGISTER) {
1512 vif->pkt_out++;
1513 vif->bytes_out += skb->len;
Pavel Emelyanovdc58c782008-05-21 14:17:54 -07001514 vif->dev->stats.tx_bytes += skb->len;
1515 vif->dev->stats.tx_packets++;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001516 ip6mr_cache_report(net, skb, vifi, MRT6MSG_WHOLEPKT);
Ilpo Järvinen8da73b72008-12-14 23:15:49 -08001517 goto out_free;
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001518 }
1519#endif
1520
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001521 ipv6h = ipv6_hdr(skb);
1522
1523 fl = (struct flowi) {
1524 .oif = vif->link,
1525 .nl_u = { .ip6_u =
1526 { .daddr = ipv6h->daddr, }
1527 }
1528 };
1529
Benjamin Thery8229efd2008-12-10 16:30:15 -08001530 dst = ip6_route_output(net, NULL, &fl);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001531 if (!dst)
1532 goto out_free;
1533
1534 dst_release(skb->dst);
1535 skb->dst = dst;
1536
1537 /*
1538 * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
1539 * not only before forwarding, but after forwarding on all output
1540 * interfaces. It is clear, if mrouter runs a multicasting
1541 * program, it should receive packets not depending to what interface
1542 * program is joined.
1543 * If we will not make it, the program will have to join on all
1544 * interfaces. On the other hand, multihoming host (or router, but
1545 * not mrouter) cannot join to more than one interface - it will
1546 * result in receiving multiple packets.
1547 */
1548 dev = vif->dev;
1549 skb->dev = dev;
1550 vif->pkt_out++;
1551 vif->bytes_out += skb->len;
1552
1553 /* We are about to write */
1554 /* XXX: extension headers? */
1555 if (skb_cow(skb, sizeof(*ipv6h) + LL_RESERVED_SPACE(dev)))
1556 goto out_free;
1557
1558 ipv6h = ipv6_hdr(skb);
1559 ipv6h->hop_limit--;
1560
1561 IP6CB(skb)->flags |= IP6SKB_FORWARDED;
1562
1563 return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dev,
1564 ip6mr_forward2_finish);
1565
1566out_free:
1567 kfree_skb(skb);
1568 return 0;
1569}
1570
1571static int ip6mr_find_vif(struct net_device *dev)
1572{
Benjamin Thery8229efd2008-12-10 16:30:15 -08001573 struct net *net = dev_net(dev);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001574 int ct;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001575 for (ct = net->ipv6.maxvif - 1; ct >= 0; ct--) {
1576 if (net->ipv6.vif6_table[ct].dev == dev)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001577 break;
1578 }
1579 return ct;
1580}
1581
1582static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache)
1583{
1584 int psend = -1;
1585 int vif, ct;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001586 struct net *net = mfc6_net(cache);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001587
1588 vif = cache->mf6c_parent;
1589 cache->mfc_un.res.pkt++;
1590 cache->mfc_un.res.bytes += skb->len;
1591
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001592 /*
1593 * Wrong interface: drop packet and (maybe) send PIM assert.
1594 */
Benjamin Thery8229efd2008-12-10 16:30:15 -08001595 if (net->ipv6.vif6_table[vif].dev != skb->dev) {
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001596 int true_vifi;
1597
1598 cache->mfc_un.res.wrong_if++;
1599 true_vifi = ip6mr_find_vif(skb->dev);
1600
Benjamin Thery8229efd2008-12-10 16:30:15 -08001601 if (true_vifi >= 0 && net->ipv6.mroute_do_assert &&
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001602 /* pimsm uses asserts, when switching from RPT to SPT,
1603 so that we cannot check that packet arrived on an oif.
1604 It is bad, but otherwise we would need to move pretty
1605 large chunk of pimd to kernel. Ough... --ANK
1606 */
Benjamin Thery8229efd2008-12-10 16:30:15 -08001607 (net->ipv6.mroute_do_pim ||
Benjamin Therya21f3f92008-12-10 16:28:44 -08001608 cache->mfc_un.res.ttls[true_vifi] < 255) &&
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001609 time_after(jiffies,
1610 cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) {
1611 cache->mfc_un.res.last_assert = jiffies;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001612 ip6mr_cache_report(net, skb, true_vifi, MRT6MSG_WRONGMIF);
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001613 }
1614 goto dont_forward;
1615 }
1616
Benjamin Thery8229efd2008-12-10 16:30:15 -08001617 net->ipv6.vif6_table[vif].pkt_in++;
1618 net->ipv6.vif6_table[vif].bytes_in += skb->len;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001619
1620 /*
1621 * Forward the frame
1622 */
1623 for (ct = cache->mfc_un.res.maxvif - 1; ct >= cache->mfc_un.res.minvif; ct--) {
1624 if (ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) {
1625 if (psend != -1) {
1626 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
1627 if (skb2)
1628 ip6mr_forward2(skb2, cache, psend);
1629 }
1630 psend = ct;
1631 }
1632 }
1633 if (psend != -1) {
1634 ip6mr_forward2(skb, cache, psend);
1635 return 0;
1636 }
1637
YOSHIFUJI Hideaki14fb64e2008-04-03 09:22:54 +09001638dont_forward:
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001639 kfree_skb(skb);
1640 return 0;
1641}
1642
1643
1644/*
1645 * Multicast packets for forwarding arrive here
1646 */
1647
1648int ip6_mr_input(struct sk_buff *skb)
1649{
1650 struct mfc6_cache *cache;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001651 struct net *net = dev_net(skb->dev);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001652
1653 read_lock(&mrt_lock);
Benjamin Thery8229efd2008-12-10 16:30:15 -08001654 cache = ip6mr_cache_find(net,
1655 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001656
1657 /*
1658 * No usable cache entry
1659 */
1660 if (cache == NULL) {
1661 int vif;
1662
1663 vif = ip6mr_find_vif(skb->dev);
1664 if (vif >= 0) {
Benjamin Thery8229efd2008-12-10 16:30:15 -08001665 int err = ip6mr_cache_unresolved(net, vif, skb);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001666 read_unlock(&mrt_lock);
1667
1668 return err;
1669 }
1670 read_unlock(&mrt_lock);
1671 kfree_skb(skb);
1672 return -ENODEV;
1673 }
1674
1675 ip6_mr_forward(skb, cache);
1676
1677 read_unlock(&mrt_lock);
1678
1679 return 0;
1680}
1681
1682
1683static int
1684ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm)
1685{
1686 int ct;
1687 struct rtnexthop *nhp;
Benjamin Thery8229efd2008-12-10 16:30:15 -08001688 struct net *net = mfc6_net(c);
1689 struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev;
YOSHIFUJI Hideaki549e0282008-04-05 22:17:39 +09001690 u8 *b = skb_tail_pointer(skb);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001691 struct rtattr *mp_head;
1692
1693 if (dev)
1694 RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
1695
1696 mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
1697
1698 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
1699 if (c->mfc_un.res.ttls[ct] < 255) {
1700 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
1701 goto rtattr_failure;
1702 nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
1703 nhp->rtnh_flags = 0;
1704 nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
Benjamin Thery8229efd2008-12-10 16:30:15 -08001705 nhp->rtnh_ifindex = net->ipv6.vif6_table[ct].dev->ifindex;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001706 nhp->rtnh_len = sizeof(*nhp);
1707 }
1708 }
1709 mp_head->rta_type = RTA_MULTIPATH;
YOSHIFUJI Hideaki549e0282008-04-05 22:17:39 +09001710 mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head;
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001711 rtm->rtm_type = RTN_MULTICAST;
1712 return 1;
1713
1714rtattr_failure:
1715 nlmsg_trim(skb, b);
1716 return -EMSGSIZE;
1717}
1718
Benjamin Thery8229efd2008-12-10 16:30:15 -08001719int ip6mr_get_route(struct net *net,
1720 struct sk_buff *skb, struct rtmsg *rtm, int nowait)
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001721{
1722 int err;
1723 struct mfc6_cache *cache;
1724 struct rt6_info *rt = (struct rt6_info *)skb->dst;
1725
1726 read_lock(&mrt_lock);
Benjamin Thery8229efd2008-12-10 16:30:15 -08001727 cache = ip6mr_cache_find(net, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001728
1729 if (!cache) {
1730 struct sk_buff *skb2;
1731 struct ipv6hdr *iph;
1732 struct net_device *dev;
1733 int vif;
1734
1735 if (nowait) {
1736 read_unlock(&mrt_lock);
1737 return -EAGAIN;
1738 }
1739
1740 dev = skb->dev;
1741 if (dev == NULL || (vif = ip6mr_find_vif(dev)) < 0) {
1742 read_unlock(&mrt_lock);
1743 return -ENODEV;
1744 }
1745
1746 /* really correct? */
1747 skb2 = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
1748 if (!skb2) {
1749 read_unlock(&mrt_lock);
1750 return -ENOMEM;
1751 }
1752
1753 skb_reset_transport_header(skb2);
1754
1755 skb_put(skb2, sizeof(struct ipv6hdr));
1756 skb_reset_network_header(skb2);
1757
1758 iph = ipv6_hdr(skb2);
1759 iph->version = 0;
1760 iph->priority = 0;
1761 iph->flow_lbl[0] = 0;
1762 iph->flow_lbl[1] = 0;
1763 iph->flow_lbl[2] = 0;
1764 iph->payload_len = 0;
1765 iph->nexthdr = IPPROTO_NONE;
1766 iph->hop_limit = 0;
1767 ipv6_addr_copy(&iph->saddr, &rt->rt6i_src.addr);
1768 ipv6_addr_copy(&iph->daddr, &rt->rt6i_dst.addr);
1769
Benjamin Thery8229efd2008-12-10 16:30:15 -08001770 err = ip6mr_cache_unresolved(net, vif, skb2);
YOSHIFUJI Hideaki7bc570c2008-04-03 09:22:53 +09001771 read_unlock(&mrt_lock);
1772
1773 return err;
1774 }
1775
1776 if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY))
1777 cache->mfc_flags |= MFC_NOTIFY;
1778
1779 err = ip6mr_fill_mroute(skb, cache, rtm);
1780 read_unlock(&mrt_lock);
1781 return err;
1782}
1783