This source file includes following definitions.
- vif_delete
- ipmr_vifi_find
- ipmr_cache_delete
- ipmr_cache_timer
- ipmr_cache_insert
- ipmr_cache_find
- ipmr_cache_alloc
- ipmr_cache_resolve
- ipmr_cache_report
- ipmr_cache_unresolved
- ipmr_mfc_modify
- ip_mroute_setsockopt
- ip_mroute_getsockopt
- ipmr_ioctl
- mroute_close
- ipmr_device_event
- ipmr_queue_xmit
- ipmr_forward
- ipmr_vif_info
- ipmr_mfc_info
- ip_mr_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <asm/system.h>
27 #include <asm/segment.h>
28 #include <linux/types.h>
29 #include <linux/sched.h>
30 #include <linux/errno.h>
31 #include <linux/timer.h>
32 #include <linux/mm.h>
33 #include <linux/kernel.h>
34 #include <linux/fcntl.h>
35 #include <linux/stat.h>
36 #include <linux/socket.h>
37 #include <linux/in.h>
38 #include <linux/inet.h>
39 #include <linux/netdevice.h>
40 #include <linux/proc_fs.h>
41 #include <linux/mroute.h>
42 #include <net/ip.h>
43 #include <net/protocol.h>
44 #include <linux/skbuff.h>
45 #include <net/sock.h>
46 #include <net/icmp.h>
47 #include <net/udp.h>
48 #include <linux/notifier.h>
49 #include <net/checksum.h>
50
51
52
53
54
55 static struct vif_device vif_table[MAXVIFS];
56 static unsigned long vifc_map;
57 int mroute_do_pim = 0;
58 static struct mfc_cache *mfc_cache_array[MFC_LINES];
59 static struct mfc_cache *cache_resolve_queue;
60 int cache_resolve_queue_len = 0;
61
62
63
64
65
66 static void vif_delete(struct vif_device *v)
67 {
68 if(!(v->flags&VIFF_TUNNEL))
69 {
70 v->dev->flags&=~IFF_ALLMULTI;
71 dev_mc_upload(v->dev);
72 }
73 v->dev=NULL;
74 }
75
76
77
78
79
80 static int ipmr_vifi_find(struct device *dev)
81 {
82 struct vif_device *v=&vif_table[0];
83 int ct;
84 for(ct=0;ct<MAXVIFS;ct++,v++)
85 {
86 if(v->dev==dev)
87 return ct;
88 }
89 return -1;
90 }
91
92
93
94
95
96 static void ipmr_cache_delete(struct mfc_cache *cache)
97 {
98 struct sk_buff *skb;
99 int line;
100 struct mfc_cache **cp;
101
102
103
104
105
106 if(cache->mfc_flags&MFC_QUEUED)
107 {
108 cp=&cache_resolve_queue;
109 del_timer(&cache->mfc_timer);
110 }
111 else
112 {
113 line=MFC_HASH(cache->mfc_mcastgrp,cache->mfc_origin);
114 cp=&(mfc_cache_array[line]);
115 }
116
117
118
119
120
121 while(*cp!=NULL)
122 {
123 if(*cp==cache)
124 {
125 *cp=cache->next;
126 break;
127 }
128 cp=&((*cp)->next);
129 }
130
131
132
133
134
135
136 if(cache->mfc_flags&MFC_QUEUED)
137 {
138 cache_resolve_queue_len--;
139 while((skb=skb_dequeue(&cache->mfc_unresolved)))
140 kfree_skb(skb, FREE_WRITE);
141 }
142 kfree_s(cache,sizeof(cache));
143 }
144
145
146
147
148
149 static void ipmr_cache_timer(unsigned long data)
150 {
151 struct mfc_cache *cache=(struct mfc_cache *)data;
152 ipmr_cache_delete(cache);
153 }
154
155
156
157
158
159 static void ipmr_cache_insert(struct mfc_cache *c)
160 {
161 int line=MFC_HASH(c->mfc_mcastgrp,c->mfc_origin);
162 c->next=mfc_cache_array[line];
163 mfc_cache_array[line]=c;
164 }
165
166
167
168
169
170 struct mfc_cache *ipmr_cache_find(__u32 origin, __u32 mcastgrp)
171 {
172 int line=MFC_HASH(mcastgrp,origin);
173 struct mfc_cache *cache;
174 cache=mfc_cache_array[line];
175 while(cache!=NULL)
176 {
177 if(cache->mfc_origin==origin && cache->mfc_mcastgrp==mcastgrp)
178 return cache;
179 cache=cache->next;
180 }
181 cache=cache_resolve_queue;
182 while(cache!=NULL)
183 {
184 if(cache->mfc_origin==origin && cache->mfc_mcastgrp==mcastgrp)
185 return cache;
186 cache=cache->next;
187 }
188 return NULL;
189 }
190
191
192
193
194
195 static struct mfc_cache *ipmr_cache_alloc(int priority)
196 {
197 struct mfc_cache *c=(struct mfc_cache *)kmalloc(sizeof(struct mfc_cache), priority);
198 if(c==NULL)
199 return NULL;
200 c->mfc_queuelen=0;
201 skb_queue_head_init(&c->mfc_unresolved);
202 init_timer(&c->mfc_timer);
203 c->mfc_timer.data=(long)c;
204 c->mfc_timer.function=ipmr_cache_timer;
205 return c;
206 }
207
208
209
210
211
212 static void ipmr_cache_resolve(struct mfc_cache *cache)
213 {
214 struct mfc_cache **p;
215 struct sk_buff *skb;
216
217
218
219 del_timer(&cache->mfc_timer);
220 cache->mfc_flags&=~MFC_QUEUED;
221
222
223
224 p=&cache_resolve_queue;
225 while((*p)!=NULL)
226 {
227 if((*p)==cache)
228 {
229 *p=cache->next;
230 break;
231 }
232 p=&((*p)->next);
233 }
234 cache_resolve_queue_len--;
235 sti();
236
237
238
239 ipmr_cache_insert(cache);
240
241
242
243 while((skb=skb_dequeue(&cache->mfc_unresolved)))
244 ipmr_forward(skb, skb->protocol);
245 }
246
247
248
249
250
251
252 static void ipmr_cache_report(struct sk_buff *pkt)
253 {
254 struct sk_buff *skb=alloc_skb(128, GFP_ATOMIC);
255 int ihl=pkt->ip_hdr->ihl<<2;
256 struct igmphdr *igmp;
257 if(!skb)
258 return;
259
260 skb->free=1;
261
262
263
264
265
266 skb->ip_hdr=(struct iphdr *)skb_put(skb,ihl);
267 skb->h.iph=skb->ip_hdr;
268 memcpy(skb->data,pkt->data,ihl);
269 skb->ip_hdr->protocol = 0;
270
271
272
273
274
275 igmp=(struct igmphdr *)skb_put(skb,sizeof(struct igmphdr));
276 igmp->type = IGMPMSG_NOCACHE;
277 igmp->code = 0;
278 skb->ip_hdr->tot_len=htons(skb->len);
279
280
281
282
283 if(sock_queue_rcv_skb(mroute_socket,skb)<0)
284 {
285 skb->sk=NULL;
286 kfree_skb(skb, FREE_READ);
287 }
288 }
289
290
291
292
293
294
295 static void ipmr_cache_unresolved(struct mfc_cache *cache, vifi_t vifi, struct sk_buff *skb, int is_frag)
296 {
297 if(cache==NULL)
298 {
299
300
301
302 if(cache_resolve_queue_len>=10 || (cache=ipmr_cache_alloc(GFP_ATOMIC))==NULL)
303 {
304 kfree_skb(skb, FREE_WRITE);
305 return;
306 }
307
308
309
310 cache->mfc_parent=vifi;
311 cache->mfc_origin=skb->ip_hdr->saddr;
312 cache->mfc_mcastgrp=skb->ip_hdr->daddr;
313 cache->mfc_flags=MFC_QUEUED;
314
315
316
317 cache->next=cache_resolve_queue;
318 cache_resolve_queue=cache;
319 cache_resolve_queue_len++;
320
321
322
323 cache->mfc_timer.expires=jiffies+10*HZ;
324 add_timer(&cache->mfc_timer);
325
326
327
328 if(mroute_socket)
329 ipmr_cache_report(skb);
330 }
331
332
333
334 if(cache->mfc_queuelen>3)
335 {
336 kfree_skb(skb, FREE_WRITE);
337 return;
338 }
339
340
341
342
343 cache->mfc_queuelen++;
344 skb->protocol=is_frag;
345 skb_queue_tail(&cache->mfc_unresolved,skb);
346 }
347
348
349
350
351
352 int ipmr_mfc_modify(int action, struct mfcctl *mfc)
353 {
354 struct mfc_cache *cache;
355 if(!MULTICAST(mfc->mfcc_mcastgrp.s_addr))
356 return -EINVAL;
357
358
359
360
361 cli();
362
363 cache=ipmr_cache_find(mfc->mfcc_origin.s_addr,mfc->mfcc_mcastgrp.s_addr);
364
365
366
367
368 if(action==MRT_DEL_MFC)
369 {
370 if(cache)
371 {
372 ipmr_cache_delete(cache);
373 sti();
374 return 0;
375 }
376 sti();
377 return -ENOENT;
378 }
379 if(cache)
380 {
381
382
383
384
385 cache->mfc_flags|=MFC_RESOLVED;
386 memcpy(cache->mfc_ttls, mfc->mfcc_ttls,sizeof(cache->mfc_ttls));
387
388
389
390
391
392
393 if(cache->mfc_flags&MFC_QUEUED)
394 ipmr_cache_resolve(cache);
395 sti();
396 return 0;
397 }
398
399
400
401
402
403 cache=ipmr_cache_alloc(GFP_ATOMIC);
404 if(cache==NULL)
405 {
406 sti();
407 return -ENOMEM;
408 }
409 cache->mfc_flags=MFC_RESOLVED;
410 cache->mfc_origin=mfc->mfcc_origin.s_addr;
411 cache->mfc_mcastgrp=mfc->mfcc_mcastgrp.s_addr;
412 cache->mfc_parent=mfc->mfcc_parent;
413 memcpy(cache->mfc_ttls, mfc->mfcc_ttls,sizeof(cache->mfc_ttls));
414 ipmr_cache_insert(cache);
415 sti();
416 return 0;
417 }
418
419
420
421
422
423
424
425
426 int ip_mroute_setsockopt(struct sock *sk,int optname,char *optval,int optlen)
427 {
428 int err;
429 struct vifctl vif;
430 struct mfcctl mfc;
431
432 if(optname!=MRT_INIT)
433 {
434 if(sk!=mroute_socket)
435 return -EACCES;
436 }
437
438 switch(optname)
439 {
440 case MRT_INIT:
441 if(sk->type!=SOCK_RAW || sk->num!=IPPROTO_IGMP)
442 return -EOPNOTSUPP;
443 if(optlen!=sizeof(int))
444 return -ENOPROTOOPT;
445 if((err=verify_area(VERIFY_READ,optval,sizeof(int)))<0)
446 return err;
447 if(get_user((int *)optval)!=1)
448 return -ENOPROTOOPT;
449 if(mroute_socket)
450 return -EADDRINUSE;
451 mroute_socket=sk;
452
453 return 0;
454 case MRT_DONE:
455 mroute_close(sk);
456 mroute_socket=NULL;
457 return 0;
458 case MRT_ADD_VIF:
459 case MRT_DEL_VIF:
460 if(optlen!=sizeof(vif))
461 return -EINVAL;
462 if((err=verify_area(VERIFY_READ, optval, sizeof(vif)))<0)
463 return err;
464 memcpy_fromfs(&vif,optval,sizeof(vif));
465 if(vif.vifc_vifi > MAXVIFS)
466 return -ENFILE;
467 if(optname==MRT_ADD_VIF)
468 {
469 struct vif_device *v=&vif_table[vif.vifc_vifi];
470 struct device *dev;
471
472 if(vifc_map&(1<<vif.vifc_vifi))
473 return -EADDRINUSE;
474
475 dev=ip_dev_find(vif.vifc_lcl_addr.s_addr);
476 if(!dev)
477 return -EADDRNOTAVAIL;
478
479 if(vif.vifc_flags&VIFF_TUNNEL)
480 {
481 if(vif.vifc_flags&VIFF_SRCRT)
482 return -EOPNOTSUPP;
483
484 }
485 else
486 {
487 if(dev->flags&IFF_MULTICAST)
488 {
489
490
491 dev->flags|=IFF_ALLMULTI;
492 dev_mc_upload(dev);
493 }
494 else
495 {
496
497 return -EOPNOTSUPP;
498 }
499 }
500
501
502
503 cli();
504 v->rate_limit=vif.vifc_rate_limit;
505 v->local=vif.vifc_lcl_addr.s_addr;
506 v->remote=vif.vifc_rmt_addr.s_addr;
507 v->flags=vif.vifc_flags;
508 v->threshold=vif.vifc_threshold;
509 v->dev=dev;
510 v->bytes_in = 0;
511 v->bytes_out = 0;
512 v->pkt_in = 0;
513 v->pkt_out = 0;
514 vifc_map|=(1<<vif.vifc_vifi);
515 sti();
516 return 0;
517 }
518 else
519
520
521
522 {
523 struct vif_device *v=&vif_table[vif.vifc_vifi];
524 if(vifc_map&(1<<vif.vifc_vifi))
525 {
526 vif_delete(v);
527 vifc_map&=~(1<<vif.vifc_vifi);
528 return 0;
529 }
530 else
531 return -EADDRNOTAVAIL;
532 }
533
534
535
536
537 case MRT_ADD_MFC:
538 case MRT_DEL_MFC:
539 err=verify_area(VERIFY_READ, optval, sizeof(mfc));
540 if(err)
541 return err;
542 memcpy_fromfs(&mfc,optval, sizeof(mfc));
543 return ipmr_mfc_modify(optname, &mfc);
544
545
546
547 case MRT_ASSERT:
548 if(optlen!=sizeof(int))
549 return -EINVAL;
550 if((err=verify_area(VERIFY_READ, optval,sizeof(int)))<0)
551 return err;
552 mroute_do_pim= (optval)?1:0;
553 return 0;
554
555
556
557
558 default:
559 return -EOPNOTSUPP;
560 }
561 }
562
563
564
565
566
567 int ip_mroute_getsockopt(struct sock *sk,int optname,char *optval,int *optlen)
568 {
569 int olr;
570 int err;
571
572 if(sk!=mroute_socket)
573 return -EACCES;
574 if(optname!=MRT_VERSION && optname!=MRT_ASSERT)
575 return -EOPNOTSUPP;
576
577 olr=get_user(optlen);
578 if(olr!=sizeof(int))
579 return -EINVAL;
580 err=verify_area(VERIFY_WRITE, optval,sizeof(int));
581 if(err)
582 return err;
583 put_user(sizeof(int),optlen);
584 if(optname==MRT_VERSION)
585 put_user(0x0305,(int *)optval);
586 else
587 put_user(mroute_do_pim,(int *)optval);
588 return 0;
589 }
590
591
592
593
594
595 int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg)
596 {
597 int err;
598 struct sioc_sg_req sr;
599 struct sioc_vif_req vr;
600 struct vif_device *vif;
601
602 switch(cmd)
603 {
604 case SIOCGETVIFCNT:
605 err=verify_area(VERIFY_WRITE, (void *)arg, sizeof(vr));
606 if(err)
607 return err;
608 memcpy_fromfs(&vr,(void *)arg,sizeof(vr));
609 if(vr.vifi>=MAXVIFS)
610 return -EINVAL;
611 vif=&vif_table[vr.vifi];
612 if(vifc_map&(1<<vr.vifi))
613 {
614 vr.icount=vif->pkt_in;
615 vr.ocount=vif->pkt_out;
616 vr.ibytes=vif->bytes_in;
617 vr.obytes=vif->bytes_out;
618 memcpy_tofs((void *)arg,&vr,sizeof(vr));
619 return 0;
620 }
621 return -EADDRNOTAVAIL;
622 case SIOCGETSGCNT:
623 err=verify_area(VERIFY_WRITE, (void *)arg, sizeof(sr));
624 if(err)
625 return err;
626 memcpy_fromfs(&sr,(void *)arg,sizeof(sr));
627 memcpy_tofs((void *)arg,&sr,sizeof(sr));
628 return 0;
629 default:
630 return -EINVAL;
631 }
632 }
633
634
635
636
637
638 void mroute_close(struct sock *sk)
639 {
640 int i;
641 struct vif_device *v=&vif_table[0];
642
643
644
645
646
647 for(i=0;i<MAXVIFS;i++)
648 {
649 if(vifc_map&(1<<i))
650 {
651 if(!(v->flags&VIFF_TUNNEL))
652 {
653 v->dev->flags&=~IFF_ALLMULTI;
654 dev_mc_upload(v->dev);
655 }
656 }
657 v++;
658 }
659 vifc_map=0;
660
661
662
663 for(i=0;i<MFC_LINES;i++)
664 {
665 while(mfc_cache_array[i]!=NULL)
666 ipmr_cache_delete(mfc_cache_array[i]);
667 }
668
669 }
670
671 static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
672 {
673 struct vif_device *v;
674 int ct;
675 if(event!=NETDEV_DOWN)
676 return NOTIFY_DONE;
677 v=&vif_table[0];
678 for(ct=0;ct<MAXVIFS;ct++)
679 {
680 if((vifc_map&(1<<ct)) && v->dev==ptr)
681 {
682 vif_delete(v);
683 vifc_map&=~(1<<ct);
684 }
685 v++;
686 }
687 return NOTIFY_DONE;
688 }
689
690
691 static struct notifier_block ip_mr_notifier={
692 ipmr_device_event,
693 NULL,
694 0
695 };
696
697
698
699
700
701 static void ipmr_queue_xmit(struct sk_buff *skb, struct vif_device *vif, struct device *in_dev, int frag)
702 {
703 int tunnel=0;
704 __u32 raddr=skb->raddr;
705 if(vif->flags&VIFF_TUNNEL)
706 {
707 tunnel=16;
708 raddr=vif->remote;
709 }
710 vif->pkt_out++;
711 vif->bytes_out+=skb->len;
712 skb->dev=vif->dev;
713 skb->raddr=skb->h.iph->daddr;
714 if(ip_forward(skb, in_dev, frag|8|tunnel, raddr)==-1)
715 kfree_skb(skb, FREE_WRITE);
716 }
717
718
719
720
721
722 void ipmr_forward(struct sk_buff *skb, int is_frag)
723 {
724 struct mfc_cache *cache;
725 struct sk_buff *skb2;
726 int psend = -1;
727 int vif=ipmr_vifi_find(skb->dev);
728 if(vif==-1)
729 {
730 kfree_skb(skb, FREE_WRITE);
731 return;
732 }
733
734 vif_table[vif].pkt_in++;
735 vif_table[vif].bytes_in+=skb->len;
736
737 cache=ipmr_cache_find(skb->ip_hdr->saddr,skb->ip_hdr->daddr);
738
739
740
741
742
743 if(cache==NULL || (cache->mfc_flags&MFC_QUEUED))
744 ipmr_cache_unresolved(cache,vif,skb, is_frag);
745 else
746 {
747
748
749
750 int ct=0;
751 while(ct<MAXVIFS)
752 {
753
754
755
756 if(skb->ip_hdr->ttl > cache->mfc_ttls[ct] && cache->mfc_ttls[ct]>0)
757 {
758 if(psend!=-1)
759 {
760 skb2=skb_clone(skb, GFP_ATOMIC);
761 if(skb2)
762 {
763 skb2->free=1;
764 ipmr_queue_xmit(skb2, &vif_table[psend], skb->dev, is_frag);
765 }
766 }
767 psend=ct;
768 }
769 ct++;
770 }
771 if(psend==-1)
772 kfree_skb(skb, FREE_WRITE);
773 else
774 {
775 ipmr_queue_xmit(skb, &vif_table[psend], skb->dev, is_frag);
776 }
777
778
779
780 }
781 }
782
783
784
785
786
787 int ipmr_vif_info(char *buffer, char **start, off_t offset, int length, int dummy)
788 {
789 struct vif_device *vif;
790 int len=0;
791 off_t pos=0;
792 off_t begin=0;
793 int size;
794 int ct;
795
796 len += sprintf(buffer,
797 "Interface Bytes In Pkts In Bytes Out Pkts Out Flags Local Remote\n");
798 pos=len;
799
800 for (ct=0;ct<MAXVIFS;ct++)
801 {
802 vif=&vif_table[ct];
803 if(!(vifc_map&(1<<ct)))
804 continue;
805 if(vif->dev==NULL)
806 continue;
807 size = sprintf(buffer+len, "%-10s %8ld %7ld %8ld %7ld %05X %08lX %08lX\n",
808 vif->dev->name,vif->bytes_in, vif->pkt_in, vif->bytes_out,vif->pkt_out,
809 vif->flags, vif->local, vif->remote);
810 len+=size;
811 pos+=size;
812 if(pos<offset)
813 {
814 len=0;
815 begin=pos;
816 }
817 if(pos>offset+length)
818 break;
819 }
820
821 *start=buffer+(offset-begin);
822 len-=(offset-begin);
823 if(len>length)
824 len=length;
825 return len;
826 }
827
828 int ipmr_mfc_info(char *buffer, char **start, off_t offset, int length, int dummy)
829 {
830 struct mfc_cache *mfc;
831 int len=0;
832 off_t pos=0;
833 off_t begin=0;
834 int size;
835 int ct;
836
837 len += sprintf(buffer,
838 "Group Origin SrcIface \n");
839 pos=len;
840
841 for (ct=0;ct<MFC_LINES;ct++)
842 {
843 cli();
844 mfc=mfc_cache_array[ct];
845 while(mfc!=NULL)
846 {
847 char *name="none";
848 char vifmap[MAXVIFS+1];
849 int n;
850
851
852
853 if(vifc_map&(1<<mfc->mfc_parent))
854 name=vif_table[mfc->mfc_parent].dev->name;
855
856
857
858 for(n=0;n<MAXVIFS;n++)
859 if(vifc_map&(1<<n) && mfc->mfc_ttls[ct])
860 vifmap[n]='X';
861 else
862 vifmap[n]='-';
863 vifmap[n]=0;
864
865
866
867 size = sprintf(buffer+len, "%08lX %08lX %-8s %s\n",
868 (unsigned long)mfc->mfc_mcastgrp,
869 (unsigned long)mfc->mfc_origin,
870 name,
871 vifmap);
872 len+=size;
873 pos+=size;
874 if(pos<offset)
875 {
876 len=0;
877 begin=pos;
878 }
879 if(pos>offset+length)
880 {
881 sti();
882 goto done;
883 }
884 mfc=mfc->next;
885 }
886 sti();
887 }
888 done:
889 *start=buffer+(offset-begin);
890 len-=(offset-begin);
891 if(len>length)
892 len=length;
893 return len;
894 }
895
896
897
898
899
900 void ip_mr_init(void)
901 {
902 printk("Linux IP multicast router 0.04-might-work 8)\n");
903 register_netdevice_notifier(&ip_mr_notifier);
904 proc_net_register(&(struct proc_dir_entry) {
905 PROC_NET_IPMR_VIF, 9 ,"ip_mr_vif",
906 S_IFREG | S_IRUGO, 1, 0, 0,
907 0, &proc_net_inode_operations,
908 ipmr_vif_info
909 });
910 proc_net_register(&(struct proc_dir_entry) {
911 PROC_NET_IPMR_MFC, 11 ,"ip_mr_cache",
912 S_IFREG | S_IRUGO, 1, 0, 0,
913 0, &proc_net_inode_operations,
914 ipmr_mfc_info
915 });
916 }