Blame view
net/ipv6/sit.c
29 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 |
/* * IPv6 over IPv4 tunnel device - Simple Internet Transition (SIT) * Linux INET6 implementation * * Authors: |
1ab1457c4 [NET] IPV6: Fix w... |
6 |
* Pedro Roque <roque@di.fc.ul.pt> |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> * |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 14 15 16 |
* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Changes: * Roger Venning <r.venning@telstra.com>: 6to4 support * Nate Thompson <nate@thebog.net>: 6to4 support |
fadf6bf06 [IPV6] SIT: Add P... |
17 |
* Fred Templin <fred.l.templin@boeing.com>: isatap support |
1da177e4c Linux-2.6.12-rc2 |
18 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
19 |
#include <linux/module.h> |
4fc268d24 [PATCH] capable/c... |
20 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 |
#include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> #include <linux/sockios.h> |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 28 29 |
#include <linux/net.h> #include <linux/in6.h> #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/icmp.h> |
5a0e3ad6a include cleanup: ... |
30 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
31 32 33 |
#include <asm/uaccess.h> #include <linux/init.h> #include <linux/netfilter_ipv4.h> |
46f25dffb [NET]: Change 150... |
34 |
#include <linux/if_ether.h> |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <net/sock.h> #include <net/snmp.h> #include <net/ipv6.h> #include <net/protocol.h> #include <net/transp_v6.h> #include <net/ip6_fib.h> #include <net/ip6_route.h> #include <net/ndisc.h> #include <net/addrconf.h> #include <net/ip.h> #include <net/udp.h> #include <net/icmp.h> #include <net/ipip.h> #include <net/inet_ecn.h> #include <net/xfrm.h> #include <net/dsfield.h> |
8190d9009 [SIT]: Introduce ... |
53 54 |
#include <net/net_namespace.h> #include <net/netns/generic.h> |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 62 |
/* This version of net/ipv6/sit.c is cloned of net/ipv4/ip_gre.c For comments look at net/ipv4/ip_gre.c --ANK */ #define HASH_SIZE 16 |
e69a4adc6 [IPV6]: Misc endi... |
63 |
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
15fc1f705 sit: percpu stats... |
65 |
static int ipip6_tunnel_init(struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
66 |
static void ipip6_tunnel_setup(struct net_device *dev); |
15fc1f705 sit: percpu stats... |
67 |
static void ipip6_dev_free(struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
68 |
|
f99189b18 netns: net_identi... |
69 |
static int sit_net_id __read_mostly; |
8190d9009 [SIT]: Introduce ... |
70 |
struct sit_net { |
3a43be3c3 sit: get rid of i... |
71 72 73 74 75 |
struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE]; struct ip_tunnel __rcu *tunnels_r[HASH_SIZE]; struct ip_tunnel __rcu *tunnels_l[HASH_SIZE]; struct ip_tunnel __rcu *tunnels_wc[1]; struct ip_tunnel __rcu **tunnels[4]; |
291821766 [SIT]: Make tunne... |
76 |
|
cd3dbc194 [SIT]: Make the f... |
77 |
struct net_device *fb_tunnel_dev; |
8190d9009 [SIT]: Introduce ... |
78 |
}; |
4543c10de ipv6 sit: RCU con... |
79 |
/* |
3a43be3c3 sit: get rid of i... |
80 |
* Locking : hash tables are protected by RCU and RTNL |
4543c10de ipv6 sit: RCU con... |
81 |
*/ |
4543c10de ipv6 sit: RCU con... |
82 83 84 |
#define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
1da177e4c Linux-2.6.12-rc2 |
85 |
|
15fc1f705 sit: percpu stats... |
86 87 88 89 90 91 |
/* often modified stats are per cpu, other are shared (netdev->stats) */ struct pcpu_tstats { unsigned long rx_packets; unsigned long rx_bytes; unsigned long tx_packets; unsigned long tx_bytes; |
8ce120f11 net: better pcpu ... |
92 |
} __attribute__((aligned(4*sizeof(unsigned long)))); |
15fc1f705 sit: percpu stats... |
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
static struct net_device_stats *ipip6_get_stats(struct net_device *dev) { struct pcpu_tstats sum = { 0 }; int i; for_each_possible_cpu(i) { const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); sum.rx_packets += tstats->rx_packets; sum.rx_bytes += tstats->rx_bytes; sum.tx_packets += tstats->tx_packets; sum.tx_bytes += tstats->tx_bytes; } dev->stats.rx_packets = sum.rx_packets; dev->stats.rx_bytes = sum.rx_bytes; dev->stats.tx_packets = sum.tx_packets; dev->stats.tx_bytes = sum.tx_bytes; return &dev->stats; } |
4543c10de ipv6 sit: RCU con... |
113 114 115 |
/* * Must be invoked with rcu_read_lock */ |
ca8def148 [SIT]: Add net/si... |
116 |
static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, |
4fddbf5d7 sit: strictly res... |
117 |
struct net_device *dev, __be32 remote, __be32 local) |
1da177e4c Linux-2.6.12-rc2 |
118 |
{ |
3a43be3c3 sit: get rid of i... |
119 120 |
unsigned int h0 = HASH(remote); unsigned int h1 = HASH(local); |
1da177e4c Linux-2.6.12-rc2 |
121 |
struct ip_tunnel *t; |
291821766 [SIT]: Make tunne... |
122 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
1da177e4c Linux-2.6.12-rc2 |
123 |
|
4543c10de ipv6 sit: RCU con... |
124 |
for_each_ip_tunnel_rcu(sitn->tunnels_r_l[h0 ^ h1]) { |
1da177e4c Linux-2.6.12-rc2 |
125 |
if (local == t->parms.iph.saddr && |
4fddbf5d7 sit: strictly res... |
126 127 128 |
remote == t->parms.iph.daddr && (!dev || !t->parms.link || dev->iflink == t->parms.link) && (t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
129 130 |
return t; } |
4543c10de ipv6 sit: RCU con... |
131 |
for_each_ip_tunnel_rcu(sitn->tunnels_r[h0]) { |
4fddbf5d7 sit: strictly res... |
132 133 134 |
if (remote == t->parms.iph.daddr && (!dev || !t->parms.link || dev->iflink == t->parms.link) && (t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
135 136 |
return t; } |
4543c10de ipv6 sit: RCU con... |
137 |
for_each_ip_tunnel_rcu(sitn->tunnels_l[h1]) { |
4fddbf5d7 sit: strictly res... |
138 139 140 |
if (local == t->parms.iph.saddr && (!dev || !t->parms.link || dev->iflink == t->parms.link) && (t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
141 142 |
return t; } |
4543c10de ipv6 sit: RCU con... |
143 |
t = rcu_dereference(sitn->tunnels_wc[0]); |
4fddbf5d7 sit: strictly res... |
144 |
if ((t != NULL) && (t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
145 146 147 |
return t; return NULL; } |
3a43be3c3 sit: get rid of i... |
148 |
static struct ip_tunnel __rcu **__ipip6_bucket(struct sit_net *sitn, |
ca8def148 [SIT]: Add net/si... |
149 |
struct ip_tunnel_parm *parms) |
1da177e4c Linux-2.6.12-rc2 |
150 |
{ |
420fe234a [IPV6] SIT: Unify... |
151 152 |
__be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; |
3a43be3c3 sit: get rid of i... |
153 |
unsigned int h = 0; |
1da177e4c Linux-2.6.12-rc2 |
154 155 156 157 158 159 160 161 162 163 |
int prio = 0; if (remote) { prio |= 2; h ^= HASH(remote); } if (local) { prio |= 1; h ^= HASH(local); } |
291821766 [SIT]: Make tunne... |
164 |
return &sitn->tunnels[prio][h]; |
1da177e4c Linux-2.6.12-rc2 |
165 |
} |
3a43be3c3 sit: get rid of i... |
166 |
static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn, |
ca8def148 [SIT]: Add net/si... |
167 |
struct ip_tunnel *t) |
420fe234a [IPV6] SIT: Unify... |
168 |
{ |
ca8def148 [SIT]: Add net/si... |
169 |
return __ipip6_bucket(sitn, &t->parms); |
420fe234a [IPV6] SIT: Unify... |
170 |
} |
ca8def148 [SIT]: Add net/si... |
171 |
static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) |
1da177e4c Linux-2.6.12-rc2 |
172 |
{ |
3a43be3c3 sit: get rid of i... |
173 174 175 176 177 178 179 |
struct ip_tunnel __rcu **tp; struct ip_tunnel *iter; for (tp = ipip6_bucket(sitn, t); (iter = rtnl_dereference(*tp)) != NULL; tp = &iter->next) { if (t == iter) { |
cf778b00e net: reintroduce ... |
180 |
rcu_assign_pointer(*tp, t->next); |
1da177e4c Linux-2.6.12-rc2 |
181 182 183 184 |
break; } } } |
ca8def148 [SIT]: Add net/si... |
185 |
static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t) |
1da177e4c Linux-2.6.12-rc2 |
186 |
{ |
3a43be3c3 sit: get rid of i... |
187 |
struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t); |
1da177e4c Linux-2.6.12-rc2 |
188 |
|
cf778b00e net: reintroduce ... |
189 190 |
rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); |
1da177e4c Linux-2.6.12-rc2 |
191 |
} |
e0c939481 ipv6 sit: Ensure ... |
192 |
static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) |
fa857afcf ipv6 sit: 6rd (IP... |
193 194 |
{ #ifdef CONFIG_IPV6_SIT_6RD |
e0c939481 ipv6 sit: Ensure ... |
195 |
struct ip_tunnel *t = netdev_priv(dev); |
fa857afcf ipv6 sit: 6rd (IP... |
196 197 198 199 200 201 202 203 204 205 206 |
if (t->dev == sitn->fb_tunnel_dev) { ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0); t->ip6rd.relay_prefix = 0; t->ip6rd.prefixlen = 16; t->ip6rd.relay_prefixlen = 0; } else { struct ip_tunnel *t0 = netdev_priv(sitn->fb_tunnel_dev); memcpy(&t->ip6rd, &t0->ip6rd, sizeof(t->ip6rd)); } #endif } |
3a43be3c3 sit: get rid of i... |
207 |
static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, |
ca8def148 [SIT]: Add net/si... |
208 |
struct ip_tunnel_parm *parms, int create) |
1da177e4c Linux-2.6.12-rc2 |
209 |
{ |
e69a4adc6 [IPV6]: Misc endi... |
210 211 |
__be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; |
3a43be3c3 sit: get rid of i... |
212 213 |
struct ip_tunnel *t, *nt; struct ip_tunnel __rcu **tp; |
1da177e4c Linux-2.6.12-rc2 |
214 |
struct net_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
215 |
char name[IFNAMSIZ]; |
ca8def148 [SIT]: Add net/si... |
216 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
1da177e4c Linux-2.6.12-rc2 |
217 |
|
3a43be3c3 sit: get rid of i... |
218 219 220 |
for (tp = __ipip6_bucket(sitn, parms); (t = rtnl_dereference(*tp)) != NULL; tp = &t->next) { |
8db99e571 sit: Fail to crea... |
221 |
if (local == t->parms.iph.saddr && |
4fddbf5d7 sit: strictly res... |
222 223 |
remote == t->parms.iph.daddr && parms->link == t->parms.link) { |
8db99e571 sit: Fail to crea... |
224 225 226 227 228 |
if (create) return NULL; else return t; } |
1da177e4c Linux-2.6.12-rc2 |
229 230 231 232 233 234 |
} if (!create) goto failed; if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); |
34cc7ba63 [IP_TUNNEL]: Don'... |
235 |
else |
15fc1f705 sit: percpu stats... |
236 |
strcpy(name, "sit%d"); |
1da177e4c Linux-2.6.12-rc2 |
237 238 239 240 |
dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) return NULL; |
7a97146cc [SIT]: Allow to c... |
241 |
dev_net_set(dev, net); |
2941a4863 [NET]: Convert ne... |
242 |
nt = netdev_priv(dev); |
1326c3d5a ipv6: convert tun... |
243 |
|
1da177e4c Linux-2.6.12-rc2 |
244 |
nt->parms = *parms; |
15fc1f705 sit: percpu stats... |
245 246 |
if (ipip6_tunnel_init(dev) < 0) goto failed_free; |
e0c939481 ipv6 sit: Ensure ... |
247 |
ipip6_tunnel_clone_6rd(dev, sitn); |
1da177e4c Linux-2.6.12-rc2 |
248 |
|
c7dc89c0a [IPV6]: Add RFC42... |
249 250 |
if (parms->i_flags & SIT_ISATAP) dev->priv_flags |= IFF_ISATAP; |
b37d428b2 [INET]: Don't cre... |
251 252 |
if (register_netdevice(dev) < 0) goto failed_free; |
1da177e4c Linux-2.6.12-rc2 |
253 |
|
72b36015b ipip, sit: copy p... |
254 |
strcpy(nt->parms.name, dev->name); |
1da177e4c Linux-2.6.12-rc2 |
255 |
dev_hold(dev); |
ca8def148 [SIT]: Add net/si... |
256 |
ipip6_tunnel_link(sitn, nt); |
1da177e4c Linux-2.6.12-rc2 |
257 |
return nt; |
b37d428b2 [INET]: Don't cre... |
258 |
failed_free: |
15fc1f705 sit: percpu stats... |
259 |
ipip6_dev_free(dev); |
1da177e4c Linux-2.6.12-rc2 |
260 261 262 |
failed: return NULL; } |
ef9a9d118 ipv6 sit: RCU con... |
263 264 265 266 |
#define for_each_prl_rcu(start) \ for (prl = rcu_dereference(start); \ prl; \ prl = rcu_dereference(prl->next)) |
fadf6bf06 [IPV6] SIT: Add P... |
267 |
static struct ip_tunnel_prl_entry * |
3fcfa1290 [IPV6] SIT: Fix l... |
268 |
__ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) |
fadf6bf06 [IPV6] SIT: Add P... |
269 |
{ |
ef9a9d118 ipv6 sit: RCU con... |
270 |
struct ip_tunnel_prl_entry *prl; |
fadf6bf06 [IPV6] SIT: Add P... |
271 |
|
ef9a9d118 ipv6 sit: RCU con... |
272 273 |
for_each_prl_rcu(t->prl) if (prl->addr == addr) |
fadf6bf06 [IPV6] SIT: Add P... |
274 |
break; |
ef9a9d118 ipv6 sit: RCU con... |
275 |
return prl; |
fadf6bf06 [IPV6] SIT: Add P... |
276 277 |
} |
2b4743bd6 ipv6 sit: Avoid e... |
278 279 |
static int ipip6_tunnel_get_prl(struct ip_tunnel *t, struct ip_tunnel_prl __user *a) |
300aaeeaa [IPV6] SIT: Add S... |
280 |
{ |
2b4743bd6 ipv6 sit: Avoid e... |
281 |
struct ip_tunnel_prl kprl, *kp; |
300aaeeaa [IPV6] SIT: Add S... |
282 283 284 |
struct ip_tunnel_prl_entry *prl; unsigned int cmax, c = 0, ca, len; int ret = 0; |
2b4743bd6 ipv6 sit: Avoid e... |
285 286 287 288 |
if (copy_from_user(&kprl, a, sizeof(kprl))) return -EFAULT; cmax = kprl.datalen / sizeof(kprl); if (cmax > 1 && kprl.addr != htonl(INADDR_ANY)) |
300aaeeaa [IPV6] SIT: Add S... |
289 290 291 292 293 294 295 296 |
cmax = 1; /* For simple GET or for root users, * we try harder to allocate. */ kp = (cmax <= 1 || capable(CAP_NET_ADMIN)) ? kcalloc(cmax, sizeof(*kp), GFP_KERNEL) : NULL; |
ef9a9d118 ipv6 sit: RCU con... |
297 |
rcu_read_lock(); |
300aaeeaa [IPV6] SIT: Add S... |
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
ca = t->prl_count < cmax ? t->prl_count : cmax; if (!kp) { /* We don't try hard to allocate much memory for * non-root users. * For root users, retry allocating enough memory for * the answer. */ kp = kcalloc(ca, sizeof(*kp), GFP_ATOMIC); if (!kp) { ret = -ENOMEM; goto out; } } c = 0; |
ef9a9d118 ipv6 sit: RCU con... |
315 |
for_each_prl_rcu(t->prl) { |
298bf12dd sit: fix off-by-o... |
316 |
if (c >= cmax) |
300aaeeaa [IPV6] SIT: Add S... |
317 |
break; |
2b4743bd6 ipv6 sit: Avoid e... |
318 |
if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) |
300aaeeaa [IPV6] SIT: Add S... |
319 320 321 322 |
continue; kp[c].addr = prl->addr; kp[c].flags = prl->flags; c++; |
2b4743bd6 ipv6 sit: Avoid e... |
323 |
if (kprl.addr != htonl(INADDR_ANY)) |
300aaeeaa [IPV6] SIT: Add S... |
324 325 326 |
break; } out: |
ef9a9d118 ipv6 sit: RCU con... |
327 |
rcu_read_unlock(); |
300aaeeaa [IPV6] SIT: Add S... |
328 329 |
len = sizeof(*kp) * c; |
2b4743bd6 ipv6 sit: Avoid e... |
330 331 332 |
ret = 0; if ((len && copy_to_user(a + 1, kp, len)) || put_user(len, &a->datalen)) ret = -EFAULT; |
300aaeeaa [IPV6] SIT: Add S... |
333 334 |
kfree(kp); |
300aaeeaa [IPV6] SIT: Add S... |
335 |
|
2b4743bd6 ipv6 sit: Avoid e... |
336 |
return ret; |
300aaeeaa [IPV6] SIT: Add S... |
337 |
} |
fadf6bf06 [IPV6] SIT: Add P... |
338 339 340 341 |
static int ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) { struct ip_tunnel_prl_entry *p; |
3fcfa1290 [IPV6] SIT: Fix l... |
342 |
int err = 0; |
0009ae1f5 [IPV6] SIT: Disal... |
343 344 |
if (a->addr == htonl(INADDR_ANY)) return -EINVAL; |
aac4dddc3 ipv6: get rid of ... |
345 |
ASSERT_RTNL(); |
fadf6bf06 [IPV6] SIT: Add P... |
346 |
|
3a43be3c3 sit: get rid of i... |
347 |
for (p = rtnl_dereference(t->prl); p; p = rtnl_dereference(p->next)) { |
300aaeeaa [IPV6] SIT: Add S... |
348 |
if (p->addr == a->addr) { |
ef9a9d118 ipv6 sit: RCU con... |
349 350 351 352 |
if (chg) { p->flags = a->flags; goto out; } |
3fcfa1290 [IPV6] SIT: Fix l... |
353 354 |
err = -EEXIST; goto out; |
fadf6bf06 [IPV6] SIT: Add P... |
355 356 |
} } |
3fcfa1290 [IPV6] SIT: Fix l... |
357 358 359 360 |
if (chg) { err = -ENXIO; goto out; } |
fadf6bf06 [IPV6] SIT: Add P... |
361 362 |
p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); |
3fcfa1290 [IPV6] SIT: Fix l... |
363 364 365 366 |
if (!p) { err = -ENOBUFS; goto out; } |
fadf6bf06 [IPV6] SIT: Add P... |
367 |
|
fadf6bf06 [IPV6] SIT: Add P... |
368 |
p->next = t->prl; |
300aaeeaa [IPV6] SIT: Add S... |
369 370 |
p->addr = a->addr; p->flags = a->flags; |
ef9a9d118 ipv6 sit: RCU con... |
371 |
t->prl_count++; |
cf778b00e net: reintroduce ... |
372 |
rcu_assign_pointer(t->prl, p); |
3fcfa1290 [IPV6] SIT: Fix l... |
373 |
out: |
3fcfa1290 [IPV6] SIT: Fix l... |
374 |
return err; |
fadf6bf06 [IPV6] SIT: Add P... |
375 |
} |
ef9a9d118 ipv6 sit: RCU con... |
376 377 378 379 380 381 |
static void prl_list_destroy_rcu(struct rcu_head *head) { struct ip_tunnel_prl_entry *p, *n; p = container_of(head, struct ip_tunnel_prl_entry, rcu_head); do { |
753ea8e96 net: ipv6: sit: f... |
382 |
n = rcu_dereference_protected(p->next, 1); |
ef9a9d118 ipv6 sit: RCU con... |
383 384 385 386 |
kfree(p); p = n; } while (p); } |
fadf6bf06 [IPV6] SIT: Add P... |
387 388 389 |
static int ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) { |
753ea8e96 net: ipv6: sit: f... |
390 391 |
struct ip_tunnel_prl_entry *x; struct ip_tunnel_prl_entry __rcu **p; |
3fcfa1290 [IPV6] SIT: Fix l... |
392 |
int err = 0; |
aac4dddc3 ipv6: get rid of ... |
393 |
ASSERT_RTNL(); |
fadf6bf06 [IPV6] SIT: Add P... |
394 |
|
0009ae1f5 [IPV6] SIT: Disal... |
395 |
if (a && a->addr != htonl(INADDR_ANY)) { |
753ea8e96 net: ipv6: sit: f... |
396 397 398 399 |
for (p = &t->prl; (x = rtnl_dereference(*p)) != NULL; p = &x->next) { if (x->addr == a->addr) { |
fadf6bf06 [IPV6] SIT: Add P... |
400 |
*p = x->next; |
11c476f31 net,rcu: convert ... |
401 |
kfree_rcu(x, rcu_head); |
300aaeeaa [IPV6] SIT: Add S... |
402 |
t->prl_count--; |
3fcfa1290 [IPV6] SIT: Fix l... |
403 |
goto out; |
fadf6bf06 [IPV6] SIT: Add P... |
404 405 |
} } |
3fcfa1290 [IPV6] SIT: Fix l... |
406 |
err = -ENXIO; |
fadf6bf06 [IPV6] SIT: Add P... |
407 |
} else { |
753ea8e96 net: ipv6: sit: f... |
408 409 |
x = rtnl_dereference(t->prl); if (x) { |
ef9a9d118 ipv6 sit: RCU con... |
410 |
t->prl_count = 0; |
ef9a9d118 ipv6 sit: RCU con... |
411 412 |
call_rcu(&x->rcu_head, prl_list_destroy_rcu); t->prl = NULL; |
fadf6bf06 [IPV6] SIT: Add P... |
413 414 |
} } |
3fcfa1290 [IPV6] SIT: Fix l... |
415 |
out: |
4b2796017 sit: ipip6_tunnel... |
416 |
return err; |
fadf6bf06 [IPV6] SIT: Add P... |
417 |
} |
fadf6bf06 [IPV6] SIT: Add P... |
418 |
static int |
b71d1d426 inet: constify ip... |
419 |
isatap_chksrc(struct sk_buff *skb, const struct iphdr *iph, struct ip_tunnel *t) |
fadf6bf06 [IPV6] SIT: Add P... |
420 |
{ |
3fcfa1290 [IPV6] SIT: Fix l... |
421 |
struct ip_tunnel_prl_entry *p; |
fadf6bf06 [IPV6] SIT: Add P... |
422 |
int ok = 1; |
ef9a9d118 ipv6 sit: RCU con... |
423 |
rcu_read_lock(); |
3fcfa1290 [IPV6] SIT: Fix l... |
424 |
p = __ipip6_tunnel_locate_prl(t, iph->saddr); |
fadf6bf06 [IPV6] SIT: Add P... |
425 |
if (p) { |
300aaeeaa [IPV6] SIT: Add S... |
426 |
if (p->flags & PRL_DEFAULT) |
fadf6bf06 [IPV6] SIT: Add P... |
427 428 429 430 |
skb->ndisc_nodetype = NDISC_NODETYPE_DEFAULT; else skb->ndisc_nodetype = NDISC_NODETYPE_NODEFAULT; } else { |
b71d1d426 inet: constify ip... |
431 |
const struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr; |
fadf6bf06 [IPV6] SIT: Add P... |
432 433 |
if (ipv6_addr_is_isatap(addr6) && (addr6->s6_addr32[3] == iph->saddr) && |
52eeeb848 [IPV6]: Unify ip6... |
434 |
ipv6_chk_prefix(addr6, t->dev)) |
fadf6bf06 [IPV6] SIT: Add P... |
435 436 437 438 |
skb->ndisc_nodetype = NDISC_NODETYPE_HOST; else ok = 0; } |
ef9a9d118 ipv6 sit: RCU con... |
439 |
rcu_read_unlock(); |
fadf6bf06 [IPV6] SIT: Add P... |
440 441 |
return ok; } |
1da177e4c Linux-2.6.12-rc2 |
442 443 |
static void ipip6_tunnel_uninit(struct net_device *dev) { |
ca8def148 [SIT]: Add net/si... |
444 445 |
struct net *net = dev_net(dev); struct sit_net *sitn = net_generic(net, sit_net_id); |
cd3dbc194 [SIT]: Make the f... |
446 |
if (dev == sitn->fb_tunnel_dev) { |
a9b3cd7f3 rcu: convert uses... |
447 |
RCU_INIT_POINTER(sitn->tunnels_wc[0], NULL); |
1da177e4c Linux-2.6.12-rc2 |
448 |
} else { |
ca8def148 [SIT]: Add net/si... |
449 |
ipip6_tunnel_unlink(sitn, netdev_priv(dev)); |
02e10b90c [IPV6] SIT: Spars... |
450 |
ipip6_tunnel_del_prl(netdev_priv(dev), NULL); |
1da177e4c Linux-2.6.12-rc2 |
451 |
} |
3a43be3c3 sit: get rid of i... |
452 |
dev_put(dev); |
1da177e4c Linux-2.6.12-rc2 |
453 |
} |
c73cb5a2d [IPSEC]: make sit... |
454 |
static int ipip6_err(struct sk_buff *skb, u32 info) |
1da177e4c Linux-2.6.12-rc2 |
455 |
{ |
1da177e4c Linux-2.6.12-rc2 |
456 |
|
071f92d05 net: The world is... |
457 |
/* All the routers (except for Linux) return only |
1da177e4c Linux-2.6.12-rc2 |
458 459 460 |
8 bytes of packet payload. It means, that precise relaying of ICMP in the real Internet is absolutely infeasible. */ |
b71d1d426 inet: constify ip... |
461 |
const struct iphdr *iph = (const struct iphdr *)skb->data; |
88c7664f1 [SK_BUFF]: Introd... |
462 463 |
const int type = icmp_hdr(skb)->type; const int code = icmp_hdr(skb)->code; |
1da177e4c Linux-2.6.12-rc2 |
464 |
struct ip_tunnel *t; |
c73cb5a2d [IPSEC]: make sit... |
465 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
466 467 468 469 |
switch (type) { default: case ICMP_PARAMETERPROB: |
c73cb5a2d [IPSEC]: make sit... |
470 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
471 472 473 474 475 476 |
case ICMP_DEST_UNREACH: switch (code) { case ICMP_SR_FAILED: case ICMP_PORT_UNREACH: /* Impossible event. */ |
c73cb5a2d [IPSEC]: make sit... |
477 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
478 479 |
case ICMP_FRAG_NEEDED: /* Soft state for pmtu is maintained by IP core. */ |
c73cb5a2d [IPSEC]: make sit... |
480 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
481 482 483 484 485 486 487 488 489 490 |
default: /* All others are translated to HOST_UNREACH. rfc2003 contains "deep thoughts" about NET_UNREACH, I believe they are just ether pollution. --ANK */ break; } break; case ICMP_TIME_EXCEEDED: if (code != ICMP_EXC_TTL) |
c73cb5a2d [IPSEC]: make sit... |
491 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
492 493 |
break; } |
c73cb5a2d [IPSEC]: make sit... |
494 |
err = -ENOENT; |
4543c10de ipv6 sit: RCU con... |
495 |
rcu_read_lock(); |
4fddbf5d7 sit: strictly res... |
496 497 498 499 |
t = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, iph->daddr, iph->saddr); |
1da177e4c Linux-2.6.12-rc2 |
500 501 |
if (t == NULL || t->parms.iph.daddr == 0) goto out; |
c73cb5a2d [IPSEC]: make sit... |
502 503 |
err = 0; |
1da177e4c Linux-2.6.12-rc2 |
504 505 |
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) goto out; |
bb80087a9 sit: used time_be... |
506 |
if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO)) |
1da177e4c Linux-2.6.12-rc2 |
507 508 509 510 511 |
t->err_count++; else t->err_count = 1; t->err_time = jiffies; out: |
4543c10de ipv6 sit: RCU con... |
512 |
rcu_read_unlock(); |
c73cb5a2d [IPSEC]: make sit... |
513 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
514 |
} |
b71d1d426 inet: constify ip... |
515 |
static inline void ipip6_ecn_decapsulate(const struct iphdr *iph, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
516 517 |
{ if (INET_ECN_is_ce(iph->tos)) |
0660e03f6 [SK_BUFF]: Introd... |
518 |
IP6_ECN_set_ce(ipv6_hdr(skb)); |
1da177e4c Linux-2.6.12-rc2 |
519 520 521 522 |
} static int ipip6_rcv(struct sk_buff *skb) { |
b71d1d426 inet: constify ip... |
523 |
const struct iphdr *iph; |
1da177e4c Linux-2.6.12-rc2 |
524 525 526 527 |
struct ip_tunnel *tunnel; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto out; |
eddc9ec53 [SK_BUFF]: Introd... |
528 |
iph = ip_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
529 |
|
4543c10de ipv6 sit: RCU con... |
530 |
rcu_read_lock(); |
4fddbf5d7 sit: strictly res... |
531 532 533 |
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, iph->saddr, iph->daddr); if (tunnel != NULL) { |
15fc1f705 sit: percpu stats... |
534 |
struct pcpu_tstats *tstats; |
1da177e4c Linux-2.6.12-rc2 |
535 |
secpath_reset(skb); |
b0e380b1d [SK_BUFF]: unions... |
536 |
skb->mac_header = skb->network_header; |
c1d2bbe1c [SK_BUFF]: Introd... |
537 |
skb_reset_network_header(skb); |
8cdfab8a4 [IPV4]: reset IPC... |
538 |
IPCB(skb)->flags = 0; |
1da177e4c Linux-2.6.12-rc2 |
539 540 |
skb->protocol = htons(ETH_P_IPV6); skb->pkt_type = PACKET_HOST; |
c7dc89c0a [IPV6]: Add RFC42... |
541 542 |
if ((tunnel->dev->priv_flags & IFF_ISATAP) && |
fadf6bf06 [IPV6] SIT: Add P... |
543 |
!isatap_chksrc(skb, iph, tunnel)) { |
4eecc107a sit: Use on-devic... |
544 |
tunnel->dev->stats.rx_errors++; |
4543c10de ipv6 sit: RCU con... |
545 |
rcu_read_unlock(); |
c7dc89c0a [IPV6]: Add RFC42... |
546 547 548 |
kfree_skb(skb); return 0; } |
d19d56ddc net: Introduce sk... |
549 |
|
15fc1f705 sit: percpu stats... |
550 551 552 553 554 |
tstats = this_cpu_ptr(tunnel->dev->tstats); tstats->rx_packets++; tstats->rx_bytes += skb->len; __skb_tunnel_rx(skb, tunnel->dev); |
d19d56ddc net: Introduce sk... |
555 |
|
1da177e4c Linux-2.6.12-rc2 |
556 |
ipip6_ecn_decapsulate(iph, skb); |
8990f468a net: rx_dropped a... |
557 |
|
caf586e5f net: add a core n... |
558 |
netif_rx(skb); |
8990f468a net: rx_dropped a... |
559 |
|
4543c10de ipv6 sit: RCU con... |
560 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
561 562 |
return 0; } |
6dcdd1b36 net/ipv6/sit.c: r... |
563 |
/* no tunnel matched, let upstream know, ipsec may handle it */ |
4543c10de ipv6 sit: RCU con... |
564 |
rcu_read_unlock(); |
6dcdd1b36 net/ipv6/sit.c: r... |
565 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
566 |
out: |
36ca34cc3 sit: Add missing ... |
567 |
kfree_skb(skb); |
1da177e4c Linux-2.6.12-rc2 |
568 569 |
return 0; } |
fa857afcf ipv6 sit: 6rd (IP... |
570 571 572 573 574 |
/* * Returns the embedded IPv4 address if the IPv6 address * comes from 6rd / 6to4 (RFC 3056) addr space. */ static inline |
b71d1d426 inet: constify ip... |
575 |
__be32 try_6rd(const struct in6_addr *v6dst, struct ip_tunnel *tunnel) |
1da177e4c Linux-2.6.12-rc2 |
576 |
{ |
e69a4adc6 [IPV6]: Misc endi... |
577 |
__be32 dst = 0; |
1da177e4c Linux-2.6.12-rc2 |
578 |
|
fa857afcf ipv6 sit: 6rd (IP... |
579 580 581 |
#ifdef CONFIG_IPV6_SIT_6RD if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix, tunnel->ip6rd.prefixlen)) { |
3a43be3c3 sit: get rid of i... |
582 |
unsigned int pbw0, pbi0; |
fa857afcf ipv6 sit: 6rd (IP... |
583 584 585 586 587 |
int pbi1; u32 d; pbw0 = tunnel->ip6rd.prefixlen >> 5; pbi0 = tunnel->ip6rd.prefixlen & 0x1f; |
e7db38c38 ipv6 sit: Fix 6rd... |
588 |
d = (ntohl(v6dst->s6_addr32[pbw0]) << pbi0) >> |
fa857afcf ipv6 sit: 6rd (IP... |
589 590 591 592 |
tunnel->ip6rd.relay_prefixlen; pbi1 = pbi0 - tunnel->ip6rd.relay_prefixlen; if (pbi1 > 0) |
e7db38c38 ipv6 sit: Fix 6rd... |
593 |
d |= ntohl(v6dst->s6_addr32[pbw0 + 1]) >> |
fa857afcf ipv6 sit: 6rd (IP... |
594 595 596 597 598 |
(32 - pbi1); dst = tunnel->ip6rd.relay_prefix | htonl(d); } #else |
1da177e4c Linux-2.6.12-rc2 |
599 |
if (v6dst->s6_addr16[0] == htons(0x2002)) { |
1ab1457c4 [NET] IPV6: Fix w... |
600 |
/* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */ |
1da177e4c Linux-2.6.12-rc2 |
601 602 |
memcpy(&dst, &v6dst->s6_addr16[1], 4); } |
fa857afcf ipv6 sit: 6rd (IP... |
603 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
604 605 606 607 608 609 610 |
return dst; } /* * This function assumes it is being called from dev_queue_xmit() * and that skb is filled properly by that function. */ |
6fef4c0c8 netdev: convert p... |
611 612 |
static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
613 |
{ |
2941a4863 [NET]: Convert ne... |
614 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
15fc1f705 sit: percpu stats... |
615 |
struct pcpu_tstats *tstats; |
b71d1d426 inet: constify ip... |
616 617 |
const struct iphdr *tiph = &tunnel->parms.iph; const struct ipv6hdr *iph6 = ipv6_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
618 |
u8 tos = tunnel->parms.iph.tos; |
292f4f3ce sit: Clean up DF ... |
619 |
__be16 df = tiph->frag_off; |
1da177e4c Linux-2.6.12-rc2 |
620 |
struct rtable *rt; /* Route to the other host */ |
15fc1f705 sit: percpu stats... |
621 |
struct net_device *tdev; /* Device to other host */ |
1da177e4c Linux-2.6.12-rc2 |
622 |
struct iphdr *iph; /* Our new IP header */ |
c2636b4d9 [NET]: Treat the ... |
623 |
unsigned int max_headroom; /* The extra header space needed */ |
e69a4adc6 [IPV6]: Misc endi... |
624 |
__be32 dst = tiph->daddr; |
31e4543db ipv4: Make caller... |
625 |
struct flowi4 fl4; |
1da177e4c Linux-2.6.12-rc2 |
626 |
int mtu; |
b71d1d426 inet: constify ip... |
627 |
const struct in6_addr *addr6; |
1da177e4c Linux-2.6.12-rc2 |
628 |
int addr_type; |
1da177e4c Linux-2.6.12-rc2 |
629 630 |
if (skb->protocol != htons(ETH_P_IPV6)) goto tx_error; |
c2bceb3d7 sit tunnels: prop... |
631 632 |
if (tos == 1) tos = ipv6_get_dsfield(iph6); |
c7dc89c0a [IPV6]: Add RFC42... |
633 634 635 |
/* ISATAP (RFC4214) - must come before 6to4 */ if (dev->priv_flags & IFF_ISATAP) { struct neighbour *neigh = NULL; |
adf30907d net: skb->dst acc... |
636 |
if (skb_dst(skb)) |
272174550 net: Rename dst_g... |
637 |
neigh = dst_get_neighbour_noref(skb_dst(skb)); |
c7dc89c0a [IPV6]: Add RFC42... |
638 639 640 641 642 643 644 |
if (neigh == NULL) { if (net_ratelimit()) printk(KERN_DEBUG "sit: nexthop == NULL "); goto tx_error; } |
b71d1d426 inet: constify ip... |
645 |
addr6 = (const struct in6_addr*)&neigh->primary_key; |
c7dc89c0a [IPV6]: Add RFC42... |
646 647 648 649 650 651 652 653 |
addr_type = ipv6_addr_type(addr6); if ((addr_type & IPV6_ADDR_UNICAST) && ipv6_addr_is_isatap(addr6)) dst = addr6->s6_addr32[3]; else goto tx_error; } |
1da177e4c Linux-2.6.12-rc2 |
654 |
if (!dst) |
fa857afcf ipv6 sit: 6rd (IP... |
655 |
dst = try_6rd(&iph6->daddr, tunnel); |
1da177e4c Linux-2.6.12-rc2 |
656 657 658 |
if (!dst) { struct neighbour *neigh = NULL; |
adf30907d net: skb->dst acc... |
659 |
if (skb_dst(skb)) |
272174550 net: Rename dst_g... |
660 |
neigh = dst_get_neighbour_noref(skb_dst(skb)); |
1da177e4c Linux-2.6.12-rc2 |
661 662 663 664 665 666 667 |
if (neigh == NULL) { if (net_ratelimit()) printk(KERN_DEBUG "sit: nexthop == NULL "); goto tx_error; } |
b71d1d426 inet: constify ip... |
668 |
addr6 = (const struct in6_addr*)&neigh->primary_key; |
1da177e4c Linux-2.6.12-rc2 |
669 670 671 |
addr_type = ipv6_addr_type(addr6); if (addr_type == IPV6_ADDR_ANY) { |
0660e03f6 [SK_BUFF]: Introd... |
672 |
addr6 = &ipv6_hdr(skb)->daddr; |
1da177e4c Linux-2.6.12-rc2 |
673 674 675 676 677 678 679 680 |
addr_type = ipv6_addr_type(addr6); } if ((addr_type & IPV6_ADDR_COMPATv4) == 0) goto tx_error_icmp; dst = addr6->s6_addr32[3]; } |
31e4543db ipv4: Make caller... |
681 |
rt = ip_route_output_ports(dev_net(dev), &fl4, NULL, |
78fbfd8a6 ipv4: Create and ... |
682 683 684 685 686 687 688 |
dst, tiph->saddr, 0, 0, IPPROTO_IPV6, RT_TOS(tos), tunnel->parms.link); if (IS_ERR(rt)) { dev->stats.tx_carrier_errors++; goto tx_error_icmp; |
1da177e4c Linux-2.6.12-rc2 |
689 690 691 |
} if (rt->rt_type != RTN_UNICAST) { ip_rt_put(rt); |
15fc1f705 sit: percpu stats... |
692 |
dev->stats.tx_carrier_errors++; |
1da177e4c Linux-2.6.12-rc2 |
693 694 |
goto tx_error_icmp; } |
d8d1f30b9 net-next: remove ... |
695 |
tdev = rt->dst.dev; |
1da177e4c Linux-2.6.12-rc2 |
696 697 698 |
if (tdev == dev) { ip_rt_put(rt); |
15fc1f705 sit: percpu stats... |
699 |
dev->stats.collisions++; |
1da177e4c Linux-2.6.12-rc2 |
700 701 |
goto tx_error; } |
292f4f3ce sit: Clean up DF ... |
702 |
if (df) { |
d8d1f30b9 net-next: remove ... |
703 |
mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); |
1da177e4c Linux-2.6.12-rc2 |
704 |
|
292f4f3ce sit: Clean up DF ... |
705 |
if (mtu < 68) { |
15fc1f705 sit: percpu stats... |
706 |
dev->stats.collisions++; |
292f4f3ce sit: Clean up DF ... |
707 708 709 |
ip_rt_put(rt); goto tx_error; } |
1da177e4c Linux-2.6.12-rc2 |
710 |
|
292f4f3ce sit: Clean up DF ... |
711 712 713 714 715 716 717 718 719 |
if (mtu < IPV6_MIN_MTU) { mtu = IPV6_MIN_MTU; df = 0; } if (tunnel->parms.iph.daddr && skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); if (skb->len > mtu) { |
3ffe533c8 ipv6: drop unused... |
720 |
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
292f4f3ce sit: Clean up DF ... |
721 722 723 |
ip_rt_put(rt); goto tx_error; } |
1da177e4c Linux-2.6.12-rc2 |
724 725 726 |
} if (tunnel->err_count > 0) { |
bb80087a9 sit: used time_be... |
727 728 |
if (time_before(jiffies, tunnel->err_time + IPTUNNEL_ERR_TIMEO)) { |
1da177e4c Linux-2.6.12-rc2 |
729 730 731 732 733 734 735 736 737 738 |
tunnel->err_count--; dst_link_failure(skb); } else tunnel->err_count = 0; } /* * Okay, now see if we can stuff it in the buffer as-is. */ max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr); |
cfbba49d8 [NET]: Avoid copy... |
739 740 |
if (skb_headroom(skb) < max_headroom || skb_shared(skb) || (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { |
1da177e4c Linux-2.6.12-rc2 |
741 742 743 |
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); |
15fc1f705 sit: percpu stats... |
744 |
dev->stats.tx_dropped++; |
1da177e4c Linux-2.6.12-rc2 |
745 |
dev_kfree_skb(skb); |
6ed106549 net: use NETDEV_T... |
746 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
747 748 749 750 751 |
} if (skb->sk) skb_set_owner_w(new_skb, skb->sk); dev_kfree_skb(skb); skb = new_skb; |
0660e03f6 [SK_BUFF]: Introd... |
752 |
iph6 = ipv6_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
753 |
} |
b0e380b1d [SK_BUFF]: unions... |
754 |
skb->transport_header = skb->network_header; |
e2d1bca7e [SK_BUFF]: Use sk... |
755 756 |
skb_push(skb, sizeof(struct iphdr)); skb_reset_network_header(skb); |
1da177e4c Linux-2.6.12-rc2 |
757 |
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
8cdfab8a4 [IPV4]: reset IPC... |
758 |
IPCB(skb)->flags = 0; |
adf30907d net: skb->dst acc... |
759 |
skb_dst_drop(skb); |
d8d1f30b9 net-next: remove ... |
760 |
skb_dst_set(skb, &rt->dst); |
1da177e4c Linux-2.6.12-rc2 |
761 762 763 764 |
/* * Push down and install the IPIP header. */ |
eddc9ec53 [SK_BUFF]: Introd... |
765 |
iph = ip_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
766 767 |
iph->version = 4; iph->ihl = sizeof(struct iphdr)>>2; |
292f4f3ce sit: Clean up DF ... |
768 |
iph->frag_off = df; |
1da177e4c Linux-2.6.12-rc2 |
769 770 |
iph->protocol = IPPROTO_IPV6; iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); |
301102cc8 ipv6: Use flowi4-... |
771 772 |
iph->daddr = fl4.daddr; iph->saddr = fl4.saddr; |
1da177e4c Linux-2.6.12-rc2 |
773 774 775 776 777 |
if ((iph->ttl = tiph->ttl) == 0) iph->ttl = iph6->hop_limit; nf_reset(skb); |
15fc1f705 sit: percpu stats... |
778 779 |
tstats = this_cpu_ptr(dev->tstats); __IPTUNNEL_XMIT(tstats, &dev->stats); |
6ed106549 net: use NETDEV_T... |
780 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
781 782 783 784 |
tx_error_icmp: dst_link_failure(skb); tx_error: |
15fc1f705 sit: percpu stats... |
785 |
dev->stats.tx_errors++; |
1da177e4c Linux-2.6.12-rc2 |
786 |
dev_kfree_skb(skb); |
6ed106549 net: use NETDEV_T... |
787 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
788 |
} |
8a4a50f98 [IPV6] sit: Rebin... |
789 790 791 792 |
static void ipip6_tunnel_bind_dev(struct net_device *dev) { struct net_device *tdev = NULL; struct ip_tunnel *tunnel; |
b71d1d426 inet: constify ip... |
793 |
const struct iphdr *iph; |
31e4543db ipv4: Make caller... |
794 |
struct flowi4 fl4; |
8a4a50f98 [IPV6] sit: Rebin... |
795 796 797 798 799 |
tunnel = netdev_priv(dev); iph = &tunnel->parms.iph; if (iph->daddr) { |
31e4543db ipv4: Make caller... |
800 |
struct rtable *rt = ip_route_output_ports(dev_net(dev), &fl4, NULL, |
78fbfd8a6 ipv4: Create and ... |
801 802 803 804 805 |
iph->daddr, iph->saddr, 0, 0, IPPROTO_IPV6, RT_TOS(iph->tos), tunnel->parms.link); |
b23dd4fe4 ipv4: Make output... |
806 807 |
if (!IS_ERR(rt)) { |
d8d1f30b9 net-next: remove ... |
808 |
tdev = rt->dst.dev; |
8a4a50f98 [IPV6] sit: Rebin... |
809 810 811 812 813 814 |
ip_rt_put(rt); } dev->flags |= IFF_POINTOPOINT; } if (!tdev && tunnel->parms.link) |
907a08c40 [SIT]: Use proper... |
815 |
tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); |
8a4a50f98 [IPV6] sit: Rebin... |
816 817 818 819 820 821 822 823 824 |
if (tdev) { dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr); dev->mtu = tdev->mtu - sizeof(struct iphdr); if (dev->mtu < IPV6_MIN_MTU) dev->mtu = IPV6_MIN_MTU; } dev->iflink = tunnel->parms.link; } |
1da177e4c Linux-2.6.12-rc2 |
825 826 827 828 829 |
static int ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) { int err = 0; struct ip_tunnel_parm p; |
fadf6bf06 [IPV6] SIT: Add P... |
830 |
struct ip_tunnel_prl prl; |
1da177e4c Linux-2.6.12-rc2 |
831 |
struct ip_tunnel *t; |
ca8def148 [SIT]: Add net/si... |
832 833 |
struct net *net = dev_net(dev); struct sit_net *sitn = net_generic(net, sit_net_id); |
fa857afcf ipv6 sit: 6rd (IP... |
834 835 836 |
#ifdef CONFIG_IPV6_SIT_6RD struct ip_tunnel_6rd ip6rd; #endif |
1da177e4c Linux-2.6.12-rc2 |
837 838 839 |
switch (cmd) { case SIOCGETTUNNEL: |
fa857afcf ipv6 sit: 6rd (IP... |
840 841 842 |
#ifdef CONFIG_IPV6_SIT_6RD case SIOCGET6RD: #endif |
1da177e4c Linux-2.6.12-rc2 |
843 |
t = NULL; |
cd3dbc194 [SIT]: Make the f... |
844 |
if (dev == sitn->fb_tunnel_dev) { |
1da177e4c Linux-2.6.12-rc2 |
845 846 847 848 |
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { err = -EFAULT; break; } |
ca8def148 [SIT]: Add net/si... |
849 |
t = ipip6_tunnel_locate(net, &p, 0); |
1da177e4c Linux-2.6.12-rc2 |
850 851 |
} if (t == NULL) |
2941a4863 [NET]: Convert ne... |
852 |
t = netdev_priv(dev); |
fa857afcf ipv6 sit: 6rd (IP... |
853 854 855 856 857 858 859 860 861 |
err = -EFAULT; if (cmd == SIOCGETTUNNEL) { memcpy(&p, &t->parms, sizeof(p)); if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) goto done; #ifdef CONFIG_IPV6_SIT_6RD } else { |
4e3fd7a06 net: remove ipv6_... |
862 |
ip6rd.prefix = t->ip6rd.prefix; |
fa857afcf ipv6 sit: 6rd (IP... |
863 864 865 866 867 868 869 870 871 |
ip6rd.relay_prefix = t->ip6rd.relay_prefix; ip6rd.prefixlen = t->ip6rd.prefixlen; ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen; if (copy_to_user(ifr->ifr_ifru.ifru_data, &ip6rd, sizeof(ip6rd))) goto done; #endif } err = 0; |
1da177e4c Linux-2.6.12-rc2 |
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 |
break; case SIOCADDTUNNEL: case SIOCCHGTUNNEL: err = -EPERM; if (!capable(CAP_NET_ADMIN)) goto done; err = -EFAULT; if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) goto done; err = -EINVAL; if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPV6 || p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF))) goto done; if (p.iph.ttl) p.iph.frag_off |= htons(IP_DF); |
ca8def148 [SIT]: Add net/si... |
890 |
t = ipip6_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL); |
1da177e4c Linux-2.6.12-rc2 |
891 |
|
cd3dbc194 [SIT]: Make the f... |
892 |
if (dev != sitn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { |
1da177e4c Linux-2.6.12-rc2 |
893 894 895 896 897 898 899 900 901 902 903 |
if (t != NULL) { if (t->dev != dev) { err = -EEXIST; break; } } else { if (((dev->flags&IFF_POINTOPOINT) && !p.iph.daddr) || (!(dev->flags&IFF_POINTOPOINT) && p.iph.daddr)) { err = -EINVAL; break; } |
2941a4863 [NET]: Convert ne... |
904 |
t = netdev_priv(dev); |
ca8def148 [SIT]: Add net/si... |
905 |
ipip6_tunnel_unlink(sitn, t); |
74b0b85b8 tunnels: Fix tunn... |
906 |
synchronize_net(); |
1da177e4c Linux-2.6.12-rc2 |
907 908 909 910 |
t->parms.iph.saddr = p.iph.saddr; t->parms.iph.daddr = p.iph.daddr; memcpy(dev->dev_addr, &p.iph.saddr, 4); memcpy(dev->broadcast, &p.iph.daddr, 4); |
ca8def148 [SIT]: Add net/si... |
911 |
ipip6_tunnel_link(sitn, t); |
1da177e4c Linux-2.6.12-rc2 |
912 913 914 915 916 917 918 919 920 |
netdev_state_change(dev); } } if (t) { err = 0; if (cmd == SIOCCHGTUNNEL) { t->parms.iph.ttl = p.iph.ttl; t->parms.iph.tos = p.iph.tos; |
8a4a50f98 [IPV6] sit: Rebin... |
921 922 923 924 925 |
if (t->parms.link != p.link) { t->parms.link = p.link; ipip6_tunnel_bind_dev(dev); netdev_state_change(dev); } |
1da177e4c Linux-2.6.12-rc2 |
926 927 928 929 930 931 932 933 934 935 936 |
} if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p))) err = -EFAULT; } else err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); break; case SIOCDELTUNNEL: err = -EPERM; if (!capable(CAP_NET_ADMIN)) goto done; |
cd3dbc194 [SIT]: Make the f... |
937 |
if (dev == sitn->fb_tunnel_dev) { |
1da177e4c Linux-2.6.12-rc2 |
938 939 940 941 |
err = -EFAULT; if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) goto done; err = -ENOENT; |
ca8def148 [SIT]: Add net/si... |
942 |
if ((t = ipip6_tunnel_locate(net, &p, 0)) == NULL) |
1da177e4c Linux-2.6.12-rc2 |
943 944 |
goto done; err = -EPERM; |
cd3dbc194 [SIT]: Make the f... |
945 |
if (t == netdev_priv(sitn->fb_tunnel_dev)) |
1da177e4c Linux-2.6.12-rc2 |
946 947 948 |
goto done; dev = t->dev; } |
22f8cde5b [NET]: unregister... |
949 950 |
unregister_netdevice(dev); err = 0; |
1da177e4c Linux-2.6.12-rc2 |
951 |
break; |
300aaeeaa [IPV6] SIT: Add S... |
952 |
case SIOCGETPRL: |
2b4743bd6 ipv6 sit: Avoid e... |
953 954 955 956 957 958 959 960 |
err = -EINVAL; if (dev == sitn->fb_tunnel_dev) goto done; err = -ENOENT; if (!(t = netdev_priv(dev))) goto done; err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); break; |
fadf6bf06 [IPV6] SIT: Add P... |
961 962 963 964 |
case SIOCADDPRL: case SIOCDELPRL: case SIOCCHGPRL: err = -EPERM; |
2b4743bd6 ipv6 sit: Avoid e... |
965 |
if (!capable(CAP_NET_ADMIN)) |
fadf6bf06 [IPV6] SIT: Add P... |
966 967 |
goto done; err = -EINVAL; |
cd3dbc194 [SIT]: Make the f... |
968 |
if (dev == sitn->fb_tunnel_dev) |
fadf6bf06 [IPV6] SIT: Add P... |
969 970 971 972 973 974 975 |
goto done; err = -EFAULT; if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) goto done; err = -ENOENT; if (!(t = netdev_priv(dev))) goto done; |
300aaeeaa [IPV6] SIT: Add S... |
976 |
switch (cmd) { |
300aaeeaa [IPV6] SIT: Add S... |
977 |
case SIOCDELPRL: |
fadf6bf06 [IPV6] SIT: Add P... |
978 |
err = ipip6_tunnel_del_prl(t, &prl); |
300aaeeaa [IPV6] SIT: Add S... |
979 980 981 |
break; case SIOCADDPRL: case SIOCCHGPRL: |
fadf6bf06 [IPV6] SIT: Add P... |
982 |
err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); |
300aaeeaa [IPV6] SIT: Add S... |
983 984 |
break; } |
2b4743bd6 ipv6 sit: Avoid e... |
985 |
netdev_state_change(dev); |
fadf6bf06 [IPV6] SIT: Add P... |
986 |
break; |
fa857afcf ipv6 sit: 6rd (IP... |
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
#ifdef CONFIG_IPV6_SIT_6RD case SIOCADD6RD: case SIOCCHG6RD: case SIOCDEL6RD: err = -EPERM; if (!capable(CAP_NET_ADMIN)) goto done; err = -EFAULT; if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data, sizeof(ip6rd))) goto done; t = netdev_priv(dev); if (cmd != SIOCDEL6RD) { struct in6_addr prefix; __be32 relay_prefix; err = -EINVAL; if (ip6rd.relay_prefixlen > 32 || ip6rd.prefixlen + (32 - ip6rd.relay_prefixlen) > 64) goto done; ipv6_addr_prefix(&prefix, &ip6rd.prefix, ip6rd.prefixlen); if (!ipv6_addr_equal(&prefix, &ip6rd.prefix)) goto done; |
91b2a3f9b ipv6 sit: Set rel... |
1015 1016 1017 1018 1019 1020 |
if (ip6rd.relay_prefixlen) relay_prefix = ip6rd.relay_prefix & htonl(0xffffffffUL << (32 - ip6rd.relay_prefixlen)); else relay_prefix = 0; |
fa857afcf ipv6 sit: 6rd (IP... |
1021 1022 |
if (relay_prefix != ip6rd.relay_prefix) goto done; |
4e3fd7a06 net: remove ipv6_... |
1023 |
t->ip6rd.prefix = prefix; |
fa857afcf ipv6 sit: 6rd (IP... |
1024 1025 1026 1027 |
t->ip6rd.relay_prefix = relay_prefix; t->ip6rd.prefixlen = ip6rd.prefixlen; t->ip6rd.relay_prefixlen = ip6rd.relay_prefixlen; } else |
e0c939481 ipv6 sit: Ensure ... |
1028 |
ipip6_tunnel_clone_6rd(dev, sitn); |
fa857afcf ipv6 sit: 6rd (IP... |
1029 1030 1031 1032 |
err = 0; break; #endif |
1da177e4c Linux-2.6.12-rc2 |
1033 1034 1035 1036 1037 1038 1039 |
default: err = -EINVAL; } done: return err; } |
1da177e4c Linux-2.6.12-rc2 |
1040 1041 1042 1043 1044 1045 1046 |
static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) { if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr)) return -EINVAL; dev->mtu = new_mtu; return 0; } |
1326c3d5a ipv6: convert tun... |
1047 1048 1049 1050 1051 |
static const struct net_device_ops ipip6_netdev_ops = { .ndo_uninit = ipip6_tunnel_uninit, .ndo_start_xmit = ipip6_tunnel_xmit, .ndo_do_ioctl = ipip6_tunnel_ioctl, .ndo_change_mtu = ipip6_tunnel_change_mtu, |
15fc1f705 sit: percpu stats... |
1052 |
.ndo_get_stats = ipip6_get_stats, |
1326c3d5a ipv6: convert tun... |
1053 |
}; |
15fc1f705 sit: percpu stats... |
1054 1055 1056 1057 1058 |
static void ipip6_dev_free(struct net_device *dev) { free_percpu(dev->tstats); free_netdev(dev); } |
1da177e4c Linux-2.6.12-rc2 |
1059 1060 |
static void ipip6_tunnel_setup(struct net_device *dev) { |
1326c3d5a ipv6: convert tun... |
1061 |
dev->netdev_ops = &ipip6_netdev_ops; |
15fc1f705 sit: percpu stats... |
1062 |
dev->destructor = ipip6_dev_free; |
1da177e4c Linux-2.6.12-rc2 |
1063 1064 1065 |
dev->type = ARPHRD_SIT; dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); |
46f25dffb [NET]: Change 150... |
1066 |
dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr); |
1da177e4c Linux-2.6.12-rc2 |
1067 |
dev->flags = IFF_NOARP; |
f2ba025b2 sit: fix regressi... |
1068 |
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
1da177e4c Linux-2.6.12-rc2 |
1069 1070 |
dev->iflink = 0; dev->addr_len = 4; |
7a97146cc [SIT]: Allow to c... |
1071 |
dev->features |= NETIF_F_NETNS_LOCAL; |
8df40d103 sit: enable lockl... |
1072 |
dev->features |= NETIF_F_LLTX; |
1da177e4c Linux-2.6.12-rc2 |
1073 |
} |
15fc1f705 sit: percpu stats... |
1074 |
static int ipip6_tunnel_init(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
1075 |
{ |
1326c3d5a ipv6: convert tun... |
1076 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
1077 1078 |
tunnel->dev = dev; |
1da177e4c Linux-2.6.12-rc2 |
1079 1080 1081 |
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); |
8a4a50f98 [IPV6] sit: Rebin... |
1082 |
ipip6_tunnel_bind_dev(dev); |
15fc1f705 sit: percpu stats... |
1083 1084 1085 1086 1087 |
dev->tstats = alloc_percpu(struct pcpu_tstats); if (!dev->tstats) return -ENOMEM; return 0; |
1da177e4c Linux-2.6.12-rc2 |
1088 |
} |
dd4080ee5 sit: fix percpu s... |
1089 |
static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
1090 |
{ |
2941a4863 [NET]: Convert ne... |
1091 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
1092 |
struct iphdr *iph = &tunnel->parms.iph; |
291821766 [SIT]: Make tunne... |
1093 1094 |
struct net *net = dev_net(dev); struct sit_net *sitn = net_generic(net, sit_net_id); |
1da177e4c Linux-2.6.12-rc2 |
1095 1096 1097 1098 1099 1100 1101 1102 |
tunnel->dev = dev; strcpy(tunnel->parms.name, dev->name); iph->version = 4; iph->protocol = IPPROTO_IPV6; iph->ihl = 5; iph->ttl = 64; |
dd4080ee5 sit: fix percpu s... |
1103 1104 1105 |
dev->tstats = alloc_percpu(struct pcpu_tstats); if (!dev->tstats) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
1106 |
dev_hold(dev); |
cf778b00e net: reintroduce ... |
1107 |
rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); |
dd4080ee5 sit: fix percpu s... |
1108 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1109 |
} |
6dcd814bd net: struct xfrm_... |
1110 |
static struct xfrm_tunnel sit_handler __read_mostly = { |
1da177e4c Linux-2.6.12-rc2 |
1111 1112 |
.handler = ipip6_rcv, .err_handler = ipip6_err, |
c73cb5a2d [IPSEC]: make sit... |
1113 |
.priority = 1, |
1da177e4c Linux-2.6.12-rc2 |
1114 |
}; |
2c8c1e729 net: spread __net... |
1115 |
static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) |
db44575f6 [NET]: fix oops a... |
1116 1117 1118 1119 1120 1121 |
{ int prio; for (prio = 1; prio < 4; prio++) { int h; for (h = 0; h < HASH_SIZE; h++) { |
753ea8e96 net: ipv6: sit: f... |
1122 |
struct ip_tunnel *t; |
62808f912 ipv6 sit: Optimiz... |
1123 |
|
753ea8e96 net: ipv6: sit: f... |
1124 |
t = rtnl_dereference(sitn->tunnels[prio][h]); |
62808f912 ipv6 sit: Optimiz... |
1125 1126 |
while (t != NULL) { unregister_netdevice_queue(t->dev, head); |
753ea8e96 net: ipv6: sit: f... |
1127 |
t = rtnl_dereference(t->next); |
62808f912 ipv6 sit: Optimiz... |
1128 |
} |
db44575f6 [NET]: fix oops a... |
1129 1130 1131 |
} } } |
2c8c1e729 net: spread __net... |
1132 |
static int __net_init sit_init_net(struct net *net) |
8190d9009 [SIT]: Introduce ... |
1133 |
{ |
671011720 net: Simplify ipi... |
1134 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
72b36015b ipip, sit: copy p... |
1135 |
struct ip_tunnel *t; |
8190d9009 [SIT]: Introduce ... |
1136 |
int err; |
8190d9009 [SIT]: Introduce ... |
1137 |
|
291821766 [SIT]: Make tunne... |
1138 1139 1140 1141 |
sitn->tunnels[0] = sitn->tunnels_wc; sitn->tunnels[1] = sitn->tunnels_l; sitn->tunnels[2] = sitn->tunnels_r; sitn->tunnels[3] = sitn->tunnels_r_l; |
cd3dbc194 [SIT]: Make the f... |
1142 1143 1144 1145 1146 1147 |
sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", ipip6_tunnel_setup); if (!sitn->fb_tunnel_dev) { err = -ENOMEM; goto err_alloc_dev; } |
be77e5930 net: fix tunnels ... |
1148 |
dev_net_set(sitn->fb_tunnel_dev, net); |
cd3dbc194 [SIT]: Make the f... |
1149 |
|
dd4080ee5 sit: fix percpu s... |
1150 1151 1152 |
err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); if (err) goto err_dev_free; |
e0c939481 ipv6 sit: Ensure ... |
1153 |
ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); |
cd3dbc194 [SIT]: Make the f... |
1154 1155 1156 |
if ((err = register_netdev(sitn->fb_tunnel_dev))) goto err_reg_dev; |
72b36015b ipip, sit: copy p... |
1157 1158 1159 |
t = netdev_priv(sitn->fb_tunnel_dev); strcpy(t->parms.name, sitn->fb_tunnel_dev->name); |
8190d9009 [SIT]: Introduce ... |
1160 |
return 0; |
cd3dbc194 [SIT]: Make the f... |
1161 |
err_reg_dev: |
1326c3d5a ipv6: convert tun... |
1162 |
dev_put(sitn->fb_tunnel_dev); |
dd4080ee5 sit: fix percpu s... |
1163 1164 |
err_dev_free: ipip6_dev_free(sitn->fb_tunnel_dev); |
cd3dbc194 [SIT]: Make the f... |
1165 |
err_alloc_dev: |
8190d9009 [SIT]: Introduce ... |
1166 1167 |
return err; } |
2c8c1e729 net: spread __net... |
1168 |
static void __net_exit sit_exit_net(struct net *net) |
8190d9009 [SIT]: Introduce ... |
1169 |
{ |
671011720 net: Simplify ipi... |
1170 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
62808f912 ipv6 sit: Optimiz... |
1171 |
LIST_HEAD(list); |
8190d9009 [SIT]: Introduce ... |
1172 |
|
cd3dbc194 [SIT]: Make the f... |
1173 |
rtnl_lock(); |
62808f912 ipv6 sit: Optimiz... |
1174 1175 1176 |
sit_destroy_tunnels(sitn, &list); unregister_netdevice_queue(sitn->fb_tunnel_dev, &list); unregister_netdevice_many(&list); |
cd3dbc194 [SIT]: Make the f... |
1177 |
rtnl_unlock(); |
8190d9009 [SIT]: Introduce ... |
1178 1179 1180 1181 1182 |
} static struct pernet_operations sit_net_ops = { .init = sit_init_net, .exit = sit_exit_net, |
671011720 net: Simplify ipi... |
1183 1184 |
.id = &sit_net_id, .size = sizeof(struct sit_net), |
8190d9009 [SIT]: Introduce ... |
1185 |
}; |
89c894581 [IPV6] net/ipv6/s... |
1186 |
static void __exit sit_cleanup(void) |
1da177e4c Linux-2.6.12-rc2 |
1187 |
{ |
c73cb5a2d [IPSEC]: make sit... |
1188 |
xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
db44575f6 [NET]: fix oops a... |
1189 |
|
671011720 net: Simplify ipi... |
1190 |
unregister_pernet_device(&sit_net_ops); |
ef9a9d118 ipv6 sit: RCU con... |
1191 |
rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
1da177e4c Linux-2.6.12-rc2 |
1192 |
} |
89c894581 [IPV6] net/ipv6/s... |
1193 |
static int __init sit_init(void) |
1da177e4c Linux-2.6.12-rc2 |
1194 1195 1196 1197 1198 |
{ int err; printk(KERN_INFO "IPv6 over IPv4 tunneling driver "); |
671011720 net: Simplify ipi... |
1199 |
err = register_pernet_device(&sit_net_ops); |
8190d9009 [SIT]: Introduce ... |
1200 |
if (err < 0) |
d5aa407f5 tunnels: fix netn... |
1201 1202 1203 1204 1205 1206 1207 |
return err; err = xfrm4_tunnel_register(&sit_handler, AF_INET6); if (err < 0) { unregister_pernet_device(&sit_net_ops); printk(KERN_INFO "sit init: Can't add protocol "); } |
1da177e4c Linux-2.6.12-rc2 |
1208 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1209 |
} |
989e5b96e [IPV6]: Seperate ... |
1210 1211 1212 |
module_init(sit_init); module_exit(sit_cleanup); |
39c850863 [IPV6] sit: Add m... |
1213 |
MODULE_LICENSE("GPL"); |
8909c9ad8 net: don't allow ... |
1214 |
MODULE_ALIAS_NETDEV("sit0"); |