1/*
2 *	  Linux IPv6 multicast routing support for BSD pim6sd
3 *
4 *	(c) 2004 Mickael Hoerdt, <hoerdt@clarinet.u-strasbg.fr>
5 *		LSIIT Laboratory, Strasbourg, France
6 *	(c) 2004 Jean-Philippe Andriot, <jean-philippe.andriot@6WIND.com>
7 *		6WIND, Paris, France
8 *
9 *	This program is free software; you can redistribute it and/or
10 *	modify it under the terms of the GNU General Public License
11 *	as published by the Free Software Foundation; either version
12 *	2 of the License, or (at your option) any later version.
13 *
14 *	Version: $Id: ip6mr.c,v 1.9 2004/10/18 08:46:04 hoerdt Exp $
15 *
16 *	Fixes:
17 *	Michael Chastain	:	Incorrect size of copying.
18 *	Alan Cox		:	Added the cache manager code
19 *	Alan Cox		:	Fixed the clone/copy bug and device race.
20 *	Mike McLagan		:	Routing by source
21 *	Malcolm Beattie		:	Buffer handling fixes.
22 *	Alexey Kuznetsov	:	Double buffer free and other fixes.
23 *	SVR Anand		:	Fixed several multicast bugs and problems.
24 *	Alexey Kuznetsov	:	Status, optimisations and more.
25 *	Brad Parker		:	Better behaviour on mrouted upcall
26 *					overflow.
27 *      Carlos Picoto           :       PIMv1 Support
28 *	Pavlin Ivanov Radoslavov:	PIMv2 Registers must checksum only PIM header
29 *					Relax this requirement to work with older peers.
30 * 	Mickael Hoerdt and	: 	IPv6 support based on linux/net/ipv4/ipmr.c [Linux 2.x]
31 *	Jean-Philippe Andriot 		     		   on netinet/ip6_mroute.c [*BSD]
32 *
33 */
34
35#include <asm/system.h>
36#include <asm/uaccess.h>
37#include <linux/types.h>
38#include <linux/sched.h>
39#include <linux/errno.h>
40#include <linux/timer.h>
41#include <linux/mm.h>
42#include <linux/kernel.h>
43#include <linux/fcntl.h>
44#include <linux/stat.h>
45#include <linux/socket.h>
46#include <linux/in.h>
47#include <linux/inet.h>
48#include <linux/netdevice.h>
49#include <linux/inetdevice.h>
50#include <linux/igmp.h>
51#include <linux/proc_fs.h>
52#include <linux/seq_file.h>
53#include <linux/mroute.h>
54#include <linux/init.h>
55#include <net/ip.h>
56#include <net/protocol.h>
57#include <linux/skbuff.h>
58#include <net/route.h>
59#include <net/sock.h>
60#include <net/icmp.h>
61#include <net/udp.h>
62#include <net/raw.h>
63#include <linux/notifier.h>
64#include <linux/if_arp.h>
65#include <linux/netfilter_ipv4.h>
66#include <net/ipip.h>
67#include <net/checksum.h>
68
69
70#include <net/ipv6.h>
71#include <net/ip6_route.h>
72#include <linux/mroute6.h>
73#include <net/addrconf.h>
74#include <linux/netfilter_ipv6.h>
75
76
77struct sock *mroute6_socket;
78
79
80/* Big lock, protecting vif table, mrt cache and mroute socket state.
81   Note that the changes are semaphored via rtnl_lock.
82 */
83
84static rwlock_t mrt_lock = RW_LOCK_UNLOCKED;
85
86/*
87 *	Multicast router control variables
88 */
89
90static struct mif_device vif6_table[MAXMIFS];		/* Devices 		*/
91static int maxvif;
92
93#define MIF_EXISTS(idx) (vif6_table[idx].dev != NULL)
94
95static int mroute_do_assert;				/* Set in PIM assert	*/
96static int mroute_do_pim;
97
98static struct mfc6_cache *mfc6_cache_array[MFC_LINES];	/* Forwarding cache	*/
99
100static struct mfc6_cache *mfc_unres_queue;		/* Queue of unresolved entries */
101static atomic_t cache_resolve_queue_len;		/* Size of unresolved	*/
102
103/* Special spinlock for queue of unresolved entries */
104static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED;
105
106/* We return to original Alan's scheme. Hash table of resolved
107   entries is changed only in process context and protected
108   with weak lock mrt_lock. Queue of unresolved entries is protected
109   with strong spinlock mfc_unres_lock.
110
111   In this case data path is free of exclusive locks at all.
112 */
113
114static kmem_cache_t *mrt_cachep;
115
116static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache, int local);
117static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert);
118static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm);
119
120static struct inet6_protocol pim6_protocol;
121
122static struct timer_list ipmr_expire_timer;
123
124
125#ifdef CONFIG_PROC_FS
126
127struct ipmr_mfc_iter {
128	struct mfc6_cache **cache;
129	int ct;
130};
131
132
133static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
134{
135	struct mfc6_cache *mfc;
136
137	it->cache = mfc6_cache_array;
138	read_lock(&mrt_lock);
139	for (it->ct = 0; it->ct < MFC_LINES; it->ct++)  {
140		for(mfc = mfc6_cache_array[it->ct]; mfc; mfc = mfc->next) {
141			if (pos-- == 0) {
142				return mfc;
143                         }
144                }
145        }
146	read_unlock(&mrt_lock);
147
148	it->cache = &mfc_unres_queue;
149	spin_lock_bh(&mfc_unres_lock);
150	for(mfc = mfc_unres_queue; mfc; mfc = mfc->next) {
151		if (pos-- == 0) {
152			return mfc;
153                  }
154         }
155	spin_unlock_bh(&mfc_unres_lock);
156
157	it->cache = NULL;
158	return NULL;
159}
160
161
162
163
164/*
165 *	The /proc interfaces to multicast routing /proc/ip6_mr_cache /proc/ip6_mr_vif
166 */
167
168struct ipmr_vif_iter {
169	int ct;
170};
171
172static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter,
173					   loff_t pos)
174{
175	for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) {
176		if(!MIF_EXISTS(iter->ct)) {
177			continue;
178                }
179		if (pos-- == 0)  {
180			return &vif6_table[iter->ct];
181                }
182	}
183	return NULL;
184}
185
186static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
187{
188	read_lock(&mrt_lock);
189	return *pos ? ip6mr_vif_seq_idx(seq->private, *pos - 1)
190		: SEQ_START_TOKEN;
191}
192
193static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
194{
195	struct ipmr_vif_iter *iter = seq->private;
196
197	++*pos;
198	if (v == SEQ_START_TOKEN)
199		return ip6mr_vif_seq_idx(iter, 0);
200
201	while (++iter->ct < maxvif) {
202		if(!MIF_EXISTS(iter->ct))
203			continue;
204		return &vif6_table[iter->ct];
205	}
206	return NULL;
207}
208
209static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
210{
211	read_unlock(&mrt_lock);
212}
213
214static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
215{
216	if (v == SEQ_START_TOKEN) {
217		seq_puts(seq,
218			 "Interface      BytesIn  PktsIn  BytesOut PktsOut Flags\n");
219	} else {
220		const struct mif_device *vif = v;
221		const char *name =  vif->dev ? vif->dev->name : "none";
222
223		seq_printf(seq,
224			   "%2Zd %-10s %8ld %7ld  %8ld %7ld %05X\n",
225			   vif - vif6_table,
226			   name, vif->bytes_in, vif->pkt_in,
227			   vif->bytes_out, vif->pkt_out,
228			   vif->flags);
229	}
230	return 0;
231}
232
233static struct seq_operations ip6mr_vif_seq_ops = {
234	.start = ip6mr_vif_seq_start,
235	.next  = ip6mr_vif_seq_next,
236	.stop  = ip6mr_vif_seq_stop,
237	.show  = ip6mr_vif_seq_show,
238};
239
240static int ip6mr_vif_open(struct inode *inode, struct file *file)
241{
242	struct seq_file *seq;
243	int rc = -ENOMEM;
244	struct ipmr_vif_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
245
246	if (!s)
247		goto out;
248
249	rc = seq_open(file, &ip6mr_vif_seq_ops);
250	if (rc)
251		goto out_kfree;
252
253	s->ct = 0;
254	seq = file->private_data;
255	seq->private = s;
256out:
257	return rc;
258out_kfree:
259	kfree(s);
260	goto out;
261
262}
263
264static struct file_operations ip6mr_vif_fops = {
265	.owner	 = THIS_MODULE,
266	.open    = ip6mr_vif_open,
267	.read    = seq_read,
268	.llseek  = seq_lseek,
269	.release = seq_release,
270};
271
272static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
273{
274	return *pos ? ipmr_mfc_seq_idx(seq->private, *pos - 1)
275		: SEQ_START_TOKEN;
276}
277
278static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
279{
280	struct mfc6_cache *mfc = v;
281	struct ipmr_mfc_iter *it = seq->private;
282
283	++*pos;
284
285	if (v == SEQ_START_TOKEN) {
286		return ipmr_mfc_seq_idx(seq->private, 0);
287         }
288
289	if (mfc->next) {
290		return mfc->next;
291      }
292
293	if (it->cache == &mfc_unres_queue)  {
294		goto end_of_list;
295         }
296
297	BUG_ON(it->cache != mfc6_cache_array);
298
299	while (++it->ct < MFC_LINES) {
300		mfc = mfc6_cache_array[it->ct];
301		if (mfc)
302			return mfc;
303	}
304
305	/* exhausted cache_array, show unresolved */
306	read_unlock(&mrt_lock);
307	it->cache = &mfc_unres_queue;
308	it->ct = 0;
309
310	spin_lock_bh(&mfc_unres_lock);
311	mfc = mfc_unres_queue;
312	if (mfc)
313		return mfc;
314
315 end_of_list:
316	spin_unlock_bh(&mfc_unres_lock);
317	it->cache = NULL;
318
319	return NULL;
320}
321
322static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
323{
324	struct ipmr_mfc_iter *it = seq->private;
325
326	if (it->cache == &mfc_unres_queue)
327		spin_unlock_bh(&mfc_unres_lock);
328	else if (it->cache == mfc6_cache_array)
329		read_unlock(&mrt_lock);
330}
331
332static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
333{
334	int n;
335
336
337	if (v == SEQ_START_TOKEN) {
338		seq_puts(seq,
339		 "Group                            Origin                           Iif      Pkts  Bytes     Wrong  Oifs\n");
340	} else {
341		const struct mfc6_cache *mfc = v;
342		const struct ipmr_mfc_iter *it = seq->private;
343		int i;
344
345		for(i=0;i<16;i++) {
346			seq_printf(seq,"%02x",mfc->mf6c_mcastgrp.s6_addr[i]);
347		}
348		seq_printf(seq," ");
349		for(i=0;i<16;i++) {
350			seq_printf(seq,"%02x",mfc->mf6c_origin.s6_addr[i]);
351		}
352		seq_printf(seq," ");
353
354		seq_printf(seq, "%-3d %8ld %8ld %8ld",
355			   mfc->mf6c_parent,
356			   mfc->mfc_un.res.pkt,
357			   mfc->mfc_un.res.bytes,
358			   mfc->mfc_un.res.wrong_if);
359
360		if (it->cache != &mfc_unres_queue) {
361			for(n = mfc->mfc_un.res.minvif;
362			    n < mfc->mfc_un.res.maxvif; n++ ) {
363				if(MIF_EXISTS(n)
364				   && mfc->mfc_un.res.ttls[n] < 255)
365				seq_printf(seq,
366					   " %2d:%-3d",
367					   n, mfc->mfc_un.res.ttls[n]);
368			}
369		}
370		seq_putc(seq, '\n');
371	}
372	return 0;
373}
374
375static struct seq_operations ipmr_mfc_seq_ops = {
376	.start = ipmr_mfc_seq_start,
377	.next  = ipmr_mfc_seq_next,
378	.stop  = ipmr_mfc_seq_stop,
379	.show  = ipmr_mfc_seq_show,
380};
381
382static int ipmr_mfc_open(struct inode *inode, struct file *file)
383{
384	struct seq_file *seq;
385	int rc = -ENOMEM;
386	struct ipmr_mfc_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
387
388	if (!s)
389		goto out;
390
391	rc = seq_open(file, &ipmr_mfc_seq_ops);
392	if (rc)
393		goto out_kfree;
394
395	memset(s, 0, sizeof(*s));
396	seq = file->private_data;
397	seq->private = s;
398out:
399	return rc;
400out_kfree:
401	kfree(s);
402	goto out;
403
404}
405
406static struct file_operations ip6mr_mfc_fops = {
407	.owner	 = THIS_MODULE,
408	.open    = ipmr_mfc_open,
409	.read    = seq_read,
410	.llseek  = seq_lseek,
411	.release = seq_release,
412};
413#endif
414
415#ifdef CONFIG_IPV6_PIMSM_V2
416static int reg_vif_num = -1;
417
418static int pim6_rcv(struct sk_buff **pskb,unsigned int *nhoffp)
419{
420	struct pimreghdr *pim;
421	struct ipv6hdr   *encap;
422	struct sk_buff *skb = *pskb;
423	struct net_device  *reg_dev = NULL;
424
425	if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
426		goto drop;
427
428	//pim = (struct pimreghdr*)skb->h.raw;
429	pim = (struct pimreghdr *)skb_transport_header(skb);
430        if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
431	    (pim->flags&PIM_NULL_REGISTER) ||
432	    (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
433	     (u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))))
434		goto drop;
435
436	/* check if the inner packet is destined to mcast group */
437	//encap = (struct ipv6hdr*)(skb->h.raw + sizeof(struct pimreghdr));
438	encap = (struct ipv6hdr *)(skb_transport_header(skb) + sizeof(*pim));
439
440	if(!(ipv6_addr_type(&encap->daddr)&IPV6_ADDR_MULTICAST) ||
441	    encap->payload_len == 0 ||
442	    ntohs(encap->payload_len) + sizeof(*pim) > skb->len)
443		goto drop;
444
445	read_lock(&mrt_lock);
446	if (reg_vif_num >= 0)
447		reg_dev = vif6_table[reg_vif_num].dev;
448	if (reg_dev)
449		dev_hold(reg_dev);
450	read_unlock(&mrt_lock);
451
452	if (reg_dev == NULL)
453		goto drop;
454
455	//skb->mac.raw = skb->nh.raw;
456	skb->mac_header = skb->network_header;
457	skb_pull(skb, (u8*)encap - skb->data);
458	//skb->nh.ipv6h = (struct ipv6hdr *)skb->data;
459	skb_reset_network_header(skb);
460	skb->dev = reg_dev;
461	skb->protocol = htons(ETH_P_IP);
462	skb->ip_summed = 0;
463	skb->pkt_type = PACKET_HOST;
464	dst_release(skb->dst);
465	((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
466	((struct net_device_stats*)reg_dev->priv)->rx_packets++;
467	skb->dst = NULL;
468#ifdef CONFIG_NETFILTER
469	//nf_conntrack_put(skb->nfct);
470	//skb->nfct = NULL;
471	nf_reset(skb);
472#endif
473	netif_rx(skb);
474	dev_put(reg_dev);
475	return 0;
476 drop:
477	kfree_skb(skb);
478	return 0;
479}
480
481static struct inet6_protocol pim6_protocol = {
482	.handler	=	pim6_rcv,
483};
484#endif
485
486/* Service routines creating virtual interfaces: PIMREG */
487#ifdef CONFIG_IPV6_PIMSM_V2
488
489
490static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
491{
492	read_lock(&mrt_lock);
493	((struct net_device_stats*)dev->priv)->tx_bytes += skb->len;
494	((struct net_device_stats*)dev->priv)->tx_packets++;
495	ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT);
496	read_unlock(&mrt_lock);
497	kfree_skb(skb);
498	return 0;
499}
500
501static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
502{
503	return (struct net_device_stats*)dev->priv;
504}
505
506static void reg_vif_setup(struct net_device *dev)
507{
508	dev->type		= ARPHRD_PIMREG;
509	dev->mtu		= 1500 - sizeof(struct ipv6hdr) - 8;
510	dev->flags		= IFF_NOARP;
511	dev->hard_start_xmit	= reg_vif_xmit;
512	dev->get_stats		= reg_vif_get_stats;
513	dev->destructor		= free_netdev;
514}
515
516static struct net_device *ip6mr_reg_vif(void)
517{
518	struct net_device *dev;
519	struct inet6_dev *in_dev;
520
521	dev = alloc_netdev(sizeof(struct net_device_stats), "pim6reg",
522			   reg_vif_setup);
523
524	if (dev == NULL)
525		return NULL;
526
527	if (register_netdevice(dev)) {
528		free_netdev(dev);
529		return NULL;
530	}
531	dev->iflink = 0;
532
533	if ((in_dev = ipv6_find_idev(dev)) == NULL) {
534		goto failure;
535	}
536
537/*
538 * 	if ((in_dev = __in6_dev_get(dev)) == NULL)
539		goto failure;
540*/
541	//in_dev->cnf.rp_filter = 0;
542
543	if (dev_open(dev))
544		goto failure;
545
546	return dev;
547
548failure:
549	/* allow the register to be completed before unregistering. */
550	rtnl_unlock();
551	rtnl_lock();
552
553	unregister_netdevice(dev);
554	return NULL;
555}
556#endif
557
558/*
559 *	Delete a VIF entry
560 */
561
562static int mif6_delete(int vifi)
563{
564	struct mif_device *v;
565	struct net_device *dev;
566	struct inet6_dev *in_dev;
567
568	if (vifi < 0 || vifi >= maxvif)
569		return -EADDRNOTAVAIL;
570
571	v = &vif6_table[vifi];
572
573	write_lock_bh(&mrt_lock);
574	dev = v->dev;
575	v->dev = NULL;
576
577	if (!dev) {
578		write_unlock_bh(&mrt_lock);
579		return -EADDRNOTAVAIL;
580	}
581
582#ifdef CONFIG_IPV6_PIMSM_V2
583	if (vifi == reg_vif_num)
584		reg_vif_num = -1;
585#endif
586
587	if (vifi+1 == maxvif) {
588		int tmp;
589		for (tmp=vifi-1; tmp>=0; tmp--) {
590			if (MIF_EXISTS(tmp))
591				break;
592		}
593		maxvif = tmp+1;
594	}
595
596	write_unlock_bh(&mrt_lock);
597
598	dev_set_allmulti(dev, -1);
599
600	if ((in_dev = __in6_dev_get(dev)) != NULL) {
601		in_dev->cnf.mc_forwarding--;
602	}
603
604	if (v->flags&(MIFF_REGISTER))
605		unregister_netdevice(dev);
606
607	dev_put(dev);
608	return 0;
609}
610
611/* Destroy an unresolved cache entry, killing queued skbs
612   and reporting error to netlink readers.
613 */
614
615static void ip6mr_destroy_unres(struct mfc6_cache *c)
616{
617	struct sk_buff *skb;
618
619	atomic_dec(&cache_resolve_queue_len);
620
621	while((skb=skb_dequeue(&c->mfc_un.unres.unresolved))) {
622		//if (skb->nh.ipv6h->version == 0) {    //bob modified
623		if (ipv6_hdr(skb)->version == 0) {
624			struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
625			nlh->nlmsg_type = NLMSG_ERROR;
626			nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
627			skb_trim(skb, nlh->nlmsg_len);
628			((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
629#if 0
630			netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
631#endif
632                        rtnl_unicast(skb, NETLINK_CB(skb).pid);
633		} else
634			kfree_skb(skb);
635	}
636
637	kmem_cache_free(mrt_cachep, c);
638}
639
640
641/* Single timer process for all the unresolved queue. */
642
643static void ipmr_expire_process(unsigned long dummy)
644{
645	unsigned long now;
646	unsigned long expires;
647	struct mfc6_cache *c, **cp;
648
649	if (!spin_trylock(&mfc_unres_lock)) {
650		mod_timer(&ipmr_expire_timer, jiffies+HZ/10);
651		return;
652	}
653
654	if (atomic_read(&cache_resolve_queue_len) == 0)
655		goto out;
656
657	now = jiffies;
658	expires = 10*HZ;
659	cp = &mfc_unres_queue;
660
661	while ((c=*cp) != NULL) {
662		if (time_after(c->mfc_un.unres.expires, now)) {
663			unsigned long interval = c->mfc_un.unres.expires - now;
664			if (interval < expires)
665				expires = interval;
666			cp = &c->next;
667			continue;
668		}
669
670		*cp = c->next;
671
672		ip6mr_destroy_unres(c);
673	}
674
675	if (atomic_read(&cache_resolve_queue_len))
676		mod_timer(&ipmr_expire_timer, jiffies + expires);
677
678out:
679	spin_unlock(&mfc_unres_lock);
680}
681
682/* Fill oifs list. It is called under write locked mrt_lock. */
683
684static void ip6mr_update_threshoulds(struct mfc6_cache *cache, unsigned char *ttls)
685{
686	int vifi;
687
688	cache->mfc_un.res.minvif = MAXVIFS;
689	cache->mfc_un.res.maxvif = 0;
690	memset(cache->mfc_un.res.ttls, 255, MAXVIFS);
691
692	for (vifi=0; vifi<maxvif; vifi++) {
693		if (MIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) {
694			cache->mfc_un.res.ttls[vifi] = ttls[vifi];
695			if (cache->mfc_un.res.minvif > vifi) {
696				cache->mfc_un.res.minvif = vifi;
697                        }
698			if (cache->mfc_un.res.maxvif <= vifi) {
699				cache->mfc_un.res.maxvif = vifi + 1;
700                         }
701		}
702	}
703}
704
705static int mif6_add(struct mif6ctl *vifc, int mrtsock)
706{
707	int vifi = vifc->mif6c_mifi;
708	struct mif_device *v = &vif6_table[vifi];
709	struct net_device *dev;
710	struct inet6_dev *in_dev;
711
712	/* Is vif busy ? */
713	if (MIF_EXISTS(vifi))
714		return -EADDRINUSE;
715
716	switch (vifc->mif6c_flags) {
717#ifdef CONFIG_IPV6_PIMSM_V2
718	case MIFF_REGISTER:
719		/*
720		 * Special Purpose VIF in PIM
721		 * All the packets will be sent to the daemon
722		 */
723		if (reg_vif_num >= 0)
724			return -EADDRINUSE;
725		dev = ip6mr_reg_vif();
726		if (!dev)
727			return -ENOBUFS;
728		break;
729#endif
730	case 0:
731		dev=dev_get_by_index(vifc->mif6c_pifi);
732		if (!dev)
733			return -EADDRNOTAVAIL;
734		dev_put(dev);
735		break;
736	default:
737		return -EINVAL;
738	}
739
740	if ((in_dev = __in6_dev_get(dev)) == NULL)
741		return -EADDRNOTAVAIL;
742	in_dev->cnf.mc_forwarding++;
743	dev_set_allmulti(dev, +1);
744
745	/*
746	 *	Fill in the VIF structures
747	 */
748	v->rate_limit=vifc->vifc_rate_limit;
749	v->flags=vifc->mif6c_flags;
750	if(!mrtsock)
751		v->flags |= VIFF_STATIC;
752	v->threshold=vifc->vifc_threshold;
753	v->bytes_in = 0;
754	v->bytes_out = 0;
755	v->pkt_in = 0;
756	v->pkt_out = 0;
757	v->link = dev->ifindex;
758	if (v->flags&(MIFF_REGISTER))
759		v->link = dev->iflink;
760
761	/* And finish update writing critical data */
762	write_lock_bh(&mrt_lock);
763	dev_hold(dev);
764	v->dev=dev;
765#ifdef CONFIG_IPV6_PIMSM_V2
766	if (v->flags&MIFF_REGISTER)
767		reg_vif_num = vifi;
768#endif
769	if (vifi+1 > maxvif)
770		maxvif = vifi+1;
771	write_unlock_bh(&mrt_lock);
772	return 0;
773}
774
775static struct mfc6_cache *ip6mr_cache_find(struct in6_addr origin,struct in6_addr mcastgrp)
776{
777	int line=MFC6_HASH(mcastgrp,origin);
778	struct mfc6_cache *c;
779
780	for (c=mfc6_cache_array[line]; c; c = c->next) {
781		if (IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&origin) &&
782		    IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mcastgrp))
783			break;
784	}
785
786#if defined(CONFIG_MIPS_BRCM)
787        if(c == NULL) {
788		for (c=mfc6_cache_array[line]; c; c = c->next) {
789		    if (IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mcastgrp))
790			break;
791            	}
792        }
793#endif /* CONFIG_MIPS_BRCM */
794	return c;
795}
796
797/*
798 *	Allocate a multicast cache entry
799 */
800static struct mfc6_cache *ip6mr_cache_alloc(void)
801{
802	struct mfc6_cache *c=kmem_cache_alloc(mrt_cachep, GFP_KERNEL);
803	if(c==NULL)
804		return NULL;
805	memset(c, 0, sizeof(*c));
806	c->mfc_un.res.minvif = MAXVIFS;
807	return c;
808}
809
810static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
811{
812	struct mfc6_cache *c=kmem_cache_alloc(mrt_cachep, GFP_ATOMIC);
813	if(c==NULL)
814		return NULL;
815	memset(c, 0, sizeof(*c));
816	skb_queue_head_init(&c->mfc_un.unres.unresolved);
817	c->mfc_un.unres.expires = jiffies + 10*HZ;
818	return c;
819}
820
821/*
822 *	A cache entry has gone into a resolved state from queued
823 */
824
825static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c)
826{
827	struct sk_buff *skb;
828
829	/*
830	 *	Play the pending entries through our router
831	 */
832
833	while((skb=__skb_dequeue(&uc->mfc_un.unres.unresolved))) {
834		//if (skb->nh.ipv6h->version == 0) {    //bob modified
835		if (ipv6_hdr(skb)->version == 0) {
836			int err;
837			struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr));
838
839			if (ip6mr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) {
840				nlh->nlmsg_len = skb->tail - (u8*)nlh;
841			} else {
842				nlh->nlmsg_type = NLMSG_ERROR;
843				nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
844				skb_trim(skb, nlh->nlmsg_len);
845				((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE;
846			}
847#if 0
848			err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
849#endif
850                        err = rtnl_unicast(skb, NETLINK_CB(skb).pid);
851		} else
852			ip6_mr_forward(skb, c, 0);
853	}
854}
855
856/*
857 *	Bounce a cache query up to pim6sd. We could use netlink for this but pim6sd
858 *	expects the following bizarre scheme.
859 *
860 *	Called under mrt_lock.
861 */
862
863static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
864{
865	struct sk_buff *skb;
866	struct mrt6msg *msg;
867	int ret;
868
869#ifdef CONFIG_IPV6_PIMSM_V2
870	if (assert == MRT6MSG_WHOLEPKT)
871		skb = skb_realloc_headroom(pkt, sizeof(struct ipv6hdr));
872	else
873#endif
874		skb = alloc_skb(128, GFP_ATOMIC);
875
876	if(!skb)
877		return -ENOBUFS;
878
879	/* I suppose that internal messages
880	 * do not require checksums */
881
882	skb->ip_summed = CHECKSUM_UNNECESSARY;
883
884#ifdef CONFIG_IPV6_PIMSM_V2
885	if (assert == MRT6MSG_WHOLEPKT) {
886		/* Ugly, but we have no choice with this interface.
887		   Duplicate old header, fix length etc.
888		   And all this only to mangle msg->im6_msgtype and
889		   to set msg->im6_mbz to "mbz" :-)
890		 */
891		skb_push(skb, -skb_network_offset(pkt));
892
893		skb_push(skb, sizeof(*msg));
894		skb_reset_transport_header(skb);
895		msg = (struct mrt6msg *)skb_transport_header(skb);
896		msg->im6_mbz = 0;
897		msg->im6_msgtype = MRT6MSG_WHOLEPKT;
898		msg->im6_mif = reg_vif_num;
899		msg->im6_pad = 0;
900		ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr);
901		ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr);
902
903		skb->ip_summed = CHECKSUM_UNNECESSARY;
904	} else
905#endif
906	{
907
908	/*
909	 *	Copy the IP header
910	 */
911#if 0       //bob modified
912	skb->nh.ipv6h = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
913	memcpy(skb->data,pkt->data,sizeof(struct ipv6hdr));
914
915	msg = (struct mrt6msg*)skb->nh.ipv6h;
916	skb->dst = dst_clone(pkt->dst);
917#endif
918    skb_put(skb, sizeof(struct ipv6hdr));
919	skb_reset_network_header(skb);
920	skb_copy_to_linear_data(skb, ipv6_hdr(pkt), sizeof(struct ipv6hdr));
921	/*
922	 *	Add our header
923	 */
924
925#if 0
926	msg->im6_msgtype = assert;
927	msg->im6_mbz = 0;
928	msg->im6_mif = vifi;
929	skb->h.raw = skb->nh.raw;
930        }
931
932	if (mroute6_socket == NULL) {
933		kfree_skb(skb);
934		return -EINVAL;
935	}
936#endif
937    skb_put(skb, sizeof(*msg));
938	skb_reset_transport_header(skb);
939	msg = (struct mrt6msg *)skb_transport_header(skb);
940
941	msg->im6_mbz = 0;
942	msg->im6_msgtype = assert;
943	msg->im6_mif = vifi;
944	msg->im6_pad = 0;
945	ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr);
946	ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr);
947
948	skb->dst = dst_clone(pkt->dst);
949	skb->ip_summed = CHECKSUM_UNNECESSARY;
950
951	skb_pull(skb, sizeof(struct ipv6hdr));
952	}
953
954	if (mroute6_socket == NULL) {
955		kfree_skb(skb);
956		return -EINVAL;
957	}
958	/*
959	 *	Deliver to user space multicast routing algorithms
960	 */
961	if ((ret=sock_queue_rcv_skb(mroute6_socket,skb))<0) {
962		if (net_ratelimit())
963			printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n");
964		kfree_skb(skb);
965	}
966
967	return ret;
968}
969
970/*
971 *	Queue a packet for resolution. It gets locked cache entry!
972 */
973
974static int
975ip6mr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
976{
977	int err;
978	struct mfc6_cache *c;
979
980	spin_lock_bh(&mfc_unres_lock);
981	for (c=mfc_unres_queue; c; c=c->next) {
982		//if (IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&skb->nh.ipv6h->daddr) &&
983		//    IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&skb->nh.ipv6h->saddr))
984		if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&    //bob modified
985		    ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr))
986			break;
987	}
988
989	if (c == NULL) {
990		/*
991		 *	Create a new entry if allowable
992		 */
993
994		if (atomic_read(&cache_resolve_queue_len)>=10 ||
995		    (c=ip6mr_cache_alloc_unres())==NULL) {
996			spin_unlock_bh(&mfc_unres_lock);
997
998			kfree_skb(skb);
999			return -ENOBUFS;
1000		}
1001
1002		/*
1003		 *	Fill in the new cache entry
1004		 */
1005		c->mf6c_parent=-1;
1006		//c->mf6c_origin=skb->nh.ipv6h->saddr;  //bob modifed
1007		c->mf6c_origin = ipv6_hdr(skb)->saddr;
1008		//c->mf6c_mcastgrp=skb->nh.ipv6h->daddr;
1009		c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr;
1010
1011		/*
1012		 *	Reflect first query at pim6sd
1013		 */
1014		if ((err = ip6mr_cache_report(skb, vifi, MRT6MSG_NOCACHE))<0) {
1015			/* If the report failed throw the cache entry
1016			   out - Brad Parker
1017			 */
1018			spin_unlock_bh(&mfc_unres_lock);
1019
1020			kmem_cache_free(mrt_cachep, c);
1021			kfree_skb(skb);
1022			return err;
1023		}
1024
1025		atomic_inc(&cache_resolve_queue_len);
1026		c->next = mfc_unres_queue;
1027		mfc_unres_queue = c;
1028
1029		mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
1030	}
1031
1032	/*
1033	 *	See if we can append the packet
1034	 */
1035	if (c->mfc_un.unres.unresolved.qlen>3) {
1036		kfree_skb(skb);
1037		err = -ENOBUFS;
1038	} else {
1039		skb_queue_tail(&c->mfc_un.unres.unresolved,skb);
1040		err = 0;
1041	}
1042
1043	spin_unlock_bh(&mfc_unres_lock);
1044	return err;
1045}
1046
1047/*
1048 *	MFC6 cache manipulation by user space
1049 */
1050
1051static int ip6mr_mfc_delete(struct mf6cctl *mfc)
1052{
1053	int line;
1054	struct mfc6_cache *c, **cp;
1055
1056	line=MFC6_HASH(mfc->mf6cc_mcastgrp.sin6_addr, mfc->mf6cc_origin.sin6_addr);
1057
1058	for (cp=&mfc6_cache_array[line]; (c=*cp) != NULL; cp = &c->next) {
1059		if (IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&mfc->mf6cc_origin.sin6_addr) &&
1060		    IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mfc->mf6cc_mcastgrp.sin6_addr)) {
1061			write_lock_bh(&mrt_lock);
1062			*cp = c->next;
1063			write_unlock_bh(&mrt_lock);
1064
1065			kmem_cache_free(mrt_cachep, c);
1066			return 0;
1067		}
1068	}
1069	return -ENOENT;
1070}
1071
1072static int ip6mr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
1073{
1074	struct mif_device *v;
1075	int ct;
1076	if (event != NETDEV_UNREGISTER)
1077		return NOTIFY_DONE;
1078	v=&vif6_table[0];
1079	for(ct=0;ct<maxvif;ct++,v++) {
1080		if (v->dev==ptr)
1081			mif6_delete(ct);
1082	}
1083	return NOTIFY_DONE;
1084}
1085
1086static struct notifier_block ip6_mr_notifier = {
1087	.notifier_call = ip6mr_device_event
1088};
1089
1090/*
1091 *	Setup for IP multicast routing
1092 */
1093
1094void __init ip6_mr_init(void)
1095{
1096	printk(KERN_INFO "6WIND/LSIIT IPv6 multicast forwarding 0.1 plus PIM-SM/SSM with *BSD API\n");
1097
1098	mrt_cachep = kmem_cache_create("ip6_mrt_cache",
1099				       sizeof(struct mfc6_cache),
1100				       0, SLAB_HWCACHE_ALIGN,
1101				       NULL, NULL);
1102	if (!mrt_cachep)
1103		panic("cannot allocate ip_mrt_cache");
1104
1105	init_timer(&ipmr_expire_timer);
1106	ipmr_expire_timer.function=ipmr_expire_process;
1107	register_netdevice_notifier(&ip6_mr_notifier);
1108#ifdef CONFIG_PROC_FS
1109	proc_net_fops_create("ip6_mr_vif", 0, &ip6mr_vif_fops);
1110	proc_net_fops_create("ip6_mr_cache", 0, &ip6mr_mfc_fops);
1111#endif
1112}
1113
1114
1115static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
1116{
1117	int line;
1118	struct mfc6_cache *uc, *c, **cp;
1119	unsigned char ttls[MAXVIFS];
1120	int i;
1121
1122	memset(ttls, 255, MAXVIFS);
1123	for(i=0;i<MAXVIFS;i++) {
1124		if(IF_ISSET(i,&mfc->mf6cc_ifset))  {
1125			ttls[i]=1;
1126                }
1127
1128	}
1129
1130	line=MFC6_HASH(mfc->mf6cc_mcastgrp.sin6_addr, mfc->mf6cc_origin.sin6_addr);
1131
1132	for (cp=&mfc6_cache_array[line]; (c=*cp) != NULL; cp = &c->next) {
1133		if (IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&mfc->mf6cc_origin.sin6_addr) &&
1134		    IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mfc->mf6cc_mcastgrp.sin6_addr))
1135			break;
1136	}
1137
1138	if (c != NULL) {
1139		write_lock_bh(&mrt_lock);
1140		c->mf6c_parent = mfc->mf6cc_parent;
1141		ip6mr_update_threshoulds(c, ttls);
1142		if (!mrtsock)
1143			c->mfc_flags |= MFC_STATIC;
1144		write_unlock_bh(&mrt_lock);
1145		return 0;
1146	}
1147
1148	if(!(ipv6_addr_type(&mfc->mf6cc_mcastgrp.sin6_addr)&IPV6_ADDR_MULTICAST))
1149		return -EINVAL;
1150
1151	c=ip6mr_cache_alloc();
1152	if (c==NULL)
1153		return -ENOMEM;
1154
1155	c->mf6c_origin=mfc->mf6cc_origin.sin6_addr;
1156	c->mf6c_mcastgrp=mfc->mf6cc_mcastgrp.sin6_addr;
1157	c->mf6c_parent=mfc->mf6cc_parent;
1158	ip6mr_update_threshoulds(c, ttls);
1159	if (!mrtsock)
1160		c->mfc_flags |= MFC_STATIC;
1161
1162	write_lock_bh(&mrt_lock);
1163	c->next = mfc6_cache_array[line];
1164	mfc6_cache_array[line] = c;
1165	write_unlock_bh(&mrt_lock);
1166
1167	/*
1168	 *	Check to see if we resolved a queued list. If so we
1169	 *	need to send on the frames and tidy up.
1170	 */
1171	spin_lock_bh(&mfc_unres_lock);
1172	for (cp = &mfc_unres_queue; (uc=*cp) != NULL;
1173	     cp = &uc->next) {
1174		if (IN6_ARE_ADDR_EQUAL(&uc->mf6c_origin,&c->mf6c_origin) &&
1175		    IN6_ARE_ADDR_EQUAL(&uc->mf6c_mcastgrp,&c->mf6c_mcastgrp)) {
1176			*cp = uc->next;
1177			if (atomic_dec_and_test(&cache_resolve_queue_len))
1178				del_timer(&ipmr_expire_timer);
1179			break;
1180		}
1181	}
1182	spin_unlock_bh(&mfc_unres_lock);
1183
1184	if (uc) {
1185		ip6mr_cache_resolve(uc, c);
1186		kmem_cache_free(mrt_cachep, uc);
1187	}
1188	return 0;
1189}
1190
1191/*
1192 *	Close the multicast socket, and clear the vif tables etc
1193 */
1194
1195static void mroute_clean_tables(struct sock *sk)
1196{
1197	int i;
1198
1199	/*
1200	 *	Shut down all active vif entries
1201	 */
1202	for(i=0; i<maxvif; i++) {
1203		if (!(vif6_table[i].flags&VIFF_STATIC))
1204			mif6_delete(i);
1205	}
1206
1207	/*
1208	 *	Wipe the cache
1209	 */
1210	for (i=0;i<MFC_LINES;i++) {
1211		struct mfc6_cache *c, **cp;
1212
1213		cp = &mfc6_cache_array[i];
1214		while ((c = *cp) != NULL) {
1215			if (c->mfc_flags&MFC_STATIC) {
1216				cp = &c->next;
1217				continue;
1218			}
1219			write_lock_bh(&mrt_lock);
1220			*cp = c->next;
1221			write_unlock_bh(&mrt_lock);
1222
1223			kmem_cache_free(mrt_cachep, c);
1224		}
1225	}
1226
1227	if (atomic_read(&cache_resolve_queue_len) != 0) {
1228		struct mfc6_cache *c;
1229
1230		spin_lock_bh(&mfc_unres_lock);
1231		while (mfc_unres_queue != NULL) {
1232			c = mfc_unres_queue;
1233			mfc_unres_queue = c->next;
1234			spin_unlock_bh(&mfc_unres_lock);
1235
1236			ip6mr_destroy_unres(c);
1237
1238			spin_lock_bh(&mfc_unres_lock);
1239		}
1240		spin_unlock_bh(&mfc_unres_lock);
1241	}
1242}
1243
1244static void mrtsock_destruct(struct sock *sk)
1245{
1246	rtnl_lock();
1247	if (sk == mroute6_socket) {
1248		ipv6_devconf.mc_forwarding--;
1249
1250		write_lock_bh(&mrt_lock);
1251		mroute6_socket=NULL;
1252		write_unlock_bh(&mrt_lock);
1253
1254		mroute_clean_tables(sk);
1255	}
1256	rtnl_unlock();
1257}
1258
1259/*
1260 *	Socket options and virtual interface manipulation. The whole
1261 *	virtual interface system is a complete heap, but unfortunately
1262 *	that's how BSD mrouted happens to think. Maybe one day with a proper
1263 *	MOSPF/PIM router set up we can clean this up.
1264 */
1265
1266int ip6_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int optlen)
1267{
1268	int ret;
1269	struct mif6ctl vif;
1270	struct mf6cctl mfc;
1271	mifi_t mifi;
1272
1273	if(optname!=MRT6_INIT)
1274	{
1275		if(sk!=mroute6_socket && !capable(CAP_NET_ADMIN))
1276			return -EACCES;
1277	}
1278
1279	switch(optname)
1280	{
1281		case MRT6_INIT:
1282			if (sk->sk_type != SOCK_RAW ||
1283			    inet_sk(sk)->num != IPPROTO_ICMPV6)
1284				return -EOPNOTSUPP;
1285			if(optlen!=sizeof(int))
1286				return -ENOPROTOOPT;
1287
1288			rtnl_lock();
1289			if (mroute6_socket) {
1290				rtnl_unlock();
1291				return -EADDRINUSE;
1292			}
1293
1294			ret = ip6_ra_control(sk, 1, mrtsock_destruct);
1295			if (ret == 0) {
1296				write_lock_bh(&mrt_lock);
1297				mroute6_socket=sk;
1298				write_unlock_bh(&mrt_lock);
1299
1300				ipv6_devconf.mc_forwarding++;
1301			}
1302			rtnl_unlock();
1303			return ret;
1304		case MRT6_DONE:
1305			if (sk!=mroute6_socket)
1306				return -EACCES;
1307			return ip6_ra_control(sk, -1, NULL);
1308		case MRT6_ADD_MIF:
1309			if(optlen!=sizeof(vif))
1310				return -EINVAL;
1311			if (copy_from_user(&vif,optval,sizeof(vif)))
1312				return -EFAULT;
1313			if(vif.mif6c_mifi >= MAXVIFS)
1314				return -ENFILE;
1315			rtnl_lock();
1316			ret = mif6_add(&vif, sk==mroute6_socket);
1317			rtnl_unlock();
1318			return ret;
1319		case MRT6_DEL_MIF:
1320			if(optlen!=sizeof(mifi_t))
1321				return -EINVAL;
1322			if (copy_from_user(&mifi,optval,sizeof(mifi_t)))
1323				return -EFAULT;
1324			rtnl_lock();
1325			ret = mif6_delete(mifi);
1326			rtnl_unlock();
1327			return ret;
1328
1329		/*
1330		 *	Manipulate the forwarding caches. These live
1331		 *	in a sort of kernel/user symbiosis.
1332		 */
1333		case MRT6_ADD_MFC:
1334		case MRT6_DEL_MFC:
1335			if(optlen!=sizeof(mfc))
1336				return -EINVAL;
1337			if (copy_from_user(&mfc,optval, sizeof(mfc)))
1338				return -EFAULT;
1339			rtnl_lock();
1340			if (optname==MRT6_DEL_MFC)
1341				ret = ip6mr_mfc_delete(&mfc);
1342			else
1343				ret = ip6mr_mfc_add(&mfc, sk==mroute6_socket);
1344			rtnl_unlock();
1345			return ret;
1346		/*
1347		 *	Control PIM assert (to activate pim will activate assert)
1348		 */
1349		case MRT6_ASSERT:
1350		{
1351			int v;
1352			if(get_user(v,(int __user *)optval))
1353				return -EFAULT;
1354			mroute_do_assert=(v)?1:0;
1355			return 0;
1356		}
1357#ifdef CONFIG_IPV6_PIMSM_V2
1358		case MRT6_PIM:
1359		{
1360			int v, ret;
1361			if(get_user(v,(int __user *)optval))
1362				return -EFAULT;
1363			v = (v)?1:0;
1364			rtnl_lock();
1365			ret = 0;
1366			if (v != mroute_do_pim) {
1367				mroute_do_pim = v;
1368				mroute_do_assert = v;
1369				if (mroute_do_pim)
1370					ret = inet6_add_protocol(&pim6_protocol,
1371								IPPROTO_PIM);
1372				else
1373					ret = inet6_del_protocol(&pim6_protocol,
1374								IPPROTO_PIM);
1375				if (ret < 0)
1376					ret = -EAGAIN;
1377			}
1378			rtnl_unlock();
1379			return ret;
1380		}
1381#endif
1382		/*
1383		 *	Spurious command, or MRT_VERSION which you cannot
1384		 *	set.
1385		 */
1386		default:
1387			return -ENOPROTOOPT;
1388	}
1389}
1390
1391/*
1392 *	Getsock opt support for the multicast routing system.
1393 */
1394
1395int ip6_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __user *optlen)
1396{
1397	int olr;
1398	int val;
1399
1400	if(optname!=MRT6_VERSION &&
1401#ifdef CONFIG_IPV6_PIMSM_V2
1402	   optname!=MRT6_PIM &&
1403#endif
1404	   optname!=MRT6_ASSERT)
1405		return -ENOPROTOOPT;
1406
1407	if (get_user(olr, optlen))
1408		return -EFAULT;
1409
1410	olr = min_t(unsigned int, olr, sizeof(int));
1411	if (olr < 0)
1412		return -EINVAL;
1413
1414	if(put_user(olr,optlen))
1415		return -EFAULT;
1416	if(optname==MRT6_VERSION)
1417		val=0x0305;
1418#ifdef CONFIG_IPV6_PIMSM_V2
1419	else if(optname==MRT6_PIM)
1420		val=mroute_do_pim;
1421#endif
1422	else
1423		val=mroute_do_assert;
1424	if(copy_to_user(optval,&val,olr))
1425		return -EFAULT;
1426	return 0;
1427}
1428
1429/*
1430 *	The IP multicast ioctl support routines.
1431 */
1432
1433int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1434{
1435	struct sioc_sg_req6 sr;
1436	struct sioc_mif_req6 vr;
1437	struct mif_device *vif;
1438	struct mfc6_cache *c;
1439
1440	switch(cmd)
1441	{
1442		case SIOCGETMIFCNT_IN6:
1443			if (copy_from_user(&vr,arg,sizeof(vr)))
1444				return -EFAULT;
1445			if(vr.mifi>=maxvif)
1446				return -EINVAL;
1447			read_lock(&mrt_lock);
1448			vif=&vif6_table[vr.mifi];
1449			if(MIF_EXISTS(vr.mifi))	{
1450				vr.icount=vif->pkt_in;
1451				vr.ocount=vif->pkt_out;
1452				vr.ibytes=vif->bytes_in;
1453				vr.obytes=vif->bytes_out;
1454				read_unlock(&mrt_lock);
1455
1456				if (copy_to_user(arg,&vr,sizeof(vr)))
1457					return -EFAULT;
1458				return 0;
1459			}
1460			read_unlock(&mrt_lock);
1461			return -EADDRNOTAVAIL;
1462		case SIOCGETSGCNT_IN6:
1463			if (copy_from_user(&sr,arg,sizeof(sr)))
1464				return -EFAULT;
1465
1466			read_lock(&mrt_lock);
1467			c = ip6mr_cache_find(sr.src.sin6_addr, sr.grp.sin6_addr);
1468			if (c) {
1469				sr.pktcnt = c->mfc_un.res.pkt;
1470				sr.bytecnt = c->mfc_un.res.bytes;
1471				sr.wrong_if = c->mfc_un.res.wrong_if;
1472				read_unlock(&mrt_lock);
1473
1474				if (copy_to_user(arg,&sr,sizeof(sr)))
1475					return -EFAULT;
1476				return 0;
1477			}
1478			read_unlock(&mrt_lock);
1479			return -EADDRNOTAVAIL;
1480		default:
1481			return -ENOIOCTLCMD;
1482	}
1483}
1484
1485
1486static inline int ip6mr_forward_finish(struct sk_buff *skb)
1487{
1488#ifdef notyet
1489	struct ip_options * opt	= &(IP6CB(skb)->opt);
1490
1491	IP_INC_STATS_BH(OutForwDatagrams);
1492
1493	if (unlikely(opt->optlen))
1494		ip_forward_options(skb);
1495#endif
1496
1497	return dst_output(skb);
1498}
1499
1500/*
1501 *	Processing handlers for ip6mr_forward
1502 */
1503
1504static void ip6mr_queue_xmit(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
1505{
1506	//struct ipv6hdr *ipv6h = skb->nh.ipv6h;    //bob modified
1507	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
1508	struct mif_device *vif = &vif6_table[vifi];
1509	struct net_device *dev;
1510	struct in6_addr *snd_addr=&ipv6h->daddr;
1511	int full_len = skb->len;
1512
1513	if (vif->dev == NULL)
1514		goto out_free;
1515
1516#ifdef CONFIG_IPV6_PIMSM_V2
1517	if (vif->flags & MIFF_REGISTER) {
1518		vif->pkt_out++;
1519		vif->bytes_out+=skb->len;
1520		((struct net_device_stats*)vif->dev->priv)->tx_bytes += skb->len;
1521		((struct net_device_stats*)vif->dev->priv)->tx_packets++;
1522		ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT);
1523		kfree_skb(skb);
1524		return;
1525	}
1526#endif
1527	/*
1528	 * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
1529	 * not only before forwarding, but after forwarding on all output
1530	 * interfaces. It is clear, if mrouter runs a multicasting
1531	 * program, it should receive packets not depending to what interface
1532	 * program is joined.
1533	 * If we will not make it, the program will have to join on all
1534	 * interfaces. On the other hand, multihoming host (or router, but
1535	 * not mrouter) cannot join to more than one interface - it will
1536	 * result in receiving multiple packets.
1537	 */
1538	dev = vif->dev;
1539	skb->dev=dev;
1540	vif->pkt_out++;
1541	vif->bytes_out+=skb->len;
1542
1543	//ipv6h = skb->nh.ipv6h;    //bob modified
1544	ipv6h = ipv6_hdr(skb);
1545
1546	ipv6h->hop_limit--;
1547
1548	if(dev->hard_header) {
1549		unsigned char ha[MAX_ADDR_LEN];
1550		ndisc_mc_map(snd_addr,ha,dev,1);
1551		if(dev->hard_header(skb,dev, ETH_P_IPV6,ha,NULL,full_len) < 0)
1552			goto out_free;
1553	}
1554
1555	NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, skb->dev, dev,
1556		dev_queue_xmit);
1557/*	NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, skb->dev, dev,
1558		ip6mr_forward_finish);
1559*/
1560
1561
1562 /* 	NF_HOOK(PF_INET6, NF_IP6_FORWARD, skb, skb->dev, dev,
1563		ip6mr_forward_finish);
1564	*/
1565	return;
1566	/* XXX */
1567
1568out_free:
1569	kfree_skb(skb);
1570	return;
1571}
1572
1573static int ip6mr_find_vif(struct net_device *dev)
1574{
1575	int ct;
1576	for (ct=maxvif-1; ct>=0; ct--) {
1577		if (vif6_table[ct].dev == dev)
1578			break;
1579	}
1580	return ct;
1581}
1582
1583static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache, int local)
1584{
1585	int psend = -1;
1586	int vif, ct;
1587	struct dst_entry *dst = skb->dst;
1588	static struct net_device *lan_device = NULL;
1589
1590	vif = cache->mf6c_parent;
1591	cache->mfc_un.res.pkt++;
1592	cache->mfc_un.res.bytes += skb->len;
1593
1594	/* Bob added start, 08/19/2009, ipv6ready v6LC.1.1.10 part J */
1595	if(! (ipv6_hdr(skb)->daddr.s6_addr[1] & 0x0f))
1596	{
1597	    goto dont_forward;
1598	}
1599	/* Bob added end, 08/19/2009, ipv6ready v6LC.1.1.10 part J */
1600
1601	/* Bob added start, 08/19/2009, ipv6ready v6LC.5.1.4 part B */
1602	if(!lan_device)
1603	    lan_device = dev_get_by_name("eth0");    //todo: not to hardcode br0
1604	    //lan_device = dev_get_by_name("br0");    //todo: not to hardcode br0
1605    if (skb->len > lan_device->mtu)
1606	{
1607		skb->dev = lan_device;
1608		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, lan_device->mtu, skb->dev);
1609		IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
1610		IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS);
1611		kfree_skb(skb);
1612		return -EMSGSIZE;
1613	}
1614	/* Bob added end, 08/19/2009, ipv6ready v6LC.5.1.4 part B */
1615
1616	/*
1617	 * Wrong interface: drop packet and (maybe) send PIM assert.
1618	 */
1619	if (vif6_table[vif].dev != skb->dev) {
1620		int true_vifi;
1621
1622		if (((struct rtable*)skb->dst)->fl.iif == 0) {
1623			/* It is our own packet, looped back.
1624			   Very complicated situation...
1625
1626			   The best workaround until routing daemons will be
1627			   fixed is not to redistribute packet, if it was
1628			   send through wrong interface. It means, that
1629			   multicast applications WILL NOT work for
1630			   (S,G), which have default multicast route pointing
1631			   to wrong oif. In any case, it is not a good
1632			   idea to use multicasting applications on router.
1633			 */
1634			goto dont_forward;
1635		}
1636
1637		cache->mfc_un.res.wrong_if++;
1638		true_vifi = ip6mr_find_vif(skb->dev);
1639
1640		if (true_vifi >= 0 && mroute_do_assert &&
1641		    /* pimsm uses asserts, when switching from RPT to SPT,
1642		       so that we cannot check that packet arrived on an oif.
1643		       It is bad, but otherwise we would need to move pretty
1644		       large chunk of pimd to kernel. Ough... --ANK
1645		     */
1646		    (mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) &&
1647		    time_after(jiffies,
1648			       cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) {
1649			cache->mfc_un.res.last_assert = jiffies;
1650			ip6mr_cache_report(skb, true_vifi, MRT6MSG_WRONGMIF);
1651		}
1652		goto dont_forward;
1653	}
1654
1655	vif6_table[vif].pkt_in++;
1656	vif6_table[vif].bytes_in+=skb->len;
1657
1658	/*
1659	 *	Forward the frame
1660	 */
1661	for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) {
1662		//if (skb->nh.ipv6h->hop_limit > cache->mfc_un.res.ttls[ct]) {  //bob modified
1663		if (ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) {    //bob modified
1664			//struct ipv6hdr *ipv6h = skb->nh.ipv6h;    //bob modified
1665			struct ipv6hdr *ipv6h = ipv6_hdr(skb);  //bob modified
1666			if (psend != -1) {
1667				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
1668				if (skb2) {
1669					ip6mr_queue_xmit(skb2, cache, psend);
1670					ipv6h->hop_limit++;
1671				}
1672			}
1673			psend=ct;
1674		}
1675	}
1676	if (psend != -1) {
1677		//struct ipv6hdr *ipv6h = skb->nh.ipv6h;    //bob modified
1678		struct ipv6hdr *ipv6h = ipv6_hdr(skb);      //bob modified
1679		if (local) {
1680			struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
1681			if (skb2) {
1682				ip6mr_queue_xmit(skb2, cache, psend);
1683				ipv6h->hop_limit++;
1684			}
1685		} else {
1686			ip6mr_queue_xmit(skb, cache, psend);
1687			ipv6h->hop_limit++;
1688			return 0;
1689		}
1690	}
1691
1692dont_forward:
1693	if (!local)
1694		kfree_skb(skb);
1695	return 0;
1696}
1697
1698
1699/*
1700 *	Multicast packets for forwarding arrive here
1701 */
1702
1703int ip6_mr_input(struct sk_buff *skb)
1704{
1705	struct mfc6_cache *cache;
1706	int local = ((struct rt6_info*)skb->dst)->rt6i_flags&RTCF_LOCAL;
1707	IP6CB(skb)->flags = 0;
1708
1709	read_lock(&mrt_lock);
1710	//cache = ip6mr_cache_find(skb->nh.ipv6h->saddr, skb->nh.ipv6h->daddr);
1711	cache = ip6mr_cache_find(ipv6_hdr(skb)->saddr, ipv6_hdr(skb)->daddr);
1712
1713	/*
1714	 *	No usable cache entry
1715	 */
1716	if (cache==NULL) {
1717		int vif;
1718
1719		vif = ip6mr_find_vif(skb->dev);
1720		if (vif >= 0) {
1721			int err = ip6mr_cache_unresolved(vif, skb);
1722			read_unlock(&mrt_lock);
1723
1724			return err;
1725		}
1726		read_unlock(&mrt_lock);
1727		kfree_skb(skb);
1728		return -ENODEV;
1729	}
1730
1731	ip6_mr_forward(skb, cache, local);
1732
1733	read_unlock(&mrt_lock);
1734
1735	return 0;
1736
1737dont_forward:
1738	kfree_skb(skb);
1739	return 0;
1740}
1741
1742
1743static int
1744ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm)
1745{
1746	int ct;
1747	struct rtnexthop *nhp;
1748	struct net_device *dev = vif6_table[c->mf6c_parent].dev;
1749	u8 *b = skb->tail;
1750	struct rtattr *mp_head;
1751
1752	if (dev)
1753		RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
1754
1755	mp_head = (struct rtattr*)skb_put(skb, RTA_LENGTH(0));
1756
1757	for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
1758		if (c->mfc_un.res.ttls[ct] < 255) {
1759			if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
1760				goto rtattr_failure;
1761			nhp = (struct rtnexthop*)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
1762			nhp->rtnh_flags = 0;
1763			nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
1764			nhp->rtnh_ifindex = vif6_table[ct].dev->ifindex;
1765			nhp->rtnh_len = sizeof(*nhp);
1766		}
1767	}
1768	mp_head->rta_type = RTA_MULTIPATH;
1769	mp_head->rta_len = skb->tail - (u8*)mp_head;
1770	rtm->rtm_type = RTN_MULTICAST;
1771	return 1;
1772
1773rtattr_failure:
1774	skb_trim(skb, b - skb->data);
1775	return -EMSGSIZE;
1776}
1777