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