This source file includes following definitions.
- ip_loopback
- ip_send
- ip_send_room
- ip_build_header
- ip_send_check
- ip_queue_xmit
- ip_build_xmit
- ip_netlink_msg
- ip_rt_event
- ip_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
28 #include <asm/segment.h>
29 #include <asm/system.h>
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/sched.h>
33 #include <linux/mm.h>
34 #include <linux/string.h>
35 #include <linux/errno.h>
36 #include <linux/config.h>
37
38 #include <linux/socket.h>
39 #include <linux/sockios.h>
40 #include <linux/in.h>
41 #include <linux/inet.h>
42 #include <linux/netdevice.h>
43 #include <linux/etherdevice.h>
44 #include <linux/proc_fs.h>
45 #include <linux/stat.h>
46
47 #include <net/snmp.h>
48 #include <net/ip.h>
49 #include <net/protocol.h>
50 #include <net/route.h>
51 #include <net/tcp.h>
52 #include <net/udp.h>
53 #include <linux/skbuff.h>
54 #include <net/sock.h>
55 #include <net/arp.h>
56 #include <net/icmp.h>
57 #include <net/raw.h>
58 #include <net/checksum.h>
59 #include <linux/igmp.h>
60 #include <linux/ip_fw.h>
61 #include <linux/firewall.h>
62 #include <linux/mroute.h>
63 #include <net/netlink.h>
64
65
66
67
68
69 static void ip_loopback(struct device *old_dev, struct sk_buff *skb)
70 {
71 struct device *dev=&loopback_dev;
72 int len=ntohs(skb->ip_hdr->tot_len);
73 struct sk_buff *newskb=dev_alloc_skb(len+dev->hard_header_len+15);
74
75 if(newskb==NULL)
76 return;
77
78 newskb->link3=NULL;
79 newskb->sk=NULL;
80 newskb->dev=dev;
81 newskb->saddr=skb->saddr;
82 newskb->daddr=skb->daddr;
83 newskb->raddr=skb->raddr;
84 newskb->free=1;
85 newskb->lock=0;
86 newskb->users=0;
87 newskb->pkt_type=skb->pkt_type;
88
89
90
91
92 ip_send(NULL,newskb, skb->ip_hdr->daddr, len, dev, skb->ip_hdr->saddr);
93
94
95
96 newskb->ip_hdr=(struct iphdr *)skb_put(newskb, len);
97 memcpy(newskb->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
98
99
100
101
102 memcpy(newskb->ip_hdr,skb->ip_hdr,len);
103
104
105
106
107 ip_queue_xmit(NULL, dev, newskb, 1);
108 }
109
110
111
112
113
114
115
116 int ip_send(struct rtable * rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr)
117 {
118 int mac = 0;
119
120 skb->dev = dev;
121 skb->arp = 1;
122 skb->protocol = htons(ETH_P_IP);
123 if (dev->hard_header)
124 {
125
126
127
128
129 skb_reserve(skb,(dev->hard_header_len+15)&~15);
130 if (rt && dev == rt->rt_dev && rt->rt_hh)
131 {
132 memcpy(skb_push(skb,dev->hard_header_len),rt->rt_hh->hh_data,dev->hard_header_len);
133 if (rt->rt_hh->hh_uptodate)
134 return dev->hard_header_len;
135 #if RT_CACHE_DEBUG >= 2
136 printk("ip_send: hh miss %08x via %08x\n", daddr, rt->rt_gateway);
137 #endif
138 skb->arp = 0;
139 skb->raddr = daddr;
140 return dev->hard_header_len;
141 }
142 mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
143 if (mac < 0)
144 {
145 mac = -mac;
146 skb->arp = 0;
147 skb->raddr = daddr;
148 }
149 }
150 return mac;
151 }
152
153 static int ip_send_room(struct rtable * rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr)
154 {
155 int mac = 0;
156
157 skb->dev = dev;
158 skb->arp = 1;
159 skb->protocol = htons(ETH_P_IP);
160 if (dev->hard_header)
161 {
162 skb_reserve(skb,MAX_HEADER);
163 if (rt && dev == rt->rt_dev && rt->rt_hh)
164 {
165 memcpy(skb_push(skb,dev->hard_header_len),rt->rt_hh->hh_data,dev->hard_header_len);
166 if (rt->rt_hh->hh_uptodate)
167 return dev->hard_header_len;
168 #if RT_CACHE_DEBUG >= 2
169 printk("ip_send_room: hh miss %08x via %08x\n", daddr, rt->rt_gateway);
170 #endif
171 skb->arp = 0;
172 skb->raddr = daddr;
173 return dev->hard_header_len;
174 }
175 mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
176 if (mac < 0)
177 {
178 mac = -mac;
179 skb->arp = 0;
180 skb->raddr = daddr;
181 }
182 }
183 return mac;
184 }
185
186 int ip_id_count = 0;
187
188
189
190
191
192
193
194 int ip_build_header(struct sk_buff *skb, __u32 saddr, __u32 daddr,
195 struct device **dev, int type, struct options *opt,
196 int len, int tos, int ttl, struct rtable ** rp)
197 {
198 struct rtable *rt;
199 __u32 raddr;
200 int tmp;
201 struct iphdr *iph;
202 __u32 final_daddr = daddr;
203
204
205 if (opt && opt->srr)
206 daddr = opt->faddr;
207
208
209
210
211
212 #ifdef CONFIG_IP_MULTICAST
213 if(MULTICAST(daddr) && *dev==NULL && skb->sk && *skb->sk->ip_mc_name)
214 *dev=dev_get(skb->sk->ip_mc_name);
215 #endif
216 if (rp)
217 {
218 rt = ip_check_route(rp, daddr, skb->localroute);
219
220
221
222
223 if (rt)
224 ATOMIC_INCR(&rt->rt_refcnt);
225 }
226 else
227 rt = ip_rt_route(daddr, skb->localroute);
228
229
230 if (*dev == NULL)
231 {
232 if (rt == NULL)
233 {
234 ip_statistics.IpOutNoRoutes++;
235 return(-ENETUNREACH);
236 }
237
238 *dev = rt->rt_dev;
239 }
240
241 if ((LOOPBACK(saddr) && !LOOPBACK(daddr)) || !saddr)
242 saddr = rt ? rt->rt_src : (*dev)->pa_addr;
243
244 raddr = rt ? rt->rt_gateway : daddr;
245
246 if (opt && opt->is_strictroute && rt && (rt->rt_flags & RTF_GATEWAY))
247 {
248 ip_rt_put(rt);
249 ip_statistics.IpOutNoRoutes++;
250 return -ENETUNREACH;
251 }
252
253
254
255
256
257 if (type==IPPROTO_TCP)
258 tmp = ip_send_room(rt, skb, raddr, len, *dev, saddr);
259 else
260 tmp = ip_send(rt, skb, raddr, len, *dev, saddr);
261
262 ip_rt_put(rt);
263
264
265
266
267
268 skb->dev = *dev;
269 skb->saddr = saddr;
270
271
272
273
274
275
276
277
278
279
280 if(type == IPPROTO_RAW)
281 return (tmp);
282
283
284
285
286
287 if (opt)
288 iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr) + opt->optlen);
289 else
290 iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr));
291
292 iph->version = 4;
293 iph->ihl = 5;
294 iph->tos = tos;
295 iph->frag_off = 0;
296 iph->ttl = ttl;
297 iph->daddr = daddr;
298 iph->saddr = saddr;
299 iph->protocol = type;
300 skb->ip_hdr = iph;
301
302 if (!opt || !opt->optlen)
303 return sizeof(struct iphdr) + tmp;
304 iph->ihl += opt->optlen>>2;
305 ip_options_build(skb, opt, final_daddr, (*dev)->pa_addr, 0);
306 return iph->ihl*4 + tmp;
307 }
308
309
310
311
312
313
314 void ip_send_check(struct iphdr *iph)
315 {
316 iph->check = 0;
317 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
318 }
319
320
321
322
323
324
325
326
327
328
329 void ip_queue_xmit(struct sock *sk, struct device *dev,
330 struct sk_buff *skb, int free)
331 {
332 struct iphdr *iph;
333
334
335
336 if (dev == NULL)
337 {
338 NETDEBUG(printk("IP: ip_queue_xmit dev = NULL\n"));
339 return;
340 }
341
342 IS_SKB(skb);
343
344
345
346
347
348
349 skb->dev = dev;
350 skb->when = jiffies;
351
352
353
354
355
356
357
358
359
360 iph = skb->ip_hdr;
361 iph->tot_len = htons(skb->len-(((unsigned char *)iph)-skb->data));
362
363 #ifdef CONFIG_FIREWALL
364 if(call_out_firewall(PF_INET, skb->dev, iph) < FW_ACCEPT)
365
366 return;
367 #endif
368
369
370
371
372
373 if(free!=2)
374 iph->id = htons(ip_id_count++);
375 else
376 free=1;
377
378
379 if (sk == NULL)
380 free = 1;
381
382 skb->free = free;
383
384
385
386
387
388
389
390 if(ntohs(iph->tot_len)> dev->mtu)
391 {
392 ip_fragment(sk,skb,dev,0);
393 IS_SKB(skb);
394 kfree_skb(skb,FREE_WRITE);
395 return;
396 }
397
398
399
400
401
402 ip_send_check(iph);
403
404
405
406
407
408
409
410
411
412 if (skb->next != NULL)
413 {
414 NETDEBUG(printk("ip_queue_xmit: next != NULL\n"));
415 skb_unlink(skb);
416 }
417
418
419
420
421
422
423
424
425 if (!free)
426 {
427 unsigned long flags;
428
429
430 sk->packets_out++;
431
432
433 save_flags(flags);
434 cli();
435
436 if (skb->link3 != NULL)
437 {
438 NETDEBUG(printk("ip.c: link3 != NULL\n"));
439 skb->link3 = NULL;
440 }
441 if (sk->send_head == NULL)
442 {
443 sk->send_tail = skb;
444 sk->send_head = skb;
445 }
446 else
447 {
448 sk->send_tail->link3 = skb;
449 sk->send_tail = skb;
450 }
451
452
453
454 restore_flags(flags);
455 }
456 else
457
458 skb->sk = sk;
459
460
461
462
463
464 ip_statistics.IpOutRequests++;
465 #ifdef CONFIG_IP_ACCT
466 ip_fw_chk(iph,dev,ip_acct_chain,IP_FW_F_ACCEPT,1);
467 #endif
468
469 #ifdef CONFIG_IP_MULTICAST
470
471
472
473
474
475 if (MULTICAST(iph->daddr) && !(dev->flags&IFF_LOOPBACK))
476 {
477 if(sk==NULL || sk->ip_mc_loop)
478 {
479 if(iph->daddr==IGMP_ALL_HOSTS || (dev->flags&IFF_ALLMULTI))
480 {
481 ip_loopback(dev,skb);
482 }
483 else
484 {
485 struct ip_mc_list *imc=dev->ip_mc_list;
486 while(imc!=NULL)
487 {
488 if(imc->multiaddr==iph->daddr)
489 {
490 ip_loopback(dev,skb);
491 break;
492 }
493 imc=imc->next;
494 }
495 }
496 }
497
498
499 if(skb->ip_hdr->ttl==0)
500 {
501 kfree_skb(skb, FREE_READ);
502 return;
503 }
504 }
505 #endif
506 if((dev->flags&IFF_BROADCAST) && (iph->daddr==dev->pa_brdaddr||iph->daddr==0xFFFFFFFF) && !(dev->flags&IFF_LOOPBACK))
507 ip_loopback(dev,skb);
508
509 if (dev->flags & IFF_UP)
510 {
511
512
513
514
515
516 if (sk != NULL)
517 {
518 dev_queue_xmit(skb, dev, sk->priority);
519 }
520 else
521 {
522 dev_queue_xmit(skb, dev, SOPRI_NORMAL);
523 }
524 }
525 else
526 {
527 if(sk)
528 sk->err = ENETDOWN;
529 ip_statistics.IpOutDiscards++;
530 if (free)
531 kfree_skb(skb, FREE_WRITE);
532 }
533 }
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556 int ip_build_xmit(struct sock *sk,
557 void getfrag (const void *,
558 __u32,
559 char *,
560 unsigned int,
561 unsigned int),
562 const void *frag,
563 unsigned short int length,
564 __u32 daddr,
565 __u32 user_saddr,
566 struct options * opt,
567 int flags,
568 int type,
569 int noblock)
570 {
571 struct rtable *rt;
572 unsigned int fraglen, maxfraglen, fragheaderlen;
573 int offset, mf;
574 __u32 saddr;
575 unsigned short id;
576 struct iphdr *iph;
577 __u32 raddr;
578 struct device *dev = NULL;
579 struct hh_cache * hh=NULL;
580 int nfrags=0;
581 __u32 true_daddr = daddr;
582
583 if (opt && opt->srr && !sk->ip_hdrincl)
584 daddr = opt->faddr;
585
586 ip_statistics.IpOutRequests++;
587
588 #ifdef CONFIG_IP_MULTICAST
589 if(sk && MULTICAST(daddr) && *sk->ip_mc_name)
590 {
591 dev=dev_get(sk->ip_mc_name);
592 if(!dev)
593 return -ENODEV;
594 rt=NULL;
595 if (sk->saddr && (!LOOPBACK(sk->saddr) || LOOPBACK(daddr)))
596 saddr = sk->saddr;
597 else
598 saddr = dev->pa_addr;
599 }
600 else
601 {
602 #endif
603 rt = ip_check_route(&sk->ip_route_cache, daddr,
604 sk->localroute || (flags&MSG_DONTROUTE) ||
605 (opt && opt->is_strictroute));
606 if (rt == NULL)
607 {
608 ip_statistics.IpOutNoRoutes++;
609 return(-ENETUNREACH);
610 }
611 saddr = rt->rt_src;
612
613 hh = rt->rt_hh;
614
615 if (sk->saddr && (!LOOPBACK(sk->saddr) || LOOPBACK(daddr)))
616 saddr = sk->saddr;
617
618 dev=rt->rt_dev;
619 #ifdef CONFIG_IP_MULTICAST
620 }
621 if (rt && !dev)
622 dev = rt->rt_dev;
623 #endif
624 if (user_saddr)
625 saddr = user_saddr;
626
627 raddr = rt ? rt->rt_gateway : daddr;
628
629
630
631
632
633
634
635
636
637 length += sizeof(struct iphdr);
638 if (!sk->ip_hdrincl && opt)
639 length += opt->optlen;
640
641 if(length <= dev->mtu && !MULTICAST(daddr) && daddr!=0xFFFFFFFF && daddr!=dev->pa_brdaddr)
642 {
643 int error;
644 struct sk_buff *skb=sock_alloc_send_skb(sk, length+15+dev->hard_header_len,0, noblock, &error);
645 if(skb==NULL)
646 {
647 ip_statistics.IpOutDiscards++;
648 return error;
649 }
650 skb->dev=dev;
651 skb->protocol = htons(ETH_P_IP);
652 skb->free=1;
653 skb->when=jiffies;
654 skb->sk=sk;
655 skb->arp=0;
656 skb->saddr=saddr;
657 skb->raddr = raddr;
658 skb_reserve(skb,(dev->hard_header_len+15)&~15);
659 if (hh)
660 {
661 skb->arp=1;
662 memcpy(skb_push(skb,dev->hard_header_len),hh->hh_data,dev->hard_header_len);
663 if (!hh->hh_uptodate)
664 {
665 skb->arp = 0;
666 #if RT_CACHE_DEBUG >= 2
667 printk("ip_build_xmit: hh miss %08x via %08x\n", rt->rt_dst, rt->rt_gateway);
668 #endif
669 }
670 }
671 else if(dev->hard_header)
672 {
673 if(dev->hard_header(skb,dev,ETH_P_IP,NULL,NULL,0)>0)
674 skb->arp=1;
675 }
676 else
677 skb->arp=1;
678 skb->ip_hdr=iph=(struct iphdr *)skb_put(skb,length);
679 dev_lock_list();
680 if(!sk->ip_hdrincl)
681 {
682 iph->version=4;
683 iph->ihl=5;
684 iph->tos=sk->ip_tos;
685 iph->tot_len = htons(length);
686 iph->id=htons(ip_id_count++);
687 iph->frag_off = 0;
688 iph->ttl=sk->ip_ttl;
689 iph->protocol=type;
690 iph->saddr=saddr;
691 iph->daddr=daddr;
692 if (opt)
693 {
694 iph->ihl += opt->optlen>>2;
695 ip_options_build(skb, opt,
696 true_daddr, dev->pa_addr, 0);
697 }
698 iph->check=0;
699 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
700 getfrag(frag,saddr,((char *)iph)+iph->ihl*4,0, length-iph->ihl*4);
701 }
702 else
703 getfrag(frag,saddr,(void *)iph,0,length-20);
704 dev_unlock_list();
705 #ifdef CONFIG_FIREWALL
706 if(call_out_firewall(PF_INET, skb->dev, iph)< FW_ACCEPT)
707 {
708 kfree_skb(skb, FREE_WRITE);
709 return -EPERM;
710 }
711 #endif
712 #ifdef CONFIG_IP_ACCT
713 ip_fw_chk(iph,dev,ip_acct_chain, IP_FW_F_ACCEPT,1);
714 #endif
715 if(dev->flags&IFF_UP)
716 dev_queue_xmit(skb,dev,sk->priority);
717 else
718 {
719 ip_statistics.IpOutDiscards++;
720 kfree_skb(skb, FREE_WRITE);
721 }
722 return 0;
723 }
724 length -= sizeof(struct iphdr);
725 if (sk && !sk->ip_hdrincl && opt)
726 {
727 length -= opt->optlen;
728 fragheaderlen = dev->hard_header_len + sizeof(struct iphdr) + opt->optlen;
729 maxfraglen = ((dev->mtu-sizeof(struct iphdr)-opt->optlen) & ~7) + fragheaderlen;
730 }
731 else
732 {
733 fragheaderlen = dev->hard_header_len;
734 if(!sk->ip_hdrincl)
735 fragheaderlen += 20;
736
737
738
739
740
741
742 maxfraglen = ((dev->mtu-20) & ~7) + fragheaderlen;
743 }
744
745
746
747
748
749 offset = length - (length % (maxfraglen - fragheaderlen));
750
751
752
753
754
755 fraglen = length - offset + fragheaderlen;
756
757 if(length-offset==0)
758 {
759 fraglen = maxfraglen;
760 offset -= maxfraglen-fragheaderlen;
761 }
762
763
764
765
766
767
768 mf = 0;
769
770
771
772
773
774 if (sk->ip_hdrincl && offset > 0)
775 return(-EMSGSIZE);
776
777
778
779
780
781 dev_lock_list();
782
783
784
785
786
787 id = htons(ip_id_count++);
788
789
790
791
792
793 do
794 {
795 struct sk_buff * skb;
796 int error;
797 char *data;
798
799
800
801
802
803 skb = sock_alloc_send_skb(sk, fraglen+15, 0, noblock, &error);
804 if (skb == NULL)
805 {
806 ip_statistics.IpOutDiscards++;
807 if(nfrags>1)
808 ip_statistics.IpFragCreates++;
809 dev_unlock_list();
810 return(error);
811 }
812
813
814
815
816
817 skb->dev = dev;
818 skb->protocol = htons(ETH_P_IP);
819 skb->when = jiffies;
820 skb->free = 1;
821 skb->sk = sk;
822 skb->arp = 0;
823 skb->saddr = saddr;
824 skb->raddr = raddr;
825 skb_reserve(skb,(dev->hard_header_len+15)&~15);
826 data = skb_put(skb, fraglen-dev->hard_header_len);
827
828
829
830
831
832
833
834
835 if (hh)
836 {
837 skb->arp=1;
838 memcpy(skb_push(skb,dev->hard_header_len),hh->hh_data,dev->hard_header_len);
839 if (!hh->hh_uptodate)
840 {
841 skb->arp = 0;
842 #if RT_CACHE_DEBUG >= 2
843 printk("ip_build_xmit: hh miss %08x via %08x\n", rt->rt_dst, rt->rt_gateway);
844 #endif
845 }
846 }
847 else if (dev->hard_header)
848 {
849 if(dev->hard_header(skb, dev, ETH_P_IP,
850 NULL, NULL, 0)>0)
851 skb->arp=1;
852 }
853
854
855
856
857
858 skb->ip_hdr = iph = (struct iphdr *)data;
859
860
861
862
863
864 if(!sk->ip_hdrincl)
865 {
866
867 iph->version = 4;
868 iph->ihl = 5;
869 if (opt) {
870 iph->ihl += opt->optlen>>2;
871 ip_options_build(skb, opt,
872 true_daddr, dev->pa_addr, offset);
873 }
874 iph->tos = sk->ip_tos;
875 iph->tot_len = htons(fraglen - fragheaderlen + iph->ihl*4);
876 iph->id = id;
877 iph->frag_off = htons(offset>>3);
878 iph->frag_off |= mf;
879 #ifdef CONFIG_IP_MULTICAST
880 if (MULTICAST(daddr))
881 iph->ttl = sk->ip_mc_ttl;
882 else
883 #endif
884 iph->ttl = sk->ip_ttl;
885 iph->protocol = type;
886 iph->check = 0;
887 iph->saddr = saddr;
888 iph->daddr = daddr;
889 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
890 data += iph->ihl*4;
891
892
893
894
895
896 mf = htons(IP_MF);
897 }
898
899
900
901
902
903 getfrag(frag, saddr, data, offset, fraglen-fragheaderlen);
904
905
906
907
908
909 #ifdef CONFIG_FIREWALL
910 if(!offset && call_out_firewall(PF_INET, skb->dev, iph) < FW_ACCEPT)
911 {
912 kfree_skb(skb, FREE_WRITE);
913 dev_unlock_list();
914 return -EPERM;
915 }
916 #endif
917 #ifdef CONFIG_IP_ACCT
918 if(!offset)
919 ip_fw_chk(iph, dev, ip_acct_chain, IP_FW_F_ACCEPT, 1);
920 #endif
921 offset -= (maxfraglen-fragheaderlen);
922 fraglen = maxfraglen;
923
924 #ifdef CONFIG_IP_MULTICAST
925
926
927
928
929
930 if (MULTICAST(daddr) && !(dev->flags&IFF_LOOPBACK))
931 {
932
933
934
935
936
937
938
939 if(sk==NULL || sk->ip_mc_loop)
940 {
941 if(skb->daddr==IGMP_ALL_HOSTS || (dev->flags&IFF_ALLMULTI))
942 ip_loopback(dev,skb);
943 else
944 {
945 struct ip_mc_list *imc=dev->ip_mc_list;
946 while(imc!=NULL)
947 {
948 if(imc->multiaddr==daddr)
949 {
950 ip_loopback(dev,skb);
951 break;
952 }
953 imc=imc->next;
954 }
955 }
956 }
957
958
959
960
961
962
963 if(skb->ip_hdr->ttl==0)
964 kfree_skb(skb, FREE_READ);
965 }
966 #endif
967
968 nfrags++;
969
970
971
972
973
974 if((dev->flags&IFF_BROADCAST) && (daddr==0xFFFFFFFF || daddr==dev->pa_brdaddr) && !(dev->flags&IFF_LOOPBACK))
975 ip_loopback(dev,skb);
976
977
978
979
980
981 if (dev->flags & IFF_UP)
982 {
983 dev_queue_xmit(skb, dev, sk->priority);
984 }
985 else
986 {
987
988
989
990
991 ip_statistics.IpOutDiscards++;
992 if(nfrags>1)
993 ip_statistics.IpFragCreates+=nfrags;
994 kfree_skb(skb, FREE_WRITE);
995 dev_unlock_list();
996
997
998
999 if(sk!=NULL)
1000 sk->err=ENETDOWN;
1001 return(0);
1002 }
1003 }
1004 while (offset >= 0);
1005 if(nfrags>1)
1006 ip_statistics.IpFragCreates+=nfrags;
1007 dev_unlock_list();
1008 return(0);
1009 }
1010
1011
1012
1013
1014
1015
1016 static struct packet_type ip_packet_type =
1017 {
1018 0,
1019 NULL,
1020 ip_rcv,
1021 NULL,
1022 NULL,
1023 };
1024
1025 #ifdef CONFIG_RTNETLINK
1026
1027
1028
1029
1030
1031 void ip_netlink_msg(unsigned long msg, __u32 daddr, __u32 gw, __u32 mask, short flags, short metric, char *name)
1032 {
1033 struct sk_buff *skb=alloc_skb(sizeof(struct netlink_rtinfo), GFP_ATOMIC);
1034 struct netlink_rtinfo *nrt;
1035 struct sockaddr_in *s;
1036 if(skb==NULL)
1037 return;
1038 skb->free=1;
1039 nrt=(struct netlink_rtinfo *)skb_put(skb, sizeof(struct netlink_rtinfo));
1040 nrt->rtmsg_type=msg;
1041 s=(struct sockaddr_in *)&nrt->rtmsg_dst;
1042 s->sin_family=AF_INET;
1043 s->sin_addr.s_addr=daddr;
1044 s=(struct sockaddr_in *)&nrt->rtmsg_gateway;
1045 s->sin_family=AF_INET;
1046 s->sin_addr.s_addr=gw;
1047 s=(struct sockaddr_in *)&nrt->rtmsg_genmask;
1048 s->sin_family=AF_INET;
1049 s->sin_addr.s_addr=mask;
1050 nrt->rtmsg_flags=flags;
1051 nrt->rtmsg_metric=metric;
1052 strcpy(nrt->rtmsg_device,name);
1053 netlink_post(NETLINK_ROUTE, skb);
1054 }
1055
1056 #endif
1057
1058
1059
1060
1061
1062 static int ip_rt_event(struct notifier_block *this, unsigned long event, void *ptr)
1063 {
1064 struct device *dev=ptr;
1065 if(event==NETDEV_DOWN)
1066 {
1067 ip_netlink_msg(RTMSG_DELDEVICE, 0,0,0,0,0,dev->name);
1068 ip_rt_flush(dev);
1069 }
1070
1071
1072
1073 if(event==NETDEV_UP)
1074 {
1075 #ifdef CONFIG_IP_MULTICAST
1076 ip_mc_allhost(dev);
1077 #endif
1078 ip_netlink_msg(RTMSG_NEWDEVICE, 0,0,0,0,0,dev->name);
1079 }
1080 return NOTIFY_DONE;
1081 }
1082
1083 struct notifier_block ip_rt_notifier={
1084 ip_rt_event,
1085 NULL,
1086 0
1087 };
1088
1089
1090
1091
1092
1093 void ip_init(void)
1094 {
1095 ip_packet_type.type=htons(ETH_P_IP);
1096 dev_add_pack(&ip_packet_type);
1097
1098
1099 register_netdevice_notifier(&ip_rt_notifier);
1100
1101
1102
1103
1104
1105
1106 #ifdef CONFIG_IP_MULTICAST
1107 proc_net_register(&(struct proc_dir_entry) {
1108 PROC_NET_IGMP, 4, "igmp",
1109 S_IFREG | S_IRUGO, 1, 0, 0,
1110 0, &proc_net_inode_operations,
1111 ip_mc_procinfo
1112 });
1113 #endif
1114 }
1115