Main Page | Class List | File List | Class Members | File Members

ip_gre.c

Go to the documentation of this file.
00001 /* 00002 * Linux NET3: GRE over IP protocol decoder. 00003 * 00004 * Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru) 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 00009 * 2 of the License, or (at your option) any later version. 00010 * 00011 */ 00012 00013 #include <linux/config.h> 00014 #include <linux/module.h> 00015 #include <linux/types.h> 00016 #include <linux/sched.h> 00017 #include <linux/kernel.h> 00018 #include <asm/uaccess.h> 00019 #include <linux/skbuff.h> 00020 #include <linux/netdevice.h> 00021 #include <linux/in.h> 00022 #include <linux/tcp.h> 00023 #include <linux/udp.h> 00024 #include <linux/if_arp.h> 00025 #include <linux/mroute.h> 00026 #include <linux/init.h> 00027 #include <linux/in6.h> 00028 #include <linux/inetdevice.h> 00029 #include <linux/igmp.h> 00030 #include <linux/netfilter_ipv4.h> 00031 00032 #include <net/sock.h> 00033 #include <net/ip.h> 00034 #include <net/icmp.h> 00035 #include <net/protocol.h> 00036 #include <net/ipip.h> 00037 #include <net/arp.h> 00038 #include <net/checksum.h> 00039 #include <net/inet_ecn.h> 00040 00041 #ifdef CONFIG_IPV6 00042 #include <net/ipv6.h> 00043 #include <net/ip6_fib.h> 00044 #include <net/ip6_route.h> 00045 #endif 00046 00047 /* 00048 Problems & solutions 00049 -------------------- 00050 00051 1. The most important issue is detecting local dead loops. 00052 They would cause complete host lockup in transmit, which 00053 would be "resolved" by stack overflow or, if queueing is enabled, 00054 with infinite looping in net_bh. 00055 00056 We cannot track such dead loops during route installation, 00057 it is infeasible task. The most general solutions would be 00058 to keep skb->encapsulation counter (sort of local ttl), 00059 and silently drop packet when it expires. It is the best 00060 solution, but it supposes maintaing new variable in ALL 00061 skb, even if no tunneling is used. 00062 00063 Current solution: t->recursion lock breaks dead loops. It looks 00064 like dev->tbusy flag, but I preferred new variable, because 00065 the semantics is different. One day, when hard_start_xmit 00066 will be multithreaded we will have to use skb->encapsulation. 00067 00068 00069 00070 2. Networking dead loops would not kill routers, but would really 00071 kill network. IP hop limit plays role of "t->recursion" in this case, 00072 if we copy it from packet being encapsulated to upper header. 00073 It is very good solution, but it introduces two problems: 00074 00075 - Routing protocols, using packets with ttl=1 (OSPF, RIP2), 00076 do not work over tunnels. 00077 - traceroute does not work. I planned to relay ICMP from tunnel, 00078 so that this problem would be solved and traceroute output 00079 would even more informative. This idea appeared to be wrong: 00080 only Linux complies to rfc1812 now (yes, guys, Linux is the only 00081 true router now :-)), all routers (at least, in neighbourhood of mine) 00082 return only 8 bytes of payload. It is the end. 00083 00084 Hence, if we want that OSPF worked or traceroute said something reasonable, 00085 we should search for another solution. 00086 00087 One of them is to parse packet trying to detect inner encapsulation 00088 made by our node. It is difficult or even impossible, especially, 00089 taking into account fragmentation. TO be short, tt is not solution at all. 00090 00091 Current solution: The solution was UNEXPECTEDLY SIMPLE. 00092 We force DF flag on tunnels with preconfigured hop limit, 00093 that is ALL. :-) Well, it does not remove the problem completely, 00094 but exponential growth of network traffic is changed to linear 00095 (branches, that exceed pmtu are pruned) and tunnel mtu 00096 fastly degrades to value <68, where looping stops. 00097 Yes, it is not good if there exists a router in the loop, 00098 which does not force DF, even when encapsulating packets have DF set. 00099 But it is not our problem! Nobody could accuse us, we made 00100 all that we could make. Even if it is your gated who injected 00101 fatal route to network, even if it were you who configured 00102 fatal static route: you are innocent. :-) 00103 00104 00105 00106 3. Really, ipv4/ipip.c, ipv4/ip_gre.c and ipv6/sit.c contain 00107 practically identical code. It would be good to glue them 00108 together, but it is not very evident, how to make them modular. 00109 sit is integral part of IPv6, ipip and gre are naturally modular. 00110 We could extract common parts (hash table, ioctl etc) 00111 to a separate module (ip_tunnel.c). 00112 00113 Alexey Kuznetsov. 00114 */ 00115 00116 static int ipgre_tunnel_init(struct net_device *dev); 00117 00118 /* Fallback tunnel: no source, no destination, no key, no options */ 00119 00120 static int ipgre_fb_tunnel_init(struct net_device *dev); 00121 00122 static struct net_device ipgre_fb_tunnel_dev = { 00123 "gre0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipgre_fb_tunnel_init, 00124 }; 00125 00126 static struct ip_tunnel ipgre_fb_tunnel = { 00127 NULL, &ipgre_fb_tunnel_dev, {0, }, 0, 0, 0, 0, 0, 0, 0, {"gre0", } 00128 }; 00129 00130 /* Tunnel hash table */ 00131 00132 /* 00133 4 hash tables: 00134 00135 3: (remote,local) 00136 2: (remote,*) 00137 1: (*,local) 00138 0: (*,*) 00139 00140 We require exact key match i.e. if a key is present in packet 00141 it will match only tunnel with the same key; if it is not present, 00142 it will match only keyless tunnel. 00143 00144 All keysless packets, if not matched configured keyless tunnels 00145 will match fallback tunnel. 00146 */ 00147 00148 #define HASH_SIZE 16 00149 #define HASH(addr) ((addr^(addr>>4))&0xF) 00150 00151 static struct ip_tunnel *tunnels[4][HASH_SIZE]; 00152 00153 #define tunnels_r_l (tunnels[3]) 00154 #define tunnels_r (tunnels[2]) 00155 #define tunnels_l (tunnels[1]) 00156 #define tunnels_wc (tunnels[0]) 00157 00158 static rwlock_t ipgre_lock = RW_LOCK_UNLOCKED; 00159 00160 /* Given src, dst and key, find approriate for input tunnel. */ 00161 00162 static struct ip_tunnel * ipgre_tunnel_lookup(u32 remote, u32 local, u32 key) 00163 { 00164 unsigned h0 = HASH(remote); 00165 unsigned h1 = HASH(key); 00166 struct ip_tunnel *t; 00167 00168 for (t = tunnels_r_l[h0^h1]; t; t = t->next) { 00169 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { 00170 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 00171 return t; 00172 } 00173 } 00174 for (t = tunnels_r[h0^h1]; t; t = t->next) { 00175 if (remote == t->parms.iph.daddr) { 00176 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 00177 return t; 00178 } 00179 } 00180 for (t = tunnels_l[h1]; t; t = t->next) { 00181 if (local == t->parms.iph.saddr || 00182 (local == t->parms.iph.daddr && MULTICAST(local))) { 00183 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 00184 return t; 00185 } 00186 } 00187 for (t = tunnels_wc[h1]; t; t = t->next) { 00188 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 00189 return t; 00190 } 00191 if (ipgre_fb_tunnel_dev.flags&IFF_UP) 00192 return &ipgre_fb_tunnel; 00193 return NULL; 00194 } 00195 00196 static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) 00197 { 00198 u32 remote = t->parms.iph.daddr; 00199 u32 local = t->parms.iph.saddr; 00200 u32 key = t->parms.i_key; 00201 unsigned h = HASH(key); 00202 int prio = 0; 00203 00204 if (local) 00205 prio |= 1; 00206 if (remote && !MULTICAST(remote)) { 00207 prio |= 2; 00208 h ^= HASH(remote); 00209 } 00210 00211 return &tunnels[prio][h]; 00212 } 00213 00214 static void ipgre_tunnel_link(struct ip_tunnel *t) 00215 { 00216 struct ip_tunnel **tp = ipgre_bucket(t); 00217 00218 t->next = *tp; 00219 write_lock_bh(&ipgre_lock); 00220 *tp = t; 00221 write_unlock_bh(&ipgre_lock); 00222 } 00223 00224 static void ipgre_tunnel_unlink(struct ip_tunnel *t) 00225 { 00226 struct ip_tunnel **tp; 00227 00228 for (tp = ipgre_bucket(t); *tp; tp = &(*tp)->next) { 00229 if (t == *tp) { 00230 write_lock_bh(&ipgre_lock); 00231 *tp = t->next; 00232 write_unlock_bh(&ipgre_lock); 00233 break; 00234 } 00235 } 00236 } 00237 00238 static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create) 00239 { 00240 u32 remote = parms->iph.daddr; 00241 u32 local = parms->iph.saddr; 00242 u32 key = parms->i_key; 00243 struct ip_tunnel *t, **tp, *nt; 00244 struct net_device *dev; 00245 unsigned h = HASH(key); 00246 int prio = 0; 00247 00248 if (local) 00249 prio |= 1; 00250 if (remote && !MULTICAST(remote)) { 00251 prio |= 2; 00252 h ^= HASH(remote); 00253 } 00254 for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) { 00255 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { 00256 if (key == t->parms.i_key) 00257 return t; 00258 } 00259 } 00260 if (!create) 00261 return NULL; 00262 00263 MOD_INC_USE_COUNT; 00264 dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); 00265 if (dev == NULL) { 00266 MOD_DEC_USE_COUNT; 00267 return NULL; 00268 } 00269 memset(dev, 0, sizeof(*dev) + sizeof(*t)); 00270 dev->priv = (void*)(dev+1); 00271 nt = (struct ip_tunnel*)dev->priv; 00272 nt->dev = dev; 00273 dev->init = ipgre_tunnel_init; 00274 dev->features |= NETIF_F_DYNALLOC; 00275 memcpy(&nt->parms, parms, sizeof(*parms)); 00276 nt->parms.name[IFNAMSIZ-1] = '\0'; 00277 strcpy(dev->name, nt->parms.name); 00278 if (dev->name[0] == 0) { 00279 int i; 00280 for (i=1; i<100; i++) { 00281 sprintf(dev->name, "gre%d", i); 00282 if (__dev_get_by_name(dev->name) == NULL) 00283 break; 00284 } 00285 if (i==100) 00286 goto failed; 00287 memcpy(nt->parms.name, dev->name, IFNAMSIZ); 00288 } 00289 if (register_netdevice(dev) < 0) 00290 goto failed; 00291 00292 dev_hold(dev); 00293 ipgre_tunnel_link(nt); 00294 /* Do not decrement MOD_USE_COUNT here. */ 00295 return nt; 00296 00297 failed: 00298 kfree(dev); 00299 MOD_DEC_USE_COUNT; 00300 return NULL; 00301 } 00302 00303 static void ipgre_tunnel_destructor(struct net_device *dev) 00304 { 00305 if (dev != &ipgre_fb_tunnel_dev) { 00306 MOD_DEC_USE_COUNT; 00307 } 00308 } 00309 00310 static void ipgre_tunnel_uninit(struct net_device *dev) 00311 { 00312 ipgre_tunnel_unlink((struct ip_tunnel*)dev->priv); 00313 dev_put(dev); 00314 } 00315 00316 00317 void ipgre_err(struct sk_buff *skb, u32 info) 00318 { 00319 #ifndef I_WISH_WORLD_WERE_PERFECT 00320 00321 /* It is not :-( All the routers (except for Linux) return only 00322 8 bytes of packet payload. It means, that precise relaying of 00323 ICMP in the real Internet is absolutely infeasible. 00324 00325 Moreover, Cisco "wise men" put GRE key to the third word 00326 in GRE header. It makes impossible maintaining even soft state for keyed 00327 GRE tunnels with enabled checksum. Tell them "thank you". 00328 00329 Well, I wonder, rfc1812 was written by Cisco employee, 00330 what the hell these idiots break standrads established 00331 by themself??? 00332 */ 00333 00334 struct iphdr *iph = (struct iphdr*)skb->data; 00335 u16 *p = (u16*)(skb->data+(iph->ihl<<2)); 00336 int grehlen = (iph->ihl<<2) + 4; 00337 int type = skb->h.icmph->type; 00338 int code = skb->h.icmph->code; 00339 struct ip_tunnel *t; 00340 u16 flags; 00341 00342 flags = p[0]; 00343 if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { 00344 if (flags&(GRE_VERSION|GRE_ROUTING)) 00345 return; 00346 if (flags&GRE_KEY) { 00347 grehlen += 4; 00348 if (flags&GRE_CSUM) 00349 grehlen += 4; 00350 } 00351 } 00352 00353 /* If only 8 bytes returned, keyed message will be dropped here */ 00354 if (skb_headlen(skb) < grehlen) 00355 return; 00356 00357 switch (type) { 00358 default: 00359 case ICMP_PARAMETERPROB: 00360 return; 00361 00362 case ICMP_DEST_UNREACH: 00363 switch (code) { 00364 case ICMP_SR_FAILED: 00365 case ICMP_PORT_UNREACH: 00366 /* Impossible event. */ 00367 return; 00368 case ICMP_FRAG_NEEDED: 00369 /* Soft state for pmtu is maintained by IP core. */ 00370 return; 00371 default: 00372 /* All others are translated to HOST_UNREACH. 00373 rfc2003 contains "deep thoughts" about NET_UNREACH, 00374 I believe they are just ether pollution. --ANK 00375 */ 00376 break; 00377 } 00378 break; 00379 case ICMP_TIME_EXCEEDED: 00380 if (code != ICMP_EXC_TTL) 00381 return; 00382 break; 00383 } 00384 00385 read_lock(&ipgre_lock); 00386 t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((u32*)p) + (grehlen>>2) - 1) : 0); 00387 if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr)) 00388 goto out; 00389 00390 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 00391 goto out; 00392 00393 if (jiffies - t->err_time < IPTUNNEL_ERR_TIMEO) 00394 t->err_count++; 00395 else 00396 t->err_count = 1; 00397 t->err_time = jiffies; 00398 out: 00399 read_unlock(&ipgre_lock); 00400 return; 00401 #else 00402 struct iphdr *iph = (struct iphdr*)dp; 00403 struct iphdr *eiph; 00404 u16 *p = (u16*)(dp+(iph->ihl<<2)); 00405 int type = skb->h.icmph->type; 00406 int code = skb->h.icmph->code; 00407 int rel_type = 0; 00408 int rel_code = 0; 00409 int rel_info = 0; 00410 u16 flags; 00411 int grehlen = (iph->ihl<<2) + 4; 00412 struct sk_buff *skb2; 00413 struct rtable *rt; 00414 00415 if (p[1] != htons(ETH_P_IP)) 00416 return; 00417 00418 flags = p[0]; 00419 if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { 00420 if (flags&(GRE_VERSION|GRE_ROUTING)) 00421 return; 00422 if (flags&GRE_CSUM) 00423 grehlen += 4; 00424 if (flags&GRE_KEY) 00425 grehlen += 4; 00426 if (flags&GRE_SEQ) 00427 grehlen += 4; 00428 } 00429 if (len < grehlen + sizeof(struct iphdr)) 00430 return; 00431 eiph = (struct iphdr*)(dp + grehlen); 00432 00433 switch (type) { 00434 default: 00435 return; 00436 case ICMP_PARAMETERPROB: 00437 if (skb->h.icmph->un.gateway < (iph->ihl<<2)) 00438 return; 00439 00440 /* So... This guy found something strange INSIDE encapsulated 00441 packet. Well, he is fool, but what can we do ? 00442 */ 00443 rel_type = ICMP_PARAMETERPROB; 00444 rel_info = skb->h.icmph->un.gateway - grehlen; 00445 break; 00446 00447 case ICMP_DEST_UNREACH: 00448 switch (code) { 00449 case ICMP_SR_FAILED: 00450 case ICMP_PORT_UNREACH: 00451 /* Impossible event. */ 00452 return; 00453 case ICMP_FRAG_NEEDED: 00454 /* And it is the only really necesary thing :-) */ 00455 rel_info = ntohs(skb->h.icmph->un.frag.mtu); 00456 if (rel_info < grehlen+68) 00457 return; 00458 rel_info -= grehlen; 00459 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ 00460 if (rel_info > ntohs(eiph->tot_len)) 00461 return; 00462 break; 00463 default: 00464 /* All others are translated to HOST_UNREACH. 00465 rfc2003 contains "deep thoughts" about NET_UNREACH, 00466 I believe, it is just ether pollution. --ANK 00467 */ 00468 rel_type = ICMP_DEST_UNREACH; 00469 rel_code = ICMP_HOST_UNREACH; 00470 break; 00471 } 00472 break; 00473 case ICMP_TIME_EXCEEDED: 00474 if (code != ICMP_EXC_TTL) 00475 return; 00476 break; 00477 } 00478 00479 /* Prepare fake skb to feed it to icmp_send */ 00480 skb2 = skb_clone(skb, GFP_ATOMIC); 00481 if (skb2 == NULL) 00482 return; 00483 dst_release(skb2->dst); 00484 skb2->dst = NULL; 00485 skb_pull(skb2, skb->data - (u8*)eiph); 00486 skb2->nh.raw = skb2->data; 00487 00488 /* Try to guess incoming interface */ 00489 if (ip_route_output(&rt, eiph->saddr, 0, RT_TOS(eiph->tos), 0)) { 00490 kfree_skb(skb2); 00491 return; 00492 } 00493 skb2->dev = rt->u.dst.dev; 00494 00495 /* route "incoming" packet */ 00496 if (rt->rt_flags&RTCF_LOCAL) { 00497 ip_rt_put(rt); 00498 rt = NULL; 00499 if (ip_route_output(&rt, eiph->daddr, eiph->saddr, eiph->tos, 0) || 00500 rt->u.dst.dev->type != ARPHRD_IPGRE) { 00501 ip_rt_put(rt); 00502 kfree_skb(skb2); 00503 return; 00504 } 00505 } else { 00506 ip_rt_put(rt); 00507 if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || 00508 skb2->dst->dev->type != ARPHRD_IPGRE) { 00509 kfree_skb(skb2); 00510 return; 00511 } 00512 } 00513 00514 /* change mtu on this route */ 00515 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 00516 if (rel_info > skb2->dst->pmtu) { 00517 kfree_skb(skb2); 00518 return; 00519 } 00520 skb2->dst->pmtu = rel_info; 00521 rel_info = htonl(rel_info); 00522 } else if (type == ICMP_TIME_EXCEEDED) { 00523 struct ip_tunnel *t = (struct ip_tunnel*)skb2->dev->priv; 00524 if (t->parms.iph.ttl) { 00525 rel_type = ICMP_DEST_UNREACH; 00526 rel_code = ICMP_HOST_UNREACH; 00527 } 00528 } 00529 00530 icmp_send(skb2, rel_type, rel_code, rel_info); 00531 kfree_skb(skb2); 00532 #endif 00533 } 00534 00535 static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) 00536 { 00537 if (INET_ECN_is_ce(iph->tos)) { 00538 if (skb->protocol == htons(ETH_P_IP)) { 00539 if (INET_ECN_is_not_ce(skb->nh.iph->tos)) 00540 IP_ECN_set_ce(skb->nh.iph); 00541 } else if (skb->protocol == htons(ETH_P_IPV6)) { 00542 if (INET_ECN_is_not_ce(ip6_get_dsfield(skb->nh.ipv6h))) 00543 IP6_ECN_set_ce(skb->nh.ipv6h); 00544 } 00545 } 00546 } 00547 00548 static inline u8 00549 ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb) 00550 { 00551 u8 inner = 0; 00552 if (skb->protocol == htons(ETH_P_IP)) 00553 inner = old_iph->tos; 00554 else if (skb->protocol == htons(ETH_P_IPV6)) 00555 inner = ip6_get_dsfield((struct ipv6hdr*)old_iph); 00556 return INET_ECN_encapsulate(tos, inner); 00557 } 00558 00559 int ipgre_rcv(struct sk_buff *skb) 00560 { 00561 struct iphdr *iph; 00562 u8 *h; 00563 u16 flags; 00564 u16 csum = 0; 00565 u32 key = 0; 00566 u32 seqno = 0; 00567 struct ip_tunnel *tunnel; 00568 int offset = 4; 00569 00570 if (!pskb_may_pull(skb, 16)) 00571 goto drop_nolock; 00572 00573 iph = skb->nh.iph; 00574 h = skb->data; 00575 flags = *(u16*)h; 00576 00577 if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) { 00578 /* - Version must be 0. 00579 - We do not support routing headers. 00580 */ 00581 if (flags&(GRE_VERSION|GRE_ROUTING)) 00582 goto drop_nolock; 00583 00584 if (flags&GRE_CSUM) { 00585 if (skb->ip_summed == CHECKSUM_HW) { 00586 csum = (u16)csum_fold(skb->csum); 00587 if (csum) 00588 skb->ip_summed = CHECKSUM_NONE; 00589 } 00590 if (skb->ip_summed == CHECKSUM_NONE) { 00591 skb->csum = skb_checksum(skb, 0, skb->len, 0); 00592 skb->ip_summed = CHECKSUM_HW; 00593 csum = (u16)csum_fold(skb->csum); 00594 } 00595 offset += 4; 00596 } 00597 if (flags&GRE_KEY) { 00598 key = *(u32*)(h + offset); 00599 offset += 4; 00600 } 00601 if (flags&GRE_SEQ) { 00602 seqno = ntohl(*(u32*)(h + offset)); 00603 offset += 4; 00604 } 00605 } 00606 00607 read_lock(&ipgre_lock); 00608 if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) { 00609 skb->mac.raw = skb->nh.raw; 00610 skb->nh.raw = __pskb_pull(skb, offset); 00611 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); 00612 if (skb->ip_summed == CHECKSUM_HW) 00613 skb->csum = csum_sub(skb->csum, 00614 csum_partial(skb->mac.raw, skb->nh.raw-skb->mac.raw, 0)); 00615 skb->protocol = *(u16*)(h + 2); 00616 skb->pkt_type = PACKET_HOST; 00617 #ifdef CONFIG_NET_IPGRE_BROADCAST 00618 if (MULTICAST(iph->daddr)) { 00619 /* Looped back packet, drop it! */ 00620 if (((struct rtable*)skb->dst)->key.iif == 0) 00621 goto drop; 00622 tunnel->stat.multicast++; 00623 skb->pkt_type = PACKET_BROADCAST; 00624 } 00625 #endif 00626 00627 if (((flags&GRE_CSUM) && csum) || 00628 (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { 00629 tunnel->stat.rx_crc_errors++; 00630 tunnel->stat.rx_errors++; 00631 goto drop; 00632 } 00633 if (tunnel->parms.i_flags&GRE_SEQ) { 00634 if (!(flags&GRE_SEQ) || 00635 (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { 00636 tunnel->stat.rx_fifo_errors++; 00637 tunnel->stat.rx_errors++; 00638 goto drop; 00639 } 00640 tunnel->i_seqno = seqno + 1; 00641 } 00642 tunnel->stat.rx_packets++; 00643 tunnel->stat.rx_bytes += skb->len; 00644 skb->dev = tunnel->dev; 00645 dst_release(skb->dst); 00646 skb->dst = NULL; 00647 #ifdef CONFIG_NETFILTER 00648 nf_conntrack_put(skb->nfct); 00649 skb->nfct = NULL; 00650 #ifdef CONFIG_NETFILTER_DEBUG 00651 skb->nf_debug = 0; 00652 #endif 00653 #endif 00654 ipgre_ecn_decapsulate(iph, skb); 00655 netif_rx(skb); 00656 read_unlock(&ipgre_lock); 00657 return(0); 00658 } 00659 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); 00660 00661 drop: 00662 read_unlock(&ipgre_lock); 00663 drop_nolock: 00664 kfree_skb(skb); 00665 return(0); 00666 } 00667 00668 /* Need this wrapper because NF_HOOK takes the function address */ 00669 static inline int do_ip_send(struct sk_buff *skb) 00670 { 00671 return ip_send(skb); 00672 } 00673 00674 static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 00675 { 00676 struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; 00677 struct net_device_stats *stats = &tunnel->stat; 00678 struct iphdr *old_iph = skb->nh.iph; 00679 struct iphdr *tiph; 00680 u8 tos; 00681 u16 df; 00682 struct rtable *rt; /* Route to the other host */ 00683 struct net_device *tdev; /* Device to other host */ 00684 struct iphdr *iph; /* Our new IP header */ 00685 int max_headroom; /* The extra header space needed */ 00686 int gre_hlen; 00687 u32 dst; 00688 int mtu; 00689 00690 if (tunnel->recursion++) { 00691 tunnel->stat.collisions++; 00692 goto tx_error; 00693 } 00694 00695 if (dev->hard_header) { 00696 gre_hlen = 0; 00697 tiph = (struct iphdr*)skb->data; 00698 } else { 00699 gre_hlen = tunnel->hlen; 00700 tiph = &tunnel->parms.iph; 00701 } 00702 00703 if ((dst = tiph->daddr) == 0) { 00704 /* NBMA tunnel */ 00705 00706 if (skb->dst == NULL) { 00707 tunnel->stat.tx_fifo_errors++; 00708 goto tx_error; 00709 } 00710 00711 if (skb->protocol == htons(ETH_P_IP)) { 00712 rt = (struct rtable*)skb->dst; 00713 if ((dst = rt->rt_gateway) == 0) 00714 goto tx_error_icmp; 00715 } 00716 #ifdef CONFIG_IPV6 00717 else if (skb->protocol == htons(ETH_P_IPV6)) { 00718 struct in6_addr *addr6; 00719 int addr_type; 00720 struct neighbour *neigh = skb->dst->neighbour; 00721 00722 if (neigh == NULL) 00723 goto tx_error; 00724 00725 addr6 = (struct in6_addr*)&neigh->primary_key; 00726 addr_type = ipv6_addr_type(addr6); 00727 00728 if (addr_type == IPV6_ADDR_ANY) { 00729 addr6 = &skb->nh.ipv6h->daddr; 00730 addr_type = ipv6_addr_type(addr6); 00731 } 00732 00733 if ((addr_type & IPV6_ADDR_COMPATv4) == 0) 00734 goto tx_error_icmp; 00735 00736 dst = addr6->s6_addr32[3]; 00737 } 00738 #endif 00739 else 00740 goto tx_error; 00741 } 00742 00743 tos = tiph->tos; 00744 if (tos&1) { 00745 if (skb->protocol == htons(ETH_P_IP)) 00746 tos = old_iph->tos; 00747 tos &= ~1; 00748 } 00749 00750 if (ip_route_output(&rt, dst, tiph->saddr, RT_TOS(tos), tunnel->parms.link)) { 00751 tunnel->stat.tx_carrier_errors++; 00752 goto tx_error; 00753 } 00754 tdev = rt->u.dst.dev; 00755 00756 if (tdev == dev) { 00757 ip_rt_put(rt); 00758 tunnel->stat.collisions++; 00759 goto tx_error; 00760 } 00761 00762 df = tiph->frag_off; 00763 if (df) 00764 mtu = rt->u.dst.pmtu - tunnel->hlen; 00765 else 00766 mtu = skb->dst ? skb->dst->pmtu : dev->mtu; 00767 00768 if (skb->protocol == htons(ETH_P_IP)) { 00769 if (skb->dst && mtu < skb->dst->pmtu && mtu >= 68) 00770 skb->dst->pmtu = mtu; 00771 00772 df |= (old_iph->frag_off&htons(IP_DF)); 00773 00774 if ((old_iph->frag_off&htons(IP_DF)) && 00775 mtu < ntohs(old_iph->tot_len)) { 00776 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); 00777 ip_rt_put(rt); 00778 goto tx_error; 00779 } 00780 } 00781 #ifdef CONFIG_IPV6 00782 else if (skb->protocol == htons(ETH_P_IPV6)) { 00783 struct rt6_info *rt6 = (struct rt6_info*)skb->dst; 00784 00785 if (rt6 && mtu < rt6->u.dst.pmtu && mtu >= IPV6_MIN_MTU) { 00786 if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) || 00787 rt6->rt6i_dst.plen == 128) { 00788 rt6->rt6i_flags |= RTF_MODIFIED; 00789 skb->dst->pmtu = mtu; 00790 } 00791 } 00792 00793 if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) { 00794 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); 00795 ip_rt_put(rt); 00796 goto tx_error; 00797 } 00798 } 00799 #endif 00800 00801 if (tunnel->err_count > 0) { 00802 if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) { 00803 tunnel->err_count--; 00804 00805 dst_link_failure(skb); 00806 } else 00807 tunnel->err_count = 0; 00808 } 00809 00810 max_headroom = ((tdev->hard_header_len+15)&~15)+ gre_hlen; 00811 00812 if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { 00813 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 00814 if (!new_skb) { 00815 ip_rt_put(rt); 00816 stats->tx_dropped++; 00817 dev_kfree_skb(skb); 00818 tunnel->recursion--; 00819 return 0; 00820 } 00821 if (skb->sk) 00822 skb_set_owner_w(new_skb, skb->sk); 00823 dev_kfree_skb(skb); 00824 skb = new_skb; 00825 old_iph = skb->nh.iph; 00826 } 00827 00828 skb->h.raw = skb->nh.raw; 00829 skb->nh.raw = skb_push(skb, gre_hlen); 00830 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 00831 dst_release(skb->dst); 00832 skb->dst = &rt->u.dst; 00833 00834 /* 00835 * Push down and install the IPIP header. 00836 */ 00837 00838 iph = skb->nh.iph; 00839 iph->version = 4; 00840 iph->ihl = sizeof(struct iphdr) >> 2; 00841 iph->frag_off = df; 00842 iph->protocol = IPPROTO_GRE; 00843 iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); 00844 iph->daddr = rt->rt_dst; 00845 iph->saddr = rt->rt_src; 00846 00847 if ((iph->ttl = tiph->ttl) == 0) { 00848 if (skb->protocol == htons(ETH_P_IP)) 00849 iph->ttl = old_iph->ttl; 00850 #ifdef CONFIG_IPV6 00851 else if (skb->protocol == htons(ETH_P_IPV6)) 00852 iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit; 00853 #endif 00854 else 00855 iph->ttl = sysctl_ip_default_ttl; 00856 } 00857 00858 ((u16*)(iph+1))[0] = tunnel->parms.o_flags; 00859 ((u16*)(iph+1))[1] = skb->protocol; 00860 00861 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { 00862 u32 *ptr = (u32*)(((u8*)iph) + tunnel->hlen - 4); 00863 00864 if (tunnel->parms.o_flags&GRE_SEQ) { 00865 ++tunnel->o_seqno; 00866 *ptr = htonl(tunnel->o_seqno); 00867 ptr--; 00868 } 00869 if (tunnel->parms.o_flags&GRE_KEY) { 00870 *ptr = tunnel->parms.o_key; 00871 ptr--; 00872 } 00873 if (tunnel->parms.o_flags&GRE_CSUM) { 00874 *ptr = 0; 00875 *(__u16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr)); 00876 } 00877 } 00878 00879 #ifdef CONFIG_NETFILTER 00880 nf_conntrack_put(skb->nfct); 00881 skb->nfct = NULL; 00882 #ifdef CONFIG_NETFILTER_DEBUG 00883 skb->nf_debug = 0; 00884 #endif 00885 #endif 00886 00887 IPTUNNEL_XMIT(); 00888 tunnel->recursion--; 00889 return 0; 00890 00891 tx_error_icmp: 00892 dst_link_failure(skb); 00893 00894 tx_error: 00895 stats->tx_errors++; 00896 dev_kfree_skb(skb); 00897 tunnel->recursion--; 00898 return 0; 00899 } 00900 00901 static int 00902 ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) 00903 { 00904 int err = 0; 00905 struct ip_tunnel_parm p; 00906 struct ip_tunnel *t; 00907 00908 MOD_INC_USE_COUNT; 00909 00910 switch (cmd) { 00911 case SIOCGETTUNNEL: 00912 t = NULL; 00913 if (dev == &ipgre_fb_tunnel_dev) { 00914 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 00915 err = -EFAULT; 00916 break; 00917 } 00918 t = ipgre_tunnel_locate(&p, 0); 00919 } 00920 if (t == NULL) 00921 t = (struct ip_tunnel*)dev->priv; 00922 memcpy(&p, &t->parms, sizeof(p)); 00923 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 00924 err = -EFAULT; 00925 break; 00926 00927 case SIOCADDTUNNEL: 00928 case SIOCCHGTUNNEL: 00929 err = -EPERM; 00930 if (!capable(CAP_NET_ADMIN)) 00931 goto done; 00932 00933 err = -EFAULT; 00934 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 00935 goto done; 00936 00937 err = -EINVAL; 00938 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE || 00939 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) || 00940 ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING))) 00941 goto done; 00942 if (p.iph.ttl) 00943 p.iph.frag_off |= htons(IP_DF); 00944 00945 if (!(p.i_flags&GRE_KEY)) 00946 p.i_key = 0; 00947 if (!(p.o_flags&GRE_KEY)) 00948 p.o_key = 0; 00949 00950 t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL); 00951 00952 if (dev != &ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL && 00953 t != &ipgre_fb_tunnel) { 00954 if (t != NULL) { 00955 if (t->dev != dev) { 00956 err = -EEXIST; 00957 break; 00958 } 00959 } else { 00960 unsigned nflags=0; 00961 00962 t = (struct ip_tunnel*)dev->priv; 00963 00964 if (MULTICAST(p.iph.daddr)) 00965 nflags = IFF_BROADCAST; 00966 else if (p.iph.daddr) 00967 nflags = IFF_POINTOPOINT; 00968 00969 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) { 00970 err = -EINVAL; 00971 break; 00972 } 00973 ipgre_tunnel_unlink(t); 00974 t->parms.iph.saddr = p.iph.saddr; 00975 t->parms.iph.daddr = p.iph.daddr; 00976 t->parms.i_key = p.i_key; 00977 t->parms.o_key = p.o_key; 00978 memcpy(dev->dev_addr, &p.iph.saddr, 4); 00979 memcpy(dev->broadcast, &p.iph.daddr, 4); 00980 ipgre_tunnel_link(t); 00981 netdev_state_change(dev); 00982 } 00983 } 00984 00985 if (t) { 00986 err = 0; 00987 if (cmd == SIOCCHGTUNNEL) { 00988 t->parms.iph.ttl = p.iph.ttl; 00989 t->parms.iph.tos = p.iph.tos; 00990 t->parms.iph.frag_off = p.iph.frag_off; 00991 } 00992 if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p))) 00993 err = -EFAULT; 00994 } else 00995 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); 00996 break; 00997 00998 case SIOCDELTUNNEL: 00999 err = -EPERM; 01000 if (!capable(CAP_NET_ADMIN)) 01001 goto done; 01002 01003 if (dev == &ipgre_fb_tunnel_dev) { 01004 err = -EFAULT; 01005 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 01006 goto done; 01007 err = -ENOENT; 01008 if ((t = ipgre_tunnel_locate(&p, 0)) == NULL) 01009 goto done; 01010 err = -EPERM; 01011 if (t == &ipgre_fb_tunnel) 01012 goto done; 01013 dev = t->dev; 01014 } 01015 err = unregister_netdevice(dev); 01016 break; 01017 01018 default: 01019 err = -EINVAL; 01020 } 01021 01022 done: 01023 MOD_DEC_USE_COUNT; 01024 return err; 01025 } 01026 01027 static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev) 01028 { 01029 return &(((struct ip_tunnel*)dev->priv)->stat); 01030 } 01031 01032 static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) 01033 { 01034 struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; 01035 if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen) 01036 return -EINVAL; 01037 dev->mtu = new_mtu; 01038 return 0; 01039 } 01040 01041 #ifdef CONFIG_NET_IPGRE_BROADCAST 01042 /* Nice toy. Unfortunately, useless in real life :-) 01043 It allows to construct virtual multiprotocol broadcast "LAN" 01044 over the Internet, provided multicast routing is tuned. 01045 01046 01047 I have no idea was this bicycle invented before me, 01048 so that I had to set ARPHRD_IPGRE to a random value. 01049 I have an impression, that Cisco could make something similar, 01050 but this feature is apparently missing in IOS<=11.2(8). 01051 01052 I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks 01053 with broadcast 224.66.66.66. If you have access to mbone, play with me :-) 01054 01055 ping -t 255 224.66.66.66 01056 01057 If nobody answers, mbone does not work. 01058 01059 ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255 01060 ip addr add 10.66.66.<somewhat>/24 dev Universe 01061 ifconfig Universe up 01062 ifconfig Universe add fe80::<Your_real_addr>/10 01063 ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96 01064 ftp 10.66.66.66 01065 ... 01066 ftp fec0:6666:6666::193.233.7.65 01067 ... 01068 01069 */ 01070 01071 static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 01072 void *daddr, void *saddr, unsigned len) 01073 { 01074 struct ip_tunnel *t = (struct ip_tunnel*)dev->priv; 01075 struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); 01076 u16 *p = (u16*)(iph+1); 01077 01078 memcpy(iph, &t->parms.iph, sizeof(struct iphdr)); 01079 p[0] = t->parms.o_flags; 01080 p[1] = htons(type); 01081 01082 /* 01083 * Set the source hardware address. 01084 */ 01085 01086 if (saddr) 01087 memcpy(&iph->saddr, saddr, 4); 01088 01089 if (daddr) { 01090 memcpy(&iph->daddr, daddr, 4); 01091 return t->hlen; 01092 } 01093 if (iph->daddr && !MULTICAST(iph->daddr)) 01094 return t->hlen; 01095 01096 return -t->hlen; 01097 } 01098 01099 static int ipgre_open(struct net_device *dev) 01100 { 01101 struct ip_tunnel *t = (struct ip_tunnel*)dev->priv; 01102 01103 MOD_INC_USE_COUNT; 01104 if (MULTICAST(t->parms.iph.daddr)) { 01105 struct rtable *rt; 01106 if (ip_route_output(&rt, t->parms.iph.daddr, 01107 t->parms.iph.saddr, RT_TOS(t->parms.iph.tos), 01108 t->parms.link)) { 01109 MOD_DEC_USE_COUNT; 01110 return -EADDRNOTAVAIL; 01111 } 01112 dev = rt->u.dst.dev; 01113 ip_rt_put(rt); 01114 if (__in_dev_get(dev) == NULL) { 01115 MOD_DEC_USE_COUNT; 01116 return -EADDRNOTAVAIL; 01117 } 01118 t->mlink = dev->ifindex; 01119 ip_mc_inc_group(__in_dev_get(dev), t->parms.iph.daddr); 01120 } 01121 return 0; 01122 } 01123 01124 static int ipgre_close(struct net_device *dev) 01125 { 01126 struct ip_tunnel *t = (struct ip_tunnel*)dev->priv; 01127 if (MULTICAST(t->parms.iph.daddr) && t->mlink) { 01128 struct in_device *in_dev = inetdev_by_index(t->mlink); 01129 if (in_dev) { 01130 ip_mc_dec_group(in_dev, t->parms.iph.daddr); 01131 in_dev_put(in_dev); 01132 } 01133 } 01134 MOD_DEC_USE_COUNT; 01135 return 0; 01136 } 01137 01138 #endif 01139 01140 static void ipgre_tunnel_init_gen(struct net_device *dev) 01141 { 01142 struct ip_tunnel *t = (struct ip_tunnel*)dev->priv; 01143 01144 dev->uninit = ipgre_tunnel_uninit; 01145 dev->destructor = ipgre_tunnel_destructor; 01146 dev->hard_start_xmit = ipgre_tunnel_xmit; 01147 dev->get_stats = ipgre_tunnel_get_stats; 01148 dev->do_ioctl = ipgre_tunnel_ioctl; 01149 dev->change_mtu = ipgre_tunnel_change_mtu; 01150 01151 dev->type = ARPHRD_IPGRE; 01152 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4; 01153 dev->mtu = 1500 - sizeof(struct iphdr) - 4; 01154 dev->flags = IFF_NOARP; 01155 dev->iflink = 0; 01156 dev->addr_len = 4; 01157 memcpy(dev->dev_addr, &t->parms.iph.saddr, 4); 01158 memcpy(dev->broadcast, &t->parms.iph.daddr, 4); 01159 } 01160 01161 static int ipgre_tunnel_init(struct net_device *dev) 01162 { 01163 struct net_device *tdev = NULL; 01164 struct ip_tunnel *tunnel; 01165 struct iphdr *iph; 01166 int hlen = LL_MAX_HEADER; 01167 int mtu = 1500; 01168 int addend = sizeof(struct iphdr) + 4; 01169 01170 tunnel = (struct ip_tunnel*)dev->priv; 01171 iph = &tunnel->parms.iph; 01172 01173 ipgre_tunnel_init_gen(dev); 01174 01175 /* Guess output device to choose reasonable mtu and hard_header_len */ 01176 01177 if (iph->daddr) { 01178 struct rtable *rt; 01179 if (!ip_route_output(&rt, iph->daddr, iph->saddr, RT_TOS(iph->tos), tunnel->parms.link)) { 01180 tdev = rt->u.dst.dev; 01181 ip_rt_put(rt); 01182 } 01183 01184 dev->flags |= IFF_POINTOPOINT; 01185 01186 #ifdef CONFIG_NET_IPGRE_BROADCAST 01187 if (MULTICAST(iph->daddr)) { 01188 if (!iph->saddr) 01189 return -EINVAL; 01190 dev->flags = IFF_BROADCAST; 01191 dev->hard_header = ipgre_header; 01192 dev->open = ipgre_open; 01193 dev->stop = ipgre_close; 01194 } 01195 #endif 01196 } 01197 01198 if (!tdev && tunnel->parms.link) 01199 tdev = __dev_get_by_index(tunnel->parms.link); 01200 01201 if (tdev) { 01202 hlen = tdev->hard_header_len; 01203 mtu = tdev->mtu; 01204 } 01205 dev->iflink = tunnel->parms.link; 01206 01207 /* Precalculate GRE options length */ 01208 if (tunnel->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) { 01209 if (tunnel->parms.o_flags&GRE_CSUM) 01210 addend += 4; 01211 if (tunnel->parms.o_flags&GRE_KEY) 01212 addend += 4; 01213 if (tunnel->parms.o_flags&GRE_SEQ) 01214 addend += 4; 01215 } 01216 dev->hard_header_len = hlen + addend; 01217 dev->mtu = mtu - addend; 01218 tunnel->hlen = addend; 01219 return 0; 01220 } 01221 01222 #ifdef MODULE 01223 static int ipgre_fb_tunnel_open(struct net_device *dev) 01224 { 01225 MOD_INC_USE_COUNT; 01226 return 0; 01227 } 01228 01229 static int ipgre_fb_tunnel_close(struct net_device *dev) 01230 { 01231 MOD_DEC_USE_COUNT; 01232 return 0; 01233 } 01234 #endif 01235 01236 int __init ipgre_fb_tunnel_init(struct net_device *dev) 01237 { 01238 struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; 01239 struct iphdr *iph; 01240 01241 ipgre_tunnel_init_gen(dev); 01242 #ifdef MODULE 01243 dev->open = ipgre_fb_tunnel_open; 01244 dev->stop = ipgre_fb_tunnel_close; 01245 #endif 01246 01247 iph = &ipgre_fb_tunnel.parms.iph; 01248 iph->version = 4; 01249 iph->protocol = IPPROTO_GRE; 01250 iph->ihl = 5; 01251 tunnel->hlen = sizeof(struct iphdr) + 4; 01252 01253 dev_hold(dev); 01254 tunnels_wc[0] = &ipgre_fb_tunnel; 01255 return 0; 01256 } 01257 01258 01259 static struct inet_protocol ipgre_protocol = { 01260 ipgre_rcv, /* GRE handler */ 01261 ipgre_err, /* TUNNEL error control */ 01262 0, /* next */ 01263 IPPROTO_GRE, /* protocol ID */ 01264 0, /* copy */ 01265 NULL, /* data */ 01266 "GRE" /* name */ 01267 }; 01268 01269 01270 /* 01271 * And now the modules code and kernel interface. 01272 */ 01273 01274 #ifdef MODULE 01275 int init_module(void) 01276 #else 01277 int __init ipgre_init(void) 01278 #endif 01279 { 01280 printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); 01281 01282 ipgre_fb_tunnel_dev.priv = (void*)&ipgre_fb_tunnel; 01283 register_netdev(&ipgre_fb_tunnel_dev); 01284 inet_add_protocol(&ipgre_protocol); 01285 return 0; 01286 } 01287 01288 #ifdef MODULE 01289 01290 void cleanup_module(void) 01291 { 01292 if ( inet_del_protocol(&ipgre_protocol) < 0 ) 01293 printk(KERN_INFO "ipgre close: can't remove protocol\n"); 01294 01295 unregister_netdev(&ipgre_fb_tunnel_dev); 01296 } 01297 01298 #endif 01299 MODULE_LICENSE("GPL");

Generated on Wed Dec 1 21:25:30 2004 for Linux 2.4.23 Networking by doxygen 1.3.8