Blame view
net/ipv6/sit.c
46.9 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 |
/* * IPv6 over IPv4 tunnel device - Simple Internet Transition (SIT) * Linux INET6 implementation * * Authors: |
1ab1457c4 [NET] IPV6: Fix w... |
7 |
* Pedro Roque <roque@di.fc.ul.pt> |
1da177e4c Linux-2.6.12-rc2 |
8 9 |
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> * |
1da177e4c Linux-2.6.12-rc2 |
10 11 12 |
* Changes: * Roger Venning <r.venning@telstra.com>: 6to4 support * Nate Thompson <nate@thebog.net>: 6to4 support |
fadf6bf06 [IPV6] SIT: Add P... |
13 |
* Fred Templin <fred.l.templin@boeing.com>: isatap support |
1da177e4c Linux-2.6.12-rc2 |
14 |
*/ |
f32138319 net: ipv6: Standa... |
15 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include <linux/module.h> |
4fc268d24 [PATCH] capable/c... |
17 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
18 19 20 21 |
#include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> #include <linux/sockios.h> |
1da177e4c Linux-2.6.12-rc2 |
22 23 24 25 26 |
#include <linux/net.h> #include <linux/in6.h> #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/icmp.h> |
5a0e3ad6a include cleanup: ... |
27 |
#include <linux/slab.h> |
7c0f6ba68 Replace <asm/uacc... |
28 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
29 30 |
#include <linux/init.h> #include <linux/netfilter_ipv4.h> |
46f25dffb [NET]: Change 150... |
31 |
#include <linux/if_ether.h> |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#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> |
c54419321 GRE: Refactor GRE... |
46 |
#include <net/ip_tunnels.h> |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 |
#include <net/inet_ecn.h> #include <net/xfrm.h> #include <net/dsfield.h> |
8190d9009 [SIT]: Introduce ... |
50 51 |
#include <net/net_namespace.h> #include <net/netns/generic.h> |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 55 56 57 |
/* 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 */ |
e87a8f24c net: resolve symb... |
58 |
#define IP6_SIT_HASH_SIZE 16 |
e69a4adc6 [IPV6]: Misc endi... |
59 |
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) |
1da177e4c Linux-2.6.12-rc2 |
60 |
|
f4e0b4c5e ip6tnl/sit: drop ... |
61 62 63 |
static bool log_ecn_error = true; module_param(log_ecn_error, bool, 0644); MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); |
15fc1f705 sit: percpu stats... |
64 |
static int ipip6_tunnel_init(struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
65 |
static void ipip6_tunnel_setup(struct net_device *dev); |
15fc1f705 sit: percpu stats... |
66 |
static void ipip6_dev_free(struct net_device *dev); |
218774dc3 ipv6: add anti-sp... |
67 68 |
static bool check_6rd(struct ip_tunnel *tunnel, const struct in6_addr *v6dst, __be32 *v4dst); |
ba3e3f50a sit: advertise tu... |
69 |
static struct rtnl_link_ops sit_link_ops __read_mostly; |
1da177e4c Linux-2.6.12-rc2 |
70 |
|
c7d03a00b netns: make struc... |
71 |
static unsigned int sit_net_id __read_mostly; |
8190d9009 [SIT]: Introduce ... |
72 |
struct sit_net { |
e87a8f24c net: resolve symb... |
73 74 75 |
struct ip_tunnel __rcu *tunnels_r_l[IP6_SIT_HASH_SIZE]; struct ip_tunnel __rcu *tunnels_r[IP6_SIT_HASH_SIZE]; struct ip_tunnel __rcu *tunnels_l[IP6_SIT_HASH_SIZE]; |
3a43be3c3 sit: get rid of i... |
76 77 |
struct ip_tunnel __rcu *tunnels_wc[1]; struct ip_tunnel __rcu **tunnels[4]; |
291821766 [SIT]: Make tunne... |
78 |
|
cd3dbc194 [SIT]: Make the f... |
79 |
struct net_device *fb_tunnel_dev; |
8190d9009 [SIT]: Introduce ... |
80 |
}; |
fd5d687b7 sit: refactor ipi... |
81 82 83 84 85 86 |
static inline struct sit_net *dev_to_sit_net(struct net_device *dev) { struct ip_tunnel *t = netdev_priv(dev); return net_generic(t->net, sit_net_id); } |
4543c10de ipv6 sit: RCU con... |
87 88 89 |
/* * Must be invoked with rcu_read_lock */ |
3e866703c net/ipv6/sit.c: C... |
90 |
static struct ip_tunnel *ipip6_tunnel_lookup(struct net *net, |
3051fbec2 net: sit: Update ... |
91 92 93 |
struct net_device *dev, __be32 remote, __be32 local, int sifindex) |
1da177e4c Linux-2.6.12-rc2 |
94 |
{ |
3a43be3c3 sit: get rid of i... |
95 96 |
unsigned int h0 = HASH(remote); unsigned int h1 = HASH(local); |
1da177e4c Linux-2.6.12-rc2 |
97 |
struct ip_tunnel *t; |
291821766 [SIT]: Make tunne... |
98 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
3051fbec2 net: sit: Update ... |
99 |
int ifindex = dev ? dev->ifindex : 0; |
1da177e4c Linux-2.6.12-rc2 |
100 |
|
e086cadc0 net: unify for_ea... |
101 |
for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) { |
1da177e4c Linux-2.6.12-rc2 |
102 |
if (local == t->parms.iph.saddr && |
4fddbf5d7 sit: strictly res... |
103 |
remote == t->parms.iph.daddr && |
3051fbec2 net: sit: Update ... |
104 105 |
(!dev || !t->parms.link || ifindex == t->parms.link || sifindex == t->parms.link) && |
4fddbf5d7 sit: strictly res... |
106 |
(t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
return t; } |
e086cadc0 net: unify for_ea... |
109 |
for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) { |
4fddbf5d7 sit: strictly res... |
110 |
if (remote == t->parms.iph.daddr && |
3051fbec2 net: sit: Update ... |
111 112 |
(!dev || !t->parms.link || ifindex == t->parms.link || sifindex == t->parms.link) && |
4fddbf5d7 sit: strictly res... |
113 |
(t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
114 115 |
return t; } |
e086cadc0 net: unify for_ea... |
116 |
for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) { |
4fddbf5d7 sit: strictly res... |
117 |
if (local == t->parms.iph.saddr && |
3051fbec2 net: sit: Update ... |
118 119 |
(!dev || !t->parms.link || ifindex == t->parms.link || sifindex == t->parms.link) && |
4fddbf5d7 sit: strictly res... |
120 |
(t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
121 122 |
return t; } |
4543c10de ipv6 sit: RCU con... |
123 |
t = rcu_dereference(sitn->tunnels_wc[0]); |
53b24b8f9 ipv6: coding styl... |
124 |
if (t && (t->dev->flags & IFF_UP)) |
1da177e4c Linux-2.6.12-rc2 |
125 126 127 |
return t; return NULL; } |
3a43be3c3 sit: get rid of i... |
128 |
static struct ip_tunnel __rcu **__ipip6_bucket(struct sit_net *sitn, |
ca8def148 [SIT]: Add net/si... |
129 |
struct ip_tunnel_parm *parms) |
1da177e4c Linux-2.6.12-rc2 |
130 |
{ |
420fe234a [IPV6] SIT: Unify... |
131 132 |
__be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; |
3a43be3c3 sit: get rid of i... |
133 |
unsigned int h = 0; |
1da177e4c Linux-2.6.12-rc2 |
134 135 136 137 138 139 140 141 142 143 |
int prio = 0; if (remote) { prio |= 2; h ^= HASH(remote); } if (local) { prio |= 1; h ^= HASH(local); } |
291821766 [SIT]: Make tunne... |
144 |
return &sitn->tunnels[prio][h]; |
1da177e4c Linux-2.6.12-rc2 |
145 |
} |
3a43be3c3 sit: get rid of i... |
146 |
static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn, |
ca8def148 [SIT]: Add net/si... |
147 |
struct ip_tunnel *t) |
420fe234a [IPV6] SIT: Unify... |
148 |
{ |
ca8def148 [SIT]: Add net/si... |
149 |
return __ipip6_bucket(sitn, &t->parms); |
420fe234a [IPV6] SIT: Unify... |
150 |
} |
ca8def148 [SIT]: Add net/si... |
151 |
static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) |
1da177e4c Linux-2.6.12-rc2 |
152 |
{ |
3a43be3c3 sit: get rid of i... |
153 154 155 156 157 158 159 |
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 ... |
160 |
rcu_assign_pointer(*tp, t->next); |
1da177e4c Linux-2.6.12-rc2 |
161 162 163 164 |
break; } } } |
ca8def148 [SIT]: Add net/si... |
165 |
static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t) |
1da177e4c Linux-2.6.12-rc2 |
166 |
{ |
3a43be3c3 sit: get rid of i... |
167 |
struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t); |
1da177e4c Linux-2.6.12-rc2 |
168 |
|
cf778b00e net: reintroduce ... |
169 170 |
rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); |
1da177e4c Linux-2.6.12-rc2 |
171 |
} |
e0c939481 ipv6 sit: Ensure ... |
172 |
static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) |
fa857afcf ipv6 sit: 6rd (IP... |
173 174 |
{ #ifdef CONFIG_IPV6_SIT_6RD |
e0c939481 ipv6 sit: Ensure ... |
175 |
struct ip_tunnel *t = netdev_priv(dev); |
79134e6ce net: do not creat... |
176 |
if (dev == sitn->fb_tunnel_dev || !sitn->fb_tunnel_dev) { |
fa857afcf ipv6 sit: 6rd (IP... |
177 178 179 180 181 182 183 184 185 186 |
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 } |
f37234160 sit: add support ... |
187 188 189 190 191 192 |
static int ipip6_tunnel_create(struct net_device *dev) { struct ip_tunnel *t = netdev_priv(dev); struct net *net = dev_net(dev); struct sit_net *sitn = net_generic(net, sit_net_id); int err; |
ebe084aaf sit: Use ipip6_tu... |
193 194 |
memcpy(dev->dev_addr, &t->parms.iph.saddr, 4); memcpy(dev->broadcast, &t->parms.iph.daddr, 4); |
f37234160 sit: add support ... |
195 |
|
d440b7206 sit: fix sparse w... |
196 |
if ((__force u16)t->parms.i_flags & SIT_ISATAP) |
f37234160 sit: add support ... |
197 |
dev->priv_flags |= IFF_ISATAP; |
87e57399e sit: set rtnl_lin... |
198 |
dev->rtnl_link_ops = &sit_link_ops; |
f37234160 sit: add support ... |
199 200 201 |
err = register_netdevice(dev); if (err < 0) goto out; |
ebe084aaf sit: Use ipip6_tu... |
202 |
ipip6_tunnel_clone_6rd(dev, sitn); |
f37234160 sit: add support ... |
203 204 205 206 207 208 209 210 |
dev_hold(dev); ipip6_tunnel_link(sitn, t); return 0; out: return err; } |
3a43be3c3 sit: get rid of i... |
211 |
static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, |
ca8def148 [SIT]: Add net/si... |
212 |
struct ip_tunnel_parm *parms, int create) |
1da177e4c Linux-2.6.12-rc2 |
213 |
{ |
e69a4adc6 [IPV6]: Misc endi... |
214 215 |
__be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; |
3a43be3c3 sit: get rid of i... |
216 217 |
struct ip_tunnel *t, *nt; struct ip_tunnel __rcu **tp; |
1da177e4c Linux-2.6.12-rc2 |
218 |
struct net_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
219 |
char name[IFNAMSIZ]; |
ca8def148 [SIT]: Add net/si... |
220 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
1da177e4c Linux-2.6.12-rc2 |
221 |
|
3a43be3c3 sit: get rid of i... |
222 223 224 |
for (tp = __ipip6_bucket(sitn, parms); (t = rtnl_dereference(*tp)) != NULL; tp = &t->next) { |
8db99e571 sit: Fail to crea... |
225 |
if (local == t->parms.iph.saddr && |
4fddbf5d7 sit: strictly res... |
226 227 |
remote == t->parms.iph.daddr && parms->link == t->parms.link) { |
8db99e571 sit: Fail to crea... |
228 229 230 231 232 |
if (create) return NULL; else return t; } |
1da177e4c Linux-2.6.12-rc2 |
233 234 235 |
} if (!create) goto failed; |
b95211e06 ipv6: sit: better... |
236 237 238 |
if (parms->name[0]) { if (!dev_valid_name(parms->name)) goto failed; |
1da177e4c Linux-2.6.12-rc2 |
239 |
strlcpy(name, parms->name, IFNAMSIZ); |
b95211e06 ipv6: sit: better... |
240 |
} else { |
15fc1f705 sit: percpu stats... |
241 |
strcpy(name, "sit%d"); |
b95211e06 ipv6: sit: better... |
242 |
} |
c835a6773 net: set name_ass... |
243 244 |
dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, ipip6_tunnel_setup); |
63159f29b ipv6: coding styl... |
245 |
if (!dev) |
1da177e4c Linux-2.6.12-rc2 |
246 |
return NULL; |
7a97146cc [SIT]: Allow to c... |
247 |
dev_net_set(dev, net); |
2941a4863 [NET]: Convert ne... |
248 |
nt = netdev_priv(dev); |
1326c3d5a ipv6: convert tun... |
249 |
|
1da177e4c Linux-2.6.12-rc2 |
250 |
nt->parms = *parms; |
f37234160 sit: add support ... |
251 |
if (ipip6_tunnel_create(dev) < 0) |
b37d428b2 [INET]: Don't cre... |
252 |
goto failed_free; |
1da177e4c Linux-2.6.12-rc2 |
253 |
|
1da177e4c Linux-2.6.12-rc2 |
254 |
return nt; |
b37d428b2 [INET]: Don't cre... |
255 |
failed_free: |
cf124db56 net: Fix inconsis... |
256 |
free_netdev(dev); |
1da177e4c Linux-2.6.12-rc2 |
257 258 259 |
failed: return NULL; } |
ef9a9d118 ipv6 sit: RCU con... |
260 261 262 263 |
#define for_each_prl_rcu(start) \ for (prl = rcu_dereference(start); \ prl; \ prl = rcu_dereference(prl->next)) |
fadf6bf06 [IPV6] SIT: Add P... |
264 |
static struct ip_tunnel_prl_entry * |
3fcfa1290 [IPV6] SIT: Fix l... |
265 |
__ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) |
fadf6bf06 [IPV6] SIT: Add P... |
266 |
{ |
ef9a9d118 ipv6 sit: RCU con... |
267 |
struct ip_tunnel_prl_entry *prl; |
fadf6bf06 [IPV6] SIT: Add P... |
268 |
|
ef9a9d118 ipv6 sit: RCU con... |
269 270 |
for_each_prl_rcu(t->prl) if (prl->addr == addr) |
fadf6bf06 [IPV6] SIT: Add P... |
271 |
break; |
ef9a9d118 ipv6 sit: RCU con... |
272 |
return prl; |
fadf6bf06 [IPV6] SIT: Add P... |
273 274 |
} |
fd5d687b7 sit: refactor ipi... |
275 |
static int ipip6_tunnel_get_prl(struct net_device *dev, struct ifreq *ifr) |
300aaeeaa [IPV6] SIT: Add S... |
276 |
{ |
fd5d687b7 sit: refactor ipi... |
277 278 |
struct ip_tunnel_prl __user *a = ifr->ifr_ifru.ifru_data; struct ip_tunnel *t = netdev_priv(dev); |
2b4743bd6 ipv6 sit: Avoid e... |
279 |
struct ip_tunnel_prl kprl, *kp; |
300aaeeaa [IPV6] SIT: Add S... |
280 281 282 |
struct ip_tunnel_prl_entry *prl; unsigned int cmax, c = 0, ca, len; int ret = 0; |
fd5d687b7 sit: refactor ipi... |
283 284 |
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) return -EINVAL; |
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 |
cmax = 1; /* For simple GET or for root users, * we try harder to allocate. */ kp = (cmax <= 1 || capable(CAP_NET_ADMIN)) ? |
0ccc22f42 sit: use __GFP_NO... |
295 |
kcalloc(cmax, sizeof(*kp), GFP_KERNEL | __GFP_NOWARN) : |
300aaeeaa [IPV6] SIT: Add S... |
296 |
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 |
} |
fd5d687b7 sit: refactor ipi... |
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
static int ipip6_tunnel_prl_ctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ip_tunnel *t = netdev_priv(dev); struct ip_tunnel_prl prl; int err; if (!ns_capable(t->net->user_ns, CAP_NET_ADMIN)) return -EPERM; if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) return -EINVAL; if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) return -EFAULT; switch (cmd) { case SIOCDELPRL: err = ipip6_tunnel_del_prl(t, &prl); break; case SIOCADDPRL: case SIOCCHGPRL: err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); break; } dst_cache_reset(&t->dst_cache); netdev_state_change(dev); return err; } |
fadf6bf06 [IPV6] SIT: Add P... |
446 |
static int |
b71d1d426 inet: constify ip... |
447 |
isatap_chksrc(struct sk_buff *skb, const struct iphdr *iph, struct ip_tunnel *t) |
fadf6bf06 [IPV6] SIT: Add P... |
448 |
{ |
3fcfa1290 [IPV6] SIT: Fix l... |
449 |
struct ip_tunnel_prl_entry *p; |
fadf6bf06 [IPV6] SIT: Add P... |
450 |
int ok = 1; |
ef9a9d118 ipv6 sit: RCU con... |
451 |
rcu_read_lock(); |
3fcfa1290 [IPV6] SIT: Fix l... |
452 |
p = __ipip6_tunnel_locate_prl(t, iph->saddr); |
fadf6bf06 [IPV6] SIT: Add P... |
453 |
if (p) { |
300aaeeaa [IPV6] SIT: Add S... |
454 |
if (p->flags & PRL_DEFAULT) |
fadf6bf06 [IPV6] SIT: Add P... |
455 456 457 458 |
skb->ndisc_nodetype = NDISC_NODETYPE_DEFAULT; else skb->ndisc_nodetype = NDISC_NODETYPE_NODEFAULT; } else { |
b71d1d426 inet: constify ip... |
459 |
const struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr; |
fadf6bf06 [IPV6] SIT: Add P... |
460 461 |
if (ipv6_addr_is_isatap(addr6) && (addr6->s6_addr32[3] == iph->saddr) && |
52eeeb848 [IPV6]: Unify ip6... |
462 |
ipv6_chk_prefix(addr6, t->dev)) |
fadf6bf06 [IPV6] SIT: Add P... |
463 464 465 466 |
skb->ndisc_nodetype = NDISC_NODETYPE_HOST; else ok = 0; } |
ef9a9d118 ipv6 sit: RCU con... |
467 |
rcu_read_unlock(); |
fadf6bf06 [IPV6] SIT: Add P... |
468 469 |
return ok; } |
1da177e4c Linux-2.6.12-rc2 |
470 471 |
static void ipip6_tunnel_uninit(struct net_device *dev) { |
5e6700b3b sit: add support ... |
472 473 |
struct ip_tunnel *tunnel = netdev_priv(dev); struct sit_net *sitn = net_generic(tunnel->net, sit_net_id); |
ca8def148 [SIT]: Add net/si... |
474 |
|
cd3dbc194 [SIT]: Make the f... |
475 |
if (dev == sitn->fb_tunnel_dev) { |
a9b3cd7f3 rcu: convert uses... |
476 |
RCU_INIT_POINTER(sitn->tunnels_wc[0], NULL); |
1da177e4c Linux-2.6.12-rc2 |
477 |
} else { |
5e6700b3b sit: add support ... |
478 479 |
ipip6_tunnel_unlink(sitn, tunnel); ipip6_tunnel_del_prl(tunnel, NULL); |
1da177e4c Linux-2.6.12-rc2 |
480 |
} |
e09acddf8 ip_tunnel: replac... |
481 |
dst_cache_reset(&tunnel->dst_cache); |
3a43be3c3 sit: get rid of i... |
482 |
dev_put(dev); |
1da177e4c Linux-2.6.12-rc2 |
483 |
} |
c73cb5a2d [IPSEC]: make sit... |
484 |
static int ipip6_err(struct sk_buff *skb, u32 info) |
1da177e4c Linux-2.6.12-rc2 |
485 |
{ |
b71d1d426 inet: constify ip... |
486 |
const struct iphdr *iph = (const struct iphdr *)skb->data; |
88c7664f1 [SK_BUFF]: Introd... |
487 488 |
const int type = icmp_hdr(skb)->type; const int code = icmp_hdr(skb)->code; |
20e1954fe ipv6: RFC 4884 pa... |
489 |
unsigned int data_len = 0; |
1da177e4c Linux-2.6.12-rc2 |
490 |
struct ip_tunnel *t; |
3051fbec2 net: sit: Update ... |
491 |
int sifindex; |
c73cb5a2d [IPSEC]: make sit... |
492 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
493 494 495 496 |
switch (type) { default: case ICMP_PARAMETERPROB: |
c73cb5a2d [IPSEC]: make sit... |
497 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
498 499 500 501 |
case ICMP_DEST_UNREACH: switch (code) { case ICMP_SR_FAILED: |
1da177e4c Linux-2.6.12-rc2 |
502 |
/* Impossible event. */ |
c73cb5a2d [IPSEC]: make sit... |
503 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
504 505 506 507 508 509 510 511 512 513 |
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... |
514 |
return 0; |
20e1954fe ipv6: RFC 4884 pa... |
515 |
data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */ |
1da177e4c Linux-2.6.12-rc2 |
516 |
break; |
ec18d9a26 ipv6: Add redirec... |
517 518 |
case ICMP_REDIRECT: break; |
1da177e4c Linux-2.6.12-rc2 |
519 |
} |
c73cb5a2d [IPSEC]: make sit... |
520 |
err = -ENOENT; |
3051fbec2 net: sit: Update ... |
521 522 523 |
sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0; t = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, iph->daddr, iph->saddr, sifindex); |
63159f29b ipv6: coding styl... |
524 |
if (!t) |
363933955 ipv4: Handle PMTU... |
525 526 527 528 |
goto out; if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { ipv4_update_pmtu(skb, dev_net(skb->dev), info, |
d888f3966 net-ipv4: remove ... |
529 |
t->parms.link, iph->protocol); |
363933955 ipv4: Handle PMTU... |
530 531 532 |
err = 0; goto out; } |
ec18d9a26 ipv6: Add redirec... |
533 |
if (type == ICMP_REDIRECT) { |
1042caa79 net-ipv4: remove ... |
534 535 |
ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, iph->protocol); |
ec18d9a26 ipv6: Add redirec... |
536 537 538 |
err = 0; goto out; } |
363933955 ipv4: Handle PMTU... |
539 |
|
2d7a3b276 ipv6: translate I... |
540 |
err = 0; |
173656acc sit: check if IPv... |
541 542 |
if (__in6_dev_get(skb->dev) && !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len)) |
1da177e4c Linux-2.6.12-rc2 |
543 |
goto out; |
c73cb5a2d [IPSEC]: make sit... |
544 |
|
2d7a3b276 ipv6: translate I... |
545 |
if (t->parms.iph.daddr == 0) |
ca15a078b sit: generate icm... |
546 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
547 548 |
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) goto out; |
bb80087a9 sit: used time_be... |
549 |
if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO)) |
1da177e4c Linux-2.6.12-rc2 |
550 551 552 553 554 |
t->err_count++; else t->err_count = 1; t->err_time = jiffies; out: |
c73cb5a2d [IPSEC]: make sit... |
555 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
556 |
} |
218774dc3 ipv6: add anti-sp... |
557 558 559 560 561 562 563 564 |
static inline bool is_spoofed_6rd(struct ip_tunnel *tunnel, const __be32 v4addr, const struct in6_addr *v6addr) { __be32 v4embed = 0; if (check_6rd(tunnel, v6addr, &v4embed) && v4addr != v4embed) return true; return false; } |
7df37ff33 IPv6 NAT: Do not ... |
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 |
/* Checks if an address matches an address on the tunnel interface. * Used to detect the NAT of proto 41 packets and let them pass spoofing test. * Long story: * This function is called after we considered the packet as spoofed * in is_spoofed_6rd. * We may have a router that is doing NAT for proto 41 packets * for an internal station. Destination a.a.a.a/PREFIX:bbbb:bbbb * will be translated to n.n.n.n/PREFIX:bbbb:bbbb. And is_spoofed_6rd * function will return true, dropping the packet. * But, we can still check if is spoofed against the IP * addresses associated with the interface. */ static bool only_dnatted(const struct ip_tunnel *tunnel, const struct in6_addr *v6dst) { int prefix_len; #ifdef CONFIG_IPV6_SIT_6RD prefix_len = tunnel->ip6rd.prefixlen + 32 - tunnel->ip6rd.relay_prefixlen; #else prefix_len = 48; #endif return ipv6_chk_custom_prefix(v6dst, prefix_len, tunnel->dev); } /* Returns true if a packet is spoofed */ static bool packet_is_spoofed(struct sk_buff *skb, const struct iphdr *iph, struct ip_tunnel *tunnel) { const struct ipv6hdr *ipv6h; if (tunnel->dev->priv_flags & IFF_ISATAP) { if (!isatap_chksrc(skb, iph, tunnel)) return true; return false; } if (tunnel->dev->flags & IFF_POINTOPOINT) return false; ipv6h = ipv6_hdr(skb); if (unlikely(is_spoofed_6rd(tunnel, iph->saddr, &ipv6h->saddr))) { net_warn_ratelimited("Src spoofed %pI4/%pI6c -> %pI4/%pI6c ", &iph->saddr, &ipv6h->saddr, &iph->daddr, &ipv6h->daddr); return true; } if (likely(!is_spoofed_6rd(tunnel, iph->daddr, &ipv6h->daddr))) return false; if (only_dnatted(tunnel, &ipv6h->daddr)) return false; net_warn_ratelimited("Dst spoofed %pI4/%pI6c -> %pI4/%pI6c ", &iph->saddr, &ipv6h->saddr, &iph->daddr, &ipv6h->daddr); return true; } |
1da177e4c Linux-2.6.12-rc2 |
630 631 |
static int ipip6_rcv(struct sk_buff *skb) { |
1ad759d84 ipv6: remove unne... |
632 |
const struct iphdr *iph = ip_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
633 |
struct ip_tunnel *tunnel; |
3051fbec2 net: sit: Update ... |
634 |
int sifindex; |
f4e0b4c5e ip6tnl/sit: drop ... |
635 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
636 |
|
3051fbec2 net: sit: Update ... |
637 |
sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0; |
4fddbf5d7 sit: strictly res... |
638 |
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, |
3051fbec2 net: sit: Update ... |
639 |
iph->saddr, iph->daddr, sifindex); |
53b24b8f9 ipv6: coding styl... |
640 |
if (tunnel) { |
8f84985fe net: unify the pc... |
641 |
struct pcpu_sw_netstats *tstats; |
15fc1f705 sit: percpu stats... |
642 |
|
32b8a8e59 sit: add IPv4 ove... |
643 644 645 |
if (tunnel->parms.iph.protocol != IPPROTO_IPV6 && tunnel->parms.iph.protocol != 0) goto out; |
b0e380b1d [SK_BUFF]: unions... |
646 |
skb->mac_header = skb->network_header; |
c1d2bbe1c [SK_BUFF]: Introd... |
647 |
skb_reset_network_header(skb); |
8cdfab8a4 [IPV4]: reset IPC... |
648 |
IPCB(skb)->flags = 0; |
a09a4c8dd tunnels: Remove e... |
649 |
skb->dev = tunnel->dev; |
c7dc89c0a [IPV6]: Add RFC42... |
650 |
|
7df37ff33 IPv6 NAT: Do not ... |
651 652 653 |
if (packet_is_spoofed(skb, iph, tunnel)) { tunnel->dev->stats.rx_errors++; goto out; |
f4e0b4c5e ip6tnl/sit: drop ... |
654 |
} |
a09a4c8dd tunnels: Remove e... |
655 656 657 |
if (iptunnel_pull_header(skb, 0, htons(ETH_P_IPV6), !net_eq(tunnel->net, dev_net(tunnel->dev)))) goto out; |
f4e0b4c5e ip6tnl/sit: drop ... |
658 |
|
bb9bd814e ipv6: sit: reset ... |
659 660 661 662 |
/* skb can be uncloned in iptunnel_pull_header, so * old iph is no longer valid */ iph = (const struct iphdr *)skb_mac_header(skb); |
f4e0b4c5e ip6tnl/sit: drop ... |
663 664 665 666 667 668 669 670 671 672 673 |
err = IP_ECN_decapsulate(iph, skb); if (unlikely(err)) { if (log_ecn_error) net_info_ratelimited("non-ECT from %pI4 with TOS=%#x ", &iph->saddr, iph->tos); if (err > 1) { ++tunnel->dev->stats.rx_frame_errors; ++tunnel->dev->stats.rx_errors; goto out; } |
c7dc89c0a [IPV6]: Add RFC42... |
674 |
} |
d19d56ddc net: Introduce sk... |
675 |
|
15fc1f705 sit: percpu stats... |
676 |
tstats = this_cpu_ptr(tunnel->dev->tstats); |
c3ac17cd6 ipv6: fix the use... |
677 |
u64_stats_update_begin(&tstats->syncp); |
15fc1f705 sit: percpu stats... |
678 679 |
tstats->rx_packets++; tstats->rx_bytes += skb->len; |
c3ac17cd6 ipv6: fix the use... |
680 |
u64_stats_update_end(&tstats->syncp); |
15fc1f705 sit: percpu stats... |
681 |
|
caf586e5f net: add a core n... |
682 |
netif_rx(skb); |
8990f468a net: rx_dropped a... |
683 |
|
1da177e4c Linux-2.6.12-rc2 |
684 685 |
return 0; } |
6dcdd1b36 net/ipv6/sit.c: r... |
686 |
/* no tunnel matched, let upstream know, ipsec may handle it */ |
6dcdd1b36 net/ipv6/sit.c: r... |
687 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
688 |
out: |
36ca34cc3 sit: Add missing ... |
689 |
kfree_skb(skb); |
1da177e4c Linux-2.6.12-rc2 |
690 691 |
return 0; } |
49dbe7ae2 sit: support MPLS... |
692 |
static const struct tnl_ptk_info ipip_tpi = { |
32b8a8e59 sit: add IPv4 ove... |
693 694 695 |
/* no tunnel info required for ipip. */ .proto = htons(ETH_P_IP), }; |
49dbe7ae2 sit: support MPLS... |
696 697 698 699 700 701 702 703 |
#if IS_ENABLED(CONFIG_MPLS) static const struct tnl_ptk_info mplsip_tpi = { /* no tunnel info required for mplsip. */ .proto = htons(ETH_P_MPLS_UC), }; #endif static int sit_tunnel_rcv(struct sk_buff *skb, u8 ipproto) |
32b8a8e59 sit: add IPv4 ove... |
704 |
{ |
3d7b46cd2 ip_tunnel: push g... |
705 |
const struct iphdr *iph; |
32b8a8e59 sit: add IPv4 ove... |
706 |
struct ip_tunnel *tunnel; |
3051fbec2 net: sit: Update ... |
707 708 709 |
int sifindex; sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0; |
32b8a8e59 sit: add IPv4 ove... |
710 |
|
3d7b46cd2 ip_tunnel: push g... |
711 |
iph = ip_hdr(skb); |
32b8a8e59 sit: add IPv4 ove... |
712 |
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, |
3051fbec2 net: sit: Update ... |
713 |
iph->saddr, iph->daddr, sifindex); |
53b24b8f9 ipv6: coding styl... |
714 |
if (tunnel) { |
49dbe7ae2 sit: support MPLS... |
715 716 717 |
const struct tnl_ptk_info *tpi; if (tunnel->parms.iph.protocol != ipproto && |
32b8a8e59 sit: add IPv4 ove... |
718 719 720 721 722 |
tunnel->parms.iph.protocol != 0) goto drop; if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) goto drop; |
49dbe7ae2 sit: support MPLS... |
723 724 725 726 727 728 729 |
#if IS_ENABLED(CONFIG_MPLS) if (ipproto == IPPROTO_MPLS) tpi = &mplsip_tpi; else #endif tpi = &ipip_tpi; if (iptunnel_pull_header(skb, 0, tpi->proto, false)) |
737e828bd ipv4 tunnels: fix... |
730 |
goto drop; |
49dbe7ae2 sit: support MPLS... |
731 |
return ip_tunnel_rcv(tunnel, skb, tpi, NULL, log_ecn_error); |
32b8a8e59 sit: add IPv4 ove... |
732 733 734 735 736 737 738 739 |
} return 1; drop: kfree_skb(skb); return 0; } |
49dbe7ae2 sit: support MPLS... |
740 741 742 743 744 745 746 747 748 749 750 |
static int ipip_rcv(struct sk_buff *skb) { return sit_tunnel_rcv(skb, IPPROTO_IPIP); } #if IS_ENABLED(CONFIG_MPLS) static int mplsip_rcv(struct sk_buff *skb) { return sit_tunnel_rcv(skb, IPPROTO_MPLS); } #endif |
fa857afcf ipv6 sit: 6rd (IP... |
751 |
/* |
218774dc3 ipv6: add anti-sp... |
752 753 |
* If the IPv6 address comes from 6rd / 6to4 (RFC 3056) addr space this function * stores the embedded IPv4 address in v4dst and returns true. |
fa857afcf ipv6 sit: 6rd (IP... |
754 |
*/ |
218774dc3 ipv6: add anti-sp... |
755 756 |
static bool check_6rd(struct ip_tunnel *tunnel, const struct in6_addr *v6dst, __be32 *v4dst) |
1da177e4c Linux-2.6.12-rc2 |
757 |
{ |
fa857afcf ipv6 sit: 6rd (IP... |
758 759 760 |
#ifdef CONFIG_IPV6_SIT_6RD if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix, tunnel->ip6rd.prefixlen)) { |
3a43be3c3 sit: get rid of i... |
761 |
unsigned int pbw0, pbi0; |
fa857afcf ipv6 sit: 6rd (IP... |
762 763 764 765 766 |
int pbi1; u32 d; pbw0 = tunnel->ip6rd.prefixlen >> 5; pbi0 = tunnel->ip6rd.prefixlen & 0x1f; |
a843dc4eb net: sit: fix UBS... |
767 768 769 |
d = tunnel->ip6rd.relay_prefixlen < 32 ? (ntohl(v6dst->s6_addr32[pbw0]) << pbi0) >> tunnel->ip6rd.relay_prefixlen : 0; |
fa857afcf ipv6 sit: 6rd (IP... |
770 771 772 |
pbi1 = pbi0 - tunnel->ip6rd.relay_prefixlen; if (pbi1 > 0) |
e7db38c38 ipv6 sit: Fix 6rd... |
773 |
d |= ntohl(v6dst->s6_addr32[pbw0 + 1]) >> |
fa857afcf ipv6 sit: 6rd (IP... |
774 |
(32 - pbi1); |
218774dc3 ipv6: add anti-sp... |
775 776 |
*v4dst = tunnel->ip6rd.relay_prefix | htonl(d); return true; |
fa857afcf ipv6 sit: 6rd (IP... |
777 778 |
} #else |
1da177e4c Linux-2.6.12-rc2 |
779 |
if (v6dst->s6_addr16[0] == htons(0x2002)) { |
1ab1457c4 [NET] IPV6: Fix w... |
780 |
/* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */ |
218774dc3 ipv6: add anti-sp... |
781 782 |
memcpy(v4dst, &v6dst->s6_addr16[1], 4); return true; |
1da177e4c Linux-2.6.12-rc2 |
783 |
} |
fa857afcf ipv6 sit: 6rd (IP... |
784 |
#endif |
218774dc3 ipv6: add anti-sp... |
785 786 787 788 789 790 791 792 |
return false; } static inline __be32 try_6rd(struct ip_tunnel *tunnel, const struct in6_addr *v6dst) { __be32 dst = 0; check_6rd(tunnel, v6dst, &dst); |
1da177e4c Linux-2.6.12-rc2 |
793 794 795 796 797 798 799 |
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... |
800 801 |
static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
802 |
{ |
2941a4863 [NET]: Convert ne... |
803 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
b71d1d426 inet: constify ip... |
804 805 |
const struct iphdr *tiph = &tunnel->parms.iph; const struct ipv6hdr *iph6 = ipv6_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
806 |
u8 tos = tunnel->parms.iph.tos; |
292f4f3ce sit: Clean up DF ... |
807 |
__be16 df = tiph->frag_off; |
67ba4152e ipv6: White-space... |
808 809 810 |
struct rtable *rt; /* Route to the other host */ struct net_device *tdev; /* Device to other host */ unsigned int max_headroom; /* The extra header space needed */ |
e69a4adc6 [IPV6]: Misc endi... |
811 |
__be32 dst = tiph->daddr; |
31e4543db ipv4: Make caller... |
812 |
struct flowi4 fl4; |
1da177e4c Linux-2.6.12-rc2 |
813 |
int mtu; |
b71d1d426 inet: constify ip... |
814 |
const struct in6_addr *addr6; |
1da177e4c Linux-2.6.12-rc2 |
815 |
int addr_type; |
0e6fbc5b6 ip_tunnels: exten... |
816 |
u8 ttl; |
14909664e sit: Setup and TX... |
817 818 |
u8 protocol = IPPROTO_IPV6; int t_hlen = tunnel->hlen + sizeof(struct iphdr); |
1da177e4c Linux-2.6.12-rc2 |
819 |
|
c2bceb3d7 sit tunnels: prop... |
820 821 |
if (tos == 1) tos = ipv6_get_dsfield(iph6); |
c7dc89c0a [IPV6]: Add RFC42... |
822 823 824 |
/* ISATAP (RFC4214) - must come before 6to4 */ if (dev->priv_flags & IFF_ISATAP) { struct neighbour *neigh = NULL; |
1e2927b08 ipv6: sit: Conver... |
825 |
bool do_tx_error = false; |
c7dc89c0a [IPV6]: Add RFC42... |
826 |
|
adf30907d net: skb->dst acc... |
827 |
if (skb_dst(skb)) |
1e2927b08 ipv6: sit: Conver... |
828 |
neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); |
c7dc89c0a [IPV6]: Add RFC42... |
829 |
|
63159f29b ipv6: coding styl... |
830 |
if (!neigh) { |
7df37ff33 IPv6 NAT: Do not ... |
831 832 |
net_dbg_ratelimited("nexthop == NULL "); |
c7dc89c0a [IPV6]: Add RFC42... |
833 834 |
goto tx_error; } |
3e866703c net/ipv6/sit.c: C... |
835 |
addr6 = (const struct in6_addr *)&neigh->primary_key; |
c7dc89c0a [IPV6]: Add RFC42... |
836 837 838 839 840 841 |
addr_type = ipv6_addr_type(addr6); if ((addr_type & IPV6_ADDR_UNICAST) && ipv6_addr_is_isatap(addr6)) dst = addr6->s6_addr32[3]; else |
1e2927b08 ipv6: sit: Conver... |
842 843 844 845 |
do_tx_error = true; neigh_release(neigh); if (do_tx_error) |
c7dc89c0a [IPV6]: Add RFC42... |
846 847 |
goto tx_error; } |
1da177e4c Linux-2.6.12-rc2 |
848 |
if (!dst) |
218774dc3 ipv6: add anti-sp... |
849 |
dst = try_6rd(tunnel, &iph6->daddr); |
1da177e4c Linux-2.6.12-rc2 |
850 851 852 |
if (!dst) { struct neighbour *neigh = NULL; |
1e2927b08 ipv6: sit: Conver... |
853 |
bool do_tx_error = false; |
1da177e4c Linux-2.6.12-rc2 |
854 |
|
adf30907d net: skb->dst acc... |
855 |
if (skb_dst(skb)) |
1e2927b08 ipv6: sit: Conver... |
856 |
neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); |
1da177e4c Linux-2.6.12-rc2 |
857 |
|
63159f29b ipv6: coding styl... |
858 |
if (!neigh) { |
7df37ff33 IPv6 NAT: Do not ... |
859 860 |
net_dbg_ratelimited("nexthop == NULL "); |
1da177e4c Linux-2.6.12-rc2 |
861 862 |
goto tx_error; } |
3e866703c net/ipv6/sit.c: C... |
863 |
addr6 = (const struct in6_addr *)&neigh->primary_key; |
1da177e4c Linux-2.6.12-rc2 |
864 865 866 |
addr_type = ipv6_addr_type(addr6); if (addr_type == IPV6_ADDR_ANY) { |
0660e03f6 [SK_BUFF]: Introd... |
867 |
addr6 = &ipv6_hdr(skb)->daddr; |
1da177e4c Linux-2.6.12-rc2 |
868 869 |
addr_type = ipv6_addr_type(addr6); } |
1e2927b08 ipv6: sit: Conver... |
870 871 872 873 |
if ((addr_type & IPV6_ADDR_COMPATv4) != 0) dst = addr6->s6_addr32[3]; else do_tx_error = true; |
1da177e4c Linux-2.6.12-rc2 |
874 |
|
1e2927b08 ipv6: sit: Conver... |
875 876 877 |
neigh_release(neigh); if (do_tx_error) goto tx_error; |
1da177e4c Linux-2.6.12-rc2 |
878 |
} |
9830ad4c6 ip_tunnel: Allow ... |
879 880 881 882 |
flowi4_init_output(&fl4, tunnel->parms.link, tunnel->fwmark, RT_TOS(tos), RT_SCOPE_UNIVERSE, IPPROTO_IPV6, 0, dst, tiph->saddr, 0, 0, sock_net_uid(tunnel->net, NULL)); |
9830ad4c6 ip_tunnel: Allow ... |
883 |
|
6e3d1bbbb sit: use dst_cach... |
884 885 886 887 888 889 890 891 |
rt = dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr); if (!rt) { rt = ip_route_output_flow(tunnel->net, &fl4, NULL); if (IS_ERR(rt)) { dev->stats.tx_carrier_errors++; goto tx_error_icmp; } dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, fl4.saddr); |
1da177e4c Linux-2.6.12-rc2 |
892 |
} |
6e3d1bbbb sit: use dst_cach... |
893 |
|
1da177e4c Linux-2.6.12-rc2 |
894 895 |
if (rt->rt_type != RTN_UNICAST) { ip_rt_put(rt); |
15fc1f705 sit: percpu stats... |
896 |
dev->stats.tx_carrier_errors++; |
1da177e4c Linux-2.6.12-rc2 |
897 898 |
goto tx_error_icmp; } |
d8d1f30b9 net-next: remove ... |
899 |
tdev = rt->dst.dev; |
1da177e4c Linux-2.6.12-rc2 |
900 901 902 |
if (tdev == dev) { ip_rt_put(rt); |
15fc1f705 sit: percpu stats... |
903 |
dev->stats.collisions++; |
1da177e4c Linux-2.6.12-rc2 |
904 905 |
goto tx_error; } |
7e13318da net: define gso t... |
906 |
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4)) { |
14909664e sit: Setup and TX... |
907 |
ip_rt_put(rt); |
aed069df0 ip_tunnel_core: i... |
908 |
goto tx_error; |
14909664e sit: Setup and TX... |
909 |
} |
292f4f3ce sit: Clean up DF ... |
910 |
if (df) { |
14909664e sit: Setup and TX... |
911 |
mtu = dst_mtu(&rt->dst) - t_hlen; |
1da177e4c Linux-2.6.12-rc2 |
912 |
|
292f4f3ce sit: Clean up DF ... |
913 |
if (mtu < 68) { |
15fc1f705 sit: percpu stats... |
914 |
dev->stats.collisions++; |
292f4f3ce sit: Clean up DF ... |
915 916 917 |
ip_rt_put(rt); goto tx_error; } |
1da177e4c Linux-2.6.12-rc2 |
918 |
|
292f4f3ce sit: Clean up DF ... |
919 920 921 922 |
if (mtu < IPV6_MIN_MTU) { mtu = IPV6_MIN_MTU; df = 0; } |
f15ca723c net: don't call u... |
923 |
if (tunnel->parms.iph.daddr) |
4d42df46d sit: do not confi... |
924 |
skb_dst_update_pmtu_no_confirm(skb, mtu); |
292f4f3ce sit: Clean up DF ... |
925 |
|
58a478244 ipv6: sit: update... |
926 |
if (skb->len > mtu && !skb_is_gso(skb)) { |
3ffe533c8 ipv6: drop unused... |
927 |
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
292f4f3ce sit: Clean up DF ... |
928 929 930 |
ip_rt_put(rt); goto tx_error; } |
1da177e4c Linux-2.6.12-rc2 |
931 932 933 |
} if (tunnel->err_count > 0) { |
bb80087a9 sit: used time_be... |
934 935 |
if (time_before(jiffies, tunnel->err_time + IPTUNNEL_ERR_TIMEO)) { |
1da177e4c Linux-2.6.12-rc2 |
936 937 938 939 940 941 942 943 944 |
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. */ |
14909664e sit: Setup and TX... |
945 |
max_headroom = LL_RESERVED_SPACE(tdev) + t_hlen; |
1da177e4c Linux-2.6.12-rc2 |
946 |
|
cfbba49d8 [NET]: Avoid copy... |
947 948 |
if (skb_headroom(skb) < max_headroom || skb_shared(skb) || (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { |
1da177e4c Linux-2.6.12-rc2 |
949 950 951 |
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); |
15fc1f705 sit: percpu stats... |
952 |
dev->stats.tx_dropped++; |
66028310a sit: use kfree_sk... |
953 |
kfree_skb(skb); |
6ed106549 net: use NETDEV_T... |
954 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
955 956 957 958 959 |
} if (skb->sk) skb_set_owner_w(new_skb, skb->sk); dev_kfree_skb(skb); skb = new_skb; |
0660e03f6 [SK_BUFF]: Introd... |
960 |
iph6 = ipv6_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
961 |
} |
0e6fbc5b6 ip_tunnels: exten... |
962 963 964 965 |
ttl = tiph->ttl; if (ttl == 0) ttl = iph6->hop_limit; tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); |
1da177e4c Linux-2.6.12-rc2 |
966 |
|
14909664e sit: Setup and TX... |
967 |
if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) { |
6a9eadccf ipv6: release dst... |
968 |
ip_rt_put(rt); |
14909664e sit: Setup and TX... |
969 |
goto tx_error; |
6a9eadccf ipv6: release dst... |
970 |
} |
3d483058c ipv6: wire up skb... |
971 |
|
469471cdf sit: Set inner IP... |
972 |
skb_set_inner_ipproto(skb, IPPROTO_IPV6); |
039f50629 ip_tunnel: Move s... |
973 974 |
iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); |
6ed106549 net: use NETDEV_T... |
975 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
976 977 978 979 |
tx_error_icmp: dst_link_failure(skb); tx_error: |
66028310a sit: use kfree_sk... |
980 |
kfree_skb(skb); |
61c1db7fa ipv6: sit: add GS... |
981 |
dev->stats.tx_errors++; |
6ed106549 net: use NETDEV_T... |
982 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
983 |
} |
49dbe7ae2 sit: support MPLS... |
984 985 |
static netdev_tx_t sit_tunnel_xmit__(struct sk_buff *skb, struct net_device *dev, u8 ipproto) |
32b8a8e59 sit: add IPv4 ove... |
986 987 988 |
{ struct ip_tunnel *tunnel = netdev_priv(dev); const struct iphdr *tiph = &tunnel->parms.iph; |
7e13318da net: define gso t... |
989 |
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4)) |
aed069df0 ip_tunnel_core: i... |
990 |
goto tx_error; |
32b8a8e59 sit: add IPv4 ove... |
991 |
|
49dbe7ae2 sit: support MPLS... |
992 |
skb_set_inner_ipproto(skb, ipproto); |
469471cdf sit: Set inner IP... |
993 |
|
49dbe7ae2 sit: support MPLS... |
994 |
ip_tunnel_xmit(skb, dev, tiph, ipproto); |
32b8a8e59 sit: add IPv4 ove... |
995 |
return NETDEV_TX_OK; |
aed069df0 ip_tunnel_core: i... |
996 997 |
tx_error: kfree_skb(skb); |
61c1db7fa ipv6: sit: add GS... |
998 999 |
dev->stats.tx_errors++; return NETDEV_TX_OK; |
32b8a8e59 sit: add IPv4 ove... |
1000 1001 1002 1003 1004 |
} static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { |
cb9f1b783 ip: validate head... |
1005 1006 |
if (!pskb_inet_may_pull(skb)) goto tx_err; |
32b8a8e59 sit: add IPv4 ove... |
1007 1008 |
switch (skb->protocol) { case htons(ETH_P_IP): |
49dbe7ae2 sit: support MPLS... |
1009 |
sit_tunnel_xmit__(skb, dev, IPPROTO_IPIP); |
32b8a8e59 sit: add IPv4 ove... |
1010 1011 1012 1013 |
break; case htons(ETH_P_IPV6): ipip6_tunnel_xmit(skb, dev); break; |
49dbe7ae2 sit: support MPLS... |
1014 1015 1016 1017 1018 |
#if IS_ENABLED(CONFIG_MPLS) case htons(ETH_P_MPLS_UC): sit_tunnel_xmit__(skb, dev, IPPROTO_MPLS); break; #endif |
32b8a8e59 sit: add IPv4 ove... |
1019 1020 1021 1022 1023 1024 1025 1026 |
default: goto tx_err; } return NETDEV_TX_OK; tx_err: dev->stats.tx_errors++; |
66028310a sit: use kfree_sk... |
1027 |
kfree_skb(skb); |
32b8a8e59 sit: add IPv4 ove... |
1028 1029 1030 |
return NETDEV_TX_OK; } |
8a4a50f98 [IPV6] sit: Rebin... |
1031 1032 1033 1034 |
static void ipip6_tunnel_bind_dev(struct net_device *dev) { struct net_device *tdev = NULL; struct ip_tunnel *tunnel; |
b71d1d426 inet: constify ip... |
1035 |
const struct iphdr *iph; |
31e4543db ipv4: Make caller... |
1036 |
struct flowi4 fl4; |
8a4a50f98 [IPV6] sit: Rebin... |
1037 1038 1039 1040 1041 |
tunnel = netdev_priv(dev); iph = &tunnel->parms.iph; if (iph->daddr) { |
5e6700b3b sit: add support ... |
1042 1043 |
struct rtable *rt = ip_route_output_ports(tunnel->net, &fl4, NULL, |
78fbfd8a6 ipv4: Create and ... |
1044 1045 1046 1047 1048 |
iph->daddr, iph->saddr, 0, 0, IPPROTO_IPV6, RT_TOS(iph->tos), tunnel->parms.link); |
b23dd4fe4 ipv4: Make output... |
1049 1050 |
if (!IS_ERR(rt)) { |
d8d1f30b9 net-next: remove ... |
1051 |
tdev = rt->dst.dev; |
8a4a50f98 [IPV6] sit: Rebin... |
1052 1053 1054 1055 1056 1057 |
ip_rt_put(rt); } dev->flags |= IFF_POINTOPOINT; } if (!tdev && tunnel->parms.link) |
5e6700b3b sit: add support ... |
1058 |
tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); |
8a4a50f98 [IPV6] sit: Rebin... |
1059 |
|
ff6ab32bd vrf: sit mtu shou... |
1060 |
if (tdev && !netif_is_l3_master(tdev)) { |
14909664e sit: Setup and TX... |
1061 |
int t_hlen = tunnel->hlen + sizeof(struct iphdr); |
14909664e sit: Setup and TX... |
1062 |
dev->mtu = tdev->mtu - t_hlen; |
8a4a50f98 [IPV6] sit: Rebin... |
1063 1064 1065 |
if (dev->mtu < IPV6_MIN_MTU) dev->mtu = IPV6_MIN_MTU; } |
8a4a50f98 [IPV6] sit: Rebin... |
1066 |
} |
9830ad4c6 ip_tunnel: Allow ... |
1067 1068 |
static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p, __u32 fwmark) |
f37234160 sit: add support ... |
1069 |
{ |
5e6700b3b sit: add support ... |
1070 |
struct net *net = t->net; |
f37234160 sit: add support ... |
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 |
struct sit_net *sitn = net_generic(net, sit_net_id); ipip6_tunnel_unlink(sitn, t); synchronize_net(); t->parms.iph.saddr = p->iph.saddr; t->parms.iph.daddr = p->iph.daddr; memcpy(t->dev->dev_addr, &p->iph.saddr, 4); memcpy(t->dev->broadcast, &p->iph.daddr, 4); ipip6_tunnel_link(sitn, t); t->parms.iph.ttl = p->iph.ttl; t->parms.iph.tos = p->iph.tos; |
f859b4af1 sit: update frag_... |
1082 |
t->parms.iph.frag_off = p->iph.frag_off; |
9830ad4c6 ip_tunnel: Allow ... |
1083 |
if (t->parms.link != p->link || t->fwmark != fwmark) { |
f37234160 sit: add support ... |
1084 |
t->parms.link = p->link; |
9830ad4c6 ip_tunnel: Allow ... |
1085 |
t->fwmark = fwmark; |
f37234160 sit: add support ... |
1086 1087 |
ipip6_tunnel_bind_dev(t->dev); } |
e09acddf8 ip_tunnel: replac... |
1088 |
dst_cache_reset(&t->dst_cache); |
f37234160 sit: add support ... |
1089 1090 |
netdev_state_change(t->dev); } |
e2f1f072d sit: allow to con... |
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 |
#ifdef CONFIG_IPV6_SIT_6RD static int ipip6_tunnel_update_6rd(struct ip_tunnel *t, struct ip_tunnel_6rd *ip6rd) { struct in6_addr prefix; __be32 relay_prefix; if (ip6rd->relay_prefixlen > 32 || ip6rd->prefixlen + (32 - ip6rd->relay_prefixlen) > 64) return -EINVAL; ipv6_addr_prefix(&prefix, &ip6rd->prefix, ip6rd->prefixlen); if (!ipv6_addr_equal(&prefix, &ip6rd->prefix)) return -EINVAL; if (ip6rd->relay_prefixlen) relay_prefix = ip6rd->relay_prefix & htonl(0xffffffffUL << (32 - ip6rd->relay_prefixlen)); else relay_prefix = 0; if (relay_prefix != ip6rd->relay_prefix) return -EINVAL; t->ip6rd.prefix = prefix; t->ip6rd.relay_prefix = relay_prefix; t->ip6rd.prefixlen = ip6rd->prefixlen; t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; |
e09acddf8 ip_tunnel: replac... |
1118 |
dst_cache_reset(&t->dst_cache); |
e2f1f072d sit: allow to con... |
1119 1120 1121 |
netdev_state_change(t->dev); return 0; } |
fd5d687b7 sit: refactor ipi... |
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 |
static int ipip6_tunnel_get6rd(struct net_device *dev, struct ifreq *ifr) { struct ip_tunnel *t = netdev_priv(dev); struct ip_tunnel_6rd ip6rd; struct ip_tunnel_parm p; if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) { if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) return -EFAULT; t = ipip6_tunnel_locate(t->net, &p, 0); } if (!t) t = netdev_priv(dev); ip6rd.prefix = t->ip6rd.prefix; 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))) return -EFAULT; return 0; } static int ipip6_tunnel_6rdctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ip_tunnel *t = netdev_priv(dev); struct ip_tunnel_6rd ip6rd; int err; if (!ns_capable(t->net->user_ns, CAP_NET_ADMIN)) return -EPERM; if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data, sizeof(ip6rd))) return -EFAULT; if (cmd != SIOCDEL6RD) { err = ipip6_tunnel_update_6rd(t, &ip6rd); if (err < 0) return err; } else ipip6_tunnel_clone_6rd(dev, dev_to_sit_net(dev)); return 0; } #endif /* CONFIG_IPV6_SIT_6RD */ |
e2f1f072d sit: allow to con... |
1169 |
|
03ff49793 sit: make functio... |
1170 |
static bool ipip6_valid_ip_proto(u8 ipproto) |
49dbe7ae2 sit: support MPLS... |
1171 1172 1173 1174 1175 1176 1177 1178 |
{ return ipproto == IPPROTO_IPV6 || ipproto == IPPROTO_IPIP || #if IS_ENABLED(CONFIG_MPLS) ipproto == IPPROTO_MPLS || #endif ipproto == 0; } |
1da177e4c Linux-2.6.12-rc2 |
1179 |
static int |
fd5d687b7 sit: refactor ipi... |
1180 |
__ipip6_tunnel_ioctl_validate(struct net *net, struct ip_tunnel_parm *p) |
1da177e4c Linux-2.6.12-rc2 |
1181 |
{ |
fd5d687b7 sit: refactor ipi... |
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 |
if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; if (!ipip6_valid_ip_proto(p->iph.protocol)) return -EINVAL; if (p->iph.version != 4 || p->iph.ihl != 5 || (p->iph.frag_off & htons(~IP_DF))) return -EINVAL; if (p->iph.ttl) p->iph.frag_off |= htons(IP_DF); return 0; } static int |
f60fe2df9 sit: impement ->n... |
1197 |
ipip6_tunnel_get(struct net_device *dev, struct ip_tunnel_parm *p) |
fd5d687b7 sit: refactor ipi... |
1198 1199 |
{ struct ip_tunnel *t = netdev_priv(dev); |
fd5d687b7 sit: refactor ipi... |
1200 |
|
f60fe2df9 sit: impement ->n... |
1201 1202 |
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) t = ipip6_tunnel_locate(t->net, p, 0); |
fd5d687b7 sit: refactor ipi... |
1203 1204 |
if (!t) t = netdev_priv(dev); |
f60fe2df9 sit: impement ->n... |
1205 |
memcpy(p, &t->parms, sizeof(*p)); |
fd5d687b7 sit: refactor ipi... |
1206 1207 1208 1209 |
return 0; } static int |
f60fe2df9 sit: impement ->n... |
1210 |
ipip6_tunnel_add(struct net_device *dev, struct ip_tunnel_parm *p) |
fd5d687b7 sit: refactor ipi... |
1211 |
{ |
9aad77c3b sit: use the righ... |
1212 |
struct ip_tunnel *t = netdev_priv(dev); |
fd5d687b7 sit: refactor ipi... |
1213 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
1214 |
|
f60fe2df9 sit: impement ->n... |
1215 |
err = __ipip6_tunnel_ioctl_validate(t->net, p); |
fd5d687b7 sit: refactor ipi... |
1216 1217 |
if (err) return err; |
fa857afcf ipv6 sit: 6rd (IP... |
1218 |
|
f60fe2df9 sit: impement ->n... |
1219 |
t = ipip6_tunnel_locate(t->net, p, 1); |
fd5d687b7 sit: refactor ipi... |
1220 1221 |
if (!t) return -ENOBUFS; |
fd5d687b7 sit: refactor ipi... |
1222 1223 1224 1225 |
return 0; } static int |
f60fe2df9 sit: impement ->n... |
1226 |
ipip6_tunnel_change(struct net_device *dev, struct ip_tunnel_parm *p) |
fd5d687b7 sit: refactor ipi... |
1227 1228 |
{ struct ip_tunnel *t = netdev_priv(dev); |
fd5d687b7 sit: refactor ipi... |
1229 |
int err; |
f60fe2df9 sit: impement ->n... |
1230 |
err = __ipip6_tunnel_ioctl_validate(t->net, p); |
fd5d687b7 sit: refactor ipi... |
1231 1232 |
if (err) return err; |
f60fe2df9 sit: impement ->n... |
1233 |
t = ipip6_tunnel_locate(t->net, p, 0); |
fd5d687b7 sit: refactor ipi... |
1234 1235 1236 1237 1238 1239 1240 |
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) { if (!t) return -ENOENT; } else { if (t) { if (t->dev != dev) return -EEXIST; |
fa857afcf ipv6 sit: 6rd (IP... |
1241 |
} else { |
f60fe2df9 sit: impement ->n... |
1242 1243 |
if (((dev->flags & IFF_POINTOPOINT) && !p->iph.daddr) || (!(dev->flags & IFF_POINTOPOINT) && p->iph.daddr)) |
fd5d687b7 sit: refactor ipi... |
1244 1245 |
return -EINVAL; t = netdev_priv(dev); |
fa857afcf ipv6 sit: 6rd (IP... |
1246 |
} |
1da177e4c Linux-2.6.12-rc2 |
1247 |
|
f60fe2df9 sit: impement ->n... |
1248 |
ipip6_tunnel_update(t, p, t->fwmark); |
fd5d687b7 sit: refactor ipi... |
1249 |
} |
1da177e4c Linux-2.6.12-rc2 |
1250 |
|
fd5d687b7 sit: refactor ipi... |
1251 1252 |
return 0; } |
f9cd5a553 sit: always notif... |
1253 |
|
fd5d687b7 sit: refactor ipi... |
1254 |
static int |
f60fe2df9 sit: impement ->n... |
1255 |
ipip6_tunnel_del(struct net_device *dev, struct ip_tunnel_parm *p) |
fd5d687b7 sit: refactor ipi... |
1256 1257 |
{ struct ip_tunnel *t = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
1258 |
|
fd5d687b7 sit: refactor ipi... |
1259 1260 |
if (!ns_capable(t->net->user_ns, CAP_NET_ADMIN)) return -EPERM; |
1da177e4c Linux-2.6.12-rc2 |
1261 |
|
fd5d687b7 sit: refactor ipi... |
1262 |
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) { |
f60fe2df9 sit: impement ->n... |
1263 |
t = ipip6_tunnel_locate(t->net, p, 0); |
fd5d687b7 sit: refactor ipi... |
1264 1265 1266 1267 1268 1269 1270 1271 1272 |
if (!t) return -ENOENT; if (t == netdev_priv(dev_to_sit_net(dev)->fb_tunnel_dev)) return -EPERM; dev = t->dev; } unregister_netdevice(dev); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
1273 |
|
fd5d687b7 sit: refactor ipi... |
1274 |
static int |
f60fe2df9 sit: impement ->n... |
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 |
ipip6_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) { switch (cmd) { case SIOCGETTUNNEL: return ipip6_tunnel_get(dev, p); case SIOCADDTUNNEL: return ipip6_tunnel_add(dev, p); case SIOCCHGTUNNEL: return ipip6_tunnel_change(dev, p); case SIOCDELTUNNEL: return ipip6_tunnel_del(dev, p); default: return -EINVAL; } } static int |
fd5d687b7 sit: refactor ipi... |
1292 1293 1294 1295 |
ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { switch (cmd) { case SIOCGETTUNNEL: |
fd5d687b7 sit: refactor ipi... |
1296 |
case SIOCADDTUNNEL: |
fd5d687b7 sit: refactor ipi... |
1297 |
case SIOCCHGTUNNEL: |
fd5d687b7 sit: refactor ipi... |
1298 |
case SIOCDELTUNNEL: |
f60fe2df9 sit: impement ->n... |
1299 |
return ip_tunnel_ioctl(dev, ifr, cmd); |
300aaeeaa [IPV6] SIT: Add S... |
1300 |
case SIOCGETPRL: |
fd5d687b7 sit: refactor ipi... |
1301 |
return ipip6_tunnel_get_prl(dev, ifr); |
fadf6bf06 [IPV6] SIT: Add P... |
1302 1303 1304 |
case SIOCADDPRL: case SIOCDELPRL: case SIOCCHGPRL: |
fd5d687b7 sit: refactor ipi... |
1305 |
return ipip6_tunnel_prl_ctl(dev, ifr, cmd); |
fa857afcf ipv6 sit: 6rd (IP... |
1306 |
#ifdef CONFIG_IPV6_SIT_6RD |
fd5d687b7 sit: refactor ipi... |
1307 1308 |
case SIOCGET6RD: return ipip6_tunnel_get6rd(dev, ifr); |
fa857afcf ipv6 sit: 6rd (IP... |
1309 1310 1311 |
case SIOCADD6RD: case SIOCCHG6RD: case SIOCDEL6RD: |
fd5d687b7 sit: refactor ipi... |
1312 |
return ipip6_tunnel_6rdctl(dev, ifr, cmd); |
fa857afcf ipv6 sit: 6rd (IP... |
1313 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1314 |
default: |
fd5d687b7 sit: refactor ipi... |
1315 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1316 |
} |
1da177e4c Linux-2.6.12-rc2 |
1317 |
} |
1326c3d5a ipv6: convert tun... |
1318 |
static const struct net_device_ops ipip6_netdev_ops = { |
ebe084aaf sit: Use ipip6_tu... |
1319 |
.ndo_init = ipip6_tunnel_init, |
1326c3d5a ipv6: convert tun... |
1320 |
.ndo_uninit = ipip6_tunnel_uninit, |
32b8a8e59 sit: add IPv4 ove... |
1321 |
.ndo_start_xmit = sit_tunnel_xmit, |
1326c3d5a ipv6: convert tun... |
1322 |
.ndo_do_ioctl = ipip6_tunnel_ioctl, |
f61dd388a Tunneling: use IP... |
1323 |
.ndo_get_stats64 = ip_tunnel_get_stats64, |
1e99584b9 ipip,gre,vti,sit:... |
1324 |
.ndo_get_iflink = ip_tunnel_get_iflink, |
f60fe2df9 sit: impement ->n... |
1325 |
.ndo_tunnel_ctl = ipip6_tunnel_ctl, |
1326c3d5a ipv6: convert tun... |
1326 |
}; |
15fc1f705 sit: percpu stats... |
1327 1328 |
static void ipip6_dev_free(struct net_device *dev) { |
cf71d2bc0 sit: fix panic wi... |
1329 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
e09acddf8 ip_tunnel: replac... |
1330 |
dst_cache_destroy(&tunnel->dst_cache); |
15fc1f705 sit: percpu stats... |
1331 |
free_percpu(dev->tstats); |
15fc1f705 sit: percpu stats... |
1332 |
} |
61c1db7fa ipv6: sit: add GS... |
1333 1334 1335 1336 1337 |
#define SIT_FEATURES (NETIF_F_SG | \ NETIF_F_FRAGLIST | \ NETIF_F_HIGHDMA | \ NETIF_F_GSO_SOFTWARE | \ NETIF_F_HW_CSUM) |
1da177e4c Linux-2.6.12-rc2 |
1338 1339 |
static void ipip6_tunnel_setup(struct net_device *dev) { |
14909664e sit: Setup and TX... |
1340 1341 |
struct ip_tunnel *tunnel = netdev_priv(dev); int t_hlen = tunnel->hlen + sizeof(struct iphdr); |
1326c3d5a ipv6: convert tun... |
1342 |
dev->netdev_ops = &ipip6_netdev_ops; |
75ea1f477 net: sit: impleme... |
1343 |
dev->header_ops = &ip_tunnel_header_ops; |
cf124db56 net: Fix inconsis... |
1344 1345 |
dev->needs_free_netdev = true; dev->priv_destructor = ipip6_dev_free; |
1da177e4c Linux-2.6.12-rc2 |
1346 1347 |
dev->type = ARPHRD_SIT; |
14909664e sit: Setup and TX... |
1348 |
dev->mtu = ETH_DATA_LEN - t_hlen; |
b96f9afee ipv4/6: use core ... |
1349 |
dev->min_mtu = IPV6_MIN_MTU; |
f7ff1fde9 ip6_tunnel: remov... |
1350 |
dev->max_mtu = IP6_MAX_MTU - t_hlen; |
1da177e4c Linux-2.6.12-rc2 |
1351 |
dev->flags = IFF_NOARP; |
028758788 net: better IFF_X... |
1352 |
netif_keep_dst(dev); |
1da177e4c Linux-2.6.12-rc2 |
1353 |
dev->addr_len = 4; |
8df40d103 sit: enable lockl... |
1354 |
dev->features |= NETIF_F_LLTX; |
61c1db7fa ipv6: sit: add GS... |
1355 1356 |
dev->features |= SIT_FEATURES; dev->hw_features |= SIT_FEATURES; |
1da177e4c Linux-2.6.12-rc2 |
1357 |
} |
15fc1f705 sit: percpu stats... |
1358 |
static int ipip6_tunnel_init(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
1359 |
{ |
1326c3d5a ipv6: convert tun... |
1360 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
e09acddf8 ip_tunnel: replac... |
1361 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
1362 1363 |
tunnel->dev = dev; |
5e6700b3b sit: add support ... |
1364 |
tunnel->net = dev_net(dev); |
ebe084aaf sit: Use ipip6_tu... |
1365 |
strcpy(tunnel->parms.name, dev->name); |
1da177e4c Linux-2.6.12-rc2 |
1366 |
|
8a4a50f98 [IPV6] sit: Rebin... |
1367 |
ipip6_tunnel_bind_dev(dev); |
1c213bd24 net: introduce ne... |
1368 |
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
15fc1f705 sit: percpu stats... |
1369 1370 |
if (!dev->tstats) return -ENOMEM; |
e09acddf8 ip_tunnel: replac... |
1371 1372 |
err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL); if (err) { |
cf71d2bc0 sit: fix panic wi... |
1373 |
free_percpu(dev->tstats); |
d7426c69a sit: fix a double... |
1374 |
dev->tstats = NULL; |
e09acddf8 ip_tunnel: replac... |
1375 |
return err; |
cf71d2bc0 sit: fix panic wi... |
1376 |
} |
15fc1f705 sit: percpu stats... |
1377 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1378 |
} |
4ece90097 sit: fix sit0 per... |
1379 |
static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
1380 |
{ |
2941a4863 [NET]: Convert ne... |
1381 |
struct ip_tunnel *tunnel = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
1382 |
struct iphdr *iph = &tunnel->parms.iph; |
291821766 [SIT]: Make tunne... |
1383 1384 |
struct net *net = dev_net(dev); struct sit_net *sitn = net_generic(net, sit_net_id); |
1da177e4c Linux-2.6.12-rc2 |
1385 |
|
1da177e4c Linux-2.6.12-rc2 |
1386 1387 1388 1389 1390 1391 |
iph->version = 4; iph->protocol = IPPROTO_IPV6; iph->ihl = 5; iph->ttl = 64; dev_hold(dev); |
cf778b00e net: reintroduce ... |
1392 |
rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); |
1da177e4c Linux-2.6.12-rc2 |
1393 |
} |
a8b8a889e net: add netlink_... |
1394 1395 |
static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) |
32b8a8e59 sit: add IPv4 ove... |
1396 1397 |
{ u8 proto; |
c2ff682a6 sit: fix an oops ... |
1398 |
if (!data || !data[IFLA_IPTUN_PROTO]) |
32b8a8e59 sit: add IPv4 ove... |
1399 1400 1401 |
return 0; proto = nla_get_u8(data[IFLA_IPTUN_PROTO]); |
49dbe7ae2 sit: support MPLS... |
1402 |
if (!ipip6_valid_ip_proto(proto)) |
32b8a8e59 sit: add IPv4 ove... |
1403 1404 1405 1406 |
return -EINVAL; return 0; } |
f37234160 sit: add support ... |
1407 |
static void ipip6_netlink_parms(struct nlattr *data[], |
9830ad4c6 ip_tunnel: Allow ... |
1408 1409 |
struct ip_tunnel_parm *parms, __u32 *fwmark) |
f37234160 sit: add support ... |
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 |
{ memset(parms, 0, sizeof(*parms)); parms->iph.version = 4; parms->iph.protocol = IPPROTO_IPV6; parms->iph.ihl = 5; parms->iph.ttl = 64; if (!data) return; if (data[IFLA_IPTUN_LINK]) parms->link = nla_get_u32(data[IFLA_IPTUN_LINK]); if (data[IFLA_IPTUN_LOCAL]) |
d440b7206 sit: fix sparse w... |
1425 |
parms->iph.saddr = nla_get_be32(data[IFLA_IPTUN_LOCAL]); |
f37234160 sit: add support ... |
1426 1427 |
if (data[IFLA_IPTUN_REMOTE]) |
d440b7206 sit: fix sparse w... |
1428 |
parms->iph.daddr = nla_get_be32(data[IFLA_IPTUN_REMOTE]); |
f37234160 sit: add support ... |
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 |
if (data[IFLA_IPTUN_TTL]) { parms->iph.ttl = nla_get_u8(data[IFLA_IPTUN_TTL]); if (parms->iph.ttl) parms->iph.frag_off = htons(IP_DF); } if (data[IFLA_IPTUN_TOS]) parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]); if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC])) parms->iph.frag_off = htons(IP_DF); if (data[IFLA_IPTUN_FLAGS]) |
d440b7206 sit: fix sparse w... |
1443 |
parms->i_flags = nla_get_be16(data[IFLA_IPTUN_FLAGS]); |
32b8a8e59 sit: add IPv4 ove... |
1444 1445 1446 |
if (data[IFLA_IPTUN_PROTO]) parms->iph.protocol = nla_get_u8(data[IFLA_IPTUN_PROTO]); |
9830ad4c6 ip_tunnel: Allow ... |
1447 1448 |
if (data[IFLA_IPTUN_FWMARK]) *fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); |
f37234160 sit: add support ... |
1449 |
} |
14909664e sit: Setup and TX... |
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 |
/* This function returns true when ENCAP attributes are present in the nl msg */ static bool ipip6_netlink_encap_parms(struct nlattr *data[], struct ip_tunnel_encap *ipencap) { bool ret = false; memset(ipencap, 0, sizeof(*ipencap)); if (!data) return ret; if (data[IFLA_IPTUN_ENCAP_TYPE]) { ret = true; ipencap->type = nla_get_u16(data[IFLA_IPTUN_ENCAP_TYPE]); } if (data[IFLA_IPTUN_ENCAP_FLAGS]) { ret = true; ipencap->flags = nla_get_u16(data[IFLA_IPTUN_ENCAP_FLAGS]); } if (data[IFLA_IPTUN_ENCAP_SPORT]) { ret = true; |
a409caecb sit: fix some __b... |
1473 |
ipencap->sport = nla_get_be16(data[IFLA_IPTUN_ENCAP_SPORT]); |
14909664e sit: Setup and TX... |
1474 1475 1476 1477 |
} if (data[IFLA_IPTUN_ENCAP_DPORT]) { ret = true; |
a409caecb sit: fix some __b... |
1478 |
ipencap->dport = nla_get_be16(data[IFLA_IPTUN_ENCAP_DPORT]); |
14909664e sit: Setup and TX... |
1479 1480 1481 1482 |
} return ret; } |
e2f1f072d sit: allow to con... |
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 |
#ifdef CONFIG_IPV6_SIT_6RD /* This function returns true when 6RD attributes are present in the nl msg */ static bool ipip6_netlink_6rd_parms(struct nlattr *data[], struct ip_tunnel_6rd *ip6rd) { bool ret = false; memset(ip6rd, 0, sizeof(*ip6rd)); if (!data) return ret; if (data[IFLA_IPTUN_6RD_PREFIX]) { ret = true; |
67b61f6c1 netlink: implemen... |
1496 |
ip6rd->prefix = nla_get_in6_addr(data[IFLA_IPTUN_6RD_PREFIX]); |
e2f1f072d sit: allow to con... |
1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 |
} if (data[IFLA_IPTUN_6RD_RELAY_PREFIX]) { ret = true; ip6rd->relay_prefix = nla_get_be32(data[IFLA_IPTUN_6RD_RELAY_PREFIX]); } if (data[IFLA_IPTUN_6RD_PREFIXLEN]) { ret = true; ip6rd->prefixlen = nla_get_u16(data[IFLA_IPTUN_6RD_PREFIXLEN]); } if (data[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]) { ret = true; ip6rd->relay_prefixlen = nla_get_u16(data[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]); } return ret; } #endif |
f37234160 sit: add support ... |
1519 |
static int ipip6_newlink(struct net *src_net, struct net_device *dev, |
7a3f4a185 net: add netlink_... |
1520 1521 |
struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) |
f37234160 sit: add support ... |
1522 1523 1524 |
{ struct net *net = dev_net(dev); struct ip_tunnel *nt; |
14909664e sit: Setup and TX... |
1525 |
struct ip_tunnel_encap ipencap; |
e2f1f072d sit: allow to con... |
1526 1527 1528 1529 |
#ifdef CONFIG_IPV6_SIT_6RD struct ip_tunnel_6rd ip6rd; #endif int err; |
f37234160 sit: add support ... |
1530 1531 |
nt = netdev_priv(dev); |
14909664e sit: Setup and TX... |
1532 1533 1534 1535 1536 1537 |
if (ipip6_netlink_encap_parms(data, &ipencap)) { err = ip_tunnel_encap_setup(nt, &ipencap); if (err < 0) return err; } |
9830ad4c6 ip_tunnel: Allow ... |
1538 |
ipip6_netlink_parms(data, &nt->parms, &nt->fwmark); |
f37234160 sit: add support ... |
1539 1540 1541 |
if (ipip6_tunnel_locate(net, &nt->parms, 0)) return -EEXIST; |
e2f1f072d sit: allow to con... |
1542 1543 1544 |
err = ipip6_tunnel_create(dev); if (err < 0) return err; |
2b3957c34 sit: fix IFLA_MTU... |
1545 1546 |
if (tb[IFLA_MTU]) { u32 mtu = nla_get_u32(tb[IFLA_MTU]); |
f7ff1fde9 ip6_tunnel: remov... |
1547 1548 |
if (mtu >= IPV6_MIN_MTU && mtu <= IP6_MAX_MTU - dev->hard_header_len) |
2b3957c34 sit: fix IFLA_MTU... |
1549 1550 |
dev->mtu = mtu; } |
e2f1f072d sit: allow to con... |
1551 1552 1553 1554 1555 1556 |
#ifdef CONFIG_IPV6_SIT_6RD if (ipip6_netlink_6rd_parms(data, &ip6rd)) err = ipip6_tunnel_update_6rd(nt, &ip6rd); #endif return err; |
f37234160 sit: add support ... |
1557 1558 1559 |
} static int ipip6_changelink(struct net_device *dev, struct nlattr *tb[], |
ad744b223 net: add netlink_... |
1560 1561 |
struct nlattr *data[], struct netlink_ext_ack *extack) |
f37234160 sit: add support ... |
1562 |
{ |
86bd68bfd sit: fix tunnel u... |
1563 |
struct ip_tunnel *t = netdev_priv(dev); |
f37234160 sit: add support ... |
1564 |
struct ip_tunnel_parm p; |
14909664e sit: Setup and TX... |
1565 |
struct ip_tunnel_encap ipencap; |
86bd68bfd sit: fix tunnel u... |
1566 |
struct net *net = t->net; |
f37234160 sit: add support ... |
1567 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
e2f1f072d sit: allow to con... |
1568 1569 1570 |
#ifdef CONFIG_IPV6_SIT_6RD struct ip_tunnel_6rd ip6rd; #endif |
9830ad4c6 ip_tunnel: Allow ... |
1571 |
__u32 fwmark = t->fwmark; |
14909664e sit: Setup and TX... |
1572 |
int err; |
f37234160 sit: add support ... |
1573 1574 1575 |
if (dev == sitn->fb_tunnel_dev) return -EINVAL; |
14909664e sit: Setup and TX... |
1576 1577 1578 1579 1580 |
if (ipip6_netlink_encap_parms(data, &ipencap)) { err = ip_tunnel_encap_setup(t, &ipencap); if (err < 0) return err; } |
9830ad4c6 ip_tunnel: Allow ... |
1581 |
ipip6_netlink_parms(data, &p, &fwmark); |
f37234160 sit: add support ... |
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 |
if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) || (!(dev->flags & IFF_POINTOPOINT) && p.iph.daddr)) return -EINVAL; t = ipip6_tunnel_locate(net, &p, 0); if (t) { if (t->dev != dev) return -EEXIST; } else t = netdev_priv(dev); |
9830ad4c6 ip_tunnel: Allow ... |
1594 |
ipip6_tunnel_update(t, &p, fwmark); |
e2f1f072d sit: allow to con... |
1595 1596 1597 1598 1599 |
#ifdef CONFIG_IPV6_SIT_6RD if (ipip6_netlink_6rd_parms(data, &ip6rd)) return ipip6_tunnel_update_6rd(t, &ip6rd); #endif |
f37234160 sit: add support ... |
1600 1601 |
return 0; } |
e4c94a9cd sit: rename rtnl ... |
1602 |
static size_t ipip6_get_size(const struct net_device *dev) |
ba3e3f50a sit: advertise tu... |
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 |
{ return /* IFLA_IPTUN_LINK */ nla_total_size(4) + /* IFLA_IPTUN_LOCAL */ nla_total_size(4) + /* IFLA_IPTUN_REMOTE */ nla_total_size(4) + /* IFLA_IPTUN_TTL */ nla_total_size(1) + /* IFLA_IPTUN_TOS */ nla_total_size(1) + |
a12c9a858 sit/rtnl: add mis... |
1615 1616 1617 1618 |
/* IFLA_IPTUN_PMTUDISC */ nla_total_size(1) + /* IFLA_IPTUN_FLAGS */ nla_total_size(2) + |
32b8a8e59 sit: add IPv4 ove... |
1619 1620 |
/* IFLA_IPTUN_PROTO */ nla_total_size(1) + |
e2f1f072d sit: allow to con... |
1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 |
#ifdef CONFIG_IPV6_SIT_6RD /* IFLA_IPTUN_6RD_PREFIX */ nla_total_size(sizeof(struct in6_addr)) + /* IFLA_IPTUN_6RD_RELAY_PREFIX */ nla_total_size(4) + /* IFLA_IPTUN_6RD_PREFIXLEN */ nla_total_size(2) + /* IFLA_IPTUN_6RD_RELAY_PREFIXLEN */ nla_total_size(2) + #endif |
14909664e sit: Setup and TX... |
1631 1632 1633 1634 1635 1636 1637 1638 |
/* IFLA_IPTUN_ENCAP_TYPE */ nla_total_size(2) + /* IFLA_IPTUN_ENCAP_FLAGS */ nla_total_size(2) + /* IFLA_IPTUN_ENCAP_SPORT */ nla_total_size(2) + /* IFLA_IPTUN_ENCAP_DPORT */ nla_total_size(2) + |
9830ad4c6 ip_tunnel: Allow ... |
1639 1640 |
/* IFLA_IPTUN_FWMARK */ nla_total_size(4) + |
ba3e3f50a sit: advertise tu... |
1641 1642 |
0; } |
e4c94a9cd sit: rename rtnl ... |
1643 |
static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev) |
ba3e3f50a sit: advertise tu... |
1644 1645 1646 1647 1648 |
{ struct ip_tunnel *tunnel = netdev_priv(dev); struct ip_tunnel_parm *parm = &tunnel->parms; if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || |
930345ea6 netlink: implemen... |
1649 1650 |
nla_put_in_addr(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || nla_put_in_addr(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || |
ba3e3f50a sit: advertise tu... |
1651 |
nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || |
a12c9a858 sit/rtnl: add mis... |
1652 1653 1654 |
nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) || nla_put_u8(skb, IFLA_IPTUN_PMTUDISC, !!(parm->iph.frag_off & htons(IP_DF))) || |
32b8a8e59 sit: add IPv4 ove... |
1655 |
nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->iph.protocol) || |
9830ad4c6 ip_tunnel: Allow ... |
1656 1657 |
nla_put_be16(skb, IFLA_IPTUN_FLAGS, parm->i_flags) || nla_put_u32(skb, IFLA_IPTUN_FWMARK, tunnel->fwmark)) |
ba3e3f50a sit: advertise tu... |
1658 |
goto nla_put_failure; |
e2f1f072d sit: allow to con... |
1659 1660 |
#ifdef CONFIG_IPV6_SIT_6RD |
930345ea6 netlink: implemen... |
1661 1662 1663 1664 |
if (nla_put_in6_addr(skb, IFLA_IPTUN_6RD_PREFIX, &tunnel->ip6rd.prefix) || nla_put_in_addr(skb, IFLA_IPTUN_6RD_RELAY_PREFIX, tunnel->ip6rd.relay_prefix) || |
e2f1f072d sit: allow to con... |
1665 1666 1667 1668 1669 1670 |
nla_put_u16(skb, IFLA_IPTUN_6RD_PREFIXLEN, tunnel->ip6rd.prefixlen) || nla_put_u16(skb, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, tunnel->ip6rd.relay_prefixlen)) goto nla_put_failure; #endif |
14909664e sit: Setup and TX... |
1671 1672 |
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || |
a409caecb sit: fix some __b... |
1673 |
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, |
14909664e sit: Setup and TX... |
1674 |
tunnel->encap.sport) || |
a409caecb sit: fix some __b... |
1675 |
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, |
14909664e sit: Setup and TX... |
1676 1677 |
tunnel->encap.dport) || nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS, |
e1b2cb655 fou: Fix typo in ... |
1678 |
tunnel->encap.flags)) |
14909664e sit: Setup and TX... |
1679 |
goto nla_put_failure; |
ba3e3f50a sit: advertise tu... |
1680 1681 1682 1683 1684 |
return 0; nla_put_failure: return -EMSGSIZE; } |
f37234160 sit: add support ... |
1685 1686 1687 1688 1689 1690 1691 1692 |
static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 }, [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 }, |
32b8a8e59 sit: add IPv4 ove... |
1693 |
[IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, |
e2f1f072d sit: allow to con... |
1694 1695 1696 1697 1698 1699 |
#ifdef CONFIG_IPV6_SIT_6RD [IFLA_IPTUN_6RD_PREFIX] = { .len = sizeof(struct in6_addr) }, [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 }, [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 }, [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 }, #endif |
14909664e sit: Setup and TX... |
1700 1701 1702 1703 |
[IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 }, [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 }, [IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 }, [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, |
9830ad4c6 ip_tunnel: Allow ... |
1704 |
[IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, |
f37234160 sit: add support ... |
1705 |
}; |
9434266f2 sit: fix use afte... |
1706 1707 1708 1709 1710 1711 1712 1713 |
static void ipip6_dellink(struct net_device *dev, struct list_head *head) { struct net *net = dev_net(dev); struct sit_net *sitn = net_generic(net, sit_net_id); if (dev != sitn->fb_tunnel_dev) unregister_netdevice_queue(dev, head); } |
ba3e3f50a sit: advertise tu... |
1714 1715 1716 |
static struct rtnl_link_ops sit_link_ops __read_mostly = { .kind = "sit", .maxtype = IFLA_IPTUN_MAX, |
f37234160 sit: add support ... |
1717 |
.policy = ipip6_policy, |
ba3e3f50a sit: advertise tu... |
1718 |
.priv_size = sizeof(struct ip_tunnel), |
f37234160 sit: add support ... |
1719 |
.setup = ipip6_tunnel_setup, |
32b8a8e59 sit: add IPv4 ove... |
1720 |
.validate = ipip6_validate, |
f37234160 sit: add support ... |
1721 1722 |
.newlink = ipip6_newlink, .changelink = ipip6_changelink, |
e4c94a9cd sit: rename rtnl ... |
1723 1724 |
.get_size = ipip6_get_size, .fill_info = ipip6_fill_info, |
9434266f2 sit: fix use afte... |
1725 |
.dellink = ipip6_dellink, |
1728d4fab tunnels: advertis... |
1726 |
.get_link_net = ip_tunnel_get_link_net, |
ba3e3f50a sit: advertise tu... |
1727 |
}; |
6dcd814bd net: struct xfrm_... |
1728 |
static struct xfrm_tunnel sit_handler __read_mostly = { |
1da177e4c Linux-2.6.12-rc2 |
1729 1730 |
.handler = ipip6_rcv, .err_handler = ipip6_err, |
c73cb5a2d [IPSEC]: make sit... |
1731 |
.priority = 1, |
1da177e4c Linux-2.6.12-rc2 |
1732 |
}; |
32b8a8e59 sit: add IPv4 ove... |
1733 1734 1735 1736 1737 |
static struct xfrm_tunnel ipip_handler __read_mostly = { .handler = ipip_rcv, .err_handler = ipip6_err, .priority = 2, }; |
49dbe7ae2 sit: support MPLS... |
1738 1739 1740 1741 1742 1743 1744 |
#if IS_ENABLED(CONFIG_MPLS) static struct xfrm_tunnel mplsip_handler __read_mostly = { .handler = mplsip_rcv, .err_handler = ipip6_err, .priority = 2, }; #endif |
9434266f2 sit: fix use afte... |
1745 1746 |
static void __net_exit sit_destroy_tunnels(struct net *net, struct list_head *head) |
db44575f6 [NET]: fix oops a... |
1747 |
{ |
9434266f2 sit: fix use afte... |
1748 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
5e6700b3b sit: add support ... |
1749 |
struct net_device *dev, *aux; |
db44575f6 [NET]: fix oops a... |
1750 |
int prio; |
5e6700b3b sit: add support ... |
1751 1752 1753 |
for_each_netdev_safe(net, dev, aux) if (dev->rtnl_link_ops == &sit_link_ops) unregister_netdevice_queue(dev, head); |
db44575f6 [NET]: fix oops a... |
1754 1755 |
for (prio = 1; prio < 4; prio++) { int h; |
e87a8f24c net: resolve symb... |
1756 |
for (h = 0; h < IP6_SIT_HASH_SIZE; h++) { |
753ea8e96 net: ipv6: sit: f... |
1757 |
struct ip_tunnel *t; |
62808f912 ipv6 sit: Optimiz... |
1758 |
|
753ea8e96 net: ipv6: sit: f... |
1759 |
t = rtnl_dereference(sitn->tunnels[prio][h]); |
53b24b8f9 ipv6: coding styl... |
1760 |
while (t) { |
5e6700b3b sit: add support ... |
1761 1762 1763 |
/* If dev is in the same netns, it has already * been added to the list by the previous loop. */ |
fc8f999da ipv4 tunnels: use... |
1764 |
if (!net_eq(dev_net(t->dev), net)) |
5e6700b3b sit: add support ... |
1765 1766 |
unregister_netdevice_queue(t->dev, head); |
753ea8e96 net: ipv6: sit: f... |
1767 |
t = rtnl_dereference(t->next); |
62808f912 ipv6 sit: Optimiz... |
1768 |
} |
db44575f6 [NET]: fix oops a... |
1769 1770 1771 |
} } } |
2c8c1e729 net: spread __net... |
1772 |
static int __net_init sit_init_net(struct net *net) |
8190d9009 [SIT]: Introduce ... |
1773 |
{ |
671011720 net: Simplify ipi... |
1774 |
struct sit_net *sitn = net_generic(net, sit_net_id); |
72b36015b ipip, sit: copy p... |
1775 |
struct ip_tunnel *t; |
8190d9009 [SIT]: Introduce ... |
1776 |
int err; |
8190d9009 [SIT]: Introduce ... |
1777 |
|
291821766 [SIT]: Make tunne... |
1778 1779 1780 1781 |
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; |
79134e6ce net: do not creat... |
1782 1783 |
if (!net_has_fallback_tunnels(net)) return 0; |
cd3dbc194 [SIT]: Make the f... |
1784 |
sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", |
c835a6773 net: set name_ass... |
1785 |
NET_NAME_UNKNOWN, |
cd3dbc194 [SIT]: Make the f... |
1786 1787 1788 1789 1790 |
ipip6_tunnel_setup); if (!sitn->fb_tunnel_dev) { err = -ENOMEM; goto err_alloc_dev; } |
be77e5930 net: fix tunnels ... |
1791 |
dev_net_set(sitn->fb_tunnel_dev, net); |
205983c43 sit: allow to use... |
1792 |
sitn->fb_tunnel_dev->rtnl_link_ops = &sit_link_ops; |
5e6700b3b sit: add support ... |
1793 1794 1795 1796 |
/* FB netdevice is special: we have one, and only one per netns. * Allowing to move it to another netns is clearly unsafe. */ sitn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL; |
cd3dbc194 [SIT]: Make the f... |
1797 |
|
e5d08d718 ipv6: coding styl... |
1798 1799 |
err = register_netdev(sitn->fb_tunnel_dev); if (err) |
cd3dbc194 [SIT]: Make the f... |
1800 |
goto err_reg_dev; |
4ece90097 sit: fix sit0 per... |
1801 1802 |
ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); |
72b36015b ipip, sit: copy p... |
1803 1804 1805 |
t = netdev_priv(sitn->fb_tunnel_dev); strcpy(t->parms.name, sitn->fb_tunnel_dev->name); |
8190d9009 [SIT]: Introduce ... |
1806 |
return 0; |
cd3dbc194 [SIT]: Make the f... |
1807 |
err_reg_dev: |
dd4080ee5 sit: fix percpu s... |
1808 |
ipip6_dev_free(sitn->fb_tunnel_dev); |
07f12b26e net: sit: fix mem... |
1809 |
free_netdev(sitn->fb_tunnel_dev); |
cd3dbc194 [SIT]: Make the f... |
1810 |
err_alloc_dev: |
8190d9009 [SIT]: Introduce ... |
1811 1812 |
return err; } |
bb401caef ipv6: speedup ipv... |
1813 |
static void __net_exit sit_exit_batch_net(struct list_head *net_list) |
8190d9009 [SIT]: Introduce ... |
1814 |
{ |
62808f912 ipv6 sit: Optimiz... |
1815 |
LIST_HEAD(list); |
bb401caef ipv6: speedup ipv... |
1816 |
struct net *net; |
8190d9009 [SIT]: Introduce ... |
1817 |
|
cd3dbc194 [SIT]: Make the f... |
1818 |
rtnl_lock(); |
bb401caef ipv6: speedup ipv... |
1819 1820 |
list_for_each_entry(net, net_list, exit_list) sit_destroy_tunnels(net, &list); |
62808f912 ipv6 sit: Optimiz... |
1821 |
unregister_netdevice_many(&list); |
cd3dbc194 [SIT]: Make the f... |
1822 |
rtnl_unlock(); |
8190d9009 [SIT]: Introduce ... |
1823 1824 1825 1826 |
} static struct pernet_operations sit_net_ops = { .init = sit_init_net, |
bb401caef ipv6: speedup ipv... |
1827 |
.exit_batch = sit_exit_batch_net, |
671011720 net: Simplify ipi... |
1828 1829 |
.id = &sit_net_id, .size = sizeof(struct sit_net), |
8190d9009 [SIT]: Introduce ... |
1830 |
}; |
89c894581 [IPV6] net/ipv6/s... |
1831 |
static void __exit sit_cleanup(void) |
1da177e4c Linux-2.6.12-rc2 |
1832 |
{ |
ba3e3f50a sit: advertise tu... |
1833 |
rtnl_link_unregister(&sit_link_ops); |
c73cb5a2d [IPSEC]: make sit... |
1834 |
xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
32b8a8e59 sit: add IPv4 ove... |
1835 |
xfrm4_tunnel_deregister(&ipip_handler, AF_INET); |
49dbe7ae2 sit: support MPLS... |
1836 1837 1838 |
#if IS_ENABLED(CONFIG_MPLS) xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS); #endif |
db44575f6 [NET]: fix oops a... |
1839 |
|
671011720 net: Simplify ipi... |
1840 |
unregister_pernet_device(&sit_net_ops); |
ef9a9d118 ipv6 sit: RCU con... |
1841 |
rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
1da177e4c Linux-2.6.12-rc2 |
1842 |
} |
89c894581 [IPV6] net/ipv6/s... |
1843 |
static int __init sit_init(void) |
1da177e4c Linux-2.6.12-rc2 |
1844 1845 |
{ int err; |
49dbe7ae2 sit: support MPLS... |
1846 1847 |
pr_info("IPv6, IPv4 and MPLS over IPv4 tunneling driver "); |
1da177e4c Linux-2.6.12-rc2 |
1848 |
|
671011720 net: Simplify ipi... |
1849 |
err = register_pernet_device(&sit_net_ops); |
8190d9009 [SIT]: Introduce ... |
1850 |
if (err < 0) |
d5aa407f5 tunnels: fix netn... |
1851 1852 1853 |
return err; err = xfrm4_tunnel_register(&sit_handler, AF_INET6); if (err < 0) { |
32b8a8e59 sit: add IPv4 ove... |
1854 1855 |
pr_info("%s: can't register ip6ip4 ", __func__); |
ba3e3f50a sit: advertise tu... |
1856 |
goto xfrm_tunnel_failed; |
d5aa407f5 tunnels: fix netn... |
1857 |
} |
32b8a8e59 sit: add IPv4 ove... |
1858 1859 1860 1861 1862 1863 |
err = xfrm4_tunnel_register(&ipip_handler, AF_INET); if (err < 0) { pr_info("%s: can't register ip4ip4 ", __func__); goto xfrm_tunnel4_failed; } |
49dbe7ae2 sit: support MPLS... |
1864 1865 1866 1867 1868 1869 1870 1871 |
#if IS_ENABLED(CONFIG_MPLS) err = xfrm4_tunnel_register(&mplsip_handler, AF_MPLS); if (err < 0) { pr_info("%s: can't register mplsip ", __func__); goto xfrm_tunnel_mpls_failed; } #endif |
ba3e3f50a sit: advertise tu... |
1872 1873 1874 1875 1876 |
err = rtnl_link_register(&sit_link_ops); if (err < 0) goto rtnl_link_failed; out: |
1da177e4c Linux-2.6.12-rc2 |
1877 |
return err; |
ba3e3f50a sit: advertise tu... |
1878 1879 |
rtnl_link_failed: |
49dbe7ae2 sit: support MPLS... |
1880 1881 1882 1883 |
#if IS_ENABLED(CONFIG_MPLS) xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS); xfrm_tunnel_mpls_failed: #endif |
32b8a8e59 sit: add IPv4 ove... |
1884 1885 |
xfrm4_tunnel_deregister(&ipip_handler, AF_INET); xfrm_tunnel4_failed: |
ba3e3f50a sit: advertise tu... |
1886 1887 1888 1889 |
xfrm4_tunnel_deregister(&sit_handler, AF_INET6); xfrm_tunnel_failed: unregister_pernet_device(&sit_net_ops); goto out; |
1da177e4c Linux-2.6.12-rc2 |
1890 |
} |
989e5b96e [IPV6]: Seperate ... |
1891 1892 1893 |
module_init(sit_init); module_exit(sit_cleanup); |
39c850863 [IPV6] sit: Add m... |
1894 |
MODULE_LICENSE("GPL"); |
f98f89a01 net: tunnels - en... |
1895 |
MODULE_ALIAS_RTNL_LINK("sit"); |
8909c9ad8 net: don't allow ... |
1896 |
MODULE_ALIAS_NETDEV("sit0"); |