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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96#include <linux/module.h>
97#include <linux/types.h>
98#include <linux/sched.h>
99#include <linux/kernel.h>
100#include <asm/uaccess.h>
101#include <linux/skbuff.h>
102#include <linux/netdevice.h>
103#include <linux/in.h>
104#include <linux/tcp.h>
105#include <linux/udp.h>
106#include <linux/if_arp.h>
107#include <linux/mroute.h>
108#include <linux/init.h>
109
110#include <net/sock.h>
111#include <net/ip.h>
112#include <net/icmp.h>
113#include <net/protocol.h>
114#include <net/ipip.h>
115
116#define HASH_SIZE 16
117#define HASH(addr) ((addr^(addr>>4))&0xF)
118
119static int ipip_fb_tunnel_init(struct device *dev);
120static int ipip_tunnel_init(struct device *dev);
121
122static struct device ipip_fb_tunnel_dev = {
123 NULL, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipip_fb_tunnel_init,
124};
125
126static struct ip_tunnel ipip_fb_tunnel = {
127 NULL, &ipip_fb_tunnel_dev, {0, }, 0, 0, 0, 0, 0, 0, 0, {"tunl0", }
128};
129
130static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
131static struct ip_tunnel *tunnels_r[HASH_SIZE];
132static struct ip_tunnel *tunnels_l[HASH_SIZE];
133static struct ip_tunnel *tunnels_wc[1];
134static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
135
136static struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local)
137{
138 unsigned h0 = HASH(remote);
139 unsigned h1 = HASH(local);
140 struct ip_tunnel *t;
141
142 for (t = tunnels_r_l[h0^h1]; t; t = t->next) {
143 if (local == t->parms.iph.saddr &&
144 remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
145 return t;
146 }
147 for (t = tunnels_r[h0]; t; t = t->next) {
148 if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
149 return t;
150 }
151 for (t = tunnels_l[h1]; t; t = t->next) {
152 if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP))
153 return t;
154 }
155 if ((t = tunnels_wc[0]) != NULL && (t->dev->flags&IFF_UP))
156 return t;
157 return NULL;
158}
159
160static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
161{
162 u32 remote = t->parms.iph.daddr;
163 u32 local = t->parms.iph.saddr;
164 unsigned h = 0;
165 int prio = 0;
166
167 if (remote) {
168 prio |= 2;
169 h ^= HASH(remote);
170 }
171 if (local) {
172 prio |= 1;
173 h ^= HASH(local);
174 }
175 return &tunnels[prio][h];
176}
177
178
179static void ipip_tunnel_unlink(struct ip_tunnel *t)
180{
181 struct ip_tunnel **tp;
182
183 for (tp = ipip_bucket(t); *tp; tp = &(*tp)->next) {
184 if (t == *tp) {
185 *tp = t->next;
186 synchronize_bh();
187 break;
188 }
189 }
190}
191
192static void ipip_tunnel_link(struct ip_tunnel *t)
193{
194 struct ip_tunnel **tp = ipip_bucket(t);
195
196 t->next = *tp;
197 wmb();
198 *tp = t;
199}
200
201struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
202{
203 u32 remote = parms->iph.daddr;
204 u32 local = parms->iph.saddr;
205 struct ip_tunnel *t, **tp, *nt;
206 struct device *dev;
207 unsigned h = 0;
208 int prio = 0;
209
210 if (remote) {
211 prio |= 2;
212 h ^= HASH(remote);
213 }
214 if (local) {
215 prio |= 1;
216 h ^= HASH(local);
217 }
218 for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
219 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
220 return t;
221 }
222 if (!create)
223 return NULL;
224
225 MOD_INC_USE_COUNT;
226 dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL);
227 if (dev == NULL) {
228 MOD_DEC_USE_COUNT;
229 return NULL;
230 }
231 memset(dev, 0, sizeof(*dev) + sizeof(*t));
232 dev->priv = (void*)(dev+1);
233 nt = (struct ip_tunnel*)dev->priv;
234 nt->dev = dev;
235 dev->name = nt->parms.name;
236 dev->init = ipip_tunnel_init;
237 memcpy(&nt->parms, parms, sizeof(*parms));
238 if (dev->name[0] == 0) {
239 int i;
240 for (i=1; i<100; i++) {
241 sprintf(dev->name, "tunl%d", i);
242 if (dev_get(dev->name) == NULL)
243 break;
244 }
245 if (i==100)
246 goto failed;
247 memcpy(parms->name, dev->name, IFNAMSIZ);
248 }
249 if (register_netdevice(dev) < 0)
250 goto failed;
251
252 ipip_tunnel_link(nt);
253
254 return nt;
255
256failed:
257 kfree(dev);
258 MOD_DEC_USE_COUNT;
259 return NULL;
260}
261
262
263static void ipip_tunnel_destroy(struct device *dev)
264{
265 if (dev == &ipip_fb_tunnel_dev) {
266 tunnels_wc[0] = NULL;
267 synchronize_bh();
268 } else {
269 ipip_tunnel_unlink((struct ip_tunnel*)dev->priv);
270 kfree(dev);
271 MOD_DEC_USE_COUNT;
272 }
273}
274
275void ipip_err(struct sk_buff *skb, unsigned char *dp, int len)
276{
277#ifndef I_WISH_WORLD_WERE_PERFECT
278
279
280
281
282
283 struct iphdr *iph = (struct iphdr*)dp;
284 int type = skb->h.icmph->type;
285 int code = skb->h.icmph->code;
286 struct ip_tunnel *t;
287
288 if (len < sizeof(struct iphdr))
289 return;
290
291 switch (type) {
292 default:
293 case ICMP_PARAMETERPROB:
294 return;
295
296 case ICMP_DEST_UNREACH:
297 switch (code) {
298 case ICMP_SR_FAILED:
299 case ICMP_PORT_UNREACH:
300
301 return;
302 case ICMP_FRAG_NEEDED:
303
304 return;
305 default:
306
307
308
309
310 break;
311 }
312 break;
313 case ICMP_TIME_EXCEEDED:
314 if (code != ICMP_EXC_TTL)
315 return;
316 break;
317 }
318
319 t = ipip_tunnel_lookup(iph->daddr, iph->saddr);
320 if (t == NULL || t->parms.iph.daddr == 0)
321 return;
322 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
323 return;
324
325 if (jiffies - t->err_time < IPTUNNEL_ERR_TIMEO)
326 t->err_count++;
327 else
328 t->err_count = 1;
329 t->err_time = jiffies;
330 return;
331#else
332 struct iphdr *iph = (struct iphdr*)dp;
333 int hlen = iph->ihl<<2;
334 struct iphdr *eiph;
335 int type = skb->h.icmph->type;
336 int code = skb->h.icmph->code;
337 int rel_type = 0;
338 int rel_code = 0;
339 int rel_info = 0;
340 struct sk_buff *skb2;
341 struct rtable *rt;
342
343 if (len < hlen + sizeof(struct iphdr))
344 return;
345 eiph = (struct iphdr*)(dp + hlen);
346
347 switch (type) {
348 default:
349 return;
350 case ICMP_PARAMETERPROB:
351 if (skb->h.icmph->un.gateway < hlen)
352 return;
353
354
355
356
357 rel_type = ICMP_PARAMETERPROB;
358 rel_info = skb->h.icmph->un.gateway - hlen;
359 break;
360
361 case ICMP_DEST_UNREACH:
362 switch (code) {
363 case ICMP_SR_FAILED:
364 case ICMP_PORT_UNREACH:
365
366 return;
367 case ICMP_FRAG_NEEDED:
368
369 rel_info = ntohs(skb->h.icmph->un.frag.mtu);
370 if (rel_info < hlen+68)
371 return;
372 rel_info -= hlen;
373
374 if (rel_info > ntohs(eiph->tot_len))
375 return;
376 break;
377 default:
378
379
380
381
382 rel_type = ICMP_DEST_UNREACH;
383 rel_code = ICMP_HOST_UNREACH;
384 break;
385 }
386 break;
387 case ICMP_TIME_EXCEEDED:
388 if (code != ICMP_EXC_TTL)
389 return;
390 break;
391 }
392
393
394 skb2 = skb_clone(skb, GFP_ATOMIC);
395 if (skb2 == NULL)
396 return;
397 dst_release(skb2->dst);
398 skb2->dst = NULL;
399 skb_pull(skb2, skb->data - (u8*)eiph);
400 skb2->nh.raw = skb2->data;
401
402
403 if (ip_route_output(&rt, eiph->saddr, 0, RT_TOS(eiph->tos), 0)) {
404 kfree_skb(skb2);
405 return;
406 }
407 skb2->dev = rt->u.dst.dev;
408
409
410 if (rt->rt_flags&RTCF_LOCAL) {
411 ip_rt_put(rt);
412 rt = NULL;
413 if (ip_route_output(&rt, eiph->daddr, eiph->saddr, eiph->tos, 0) ||
414 rt->u.dst.dev->type != ARPHRD_IPGRE) {
415 ip_rt_put(rt);
416 kfree_skb(skb2);
417 return;
418 }
419 } else {
420 ip_rt_put(rt);
421 if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) ||
422 skb2->dst->dev->type != ARPHRD_IPGRE) {
423 kfree_skb(skb2);
424 return;
425 }
426 }
427
428
429 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
430 if (rel_info > skb2->dst->pmtu) {
431 kfree_skb(skb2);
432 return;
433 }
434 skb2->dst->pmtu = rel_info;
435 rel_info = htonl(rel_info);
436 } else if (type == ICMP_TIME_EXCEEDED) {
437 struct ip_tunnel *t = (struct ip_tunnel*)skb2->dev->priv;
438 if (t->parms.iph.ttl) {
439 rel_type = ICMP_DEST_UNREACH;
440 rel_code = ICMP_HOST_UNREACH;
441 }
442 }
443
444 icmp_send(skb2, rel_type, rel_code, rel_info);
445 kfree_skb(skb2);
446 return;
447#endif
448}
449
450int ipip_rcv(struct sk_buff *skb, unsigned short len)
451{
452 struct iphdr *iph;
453 struct ip_tunnel *tunnel;
454
455 iph = skb->nh.iph;
456 skb->mac.raw = skb->nh.raw;
457 skb->nh.raw = skb_pull(skb, skb->h.raw - skb->data);
458 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
459 skb->protocol = __constant_htons(ETH_P_IP);
460 skb->ip_summed = 0;
461 skb->pkt_type = PACKET_HOST;
462
463 if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
464 tunnel->stat.rx_packets++;
465 tunnel->stat.rx_bytes += skb->len;
466 skb->dev = tunnel->dev;
467 dst_release(skb->dst);
468 skb->dst = NULL;
469 netif_rx(skb);
470 return 0;
471 }
472
473 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0);
474 kfree_skb(skb);
475 return 0;
476}
477
478
479
480
481
482
483static int ipip_tunnel_xmit(struct sk_buff *skb, struct device *dev)
484{
485 struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
486 struct net_device_stats *stats = &tunnel->stat;
487 struct iphdr *tiph = &tunnel->parms.iph;
488 u8 tos = tunnel->parms.iph.tos;
489 u16 df = tiph->frag_off;
490 struct rtable *rt;
491 struct device *tdev;
492 struct iphdr *old_iph = skb->nh.iph;
493 struct iphdr *iph;
494 int max_headroom;
495 u32 dst = tiph->daddr;
496 int mtu;
497
498 if (tunnel->recursion++) {
499 tunnel->stat.collisions++;
500 goto tx_error;
501 }
502
503 if (skb->protocol != __constant_htons(ETH_P_IP))
504 goto tx_error;
505
506 if (tos&1)
507 tos = old_iph->tos;
508
509 if (!dst) {
510
511 if ((rt = (struct rtable*)skb->dst) == NULL) {
512 tunnel->stat.tx_fifo_errors++;
513 goto tx_error;
514 }
515 if ((dst = rt->rt_gateway) == 0)
516 goto tx_error_icmp;
517 }
518
519 if (ip_route_output(&rt, dst, tiph->saddr, RT_TOS(tos), tunnel->parms.link)) {
520 tunnel->stat.tx_carrier_errors++;
521 goto tx_error_icmp;
522 }
523 tdev = rt->u.dst.dev;
524
525 if (tdev == dev) {
526 ip_rt_put(rt);
527 tunnel->stat.collisions++;
528 goto tx_error;
529 }
530
531 mtu = rt->u.dst.pmtu - sizeof(struct iphdr);
532 if (mtu < 68) {
533 tunnel->stat.collisions++;
534 ip_rt_put(rt);
535 goto tx_error;
536 }
537 if (skb->dst && mtu < skb->dst->pmtu)
538 skb->dst->pmtu = mtu;
539
540 df |= (old_iph->frag_off&__constant_htons(IP_DF));
541
542 if ((old_iph->frag_off&__constant_htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
543 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
544 ip_rt_put(rt);
545 goto tx_error;
546 }
547
548 if (tunnel->err_count > 0) {
549 if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
550 tunnel->err_count--;
551 dst_link_failure(skb);
552 } else
553 tunnel->err_count = 0;
554 }
555
556 skb->h.raw = skb->nh.raw;
557
558
559
560
561 max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
562
563 if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
564 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
565 if (!new_skb) {
566 ip_rt_put(rt);
567 stats->tx_dropped++;
568 dev_kfree_skb(skb);
569 tunnel->recursion--;
570 return 0;
571 }
572 if (skb->sk)
573 skb_set_owner_w(new_skb, skb->sk);
574 dev_kfree_skb(skb);
575 skb = new_skb;
576 }
577
578 skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
579 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
580 dst_release(skb->dst);
581 skb->dst = &rt->u.dst;
582
583
584
585
586
587 iph = skb->nh.iph;
588 iph->version = 4;
589 iph->ihl = sizeof(struct iphdr)>>2;
590 iph->frag_off = df;
591 iph->protocol = IPPROTO_IPIP;
592 iph->tos = tos;
593 iph->daddr = rt->rt_dst;
594 iph->saddr = rt->rt_src;
595
596 if ((iph->ttl = tiph->ttl) == 0)
597 iph->ttl = old_iph->ttl;
598
599 iph->tot_len = htons(skb->len);
600 iph->id = htons(ip_id_count++);
601 ip_send_check(iph);
602
603 stats->tx_bytes += skb->len;
604 stats->tx_packets++;
605 ip_send(skb);
606 tunnel->recursion--;
607 return 0;
608
609tx_error_icmp:
610 dst_link_failure(skb);
611tx_error:
612 stats->tx_errors++;
613 dev_kfree_skb(skb);
614 tunnel->recursion--;
615 return 0;
616}
617
618static int
619ipip_tunnel_ioctl (struct device *dev, struct ifreq *ifr, int cmd)
620{
621 int err = 0;
622 struct ip_tunnel_parm p;
623 struct ip_tunnel *t;
624
625 MOD_INC_USE_COUNT;
626
627 switch (cmd) {
628 case SIOCGETTUNNEL:
629 t = NULL;
630 if (dev == &ipip_fb_tunnel_dev) {
631 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
632 err = -EFAULT;
633 break;
634 }
635 t = ipip_tunnel_locate(&p, 0);
636 }
637 if (t == NULL)
638 t = (struct ip_tunnel*)dev->priv;
639 memcpy(&p, &t->parms, sizeof(p));
640 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
641 err = -EFAULT;
642 break;
643
644 case SIOCADDTUNNEL:
645 case SIOCCHGTUNNEL:
646 err = -EPERM;
647 if (!capable(CAP_NET_ADMIN))
648 goto done;
649
650 err = -EFAULT;
651 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
652 goto done;
653
654 err = -EINVAL;
655 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPIP ||
656 p.iph.ihl != 5 || (p.iph.frag_off&__constant_htons(~IP_DF)))
657 goto done;
658 if (p.iph.ttl)
659 p.iph.frag_off |= __constant_htons(IP_DF);
660
661 t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
662
663 if (dev != &ipip_fb_tunnel_dev && cmd == SIOCCHGTUNNEL &&
664 t != &ipip_fb_tunnel) {
665 if (t != NULL) {
666 if (t->dev != dev) {
667 err = -EEXIST;
668 break;
669 }
670 } else {
671 if (((dev->flags&IFF_POINTOPOINT) && !p.iph.daddr) ||
672 (!(dev->flags&IFF_POINTOPOINT) && p.iph.daddr)) {
673 err = -EINVAL;
674 break;
675 }
676 t = (struct ip_tunnel*)dev->priv;
677 start_bh_atomic();
678 ipip_tunnel_unlink(t);
679 t->parms.iph.saddr = p.iph.saddr;
680 t->parms.iph.daddr = p.iph.daddr;
681 memcpy(dev->dev_addr, &p.iph.saddr, 4);
682 memcpy(dev->broadcast, &p.iph.daddr, 4);
683 ipip_tunnel_link(t);
684 end_bh_atomic();
685 netdev_state_change(dev);
686 }
687 }
688
689 if (t) {
690 err = 0;
691 if (cmd == SIOCCHGTUNNEL) {
692 t->parms.iph.ttl = p.iph.ttl;
693 t->parms.iph.tos = p.iph.tos;
694 t->parms.iph.frag_off = p.iph.frag_off;
695 }
696 if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
697 err = -EFAULT;
698 } else
699 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
700 break;
701
702 case SIOCDELTUNNEL:
703 err = -EPERM;
704 if (!capable(CAP_NET_ADMIN))
705 goto done;
706
707 if (dev == &ipip_fb_tunnel_dev) {
708 err = -EFAULT;
709 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
710 goto done;
711 err = -ENOENT;
712 if ((t = ipip_tunnel_locate(&p, 0)) == NULL)
713 goto done;
714 err = -EPERM;
715 if (t == &ipip_fb_tunnel)
716 goto done;
717 }
718 err = unregister_netdevice(dev);
719 break;
720
721 default:
722 err = -EINVAL;
723 }
724
725done:
726 MOD_DEC_USE_COUNT;
727 return err;
728}
729
730static struct net_device_stats *ipip_tunnel_get_stats(struct device *dev)
731{
732 return &(((struct ip_tunnel*)dev->priv)->stat);
733}
734
735static int ipip_tunnel_change_mtu(struct device *dev, int new_mtu)
736{
737 if (new_mtu < 68 || new_mtu > 0xFFF8 - sizeof(struct iphdr))
738 return -EINVAL;
739 dev->mtu = new_mtu;
740 return 0;
741}
742
743static void ipip_tunnel_init_gen(struct device *dev)
744{
745 struct ip_tunnel *t = (struct ip_tunnel*)dev->priv;
746
747 dev->destructor = ipip_tunnel_destroy;
748 dev->hard_start_xmit = ipip_tunnel_xmit;
749 dev->get_stats = ipip_tunnel_get_stats;
750 dev->do_ioctl = ipip_tunnel_ioctl;
751 dev->change_mtu = ipip_tunnel_change_mtu;
752
753 dev_init_buffers(dev);
754
755 dev->type = ARPHRD_TUNNEL;
756 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
757 dev->mtu = 1500 - sizeof(struct iphdr);
758 dev->flags = IFF_NOARP;
759 dev->iflink = 0;
760 dev->addr_len = 4;
761 memcpy(dev->dev_addr, &t->parms.iph.saddr, 4);
762 memcpy(dev->broadcast, &t->parms.iph.daddr, 4);
763}
764
765static int ipip_tunnel_init(struct device *dev)
766{
767 struct device *tdev = NULL;
768 struct ip_tunnel *tunnel;
769 struct iphdr *iph;
770
771 tunnel = (struct ip_tunnel*)dev->priv;
772 iph = &tunnel->parms.iph;
773
774 ipip_tunnel_init_gen(dev);
775
776 if (iph->daddr) {
777 struct rtable *rt;
778 if (!ip_route_output(&rt, iph->daddr, iph->saddr, RT_TOS(iph->tos), tunnel->parms.link)) {
779 tdev = rt->u.dst.dev;
780 ip_rt_put(rt);
781 }
782 dev->flags |= IFF_POINTOPOINT;
783 }
784
785 if (!tdev && tunnel->parms.link)
786 tdev = dev_get_by_index(tunnel->parms.link);
787
788 if (tdev) {
789 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
790 dev->mtu = tdev->mtu - sizeof(struct iphdr);
791 }
792 dev->iflink = tunnel->parms.link;
793
794 return 0;
795}
796
797#ifdef MODULE
798static int ipip_fb_tunnel_open(struct device *dev)
799{
800 MOD_INC_USE_COUNT;
801 return 0;
802}
803
804static int ipip_fb_tunnel_close(struct device *dev)
805{
806 MOD_DEC_USE_COUNT;
807 return 0;
808}
809#endif
810
811__initfunc(int ipip_fb_tunnel_init(struct device *dev))
812{
813 struct iphdr *iph;
814
815 ipip_tunnel_init_gen(dev);
816#ifdef MODULE
817 dev->open = ipip_fb_tunnel_open;
818 dev->stop = ipip_fb_tunnel_close;
819#endif
820
821 iph = &ipip_fb_tunnel.parms.iph;
822 iph->version = 4;
823 iph->protocol = IPPROTO_IPIP;
824 iph->ihl = 5;
825
826 tunnels_wc[0] = &ipip_fb_tunnel;
827 return 0;
828}
829
830static struct inet_protocol ipip_protocol = {
831 ipip_rcv,
832 ipip_err,
833 0,
834 IPPROTO_IPIP,
835 0,
836 NULL,
837 "IPIP"
838};
839
840#ifdef MODULE
841int init_module(void)
842#else
843__initfunc(int ipip_init(void))
844#endif
845{
846 printk(KERN_INFO "IPv4 over IPv4 tunneling driver\n");
847
848 ipip_fb_tunnel_dev.priv = (void*)&ipip_fb_tunnel;
849 ipip_fb_tunnel_dev.name = ipip_fb_tunnel.parms.name;
850#ifdef MODULE
851 register_netdev(&ipip_fb_tunnel_dev);
852#else
853 register_netdevice(&ipip_fb_tunnel_dev);
854#endif
855
856 inet_add_protocol(&ipip_protocol);
857 return 0;
858}
859
860#ifdef MODULE
861
862void cleanup_module(void)
863{
864 if ( inet_del_protocol(&ipip_protocol) < 0 )
865 printk(KERN_INFO "ipip close: can't remove protocol\n");
866
867 unregister_netdevice(&ipip_fb_tunnel_dev);
868}
869
870#endif
871