blob: e657a6605e084df730425a5eb2da8eed6b8acf61 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09002 * Linux NET3: IP/IP protocol decoder.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Version: $Id: ipip.c,v 1.50 2001/10/02 02:22:36 davem Exp $
5 *
6 * Authors:
7 * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
8 *
9 * Fixes:
10 * Alan Cox : Merged and made usable non modular (its so tiny its silly as
11 * a module taking up 2 pages).
12 * Alan Cox : Fixed bug with 1.3.18 and IPIP not working (now needs to set skb->h.iph)
13 * to keep ip_forward happy.
14 * Alan Cox : More fixes for 1.3.21, and firewall fix. Maybe this will work soon 8).
15 * Kai Schulte : Fixed #defines for IP_FIREWALL->FIREWALL
16 * David Woodhouse : Perform some basic ICMP handling.
17 * IPIP Routing without decapsulation.
18 * Carlos Picoto : GRE over IP support
19 * Alexey Kuznetsov: Reworked. Really, now it is truncated version of ipv4/ip_gre.c.
20 * I do not want to merge them together.
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version
25 * 2 of the License, or (at your option) any later version.
26 *
27 */
28
29/* tunnel.c: an IP tunnel driver
30
31 The purpose of this driver is to provide an IP tunnel through
32 which you can tunnel network traffic transparently across subnets.
33
34 This was written by looking at Nick Holloway's dummy driver
35 Thanks for the great code!
36
37 -Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090038
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 Minor tweaks:
40 Cleaned up the code a little and added some pre-1.3.0 tweaks.
41 dev->hard_header/hard_header_len changed to use no headers.
42 Comments/bracketing tweaked.
43 Made the tunnels use dev->name not tunnel: when error reporting.
44 Added tx_dropped stat
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090045
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 -Alan Cox (Alan.Cox@linux.org) 21 March 95
47
48 Reworked:
49 Changed to tunnel to destination gateway in addition to the
50 tunnel's pointopoint address
51 Almost completely rewritten
52 Note: There is currently no firewall or ICMP handling done.
53
54 -Sam Lantinga (slouken@cs.ucdavis.edu) 02/13/96
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090055
Linus Torvalds1da177e2005-04-16 15:20:36 -070056*/
57
58/* Things I wish I had known when writing the tunnel driver:
59
60 When the tunnel_xmit() function is called, the skb contains the
61 packet to be sent (plus a great deal of extra info), and dev
62 contains the tunnel device that _we_ are.
63
64 When we are passed a packet, we are expected to fill in the
65 source address with our source IP address.
66
67 What is the proper way to allocate, copy and free a buffer?
68 After you allocate it, it is a "0 length" chunk of memory
69 starting at zero. If you want to add headers to the buffer
70 later, you'll have to call "skb_reserve(skb, amount)" with
71 the amount of memory you want reserved. Then, you call
72 "skb_put(skb, amount)" with the amount of space you want in
73 the buffer. skb_put() returns a pointer to the top (#0) of
74 that buffer. skb->len is set to the amount of space you have
75 "allocated" with skb_put(). You can then write up to skb->len
76 bytes to that buffer. If you need more, you can call skb_put()
77 again with the additional amount of space you need. You can
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090078 find out how much more space you can allocate by calling
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 "skb_tailroom(skb)".
80 Now, to add header space, call "skb_push(skb, header_len)".
81 This creates space at the beginning of the buffer and returns
82 a pointer to this new space. If later you need to strip a
83 header from a buffer, call "skb_pull(skb, header_len)".
84 skb_headroom() will return how much space is left at the top
85 of the buffer (before the main data). Remember, this headroom
86 space must be reserved before the skb_put() function is called.
87 */
88
89/*
90 This version of net/ipv4/ipip.c is cloned of net/ipv4/ip_gre.c
91
92 For comments look at net/ipv4/ip_gre.c --ANK
93 */
94
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090095
Randy Dunlap4fc268d2006-01-11 12:17:47 -080096#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070097#include <linux/module.h>
98#include <linux/types.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070099#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#include <linux/netfilter_ipv4.h>
Kris Katterjohn46f25df2006-01-05 16:35:42 -0800110#include <linux/if_ether.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112#include <net/sock.h>
113#include <net/ip.h>
114#include <net/icmp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115#include <net/ipip.h>
116#include <net/inet_ecn.h>
117#include <net/xfrm.h>
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700118#include <net/net_namespace.h>
119#include <net/netns/generic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
121#define HASH_SIZE 16
Al Virod5a0a1e2006-11-08 00:23:14 -0800122#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700124static int ipip_net_id;
125struct ipip_net {
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700126 struct net_device *fb_tunnel_dev;
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700127};
128
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129static int ipip_fb_tunnel_init(struct net_device *dev);
130static int ipip_tunnel_init(struct net_device *dev);
131static void ipip_tunnel_setup(struct net_device *dev);
132
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
134static struct ip_tunnel *tunnels_r[HASH_SIZE];
135static struct ip_tunnel *tunnels_l[HASH_SIZE];
136static struct ip_tunnel *tunnels_wc[1];
137static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
138
139static DEFINE_RWLOCK(ipip_lock);
140
Al Virod5a0a1e2006-11-08 00:23:14 -0800141static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
143 unsigned h0 = HASH(remote);
144 unsigned h1 = HASH(local);
145 struct ip_tunnel *t;
146
147 for (t = tunnels_r_l[h0^h1]; t; t = t->next) {
148 if (local == t->parms.iph.saddr &&
149 remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
150 return t;
151 }
152 for (t = tunnels_r[h0]; t; t = t->next) {
153 if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
154 return t;
155 }
156 for (t = tunnels_l[h1]; t; t = t->next) {
157 if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP))
158 return t;
159 }
160 if ((t = tunnels_wc[0]) != NULL && (t->dev->flags&IFF_UP))
161 return t;
162 return NULL;
163}
164
YOSHIFUJI Hideaki87d1a162007-04-24 20:44:47 +0900165static struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166{
YOSHIFUJI Hideaki87d1a162007-04-24 20:44:47 +0900167 __be32 remote = parms->iph.daddr;
168 __be32 local = parms->iph.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 unsigned h = 0;
170 int prio = 0;
171
172 if (remote) {
173 prio |= 2;
174 h ^= HASH(remote);
175 }
176 if (local) {
177 prio |= 1;
178 h ^= HASH(local);
179 }
180 return &tunnels[prio][h];
181}
182
YOSHIFUJI Hideaki87d1a162007-04-24 20:44:47 +0900183static inline struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
184{
185 return __ipip_bucket(&t->parms);
186}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
188static void ipip_tunnel_unlink(struct ip_tunnel *t)
189{
190 struct ip_tunnel **tp;
191
192 for (tp = ipip_bucket(t); *tp; tp = &(*tp)->next) {
193 if (t == *tp) {
194 write_lock_bh(&ipip_lock);
195 *tp = t->next;
196 write_unlock_bh(&ipip_lock);
197 break;
198 }
199 }
200}
201
202static void ipip_tunnel_link(struct ip_tunnel *t)
203{
204 struct ip_tunnel **tp = ipip_bucket(t);
205
206 t->next = *tp;
207 write_lock_bh(&ipip_lock);
208 *tp = t;
209 write_unlock_bh(&ipip_lock);
210}
211
212static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
213{
Al Virod5a0a1e2006-11-08 00:23:14 -0800214 __be32 remote = parms->iph.daddr;
215 __be32 local = parms->iph.saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 struct ip_tunnel *t, **tp, *nt;
217 struct net_device *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 char name[IFNAMSIZ];
219
YOSHIFUJI Hideaki87d1a162007-04-24 20:44:47 +0900220 for (tp = __ipip_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
222 return t;
223 }
224 if (!create)
225 return NULL;
226
227 if (parms->name[0])
228 strlcpy(name, parms->name, IFNAMSIZ);
Pavel Emelyanov34cc7ba2008-02-23 20:19:20 -0800229 else
230 sprintf(name, "tunl%%d");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
232 dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup);
233 if (dev == NULL)
234 return NULL;
235
Pavel Emelyanovb37d4282008-02-26 23:51:04 -0800236 if (strchr(name, '%')) {
237 if (dev_alloc_name(dev, name) < 0)
238 goto failed_free;
239 }
240
Patrick McHardy2941a482006-01-08 22:05:26 -0800241 nt = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 dev->init = ipip_tunnel_init;
243 nt->parms = *parms;
244
Pavel Emelyanovb37d4282008-02-26 23:51:04 -0800245 if (register_netdevice(dev) < 0)
246 goto failed_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248 dev_hold(dev);
249 ipip_tunnel_link(nt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 return nt;
251
Pavel Emelyanovb37d4282008-02-26 23:51:04 -0800252failed_free:
253 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 return NULL;
255}
256
257static void ipip_tunnel_uninit(struct net_device *dev)
258{
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700259 struct net *net = dev_net(dev);
260 struct ipip_net *ipn = net_generic(net, ipip_net_id);
261
262 if (dev == ipn->fb_tunnel_dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 write_lock_bh(&ipip_lock);
264 tunnels_wc[0] = NULL;
265 write_unlock_bh(&ipip_lock);
266 } else
Patrick McHardy2941a482006-01-08 22:05:26 -0800267 ipip_tunnel_unlink(netdev_priv(dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 dev_put(dev);
269}
270
Herbert Xud2acc342006-03-28 01:12:13 -0800271static int ipip_err(struct sk_buff *skb, u32 info)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272{
273#ifndef I_WISH_WORLD_WERE_PERFECT
274
275/* It is not :-( All the routers (except for Linux) return only
276 8 bytes of packet payload. It means, that precise relaying of
277 ICMP in the real Internet is absolutely infeasible.
278 */
279 struct iphdr *iph = (struct iphdr*)skb->data;
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300280 const int type = icmp_hdr(skb)->type;
281 const int code = icmp_hdr(skb)->code;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 struct ip_tunnel *t;
Herbert Xud2acc342006-03-28 01:12:13 -0800283 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284
285 switch (type) {
286 default:
287 case ICMP_PARAMETERPROB:
Herbert Xud2acc342006-03-28 01:12:13 -0800288 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289
290 case ICMP_DEST_UNREACH:
291 switch (code) {
292 case ICMP_SR_FAILED:
293 case ICMP_PORT_UNREACH:
294 /* Impossible event. */
Herbert Xud2acc342006-03-28 01:12:13 -0800295 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 case ICMP_FRAG_NEEDED:
297 /* Soft state for pmtu is maintained by IP core. */
Herbert Xud2acc342006-03-28 01:12:13 -0800298 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 default:
300 /* All others are translated to HOST_UNREACH.
301 rfc2003 contains "deep thoughts" about NET_UNREACH,
302 I believe they are just ether pollution. --ANK
303 */
304 break;
305 }
306 break;
307 case ICMP_TIME_EXCEEDED:
308 if (code != ICMP_EXC_TTL)
Herbert Xud2acc342006-03-28 01:12:13 -0800309 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 break;
311 }
312
Herbert Xud2acc342006-03-28 01:12:13 -0800313 err = -ENOENT;
314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 read_lock(&ipip_lock);
316 t = ipip_tunnel_lookup(iph->daddr, iph->saddr);
317 if (t == NULL || t->parms.iph.daddr == 0)
318 goto out;
Herbert Xud2acc342006-03-28 01:12:13 -0800319
320 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
322 goto out;
323
324 if (jiffies - t->err_time < IPTUNNEL_ERR_TIMEO)
325 t->err_count++;
326 else
327 t->err_count = 1;
328 t->err_time = jiffies;
329out:
330 read_unlock(&ipip_lock);
Herbert Xud2acc342006-03-28 01:12:13 -0800331 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332#else
333 struct iphdr *iph = (struct iphdr*)dp;
334 int hlen = iph->ihl<<2;
335 struct iphdr *eiph;
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300336 const int type = icmp_hdr(skb)->type;
337 const int code = icmp_hdr(skb)->code;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 int rel_type = 0;
339 int rel_code = 0;
Al Viroc55e2f42006-09-19 13:23:19 -0700340 __be32 rel_info = 0;
341 __u32 n = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 struct sk_buff *skb2;
343 struct flowi fl;
344 struct rtable *rt;
345
346 if (len < hlen + sizeof(struct iphdr))
Herbert Xud2acc342006-03-28 01:12:13 -0800347 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 eiph = (struct iphdr*)(dp + hlen);
349
350 switch (type) {
351 default:
Herbert Xud2acc342006-03-28 01:12:13 -0800352 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 case ICMP_PARAMETERPROB:
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300354 n = ntohl(icmp_hdr(skb)->un.gateway) >> 24;
Al Viroc55e2f42006-09-19 13:23:19 -0700355 if (n < hlen)
Herbert Xud2acc342006-03-28 01:12:13 -0800356 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358 /* So... This guy found something strange INSIDE encapsulated
359 packet. Well, he is fool, but what can we do ?
360 */
361 rel_type = ICMP_PARAMETERPROB;
Al Viroc55e2f42006-09-19 13:23:19 -0700362 rel_info = htonl((n - hlen) << 24);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 break;
364
365 case ICMP_DEST_UNREACH:
366 switch (code) {
367 case ICMP_SR_FAILED:
368 case ICMP_PORT_UNREACH:
369 /* Impossible event. */
Herbert Xud2acc342006-03-28 01:12:13 -0800370 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 case ICMP_FRAG_NEEDED:
372 /* And it is the only really necessary thing :-) */
Arnaldo Carvalho de Melo88c76642007-03-13 14:43:18 -0300373 n = ntohs(icmp_hdr(skb)->un.frag.mtu);
Al Viroc55e2f42006-09-19 13:23:19 -0700374 if (n < hlen+68)
Herbert Xud2acc342006-03-28 01:12:13 -0800375 return 0;
Al Viroc55e2f42006-09-19 13:23:19 -0700376 n -= hlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */
Al Viroc55e2f42006-09-19 13:23:19 -0700378 if (n > ntohs(eiph->tot_len))
Herbert Xud2acc342006-03-28 01:12:13 -0800379 return 0;
Al Viroc55e2f42006-09-19 13:23:19 -0700380 rel_info = htonl(n);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 break;
382 default:
383 /* All others are translated to HOST_UNREACH.
384 rfc2003 contains "deep thoughts" about NET_UNREACH,
385 I believe, it is just ether pollution. --ANK
386 */
387 rel_type = ICMP_DEST_UNREACH;
388 rel_code = ICMP_HOST_UNREACH;
389 break;
390 }
391 break;
392 case ICMP_TIME_EXCEEDED:
393 if (code != ICMP_EXC_TTL)
Herbert Xud2acc342006-03-28 01:12:13 -0800394 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 break;
396 }
397
398 /* Prepare fake skb to feed it to icmp_send */
399 skb2 = skb_clone(skb, GFP_ATOMIC);
400 if (skb2 == NULL)
Herbert Xud2acc342006-03-28 01:12:13 -0800401 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 dst_release(skb2->dst);
403 skb2->dst = NULL;
404 skb_pull(skb2, skb->data - (u8*)eiph);
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -0700405 skb_reset_network_header(skb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
407 /* Try to guess incoming interface */
408 memset(&fl, 0, sizeof(fl));
409 fl.fl4_daddr = eiph->saddr;
410 fl.fl4_tos = RT_TOS(eiph->tos);
411 fl.proto = IPPROTO_IPIP;
Denis V. Lunevf2063512008-01-22 22:07:34 -0800412 if (ip_route_output_key(&init_net, &rt, &key)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 kfree_skb(skb2);
Herbert Xud2acc342006-03-28 01:12:13 -0800414 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 }
416 skb2->dev = rt->u.dst.dev;
417
418 /* route "incoming" packet */
419 if (rt->rt_flags&RTCF_LOCAL) {
420 ip_rt_put(rt);
421 rt = NULL;
422 fl.fl4_daddr = eiph->daddr;
423 fl.fl4_src = eiph->saddr;
424 fl.fl4_tos = eiph->tos;
Denis V. Lunevf2063512008-01-22 22:07:34 -0800425 if (ip_route_output_key(&init_net, &rt, &fl) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 rt->u.dst.dev->type != ARPHRD_TUNNEL) {
427 ip_rt_put(rt);
428 kfree_skb(skb2);
Herbert Xud2acc342006-03-28 01:12:13 -0800429 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 }
431 } else {
432 ip_rt_put(rt);
433 if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) ||
434 skb2->dst->dev->type != ARPHRD_TUNNEL) {
435 kfree_skb(skb2);
Herbert Xud2acc342006-03-28 01:12:13 -0800436 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 }
438 }
439
440 /* change mtu on this route */
441 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
Al Viroc55e2f42006-09-19 13:23:19 -0700442 if (n > dst_mtu(skb2->dst)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 kfree_skb(skb2);
Herbert Xud2acc342006-03-28 01:12:13 -0800444 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
Al Viroc55e2f42006-09-19 13:23:19 -0700446 skb2->dst->ops->update_pmtu(skb2->dst, n);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 } else if (type == ICMP_TIME_EXCEEDED) {
Patrick McHardy2941a482006-01-08 22:05:26 -0800448 struct ip_tunnel *t = netdev_priv(skb2->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 if (t->parms.iph.ttl) {
450 rel_type = ICMP_DEST_UNREACH;
451 rel_code = ICMP_HOST_UNREACH;
452 }
453 }
454
455 icmp_send(skb2, rel_type, rel_code, rel_info);
456 kfree_skb(skb2);
Herbert Xud2acc342006-03-28 01:12:13 -0800457 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458#endif
459}
460
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700461static inline void ipip_ecn_decapsulate(const struct iphdr *outer_iph,
462 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463{
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700464 struct iphdr *inner_iph = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
466 if (INET_ECN_is_ce(outer_iph->tos))
467 IP_ECN_set_ce(inner_iph);
468}
469
470static int ipip_rcv(struct sk_buff *skb)
471{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 struct ip_tunnel *tunnel;
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700473 const struct iphdr *iph = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 read_lock(&ipip_lock);
476 if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
477 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
478 read_unlock(&ipip_lock);
479 kfree_skb(skb);
480 return 0;
481 }
482
483 secpath_reset(skb);
484
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700485 skb->mac_header = skb->network_header;
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -0700486 skb_reset_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 skb->protocol = htons(ETH_P_IP);
488 skb->pkt_type = PACKET_HOST;
489
490 tunnel->stat.rx_packets++;
491 tunnel->stat.rx_bytes += skb->len;
492 skb->dev = tunnel->dev;
493 dst_release(skb->dst);
494 skb->dst = NULL;
495 nf_reset(skb);
496 ipip_ecn_decapsulate(iph, skb);
497 netif_rx(skb);
498 read_unlock(&ipip_lock);
499 return 0;
500 }
501 read_unlock(&ipip_lock);
502
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 return -1;
504}
505
506/*
507 * This function assumes it is being called from dev_queue_xmit()
508 * and that skb is filled properly by that function.
509 */
510
511static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
512{
Patrick McHardy2941a482006-01-08 22:05:26 -0800513 struct ip_tunnel *tunnel = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 struct net_device_stats *stats = &tunnel->stat;
515 struct iphdr *tiph = &tunnel->parms.iph;
516 u8 tos = tunnel->parms.iph.tos;
Al Virod5a0a1e2006-11-08 00:23:14 -0800517 __be16 df = tiph->frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 struct rtable *rt; /* Route to the other host */
519 struct net_device *tdev; /* Device to other host */
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700520 struct iphdr *old_iph = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 struct iphdr *iph; /* Our new IP header */
Chuck Leverc2636b42007-10-23 21:07:32 -0700522 unsigned int max_headroom; /* The extra header space needed */
Al Virod5a0a1e2006-11-08 00:23:14 -0800523 __be32 dst = tiph->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 int mtu;
525
526 if (tunnel->recursion++) {
527 tunnel->stat.collisions++;
528 goto tx_error;
529 }
530
531 if (skb->protocol != htons(ETH_P_IP))
532 goto tx_error;
533
534 if (tos&1)
535 tos = old_iph->tos;
536
537 if (!dst) {
538 /* NBMA tunnel */
Eric Dumazetee6b9672008-03-05 18:30:47 -0800539 if ((rt = skb->rtable) == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 tunnel->stat.tx_fifo_errors++;
541 goto tx_error;
542 }
543 if ((dst = rt->rt_gateway) == 0)
544 goto tx_error_icmp;
545 }
546
547 {
548 struct flowi fl = { .oif = tunnel->parms.link,
549 .nl_u = { .ip4_u =
550 { .daddr = dst,
551 .saddr = tiph->saddr,
552 .tos = RT_TOS(tos) } },
553 .proto = IPPROTO_IPIP };
Denis V. Lunevf2063512008-01-22 22:07:34 -0800554 if (ip_route_output_key(&init_net, &rt, &fl)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 tunnel->stat.tx_carrier_errors++;
556 goto tx_error_icmp;
557 }
558 }
559 tdev = rt->u.dst.dev;
560
561 if (tdev == dev) {
562 ip_rt_put(rt);
563 tunnel->stat.collisions++;
564 goto tx_error;
565 }
566
567 if (tiph->frag_off)
568 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
569 else
570 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
571
572 if (mtu < 68) {
573 tunnel->stat.collisions++;
574 ip_rt_put(rt);
575 goto tx_error;
576 }
577 if (skb->dst)
578 skb->dst->ops->update_pmtu(skb->dst, mtu);
579
580 df |= (old_iph->frag_off&htons(IP_DF));
581
582 if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
583 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
584 ip_rt_put(rt);
585 goto tx_error;
586 }
587
588 if (tunnel->err_count > 0) {
589 if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
590 tunnel->err_count--;
591 dst_link_failure(skb);
592 } else
593 tunnel->err_count = 0;
594 }
595
596 /*
597 * Okay, now see if we can stuff it in the buffer as-is.
598 */
599 max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
600
Patrick McHardycfbba492007-07-09 15:33:40 -0700601 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
602 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
604 if (!new_skb) {
605 ip_rt_put(rt);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900606 stats->tx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 dev_kfree_skb(skb);
608 tunnel->recursion--;
609 return 0;
610 }
611 if (skb->sk)
612 skb_set_owner_w(new_skb, skb->sk);
613 dev_kfree_skb(skb);
614 skb = new_skb;
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700615 old_iph = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 }
617
Arnaldo Carvalho de Melob0e380b2007-04-10 21:21:55 -0700618 skb->transport_header = skb->network_header;
Arnaldo Carvalho de Meloe2d1bca2007-04-10 20:46:21 -0700619 skb_push(skb, sizeof(struct iphdr));
620 skb_reset_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
Patrick McHardy48d5cad2006-02-15 15:10:22 -0800622 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
623 IPSKB_REROUTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 dst_release(skb->dst);
625 skb->dst = &rt->u.dst;
626
627 /*
628 * Push down and install the IPIP header.
629 */
630
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700631 iph = ip_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 iph->version = 4;
633 iph->ihl = sizeof(struct iphdr)>>2;
634 iph->frag_off = df;
635 iph->protocol = IPPROTO_IPIP;
636 iph->tos = INET_ECN_encapsulate(tos, old_iph->tos);
637 iph->daddr = rt->rt_dst;
638 iph->saddr = rt->rt_src;
639
640 if ((iph->ttl = tiph->ttl) == 0)
641 iph->ttl = old_iph->ttl;
642
643 nf_reset(skb);
644
645 IPTUNNEL_XMIT();
646 tunnel->recursion--;
647 return 0;
648
649tx_error_icmp:
650 dst_link_failure(skb);
651tx_error:
652 stats->tx_errors++;
653 dev_kfree_skb(skb);
654 tunnel->recursion--;
655 return 0;
656}
657
Michal Schmidt55339952007-12-12 11:01:43 -0800658static void ipip_tunnel_bind_dev(struct net_device *dev)
659{
660 struct net_device *tdev = NULL;
661 struct ip_tunnel *tunnel;
662 struct iphdr *iph;
663
664 tunnel = netdev_priv(dev);
665 iph = &tunnel->parms.iph;
666
667 if (iph->daddr) {
668 struct flowi fl = { .oif = tunnel->parms.link,
669 .nl_u = { .ip4_u =
670 { .daddr = iph->daddr,
671 .saddr = iph->saddr,
672 .tos = RT_TOS(iph->tos) } },
673 .proto = IPPROTO_IPIP };
674 struct rtable *rt;
Denis V. Lunevf2063512008-01-22 22:07:34 -0800675 if (!ip_route_output_key(&init_net, &rt, &fl)) {
Michal Schmidt55339952007-12-12 11:01:43 -0800676 tdev = rt->u.dst.dev;
677 ip_rt_put(rt);
678 }
679 dev->flags |= IFF_POINTOPOINT;
680 }
681
682 if (!tdev && tunnel->parms.link)
683 tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
684
685 if (tdev) {
686 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
687 dev->mtu = tdev->mtu - sizeof(struct iphdr);
688 }
689 dev->iflink = tunnel->parms.link;
690}
691
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692static int
693ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
694{
695 int err = 0;
696 struct ip_tunnel_parm p;
697 struct ip_tunnel *t;
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700698 struct net *net = dev_net(dev);
699 struct ipip_net *ipn = net_generic(net, ipip_net_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 switch (cmd) {
702 case SIOCGETTUNNEL:
703 t = NULL;
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700704 if (dev == ipn->fb_tunnel_dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
706 err = -EFAULT;
707 break;
708 }
709 t = ipip_tunnel_locate(&p, 0);
710 }
711 if (t == NULL)
Patrick McHardy2941a482006-01-08 22:05:26 -0800712 t = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 memcpy(&p, &t->parms, sizeof(p));
714 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
715 err = -EFAULT;
716 break;
717
718 case SIOCADDTUNNEL:
719 case SIOCCHGTUNNEL:
720 err = -EPERM;
721 if (!capable(CAP_NET_ADMIN))
722 goto done;
723
724 err = -EFAULT;
725 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
726 goto done;
727
728 err = -EINVAL;
729 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPIP ||
730 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
731 goto done;
732 if (p.iph.ttl)
733 p.iph.frag_off |= htons(IP_DF);
734
735 t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
736
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700737 if (dev != ipn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 if (t != NULL) {
739 if (t->dev != dev) {
740 err = -EEXIST;
741 break;
742 }
743 } else {
744 if (((dev->flags&IFF_POINTOPOINT) && !p.iph.daddr) ||
745 (!(dev->flags&IFF_POINTOPOINT) && p.iph.daddr)) {
746 err = -EINVAL;
747 break;
748 }
Patrick McHardy2941a482006-01-08 22:05:26 -0800749 t = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 ipip_tunnel_unlink(t);
751 t->parms.iph.saddr = p.iph.saddr;
752 t->parms.iph.daddr = p.iph.daddr;
753 memcpy(dev->dev_addr, &p.iph.saddr, 4);
754 memcpy(dev->broadcast, &p.iph.daddr, 4);
755 ipip_tunnel_link(t);
756 netdev_state_change(dev);
757 }
758 }
759
760 if (t) {
761 err = 0;
762 if (cmd == SIOCCHGTUNNEL) {
763 t->parms.iph.ttl = p.iph.ttl;
764 t->parms.iph.tos = p.iph.tos;
765 t->parms.iph.frag_off = p.iph.frag_off;
Michal Schmidt55339952007-12-12 11:01:43 -0800766 if (t->parms.link != p.link) {
767 t->parms.link = p.link;
768 ipip_tunnel_bind_dev(dev);
769 netdev_state_change(dev);
770 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 }
772 if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
773 err = -EFAULT;
774 } else
775 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
776 break;
777
778 case SIOCDELTUNNEL:
779 err = -EPERM;
780 if (!capable(CAP_NET_ADMIN))
781 goto done;
782
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700783 if (dev == ipn->fb_tunnel_dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 err = -EFAULT;
785 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
786 goto done;
787 err = -ENOENT;
788 if ((t = ipip_tunnel_locate(&p, 0)) == NULL)
789 goto done;
790 err = -EPERM;
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700791 if (t->dev == ipn->fb_tunnel_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 goto done;
793 dev = t->dev;
794 }
Stephen Hemminger22f8cde2007-02-07 00:09:58 -0800795 unregister_netdevice(dev);
796 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 break;
798
799 default:
800 err = -EINVAL;
801 }
802
803done:
804 return err;
805}
806
807static struct net_device_stats *ipip_tunnel_get_stats(struct net_device *dev)
808{
Patrick McHardy2941a482006-01-08 22:05:26 -0800809 return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810}
811
812static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
813{
814 if (new_mtu < 68 || new_mtu > 0xFFF8 - sizeof(struct iphdr))
815 return -EINVAL;
816 dev->mtu = new_mtu;
817 return 0;
818}
819
820static void ipip_tunnel_setup(struct net_device *dev)
821{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 dev->uninit = ipip_tunnel_uninit;
823 dev->hard_start_xmit = ipip_tunnel_xmit;
824 dev->get_stats = ipip_tunnel_get_stats;
825 dev->do_ioctl = ipip_tunnel_ioctl;
826 dev->change_mtu = ipip_tunnel_change_mtu;
827 dev->destructor = free_netdev;
828
829 dev->type = ARPHRD_TUNNEL;
830 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
Kris Katterjohn46f25df2006-01-05 16:35:42 -0800831 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 dev->flags = IFF_NOARP;
833 dev->iflink = 0;
834 dev->addr_len = 4;
835}
836
837static int ipip_tunnel_init(struct net_device *dev)
838{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 struct ip_tunnel *tunnel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Patrick McHardy2941a482006-01-08 22:05:26 -0800841 tunnel = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
843 tunnel->dev = dev;
844 strcpy(tunnel->parms.name, dev->name);
845
846 memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
847 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
848
Michal Schmidt55339952007-12-12 11:01:43 -0800849 ipip_tunnel_bind_dev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
851 return 0;
852}
853
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700854static int ipip_fb_tunnel_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855{
Patrick McHardy2941a482006-01-08 22:05:26 -0800856 struct ip_tunnel *tunnel = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 struct iphdr *iph = &tunnel->parms.iph;
858
859 tunnel->dev = dev;
860 strcpy(tunnel->parms.name, dev->name);
861
862 iph->version = 4;
863 iph->protocol = IPPROTO_IPIP;
864 iph->ihl = 5;
865
866 dev_hold(dev);
867 tunnels_wc[0] = tunnel;
868 return 0;
869}
870
871static struct xfrm_tunnel ipip_handler = {
872 .handler = ipip_rcv,
873 .err_handler = ipip_err,
Herbert Xud2acc342006-03-28 01:12:13 -0800874 .priority = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875};
876
877static char banner[] __initdata =
878 KERN_INFO "IPv4 over IPv4 tunneling driver\n";
879
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700880static int ipip_init_net(struct net *net)
881{
882 int err;
883 struct ipip_net *ipn;
884
885 err = -ENOMEM;
886 ipn = kmalloc(sizeof(struct ipip_net), GFP_KERNEL);
887 if (ipn == NULL)
888 goto err_alloc;
889
890 err = net_assign_generic(net, ipip_net_id, ipn);
891 if (err < 0)
892 goto err_assign;
893
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700894 ipn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel),
895 "tunl0",
896 ipip_tunnel_setup);
897 if (!ipn->fb_tunnel_dev) {
898 err = -ENOMEM;
899 goto err_alloc_dev;
900 }
901
902 ipn->fb_tunnel_dev->init = ipip_fb_tunnel_init;
903 dev_net_set(ipn->fb_tunnel_dev, net);
904
905 if ((err = register_netdev(ipn->fb_tunnel_dev)))
906 goto err_reg_dev;
907
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700908 return 0;
909
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700910err_reg_dev:
911 free_netdev(ipn->fb_tunnel_dev);
912err_alloc_dev:
913 /* nothing */
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700914err_assign:
915 kfree(ipn);
916err_alloc:
917 return err;
918}
919
920static void ipip_exit_net(struct net *net)
921{
922 struct ipip_net *ipn;
923
924 ipn = net_generic(net, ipip_net_id);
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700925 rtnl_lock();
926 unregister_netdevice(ipn->fb_tunnel_dev);
927 rtnl_unlock();
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700928 kfree(ipn);
929}
930
931static struct pernet_operations ipip_net_ops = {
932 .init = ipip_init_net,
933 .exit = ipip_exit_net,
934};
935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936static int __init ipip_init(void)
937{
938 int err;
939
940 printk(banner);
941
Kazunori MIYAZAWAc0d56402007-02-13 12:54:47 -0800942 if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 printk(KERN_INFO "ipip init: can't register tunnel\n");
944 return -EAGAIN;
945 }
946
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700947 err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops);
948 if (err)
Pavel Emelyanovb9855c52008-04-16 01:04:13 -0700949 xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
950
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952}
953
Alexey Kuznetsovdb445752005-07-30 17:46:44 -0700954static void __exit ipip_destroy_tunnels(void)
955{
956 int prio;
957
958 for (prio = 1; prio < 4; prio++) {
959 int h;
960 for (h = 0; h < HASH_SIZE; h++) {
961 struct ip_tunnel *t;
962 while ((t = tunnels[prio][h]) != NULL)
963 unregister_netdevice(t->dev);
964 }
965 }
966}
967
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968static void __exit ipip_fini(void)
969{
Kazunori MIYAZAWAc0d56402007-02-13 12:54:47 -0800970 if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 printk(KERN_INFO "ipip close: can't deregister tunnel\n");
972
Alexey Kuznetsovdb445752005-07-30 17:46:44 -0700973 rtnl_lock();
974 ipip_destroy_tunnels();
Alexey Kuznetsovdb445752005-07-30 17:46:44 -0700975 rtnl_unlock();
Pavel Emelyanov10dc4c72008-04-16 01:03:13 -0700976
977 unregister_pernet_gen_device(ipip_net_id, &ipip_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978}
979
980module_init(ipip_init);
981module_exit(ipip_fini);
982MODULE_LICENSE("GPL");