Blame view
net/ipv6/raw.c
31.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * RAW sockets for IPv6 |
1ab1457c4 [NET] IPV6: Fix w... |
3 |
* Linux INET6 implementation |
1da177e4c Linux-2.6.12-rc2 |
4 5 |
* * Authors: |
1ab1457c4 [NET] IPV6: Fix w... |
6 |
* Pedro Roque <roque@di.fc.ul.pt> |
1da177e4c Linux-2.6.12-rc2 |
7 8 9 |
* * Adapted from linux/net/ipv4/raw.c * |
1da177e4c Linux-2.6.12-rc2 |
10 11 |
* Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support |
1ab1457c4 [NET] IPV6: Fix w... |
12 |
* YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) |
1da177e4c Linux-2.6.12-rc2 |
13 14 15 16 17 18 19 20 21 22 23 |
* Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data * * 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. */ #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> |
5a0e3ad6a include cleanup: ... |
24 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
#include <linux/sockios.h> |
1da177e4c Linux-2.6.12-rc2 |
26 27 28 29 30 31 32 |
#include <linux/net.h> #include <linux/in6.h> #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/icmpv6.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv6.h> |
3305b80c2 [IP]: Simplify an... |
33 |
#include <linux/skbuff.h> |
e2d57766e net: Provide comp... |
34 |
#include <linux/compat.h> |
29778bec1 ipv6: Replace "#i... |
35 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
36 |
#include <asm/ioctls.h> |
457c4cbc5 [NET]: Make /proc... |
37 |
#include <net/net_namespace.h> |
1da177e4c Linux-2.6.12-rc2 |
38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include <net/ip.h> #include <net/sock.h> #include <net/snmp.h> #include <net/ipv6.h> #include <net/ndisc.h> #include <net/protocol.h> #include <net/ip6_route.h> #include <net/ip6_checksum.h> #include <net/addrconf.h> #include <net/transp_v6.h> #include <net/udp.h> #include <net/inet_common.h> |
c752f0739 [TCP]: Move the t... |
51 |
#include <net/tcp_states.h> |
07a936260 ipv6: use IS_ENAB... |
52 |
#if IS_ENABLED(CONFIG_IPV6_MIP6) |
7be96f762 [IPV6] MIP6: Add ... |
53 54 |
#include <net/mip6.h> #endif |
7bc570c8b [IPV6] MROUTE: Su... |
55 |
#include <linux/mroute6.h> |
1da177e4c Linux-2.6.12-rc2 |
56 |
|
b673e4dfc [RAW]: Introduce ... |
57 |
#include <net/raw.h> |
1da177e4c Linux-2.6.12-rc2 |
58 59 60 61 62 |
#include <net/rawv6.h> #include <net/xfrm.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> |
bc3b2d7fb net: Add export.h... |
63 |
#include <linux/export.h> |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
d1c53c8e8 icmpv6_filter: al... |
65 |
#define ICMPV6_HDRLEN 4 /* ICMPv6 header, RFC 4443 Section 2.1 */ |
432490f9d net: ip, diag -- ... |
66 |
struct raw_hashinfo raw_v6_hashinfo = { |
938b93adb [NET]: Add debugg... |
67 |
.lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock), |
b673e4dfc [RAW]: Introduce ... |
68 |
}; |
432490f9d net: ip, diag -- ... |
69 |
EXPORT_SYMBOL_GPL(raw_v6_hashinfo); |
1da177e4c Linux-2.6.12-rc2 |
70 |
|
432490f9d net: ip, diag -- ... |
71 |
struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, |
b71d1d426 inet: constify ip... |
72 |
unsigned short num, const struct in6_addr *loc_addr, |
5108ab4bf net: ipv6: add se... |
73 |
const struct in6_addr *rmt_addr, int dif, int sdif) |
1da177e4c Linux-2.6.12-rc2 |
74 |
{ |
a50feda54 ipv6: bool/const ... |
75 |
bool is_multicast = ipv6_addr_is_multicast(loc_addr); |
1da177e4c Linux-2.6.12-rc2 |
76 |
|
b67bfe0d4 hlist: drop the n... |
77 |
sk_for_each_from(sk) |
c720c7e83 inet: rename some... |
78 |
if (inet_sk(sk)->inet_num == num) { |
1da177e4c Linux-2.6.12-rc2 |
79 |
|
878628fbf [NET] NETNS: Omit... |
80 |
if (!net_eq(sock_net(sk), net)) |
be185884b [NETNS][RAW]: Mak... |
81 |
continue; |
efe4208f4 ipv6: make lookup... |
82 83 |
if (!ipv6_addr_any(&sk->sk_v6_daddr) && !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) |
1da177e4c Linux-2.6.12-rc2 |
84 |
continue; |
5108ab4bf net: ipv6: add se... |
85 86 87 |
if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && sk->sk_bound_dev_if != sdif) |
0bd1b59b1 [IPV6]: Check int... |
88 |
continue; |
efe4208f4 ipv6: make lookup... |
89 90 |
if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { if (ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)) |
1da177e4c Linux-2.6.12-rc2 |
91 92 93 94 95 96 97 98 99 100 101 102 |
goto found; if (is_multicast && inet6_mc_check(sk, loc_addr, rmt_addr)) goto found; continue; } goto found; } sk = NULL; found: return sk; } |
432490f9d net: ip, diag -- ... |
103 |
EXPORT_SYMBOL_GPL(__raw_v6_lookup); |
1da177e4c Linux-2.6.12-rc2 |
104 105 106 107 108 |
/* * 0 - deliver * 1 - block */ |
1b05c4b50 ipv6: raw: fix ic... |
109 |
static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
110 |
{ |
9cc08af3a icmpv6_filter: fi... |
111 |
struct icmp6hdr _hdr; |
1b05c4b50 ipv6: raw: fix ic... |
112 |
const struct icmp6hdr *hdr; |
1da177e4c Linux-2.6.12-rc2 |
113 |
|
d1c53c8e8 icmpv6_filter: al... |
114 115 116 |
/* We require only the four bytes of the ICMPv6 header, not any * additional bytes of message body in "struct icmp6hdr". */ |
1b05c4b50 ipv6: raw: fix ic... |
117 |
hdr = skb_header_pointer(skb, skb_transport_offset(skb), |
d1c53c8e8 icmpv6_filter: al... |
118 |
ICMPV6_HDRLEN, &_hdr); |
1b05c4b50 ipv6: raw: fix ic... |
119 120 121 |
if (hdr) { const __u32 *data = &raw6_sk(sk)->filter.data[0]; unsigned int type = hdr->icmp6_type; |
1da177e4c Linux-2.6.12-rc2 |
122 |
|
1b05c4b50 ipv6: raw: fix ic... |
123 |
return (data[type >> 5] & (1U << (type & 31))) != 0; |
1da177e4c Linux-2.6.12-rc2 |
124 |
} |
1b05c4b50 ipv6: raw: fix ic... |
125 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
126 |
} |
07a936260 ipv6: use IS_ENAB... |
127 |
#if IS_ENABLED(CONFIG_IPV6_MIP6) |
f2eda47df ipv6: raw: rcu an... |
128 |
typedef int mh_filter_t(struct sock *sock, struct sk_buff *skb); |
59fbb3a61 [IPV6] MIP6: Load... |
129 |
|
f2eda47df ipv6: raw: rcu an... |
130 131 132 |
static mh_filter_t __rcu *mh_filter __read_mostly; int rawv6_mh_filter_register(mh_filter_t filter) |
59fbb3a61 [IPV6] MIP6: Load... |
133 |
{ |
cf778b00e net: reintroduce ... |
134 |
rcu_assign_pointer(mh_filter, filter); |
59fbb3a61 [IPV6] MIP6: Load... |
135 136 137 |
return 0; } EXPORT_SYMBOL(rawv6_mh_filter_register); |
f2eda47df ipv6: raw: rcu an... |
138 |
int rawv6_mh_filter_unregister(mh_filter_t filter) |
59fbb3a61 [IPV6] MIP6: Load... |
139 |
{ |
a9b3cd7f3 rcu: convert uses... |
140 |
RCU_INIT_POINTER(mh_filter, NULL); |
59fbb3a61 [IPV6] MIP6: Load... |
141 142 143 144 145 146 |
synchronize_rcu(); return 0; } EXPORT_SYMBOL(rawv6_mh_filter_unregister); #endif |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 150 151 152 153 |
/* * demultiplex raw sockets. * (should consider queueing the skb in the sock receive_queue * without calling rawv6.c) * * Caller owns SKB so we must make clones. */ |
a50feda54 ipv6: bool/const ... |
154 |
static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) |
1da177e4c Linux-2.6.12-rc2 |
155 |
{ |
b71d1d426 inet: constify ip... |
156 157 |
const struct in6_addr *saddr; const struct in6_addr *daddr; |
1da177e4c Linux-2.6.12-rc2 |
158 |
struct sock *sk; |
a50feda54 ipv6: bool/const ... |
159 |
bool delivered = false; |
1da177e4c Linux-2.6.12-rc2 |
160 |
__u8 hash; |
be185884b [NETNS][RAW]: Mak... |
161 |
struct net *net; |
1da177e4c Linux-2.6.12-rc2 |
162 |
|
0660e03f6 [SK_BUFF]: Introd... |
163 |
saddr = &ipv6_hdr(skb)->saddr; |
1da177e4c Linux-2.6.12-rc2 |
164 |
daddr = saddr + 1; |
f9242b6b2 inet: Sanitize in... |
165 |
hash = nexthdr & (RAW_HTABLE_SIZE - 1); |
1da177e4c Linux-2.6.12-rc2 |
166 |
|
b673e4dfc [RAW]: Introduce ... |
167 168 |
read_lock(&raw_v6_hashinfo.lock); sk = sk_head(&raw_v6_hashinfo.ht[hash]); |
1da177e4c Linux-2.6.12-rc2 |
169 |
|
63159f29b ipv6: coding styl... |
170 |
if (!sk) |
1da177e4c Linux-2.6.12-rc2 |
171 |
goto out; |
c346dca10 [NET] NETNS: Omit... |
172 |
net = dev_net(skb->dev); |
5108ab4bf net: ipv6: add se... |
173 174 |
sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, inet6_iif(skb), inet6_sdif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
175 176 |
while (sk) { |
7be96f762 [IPV6] MIP6: Add ... |
177 |
int filtered; |
a50feda54 ipv6: bool/const ... |
178 |
delivered = true; |
7be96f762 [IPV6] MIP6: Add ... |
179 180 181 182 |
switch (nexthdr) { case IPPROTO_ICMPV6: filtered = icmpv6_filter(sk, skb); break; |
59fbb3a61 [IPV6] MIP6: Load... |
183 |
|
07a936260 ipv6: use IS_ENAB... |
184 |
#if IS_ENABLED(CONFIG_IPV6_MIP6) |
7be96f762 [IPV6] MIP6: Add ... |
185 |
case IPPROTO_MH: |
59fbb3a61 [IPV6] MIP6: Load... |
186 |
{ |
7be96f762 [IPV6] MIP6: Add ... |
187 188 189 190 191 192 |
/* XXX: To validate MH only once for each packet, * this is placed here. It should be after checking * xfrm policy, however it doesn't. The checking xfrm * policy is placed in rawv6_rcv() because it is * required for each socket. */ |
f2eda47df ipv6: raw: rcu an... |
193 |
mh_filter_t *filter; |
59fbb3a61 [IPV6] MIP6: Load... |
194 195 |
filter = rcu_dereference(mh_filter); |
f2eda47df ipv6: raw: rcu an... |
196 |
filtered = filter ? (*filter)(sk, skb) : 0; |
7be96f762 [IPV6] MIP6: Add ... |
197 |
break; |
59fbb3a61 [IPV6] MIP6: Load... |
198 |
} |
7be96f762 [IPV6] MIP6: Add ... |
199 200 201 202 203 204 205 206 207 |
#endif default: filtered = 0; break; } if (filtered < 0) break; if (filtered == 0) { |
1da177e4c Linux-2.6.12-rc2 |
208 209 210 |
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); /* Not releasing hash table! */ |
9fb9cbb10 [NETFILTER]: Add ... |
211 212 |
if (clone) { nf_reset(clone); |
1da177e4c Linux-2.6.12-rc2 |
213 |
rawv6_rcv(sk, clone); |
9fb9cbb10 [NETFILTER]: Add ... |
214 |
} |
1da177e4c Linux-2.6.12-rc2 |
215 |
} |
be185884b [NETNS][RAW]: Mak... |
216 |
sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr, |
5108ab4bf net: ipv6: add se... |
217 |
inet6_iif(skb), inet6_sdif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
218 219 |
} out: |
b673e4dfc [RAW]: Introduce ... |
220 |
read_unlock(&raw_v6_hashinfo.lock); |
d13964f44 [IPV4/6]: Check i... |
221 |
return delivered; |
1da177e4c Linux-2.6.12-rc2 |
222 |
} |
a50feda54 ipv6: bool/const ... |
223 |
bool raw6_local_deliver(struct sk_buff *skb, int nexthdr) |
69d6da0b0 [IPv6] RAW: Compa... |
224 225 |
{ struct sock *raw_sk; |
f9242b6b2 inet: Sanitize in... |
226 |
raw_sk = sk_head(&raw_v6_hashinfo.ht[nexthdr & (RAW_HTABLE_SIZE - 1)]); |
69d6da0b0 [IPv6] RAW: Compa... |
227 228 229 230 231 |
if (raw_sk && !ipv6_raw_deliver(skb, nexthdr)) raw_sk = NULL; return raw_sk != NULL; } |
1da177e4c Linux-2.6.12-rc2 |
232 233 234 235 236 237 |
/* This cleans up af_inet6 a bit. -DaveM */ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr; |
e69a4adc6 [IPV6]: Misc endi... |
238 |
__be32 v4addr = 0; |
1da177e4c Linux-2.6.12-rc2 |
239 240 241 242 243 |
int addr_type; int err; if (addr_len < SIN6_LEN_RFC2133) return -EINVAL; |
82b276cd2 ipv6: protect pro... |
244 245 246 |
if (addr->sin6_family != AF_INET6) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
247 248 249 250 |
addr_type = ipv6_addr_type(&addr->sin6_addr); /* Raw sockets are IPv6 only */ if (addr_type == IPV6_ADDR_MAPPED) |
fd5c00276 ipv6: avoid dev_h... |
251 |
return -EADDRNOTAVAIL; |
1da177e4c Linux-2.6.12-rc2 |
252 253 254 255 256 257 |
lock_sock(sk); err = -EINVAL; if (sk->sk_state != TCP_CLOSE) goto out; |
fd5c00276 ipv6: avoid dev_h... |
258 |
rcu_read_lock(); |
1da177e4c Linux-2.6.12-rc2 |
259 260 261 |
/* Check if the address belongs to the host. */ if (addr_type != IPV6_ADDR_ANY) { struct net_device *dev = NULL; |
842df0739 ipv6: use newly i... |
262 |
if (__ipv6_addr_needs_scope_id(addr_type)) { |
1da177e4c Linux-2.6.12-rc2 |
263 264 265 266 267 268 269 |
if (addr_len >= sizeof(struct sockaddr_in6) && addr->sin6_scope_id) { /* Override any existing binding, if another * one is supplied by user. */ sk->sk_bound_dev_if = addr->sin6_scope_id; } |
1ab1457c4 [NET] IPV6: Fix w... |
270 |
|
1da177e4c Linux-2.6.12-rc2 |
271 272 |
/* Binding to link-local address requires an interface */ if (!sk->sk_bound_dev_if) |
fd5c00276 ipv6: avoid dev_h... |
273 |
goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
274 |
|
fd5c00276 ipv6: avoid dev_h... |
275 276 277 278 279 |
err = -ENODEV; dev = dev_get_by_index_rcu(sock_net(sk), sk->sk_bound_dev_if); if (!dev) goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
280 |
} |
1ab1457c4 [NET] IPV6: Fix w... |
281 |
|
1da177e4c Linux-2.6.12-rc2 |
282 283 284 285 |
/* ipv4 addr of the socket is invalid. Only the * unspecified and mapped address have a v4 equivalent. */ v4addr = LOOPBACK4_IPV6; |
35a256fee ipv6: Nonlocal bind |
286 287 |
if (!(addr_type & IPV6_ADDR_MULTICAST) && !sock_net(sk)->ipv6.sysctl.ip_nonlocal_bind) { |
1da177e4c Linux-2.6.12-rc2 |
288 |
err = -EADDRNOTAVAIL; |
3b1e0a655 [NET] NETNS: Omit... |
289 |
if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr, |
bfeade087 [NETNS][IPV6]: in... |
290 |
dev, 0)) { |
fd5c00276 ipv6: avoid dev_h... |
291 |
goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
292 293 |
} } |
1da177e4c Linux-2.6.12-rc2 |
294 |
} |
c720c7e83 inet: rename some... |
295 |
inet->inet_rcv_saddr = inet->inet_saddr = v4addr; |
efe4208f4 ipv6: make lookup... |
296 |
sk->sk_v6_rcv_saddr = addr->sin6_addr; |
1da177e4c Linux-2.6.12-rc2 |
297 |
if (!(addr_type & IPV6_ADDR_MULTICAST)) |
4e3fd7a06 net: remove ipv6_... |
298 |
np->saddr = addr->sin6_addr; |
1da177e4c Linux-2.6.12-rc2 |
299 |
err = 0; |
fd5c00276 ipv6: avoid dev_h... |
300 301 |
out_unlock: rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
302 303 304 305 |
out: release_sock(sk); return err; } |
69d6da0b0 [IPv6] RAW: Compa... |
306 |
static void rawv6_err(struct sock *sk, struct sk_buff *skb, |
1da177e4c Linux-2.6.12-rc2 |
307 |
struct inet6_skb_parm *opt, |
d5fdd6bab ipv6: Use correct... |
308 |
u8 type, u8 code, int offset, __be32 info) |
1da177e4c Linux-2.6.12-rc2 |
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
{ struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); int err; int harderr; /* Report error on raw socket, if: 1. User requested recverr. 2. Socket is connected (otherwise the error indication is useless without recverr and error is hard. */ if (!np->recverr && sk->sk_state != TCP_ESTABLISHED) return; harderr = icmpv6_err_convert(type, code, &err); |
81aded246 ipv6: Handle PMTU... |
324 325 |
if (type == ICMPV6_PKT_TOOBIG) { ip6_sk_update_pmtu(skb, sk, info); |
1da177e4c Linux-2.6.12-rc2 |
326 |
harderr = (np->pmtudisc == IPV6_PMTUDISC_DO); |
81aded246 ipv6: Handle PMTU... |
327 |
} |
8d65b1190 net: raw: do not ... |
328 |
if (type == NDISC_REDIRECT) { |
ec18d9a26 ipv6: Add redirec... |
329 |
ip6_sk_redirect(skb, sk); |
8d65b1190 net: raw: do not ... |
330 331 |
return; } |
1da177e4c Linux-2.6.12-rc2 |
332 333 334 335 336 337 338 339 340 341 342 343 |
if (np->recverr) { u8 *payload = skb->data; if (!inet->hdrincl) payload += offset; ipv6_icmp_error(sk, skb, err, 0, ntohl(info), payload); } if (np->recverr || harderr) { sk->sk_err = err; sk->sk_error_report(sk); } } |
69d6da0b0 [IPv6] RAW: Compa... |
344 |
void raw6_icmp_error(struct sk_buff *skb, int nexthdr, |
d5fdd6bab ipv6: Use correct... |
345 |
u8 type, u8 code, int inner_offset, __be32 info) |
69d6da0b0 [IPv6] RAW: Compa... |
346 347 348 |
{ struct sock *sk; int hash; |
b71d1d426 inet: constify ip... |
349 |
const struct in6_addr *saddr, *daddr; |
be185884b [NETNS][RAW]: Mak... |
350 |
struct net *net; |
69d6da0b0 [IPv6] RAW: Compa... |
351 |
|
b673e4dfc [RAW]: Introduce ... |
352 |
hash = nexthdr & (RAW_HTABLE_SIZE - 1); |
69d6da0b0 [IPv6] RAW: Compa... |
353 |
|
b673e4dfc [RAW]: Introduce ... |
354 355 |
read_lock(&raw_v6_hashinfo.lock); sk = sk_head(&raw_v6_hashinfo.ht[hash]); |
53b24b8f9 ipv6: coding styl... |
356 |
if (sk) { |
05f175cdc [IPV6]: Fix IPV6_... |
357 |
/* Note: ipv6_hdr(skb) != skb->data */ |
b71d1d426 inet: constify ip... |
358 |
const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data; |
05f175cdc [IPV6]: Fix IPV6_... |
359 360 |
saddr = &ip6h->saddr; daddr = &ip6h->daddr; |
c346dca10 [NET] NETNS: Omit... |
361 |
net = dev_net(skb->dev); |
69d6da0b0 [IPv6] RAW: Compa... |
362 |
|
be185884b [NETNS][RAW]: Mak... |
363 |
while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, |
5108ab4bf net: ipv6: add se... |
364 |
inet6_iif(skb), inet6_iif(skb)))) { |
69d6da0b0 [IPv6] RAW: Compa... |
365 366 367 368 369 |
rawv6_err(sk, skb, NULL, type, code, inner_offset, info); sk = sk_next(sk); } } |
b673e4dfc [RAW]: Introduce ... |
370 |
read_unlock(&raw_v6_hashinfo.lock); |
69d6da0b0 [IPv6] RAW: Compa... |
371 |
} |
33d480ce6 net: cleanup some... |
372 |
static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
373 |
{ |
33d480ce6 net: cleanup some... |
374 |
if ((raw6_sk(sk)->checksum || rcu_access_pointer(sk->sk_filter)) && |
fb286bb29 [NET]: Detect har... |
375 |
skb_checksum_complete(skb)) { |
a92aa318b [IPV6]: Add raw6 ... |
376 |
atomic_inc(&sk->sk_drops); |
fb286bb29 [NET]: Detect har... |
377 |
kfree_skb(skb); |
3cc76caa9 ipv6: When we dro... |
378 |
return NET_RX_DROP; |
1da177e4c Linux-2.6.12-rc2 |
379 380 381 |
} /* Charge it to the socket. */ |
d826eb14e ipv4: PKTINFO doe... |
382 383 |
skb_dst_drop(skb); if (sock_queue_rcv_skb(sk, skb) < 0) { |
1da177e4c Linux-2.6.12-rc2 |
384 |
kfree_skb(skb); |
3cc76caa9 ipv6: When we dro... |
385 |
return NET_RX_DROP; |
1da177e4c Linux-2.6.12-rc2 |
386 387 388 389 390 391 |
} return 0; } /* |
1ab1457c4 [NET] IPV6: Fix w... |
392 |
* This is next to useless... |
1da177e4c Linux-2.6.12-rc2 |
393 |
* if we demultiplex in network layer we don't need the extra call |
1ab1457c4 [NET] IPV6: Fix w... |
394 395 |
* just to queue the skb... * maybe we could have the network decide upon a hint if it |
1da177e4c Linux-2.6.12-rc2 |
396 397 398 399 400 401 |
* should call raw_rcv for demultiplexing */ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) { struct inet_sock *inet = inet_sk(sk); struct raw6_sock *rp = raw6_sk(sk); |
1ab1457c4 [NET] IPV6: Fix w... |
402 |
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { |
a92aa318b [IPV6]: Add raw6 ... |
403 |
atomic_inc(&sk->sk_drops); |
1ab1457c4 [NET] IPV6: Fix w... |
404 405 406 |
kfree_skb(skb); return NET_RX_DROP; } |
1da177e4c Linux-2.6.12-rc2 |
407 408 409 |
if (!rp->checksum) skb->ip_summed = CHECKSUM_UNNECESSARY; |
84fa7933a [NET]: Replace CH... |
410 |
if (skb->ip_summed == CHECKSUM_COMPLETE) { |
d56f90a7c [SK_BUFF]: Introd... |
411 |
skb_postpull_rcsum(skb, skb_network_header(skb), |
cfe1fc775 [SK_BUFF]: Introd... |
412 |
skb_network_header_len(skb)); |
0660e03f6 [SK_BUFF]: Introd... |
413 414 |
if (!csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
c720c7e83 inet: rename some... |
415 |
skb->len, inet->inet_num, skb->csum)) |
1da177e4c Linux-2.6.12-rc2 |
416 |
skb->ip_summed = CHECKSUM_UNNECESSARY; |
1da177e4c Linux-2.6.12-rc2 |
417 |
} |
604763722 [NET]: Treat CHEC... |
418 |
if (!skb_csum_unnecessary(skb)) |
0660e03f6 [SK_BUFF]: Introd... |
419 420 421 |
skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->len, |
c720c7e83 inet: rename some... |
422 |
inet->inet_num, 0)); |
1da177e4c Linux-2.6.12-rc2 |
423 424 |
if (inet->hdrincl) { |
fb286bb29 [NET]: Detect har... |
425 |
if (skb_checksum_complete(skb)) { |
a92aa318b [IPV6]: Add raw6 ... |
426 |
atomic_inc(&sk->sk_drops); |
1da177e4c Linux-2.6.12-rc2 |
427 |
kfree_skb(skb); |
3cc76caa9 ipv6: When we dro... |
428 |
return NET_RX_DROP; |
1da177e4c Linux-2.6.12-rc2 |
429 |
} |
1da177e4c Linux-2.6.12-rc2 |
430 431 432 433 434 435 436 437 438 439 440 |
} rawv6_rcv_skb(sk, skb); return 0; } /* * This should be easy, if there is something there * we return it, otherwise we block. */ |
1b7841404 net: Remove iocb ... |
441 442 |
static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, int flags, int *addr_len) |
1da177e4c Linux-2.6.12-rc2 |
443 444 |
{ struct ipv6_pinfo *np = inet6_sk(sk); |
342dfc306 net: add build-ti... |
445 |
DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
1da177e4c Linux-2.6.12-rc2 |
446 447 448 449 450 451 |
struct sk_buff *skb; size_t copied; int err; if (flags & MSG_OOB) return -EOPNOTSUPP; |
1ab1457c4 [NET] IPV6: Fix w... |
452 |
|
1da177e4c Linux-2.6.12-rc2 |
453 |
if (flags & MSG_ERRQUEUE) |
85fbaa750 inet: fix addr_le... |
454 |
return ipv6_recv_error(sk, msg, len, addr_len); |
1da177e4c Linux-2.6.12-rc2 |
455 |
|
4b340ae20 IPv6: Complete IP... |
456 |
if (np->rxpmtu && np->rxopt.bits.rxpmtu) |
85fbaa750 inet: fix addr_le... |
457 |
return ipv6_recv_rxpmtu(sk, msg, len, addr_len); |
4b340ae20 IPv6: Complete IP... |
458 |
|
1da177e4c Linux-2.6.12-rc2 |
459 460 461 462 463 |
skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) goto out; copied = skb->len; |
1ab1457c4 [NET] IPV6: Fix w... |
464 465 466 467 |
if (copied > len) { copied = len; msg->msg_flags |= MSG_TRUNC; } |
1da177e4c Linux-2.6.12-rc2 |
468 |
|
604763722 [NET]: Treat CHEC... |
469 |
if (skb_csum_unnecessary(skb)) { |
51f3d02b9 net: Add and use ... |
470 |
err = skb_copy_datagram_msg(skb, 0, msg, copied); |
1da177e4c Linux-2.6.12-rc2 |
471 |
} else if (msg->msg_flags&MSG_TRUNC) { |
fb286bb29 [NET]: Detect har... |
472 |
if (__skb_checksum_complete(skb)) |
1da177e4c Linux-2.6.12-rc2 |
473 |
goto csum_copy_err; |
51f3d02b9 net: Add and use ... |
474 |
err = skb_copy_datagram_msg(skb, 0, msg, copied); |
1da177e4c Linux-2.6.12-rc2 |
475 |
} else { |
227158db1 new helper: skb_c... |
476 |
err = skb_copy_and_csum_datagram_msg(skb, 0, msg); |
1da177e4c Linux-2.6.12-rc2 |
477 478 479 480 481 482 483 484 485 |
if (err == -EINVAL) goto csum_copy_err; } if (err) goto out_free; /* Copy the address. */ if (sin6) { sin6->sin6_family = AF_INET6; |
f59fc7f30 [IPV4/IPV6]: Sett... |
486 |
sin6->sin6_port = 0; |
4e3fd7a06 net: remove ipv6_... |
487 |
sin6->sin6_addr = ipv6_hdr(skb)->saddr; |
1da177e4c Linux-2.6.12-rc2 |
488 |
sin6->sin6_flowinfo = 0; |
842df0739 ipv6: use newly i... |
489 |
sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, |
4330487ac net: use inet6_ii... |
490 |
inet6_iif(skb)); |
bceaa9024 inet: prevent lea... |
491 |
*addr_len = sizeof(*sin6); |
1da177e4c Linux-2.6.12-rc2 |
492 |
} |
3b885787e net: Generalize s... |
493 |
sock_recv_ts_and_drops(msg, sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
494 495 |
if (np->rxopt.all) |
73df66f8b ipv6: rename data... |
496 |
ip6_datagram_recv_ctl(sk, msg, skb); |
1da177e4c Linux-2.6.12-rc2 |
497 498 499 500 501 502 503 504 505 506 507 |
err = copied; if (flags & MSG_TRUNC) err = skb->len; out_free: skb_free_datagram(sk, skb); out: return err; csum_copy_err: |
3305b80c2 [IP]: Simplify an... |
508 |
skb_kill_datagram(sk, skb, flags); |
1da177e4c Linux-2.6.12-rc2 |
509 510 511 512 513 |
/* Error for blocking case is chosen to masquerade as some normal condition. */ err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; |
3305b80c2 [IP]: Simplify an... |
514 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
515 |
} |
4c9483b2f ipv6: Convert to ... |
516 |
static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, |
357b40a18 [IPV6]: IPV6_CHEC... |
517 |
struct raw6_sock *rp) |
1da177e4c Linux-2.6.12-rc2 |
518 519 520 |
{ struct sk_buff *skb; int err = 0; |
357b40a18 [IPV6]: IPV6_CHEC... |
521 522 |
int offset; int len; |
679a87382 [IPV6]: Fix raw s... |
523 |
int total_len; |
868c86bcb [NET]: annotate c... |
524 525 |
__wsum tmp_csum; __sum16 csum; |
1da177e4c Linux-2.6.12-rc2 |
526 527 528 |
if (!rp->checksum) goto send; |
43728fa5c ipv6: remove assi... |
529 530 |
skb = skb_peek(&sk->sk_write_queue); if (!skb) |
1da177e4c Linux-2.6.12-rc2 |
531 |
goto out; |
357b40a18 [IPV6]: IPV6_CHEC... |
532 |
offset = rp->offset; |
299b07676 ipv6: Fix IPsec s... |
533 |
total_len = inet_sk(sk)->cork.base.length; |
679a87382 [IPV6]: Fix raw s... |
534 |
if (offset >= total_len - 1) { |
1da177e4c Linux-2.6.12-rc2 |
535 |
err = -EINVAL; |
357b40a18 [IPV6]: IPV6_CHEC... |
536 |
ip6_flush_pending_frames(sk); |
1da177e4c Linux-2.6.12-rc2 |
537 538 539 540 541 542 543 544 545 546 |
goto out; } /* should be check HW csum miyazawa */ if (skb_queue_len(&sk->sk_write_queue) == 1) { /* * Only one fragment on the socket. */ tmp_csum = skb->csum; } else { |
357b40a18 [IPV6]: IPV6_CHEC... |
547 |
struct sk_buff *csum_skb = NULL; |
1da177e4c Linux-2.6.12-rc2 |
548 549 550 551 |
tmp_csum = 0; skb_queue_walk(&sk->sk_write_queue, skb) { tmp_csum = csum_add(tmp_csum, skb->csum); |
357b40a18 [IPV6]: IPV6_CHEC... |
552 553 554 |
if (csum_skb) continue; |
ea2ae17d6 [SK_BUFF]: Introd... |
555 |
len = skb->len - skb_transport_offset(skb); |
357b40a18 [IPV6]: IPV6_CHEC... |
556 557 558 559 560 561 |
if (offset >= len) { offset -= len; continue; } csum_skb = skb; |
1da177e4c Linux-2.6.12-rc2 |
562 |
} |
357b40a18 [IPV6]: IPV6_CHEC... |
563 564 |
skb = csum_skb; |
1da177e4c Linux-2.6.12-rc2 |
565 |
} |
ea2ae17d6 [SK_BUFF]: Introd... |
566 |
offset += skb_transport_offset(skb); |
a98f91758 ipv6: handle -EFA... |
567 568 569 570 571 |
err = skb_copy_bits(skb, offset, &csum, 2); if (err < 0) { ip6_flush_pending_frames(sk); goto out; } |
357b40a18 [IPV6]: IPV6_CHEC... |
572 |
|
1da177e4c Linux-2.6.12-rc2 |
573 |
/* in case cksum was not initialized */ |
357b40a18 [IPV6]: IPV6_CHEC... |
574 |
if (unlikely(csum)) |
5f92a7388 [NET]: Annotate c... |
575 |
tmp_csum = csum_sub(tmp_csum, csum_unfold(csum)); |
357b40a18 [IPV6]: IPV6_CHEC... |
576 |
|
4c9483b2f ipv6: Convert to ... |
577 578 |
csum = csum_ipv6_magic(&fl6->saddr, &fl6->daddr, total_len, fl6->flowi6_proto, tmp_csum); |
357b40a18 [IPV6]: IPV6_CHEC... |
579 |
|
4c9483b2f ipv6: Convert to ... |
580 |
if (csum == 0 && fl6->flowi6_proto == IPPROTO_UDP) |
f6ab02880 [NET]: Make mangl... |
581 |
csum = CSUM_MANGLED_0; |
1da177e4c Linux-2.6.12-rc2 |
582 |
|
8242fc339 net: ipv6: Use BU... |
583 |
BUG_ON(skb_store_bits(skb, offset, &csum, 2)); |
1da177e4c Linux-2.6.12-rc2 |
584 |
|
1da177e4c Linux-2.6.12-rc2 |
585 586 587 588 589 |
send: err = ip6_push_pending_frames(sk); out: return err; } |
c3c1a7dbe ipv6: rawv6_send_... |
590 |
static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, |
4c9483b2f ipv6: Convert to ... |
591 |
struct flowi6 *fl6, struct dst_entry **dstp, |
1da177e4c Linux-2.6.12-rc2 |
592 593 |
unsigned int flags) { |
3320da890 [IPV6]: Replace b... |
594 |
struct ipv6_pinfo *np = inet6_sk(sk); |
adb28c9d3 ipv6: Compute net... |
595 |
struct net *net = sock_net(sk); |
1da177e4c Linux-2.6.12-rc2 |
596 597 |
struct ipv6hdr *iph; struct sk_buff *skb; |
1da177e4c Linux-2.6.12-rc2 |
598 |
int err; |
1789a640f raw: avoid two at... |
599 |
struct rt6_info *rt = (struct rt6_info *)*dstp; |
a7ae19922 ipv6: Remove all ... |
600 601 |
int hlen = LL_RESERVED_SPACE(rt->dst.dev); int tlen = rt->dst.dev->needed_tailroom; |
1da177e4c Linux-2.6.12-rc2 |
602 |
|
d8d1f30b9 net-next: remove ... |
603 |
if (length > rt->dst.dev->mtu) { |
4c9483b2f ipv6: Convert to ... |
604 |
ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); |
1da177e4c Linux-2.6.12-rc2 |
605 606 |
return -EMSGSIZE; } |
86f4c90a1 ipv4, ipv6: ensur... |
607 608 |
if (length < sizeof(struct ipv6hdr)) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
609 610 |
if (flags&MSG_PROBE) goto out; |
f5184d267 net: Allow netdev... |
611 |
skb = sock_alloc_send_skb(sk, |
a7ae19922 ipv6: Remove all ... |
612 |
length + hlen + tlen + 15, |
f5184d267 net: Allow netdev... |
613 |
flags & MSG_DONTWAIT, &err); |
63159f29b ipv6: coding styl... |
614 |
if (!skb) |
1ab1457c4 [NET] IPV6: Fix w... |
615 |
goto error; |
a7ae19922 ipv6: Remove all ... |
616 |
skb_reserve(skb, hlen); |
1da177e4c Linux-2.6.12-rc2 |
617 |
|
9c9c9ad5f ipv6: set skb->pr... |
618 |
skb->protocol = htons(ETH_P_IPV6); |
1da177e4c Linux-2.6.12-rc2 |
619 |
skb->priority = sk->sk_priority; |
4a19ec580 [NET]: Introducin... |
620 |
skb->mark = sk->sk_mark; |
1da177e4c Linux-2.6.12-rc2 |
621 |
|
1ced98e81 [SK_BUFF] ipv6: M... |
622 623 |
skb_put(skb, length); skb_reset_network_header(skb); |
0660e03f6 [SK_BUFF]: Introd... |
624 |
iph = ipv6_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
625 626 |
skb->ip_summed = CHECKSUM_NONE; |
0dec879f6 net: use dst_conf... |
627 628 |
if (flags & MSG_CONFIRM) skb_set_dst_pending_confirm(skb, 1); |
b0e380b1d [SK_BUFF]: unions... |
629 |
skb->transport_header = skb->network_header; |
21226abb4 net: switch memcp... |
630 |
err = memcpy_from_msg(iph, msg, length); |
48c14f2ea ipv6: take rcu lo... |
631 632 633 634 635 636 637 638 |
if (err) { err = -EFAULT; kfree_skb(skb); goto error; } skb_dst_set(skb, &rt->dst); *dstp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
639 |
|
a8e3e1a9f net: l3mdev: Add ... |
640 641 642 643 644 645 |
/* if egress device is enslaved to an L3 master device pass the * skb to its handler for processing */ skb = l3mdev_ip6_out(sk, skb); if (unlikely(!skb)) return 0; |
48c14f2ea ipv6: take rcu lo... |
646 647 648 649 650 |
/* Acquire rcu_read_lock() in case we need to use rt->rt6i_idev * in the error path. Since skb has been freed, the dst could * have been queued for deletion. */ rcu_read_lock(); |
adb28c9d3 ipv6: Compute net... |
651 |
IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); |
29a26a568 netfilter: Pass s... |
652 |
err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, |
13206b6bf net: Pass net int... |
653 |
NULL, rt->dst.dev, dst_output); |
1da177e4c Linux-2.6.12-rc2 |
654 |
if (err > 0) |
6ce9e7b5f ip: Report qdisc ... |
655 |
err = net_xmit_errno(err); |
48c14f2ea ipv6: take rcu lo... |
656 657 658 659 660 661 |
if (err) { IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); rcu_read_unlock(); goto error_check; } rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
662 663 |
out: return 0; |
1da177e4c Linux-2.6.12-rc2 |
664 |
error: |
adb28c9d3 ipv6: Compute net... |
665 |
IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); |
48c14f2ea ipv6: take rcu lo... |
666 |
error_check: |
6ce9e7b5f ip: Report qdisc ... |
667 668 |
if (err == -ENOBUFS && !np->recverr) err = 0; |
1ab1457c4 [NET] IPV6: Fix w... |
669 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
670 |
} |
19e3c66b5 ipv6 equivalent o... |
671 672 673 674 675 676 677 |
struct raw6_frag_vec { struct msghdr *msg; int hlen; char c[4]; }; static int rawv6_probe_proto_opt(struct raw6_frag_vec *rfv, struct flowi6 *fl6) |
1da177e4c Linux-2.6.12-rc2 |
678 |
{ |
19e3c66b5 ipv6 equivalent o... |
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 |
int err = 0; switch (fl6->flowi6_proto) { case IPPROTO_ICMPV6: rfv->hlen = 2; err = memcpy_from_msg(rfv->c, rfv->msg, rfv->hlen); if (!err) { fl6->fl6_icmp_type = rfv->c[0]; fl6->fl6_icmp_code = rfv->c[1]; } break; case IPPROTO_MH: rfv->hlen = 4; err = memcpy_from_msg(rfv->c, rfv->msg, rfv->hlen); if (!err) fl6->fl6_mh_type = rfv->c[2]; } return err; } |
1da177e4c Linux-2.6.12-rc2 |
697 |
|
19e3c66b5 ipv6 equivalent o... |
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
static int raw6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) { struct raw6_frag_vec *rfv = from; if (offset < rfv->hlen) { int copy = min(rfv->hlen - offset, len); if (skb->ip_summed == CHECKSUM_PARTIAL) memcpy(to, rfv->c + offset, copy); else skb->csum = csum_block_add( skb->csum, csum_partial_copy_nocheck(rfv->c + offset, to, copy, 0), odd); odd = 0; offset += copy; to += copy; len -= copy; if (!len) return 0; } |
1da177e4c Linux-2.6.12-rc2 |
723 |
|
19e3c66b5 ipv6 equivalent o... |
724 |
offset -= rfv->hlen; |
6e8f4d48b [IPV6] MIP6: Add ... |
725 |
|
f69e6d131 ip_generic_getfra... |
726 |
return ip_generic_getfrag(rfv->msg, to, offset, len, odd, skb); |
1da177e4c Linux-2.6.12-rc2 |
727 |
} |
1b7841404 net: Remove iocb ... |
728 |
static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1da177e4c Linux-2.6.12-rc2 |
729 |
{ |
45f6fad84 ipv6: add complet... |
730 |
struct ipv6_txoptions *opt_to_free = NULL; |
1da177e4c Linux-2.6.12-rc2 |
731 |
struct ipv6_txoptions opt_space; |
342dfc306 net: add build-ti... |
732 |
DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
20c59de2e ipv6: Refactor up... |
733 |
struct in6_addr *daddr, *final_p, final; |
1da177e4c Linux-2.6.12-rc2 |
734 735 736 737 738 739 |
struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct raw6_sock *rp = raw6_sk(sk); struct ipv6_txoptions *opt = NULL; struct ip6_flowlabel *flowlabel = NULL; struct dst_entry *dst = NULL; |
19e3c66b5 ipv6 equivalent o... |
740 |
struct raw6_frag_vec rfv; |
4c9483b2f ipv6: Convert to ... |
741 |
struct flowi6 fl6; |
ad1e46a83 ipv6: process soc... |
742 |
struct sockcm_cookie sockc; |
26879da58 ipv6: add new str... |
743 |
struct ipcm6_cookie ipc6; |
1da177e4c Linux-2.6.12-rc2 |
744 |
int addr_len = msg->msg_namelen; |
1da177e4c Linux-2.6.12-rc2 |
745 746 747 748 |
u16 proto; int err; /* Rough check on arithmetic overflow, |
b59e139bb [IPv6]: Fix incor... |
749 |
better check is made in ip6_append_data(). |
1da177e4c Linux-2.6.12-rc2 |
750 |
*/ |
b59e139bb [IPv6]: Fix incor... |
751 |
if (len > INT_MAX) |
1da177e4c Linux-2.6.12-rc2 |
752 753 754 |
return -EMSGSIZE; /* Mirror BSD error message compatibility */ |
1ab1457c4 [NET] IPV6: Fix w... |
755 |
if (msg->msg_flags & MSG_OOB) |
1da177e4c Linux-2.6.12-rc2 |
756 757 758 |
return -EOPNOTSUPP; /* |
1ab1457c4 [NET] IPV6: Fix w... |
759 |
* Get and verify the address. |
1da177e4c Linux-2.6.12-rc2 |
760 |
*/ |
4c9483b2f ipv6: Convert to ... |
761 |
memset(&fl6, 0, sizeof(fl6)); |
1da177e4c Linux-2.6.12-rc2 |
762 |
|
4c9483b2f ipv6: Convert to ... |
763 |
fl6.flowi6_mark = sk->sk_mark; |
e2d118a1c net: inet: Suppor... |
764 |
fl6.flowi6_uid = sk->sk_uid; |
4a19ec580 [NET]: Introducin... |
765 |
|
26879da58 ipv6: add new str... |
766 767 768 769 |
ipc6.hlimit = -1; ipc6.tclass = -1; ipc6.dontfrag = -1; ipc6.opt = NULL; |
1da177e4c Linux-2.6.12-rc2 |
770 |
if (sin6) { |
1ab1457c4 [NET] IPV6: Fix w... |
771 |
if (addr_len < SIN6_LEN_RFC2133) |
1da177e4c Linux-2.6.12-rc2 |
772 |
return -EINVAL; |
1ab1457c4 [NET] IPV6: Fix w... |
773 |
if (sin6->sin6_family && sin6->sin6_family != AF_INET6) |
a02cec215 net: return opera... |
774 |
return -EAFNOSUPPORT; |
1da177e4c Linux-2.6.12-rc2 |
775 776 777 778 779 |
/* port is the proto value [0..255] carried in nexthdr */ proto = ntohs(sin6->sin6_port); if (!proto) |
c720c7e83 inet: rename some... |
780 781 |
proto = inet->inet_num; else if (proto != inet->inet_num) |
a02cec215 net: return opera... |
782 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
783 784 |
if (proto > 255) |
a02cec215 net: return opera... |
785 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
786 787 788 |
daddr = &sin6->sin6_addr; if (np->sndflow) { |
4c9483b2f ipv6: Convert to ... |
789 790 791 |
fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
63159f29b ipv6: coding styl... |
792 |
if (!flowlabel) |
1da177e4c Linux-2.6.12-rc2 |
793 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
794 795 796 797 798 799 800 801 |
} } /* * Otherwise it will be difficult to maintain * sk->sk_dst_cache. */ if (sk->sk_state == TCP_ESTABLISHED && |
efe4208f4 ipv6: make lookup... |
802 803 |
ipv6_addr_equal(daddr, &sk->sk_v6_daddr)) daddr = &sk->sk_v6_daddr; |
1da177e4c Linux-2.6.12-rc2 |
804 805 806 |
if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && |
842df0739 ipv6: use newly i... |
807 |
__ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr))) |
4c9483b2f ipv6: Convert to ... |
808 |
fl6.flowi6_oif = sin6->sin6_scope_id; |
1da177e4c Linux-2.6.12-rc2 |
809 |
} else { |
1ab1457c4 [NET] IPV6: Fix w... |
810 |
if (sk->sk_state != TCP_ESTABLISHED) |
1da177e4c Linux-2.6.12-rc2 |
811 |
return -EDESTADDRREQ; |
1ab1457c4 [NET] IPV6: Fix w... |
812 |
|
c720c7e83 inet: rename some... |
813 |
proto = inet->inet_num; |
efe4208f4 ipv6: make lookup... |
814 |
daddr = &sk->sk_v6_daddr; |
4c9483b2f ipv6: Convert to ... |
815 |
fl6.flowlabel = np->flow_label; |
1da177e4c Linux-2.6.12-rc2 |
816 |
} |
4c9483b2f ipv6: Convert to ... |
817 818 |
if (fl6.flowi6_oif == 0) fl6.flowi6_oif = sk->sk_bound_dev_if; |
1da177e4c Linux-2.6.12-rc2 |
819 |
|
c14ac9451 sock: enable time... |
820 |
sockc.tsflags = sk->sk_tsflags; |
1da177e4c Linux-2.6.12-rc2 |
821 822 823 824 |
if (msg->msg_controllen) { opt = &opt_space; memset(opt, 0, sizeof(struct ipv6_txoptions)); opt->tot_len = sizeof(struct ipv6_txoptions); |
26879da58 ipv6: add new str... |
825 |
ipc6.opt = opt; |
1da177e4c Linux-2.6.12-rc2 |
826 |
|
26879da58 ipv6: add new str... |
827 |
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc); |
1da177e4c Linux-2.6.12-rc2 |
828 829 830 831 |
if (err < 0) { fl6_sock_release(flowlabel); return err; } |
4c9483b2f ipv6: Convert to ... |
832 833 |
if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
63159f29b ipv6: coding styl... |
834 |
if (!flowlabel) |
1da177e4c Linux-2.6.12-rc2 |
835 836 837 838 839 |
return -EINVAL; } if (!(opt->opt_nflen|opt->opt_flen)) opt = NULL; } |
45f6fad84 ipv6: add complet... |
840 841 842 |
if (!opt) { opt = txopt_get(np); opt_to_free = opt; |
26879da58 ipv6: add new str... |
843 |
} |
df9890c31 [IPV6]: Fix sendi... |
844 845 846 |
if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); |
1da177e4c Linux-2.6.12-rc2 |
847 |
|
4c9483b2f ipv6: Convert to ... |
848 |
fl6.flowi6_proto = proto; |
19e3c66b5 ipv6 equivalent o... |
849 850 851 |
rfv.msg = msg; rfv.hlen = 0; err = rawv6_probe_proto_opt(&rfv, &fl6); |
a27b58fed [NET]: fix uacces... |
852 853 |
if (err) goto out; |
1ab1457c4 [NET] IPV6: Fix w... |
854 |
|
876c7f419 [IPv6]: Change IP... |
855 |
if (!ipv6_addr_any(daddr)) |
4e3fd7a06 net: remove ipv6_... |
856 |
fl6.daddr = *daddr; |
876c7f419 [IPv6]: Change IP... |
857 |
else |
4c9483b2f ipv6: Convert to ... |
858 859 |
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) |
4e3fd7a06 net: remove ipv6_... |
860 |
fl6.saddr = np->saddr; |
1da177e4c Linux-2.6.12-rc2 |
861 |
|
4c9483b2f ipv6: Convert to ... |
862 |
final_p = fl6_update_dst(&fl6, opt, &final); |
1da177e4c Linux-2.6.12-rc2 |
863 |
|
4c9483b2f ipv6: Convert to ... |
864 865 |
if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) fl6.flowi6_oif = np->mcast_oif; |
c4062dfc4 ipv6: Implement I... |
866 867 |
else if (!fl6.flowi6_oif) fl6.flowi6_oif = np->ucast_oif; |
4c9483b2f ipv6: Convert to ... |
868 |
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
1da177e4c Linux-2.6.12-rc2 |
869 |
|
48e8aa6e3 ipv6: Set FLOWI_F... |
870 871 |
if (inet->hdrincl) fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH; |
38b7097b5 ipv6: use TOS mar... |
872 873 874 875 |
if (ipc6.tclass < 0) ipc6.tclass = np->tclass; fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); |
0e0d44ab4 net: Remove FLOWI... |
876 |
dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
68d0c6d34 ipv6: Consolidate... |
877 878 |
if (IS_ERR(dst)) { err = PTR_ERR(dst); |
1da177e4c Linux-2.6.12-rc2 |
879 |
goto out; |
14e50e57a [XFRM]: Allow pac... |
880 |
} |
26879da58 ipv6: add new str... |
881 882 |
if (ipc6.hlimit < 0) ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); |
1da177e4c Linux-2.6.12-rc2 |
883 |
|
26879da58 ipv6: add new str... |
884 885 |
if (ipc6.dontfrag < 0) ipc6.dontfrag = np->dontfrag; |
13b52cd44 IPv6: Add dontfra... |
886 |
|
1da177e4c Linux-2.6.12-rc2 |
887 888 889 890 |
if (msg->msg_flags&MSG_CONFIRM) goto do_confirm; back_from_confirm: |
1789a640f raw: avoid two at... |
891 |
if (inet->hdrincl) |
c3c1a7dbe ipv6: rawv6_send_... |
892 |
err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, msg->msg_flags); |
1789a640f raw: avoid two at... |
893 |
else { |
26879da58 ipv6: add new str... |
894 |
ipc6.opt = opt; |
1da177e4c Linux-2.6.12-rc2 |
895 |
lock_sock(sk); |
19e3c66b5 ipv6 equivalent o... |
896 |
err = ip6_append_data(sk, raw6_getfrag, &rfv, |
26879da58 ipv6: add new str... |
897 898 |
len, 0, &ipc6, &fl6, (struct rt6_info *)dst, msg->msg_flags, &sockc); |
1da177e4c Linux-2.6.12-rc2 |
899 900 901 902 |
if (err) ip6_flush_pending_frames(sk); else if (!(msg->msg_flags & MSG_MORE)) |
4c9483b2f ipv6: Convert to ... |
903 |
err = rawv6_push_pending_frames(sk, &fl6, rp); |
3ef9d943d [IPV6]: Fix unbal... |
904 |
release_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
905 906 |
} done: |
6d3e85ecf [IPV6] Don't stor... |
907 |
dst_release(dst); |
1ab1457c4 [NET] IPV6: Fix w... |
908 |
out: |
1da177e4c Linux-2.6.12-rc2 |
909 |
fl6_sock_release(flowlabel); |
45f6fad84 ipv6: add complet... |
910 |
txopt_put(opt_to_free); |
67ba4152e ipv6: White-space... |
911 |
return err < 0 ? err : len; |
1da177e4c Linux-2.6.12-rc2 |
912 |
do_confirm: |
0dec879f6 net: use dst_conf... |
913 914 |
if (msg->msg_flags & MSG_PROBE) dst_confirm_neigh(dst, &fl6.daddr); |
1da177e4c Linux-2.6.12-rc2 |
915 916 917 918 919 |
if (!(msg->msg_flags & MSG_PROBE) || len) goto back_from_confirm; err = 0; goto done; } |
1ab1457c4 [NET] IPV6: Fix w... |
920 |
static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, |
1da177e4c Linux-2.6.12-rc2 |
921 922 923 924 925 926 927 928 929 930 931 |
char __user *optval, int optlen) { switch (optname) { case ICMPV6_FILTER: if (optlen > sizeof(struct icmp6_filter)) optlen = sizeof(struct icmp6_filter); if (copy_from_user(&raw6_sk(sk)->filter, optval, optlen)) return -EFAULT; return 0; default: return -ENOPROTOOPT; |
3ff50b799 [NET]: cleanup ex... |
932 |
} |
1da177e4c Linux-2.6.12-rc2 |
933 934 935 |
return 0; } |
1ab1457c4 [NET] IPV6: Fix w... |
936 |
static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, |
1da177e4c Linux-2.6.12-rc2 |
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 |
char __user *optval, int __user *optlen) { int len; switch (optname) { case ICMPV6_FILTER: if (get_user(len, optlen)) return -EFAULT; if (len < 0) return -EINVAL; if (len > sizeof(struct icmp6_filter)) len = sizeof(struct icmp6_filter); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &raw6_sk(sk)->filter, len)) return -EFAULT; return 0; default: return -ENOPROTOOPT; |
3ff50b799 [NET]: cleanup ex... |
956 |
} |
1da177e4c Linux-2.6.12-rc2 |
957 958 959 |
return 0; } |
3fdadf7d2 [NET]: {get|set}s... |
960 |
static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, |
b7058842c net: Make setsock... |
961 |
char __user *optval, unsigned int optlen) |
1da177e4c Linux-2.6.12-rc2 |
962 963 964 |
{ struct raw6_sock *rp = raw6_sk(sk); int val; |
1ab1457c4 [NET] IPV6: Fix w... |
965 |
if (get_user(val, (int __user *)optval)) |
1da177e4c Linux-2.6.12-rc2 |
966 967 968 |
return -EFAULT; switch (optname) { |
715f504b1 ipv6: add IPV6_HD... |
969 970 971 972 973 |
case IPV6_HDRINCL: if (sk->sk_type != SOCK_RAW) return -EINVAL; inet_sk(sk)->hdrincl = !!val; return 0; |
207ec0abb ipv6: Reduce swit... |
974 975 976 977 978 979 980 981 982 983 984 985 986 |
case IPV6_CHECKSUM: if (inet_sk(sk)->inet_num == IPPROTO_ICMPV6 && level == IPPROTO_IPV6) { /* * RFC3542 tells that IPV6_CHECKSUM socket * option in the IPPROTO_IPV6 level is not * allowed on ICMPv6 sockets. * If you want to set it, use IPPROTO_RAW * level IPV6_CHECKSUM socket option * (Linux extension). */ return -EINVAL; } |
1a98d05f5 ipv6 RAW: Disallo... |
987 |
|
207ec0abb ipv6: Reduce swit... |
988 989 990 991 992 993 994 995 996 997 |
/* You may get strange result with a positive odd offset; RFC2292bis agrees with me. */ if (val > 0 && (val&1)) return -EINVAL; if (val < 0) { rp->checksum = 0; } else { rp->checksum = 1; rp->offset = val; } |
1da177e4c Linux-2.6.12-rc2 |
998 |
|
207ec0abb ipv6: Reduce swit... |
999 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1000 |
|
207ec0abb ipv6: Reduce swit... |
1001 1002 |
default: return -ENOPROTOOPT; |
1da177e4c Linux-2.6.12-rc2 |
1003 1004 |
} } |
3fdadf7d2 [NET]: {get|set}s... |
1005 |
static int rawv6_setsockopt(struct sock *sk, int level, int optname, |
b7058842c net: Make setsock... |
1006 |
char __user *optval, unsigned int optlen) |
1da177e4c Linux-2.6.12-rc2 |
1007 |
{ |
207ec0abb ipv6: Reduce swit... |
1008 1009 1010 |
switch (level) { case SOL_RAW: break; |
1da177e4c Linux-2.6.12-rc2 |
1011 |
|
207ec0abb ipv6: Reduce swit... |
1012 1013 1014 1015 1016 |
case SOL_ICMPV6: if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6) return -EOPNOTSUPP; return rawv6_seticmpfilter(sk, level, optname, optval, optlen); case SOL_IPV6: |
715f504b1 ipv6: add IPV6_HD... |
1017 1018 |
if (optname == IPV6_CHECKSUM || optname == IPV6_HDRINCL) |
207ec0abb ipv6: Reduce swit... |
1019 1020 1021 |
break; default: return ipv6_setsockopt(sk, level, optname, optval, optlen); |
3ff50b799 [NET]: cleanup ex... |
1022 |
} |
3fdadf7d2 [NET]: {get|set}s... |
1023 1024 1025 1026 1027 |
return do_rawv6_setsockopt(sk, level, optname, optval, optlen); } #ifdef CONFIG_COMPAT static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, |
b7058842c net: Make setsock... |
1028 |
char __user *optval, unsigned int optlen) |
3fdadf7d2 [NET]: {get|set}s... |
1029 |
{ |
543d9cfee [NET]: Identation... |
1030 1031 1032 1033 |
switch (level) { case SOL_RAW: break; case SOL_ICMPV6: |
c720c7e83 inet: rename some... |
1034 |
if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6) |
543d9cfee [NET]: Identation... |
1035 1036 1037 |
return -EOPNOTSUPP; return rawv6_seticmpfilter(sk, level, optname, optval, optlen); case SOL_IPV6: |
715f504b1 ipv6: add IPV6_HD... |
1038 1039 |
if (optname == IPV6_CHECKSUM || optname == IPV6_HDRINCL) |
3fdadf7d2 [NET]: {get|set}s... |
1040 |
break; |
543d9cfee [NET]: Identation... |
1041 1042 1043 |
default: return compat_ipv6_setsockopt(sk, level, optname, optval, optlen); |
3ff50b799 [NET]: cleanup ex... |
1044 |
} |
3fdadf7d2 [NET]: {get|set}s... |
1045 1046 1047 1048 1049 1050 1051 1052 1053 |
return do_rawv6_setsockopt(sk, level, optname, optval, optlen); } #endif static int do_rawv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen) { struct raw6_sock *rp = raw6_sk(sk); int val, len; |
1da177e4c Linux-2.6.12-rc2 |
1054 |
|
67ba4152e ipv6: White-space... |
1055 |
if (get_user(len, optlen)) |
1da177e4c Linux-2.6.12-rc2 |
1056 1057 1058 |
return -EFAULT; switch (optname) { |
715f504b1 ipv6: add IPV6_HD... |
1059 1060 1061 |
case IPV6_HDRINCL: val = inet_sk(sk)->hdrincl; break; |
1da177e4c Linux-2.6.12-rc2 |
1062 |
case IPV6_CHECKSUM: |
1a98d05f5 ipv6 RAW: Disallo... |
1063 1064 1065 1066 1067 |
/* * We allow getsockopt() for IPPROTO_IPV6-level * IPV6_CHECKSUM socket option on ICMPv6 sockets * since RFC3542 is silent about it. */ |
1da177e4c Linux-2.6.12-rc2 |
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 |
if (rp->checksum == 0) val = -1; else val = rp->offset; break; default: return -ENOPROTOOPT; } len = min_t(unsigned int, sizeof(int), len); if (put_user(len, optlen)) return -EFAULT; |
67ba4152e ipv6: White-space... |
1082 |
if (copy_to_user(optval, &val, len)) |
1da177e4c Linux-2.6.12-rc2 |
1083 1084 1085 |
return -EFAULT; return 0; } |
3fdadf7d2 [NET]: {get|set}s... |
1086 1087 1088 |
static int rawv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen) { |
207ec0abb ipv6: Reduce swit... |
1089 1090 1091 |
switch (level) { case SOL_RAW: break; |
3fdadf7d2 [NET]: {get|set}s... |
1092 |
|
207ec0abb ipv6: Reduce swit... |
1093 1094 1095 1096 1097 |
case SOL_ICMPV6: if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6) return -EOPNOTSUPP; return rawv6_geticmpfilter(sk, level, optname, optval, optlen); case SOL_IPV6: |
715f504b1 ipv6: add IPV6_HD... |
1098 1099 |
if (optname == IPV6_CHECKSUM || optname == IPV6_HDRINCL) |
207ec0abb ipv6: Reduce swit... |
1100 1101 1102 |
break; default: return ipv6_getsockopt(sk, level, optname, optval, optlen); |
3ff50b799 [NET]: cleanup ex... |
1103 |
} |
3fdadf7d2 [NET]: {get|set}s... |
1104 1105 1106 1107 1108 |
return do_rawv6_getsockopt(sk, level, optname, optval, optlen); } #ifdef CONFIG_COMPAT static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname, |
543d9cfee [NET]: Identation... |
1109 |
char __user *optval, int __user *optlen) |
3fdadf7d2 [NET]: {get|set}s... |
1110 |
{ |
543d9cfee [NET]: Identation... |
1111 1112 1113 1114 |
switch (level) { case SOL_RAW: break; case SOL_ICMPV6: |
c720c7e83 inet: rename some... |
1115 |
if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6) |
543d9cfee [NET]: Identation... |
1116 1117 1118 |
return -EOPNOTSUPP; return rawv6_geticmpfilter(sk, level, optname, optval, optlen); case SOL_IPV6: |
715f504b1 ipv6: add IPV6_HD... |
1119 1120 |
if (optname == IPV6_CHECKSUM || optname == IPV6_HDRINCL) |
3fdadf7d2 [NET]: {get|set}s... |
1121 |
break; |
543d9cfee [NET]: Identation... |
1122 1123 1124 |
default: return compat_ipv6_getsockopt(sk, level, optname, optval, optlen); |
3ff50b799 [NET]: cleanup ex... |
1125 |
} |
3fdadf7d2 [NET]: {get|set}s... |
1126 1127 1128 |
return do_rawv6_getsockopt(sk, level, optname, optval, optlen); } #endif |
1da177e4c Linux-2.6.12-rc2 |
1129 1130 |
static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) { |
207ec0abb ipv6: Reduce swit... |
1131 1132 1133 |
switch (cmd) { case SIOCOUTQ: { int amount = sk_wmem_alloc_get(sk); |
31e6d363a net: correct off-... |
1134 |
|
207ec0abb ipv6: Reduce swit... |
1135 1136 1137 1138 1139 1140 1141 1142 |
return put_user(amount, (int __user *)arg); } case SIOCINQ: { struct sk_buff *skb; int amount = 0; spin_lock_bh(&sk->sk_receive_queue.lock); skb = skb_peek(&sk->sk_receive_queue); |
53b24b8f9 ipv6: coding styl... |
1143 |
if (skb) |
105f5528b ipv6: check raw p... |
1144 |
amount = skb->len; |
207ec0abb ipv6: Reduce swit... |
1145 1146 1147 |
spin_unlock_bh(&sk->sk_receive_queue.lock); return put_user(amount, (int __user *)arg); } |
1da177e4c Linux-2.6.12-rc2 |
1148 |
|
207ec0abb ipv6: Reduce swit... |
1149 |
default: |
7bc570c8b [IPV6] MROUTE: Su... |
1150 |
#ifdef CONFIG_IPV6_MROUTE |
207ec0abb ipv6: Reduce swit... |
1151 |
return ip6mr_ioctl(sk, cmd, (void __user *)arg); |
7bc570c8b [IPV6] MROUTE: Su... |
1152 |
#else |
207ec0abb ipv6: Reduce swit... |
1153 |
return -ENOIOCTLCMD; |
7bc570c8b [IPV6] MROUTE: Su... |
1154 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1155 1156 |
} } |
e2d57766e net: Provide comp... |
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 |
#ifdef CONFIG_COMPAT static int compat_rawv6_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) { switch (cmd) { case SIOCOUTQ: case SIOCINQ: return -ENOIOCTLCMD; default: #ifdef CONFIG_IPV6_MROUTE return ip6mr_compat_ioctl(sk, cmd, compat_ptr(arg)); #else return -ENOIOCTLCMD; #endif } } #endif |
1da177e4c Linux-2.6.12-rc2 |
1173 1174 |
static void rawv6_close(struct sock *sk, long timeout) { |
c720c7e83 inet: rename some... |
1175 |
if (inet_sk(sk)->inet_num == IPPROTO_RAW) |
725a8ff04 ipv6: remove unus... |
1176 |
ip6_ra_control(sk, -1); |
7bc570c8b [IPV6] MROUTE: Su... |
1177 |
ip6mr_sk_done(sk); |
1da177e4c Linux-2.6.12-rc2 |
1178 1179 |
sk_common_release(sk); } |
7d06b2e05 net: change proto... |
1180 |
static void raw6_destroy(struct sock *sk) |
22dd48502 raw: Raw socket l... |
1181 1182 1183 1184 |
{ lock_sock(sk); ip6_flush_pending_frames(sk); release_sock(sk); |
f23d60de7 ipv6: Fix duplica... |
1185 |
|
7d06b2e05 net: change proto... |
1186 |
inet6_destroy_sock(sk); |
22dd48502 raw: Raw socket l... |
1187 |
} |
1da177e4c Linux-2.6.12-rc2 |
1188 1189 |
static int rawv6_init_sk(struct sock *sk) { |
f48d5ff1e [IPV6] RAW: Add c... |
1190 |
struct raw6_sock *rp = raw6_sk(sk); |
c720c7e83 inet: rename some... |
1191 |
switch (inet_sk(sk)->inet_num) { |
f48d5ff1e [IPV6] RAW: Add c... |
1192 |
case IPPROTO_ICMPV6: |
1da177e4c Linux-2.6.12-rc2 |
1193 1194 |
rp->checksum = 1; rp->offset = 2; |
f48d5ff1e [IPV6] RAW: Add c... |
1195 1196 1197 1198 1199 1200 1201 |
break; case IPPROTO_MH: rp->checksum = 1; rp->offset = 4; break; default: break; |
1da177e4c Linux-2.6.12-rc2 |
1202 |
} |
a02cec215 net: return opera... |
1203 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1204 1205 1206 |
} struct proto rawv6_prot = { |
543d9cfee [NET]: Identation... |
1207 1208 1209 |
.name = "RAWv6", .owner = THIS_MODULE, .close = rawv6_close, |
22dd48502 raw: Raw socket l... |
1210 |
.destroy = raw6_destroy, |
82b276cd2 ipv6: protect pro... |
1211 |
.connect = ip6_datagram_connect_v6_only, |
286c72dea udp: must lock th... |
1212 |
.disconnect = __udp_disconnect, |
543d9cfee [NET]: Identation... |
1213 1214 |
.ioctl = rawv6_ioctl, .init = rawv6_init_sk, |
543d9cfee [NET]: Identation... |
1215 1216 1217 1218 1219 1220 |
.setsockopt = rawv6_setsockopt, .getsockopt = rawv6_getsockopt, .sendmsg = rawv6_sendmsg, .recvmsg = rawv6_recvmsg, .bind = rawv6_bind, .backlog_rcv = rawv6_rcv_skb, |
fc8717baa [RAW]: Add raw_ha... |
1221 1222 |
.hash = raw_hash_sk, .unhash = raw_unhash_sk, |
543d9cfee [NET]: Identation... |
1223 |
.obj_size = sizeof(struct raw6_sock), |
fc8717baa [RAW]: Add raw_ha... |
1224 |
.h.raw_hash = &raw_v6_hashinfo, |
3fdadf7d2 [NET]: {get|set}s... |
1225 |
#ifdef CONFIG_COMPAT |
543d9cfee [NET]: Identation... |
1226 1227 |
.compat_setsockopt = compat_rawv6_setsockopt, .compat_getsockopt = compat_rawv6_getsockopt, |
e2d57766e net: Provide comp... |
1228 |
.compat_ioctl = compat_rawv6_ioctl, |
3fdadf7d2 [NET]: {get|set}s... |
1229 |
#endif |
432490f9d net: ip, diag -- ... |
1230 |
.diag_destroy = raw_abort, |
1da177e4c Linux-2.6.12-rc2 |
1231 1232 1233 |
}; #ifdef CONFIG_PROC_FS |
1da177e4c Linux-2.6.12-rc2 |
1234 1235 |
static int raw6_seq_show(struct seq_file *seq, void *v) { |
17ef66afc net: ipv6: Unify ... |
1236 1237 1238 1239 1240 1241 1242 1243 |
if (v == SEQ_START_TOKEN) { seq_puts(seq, IPV6_SEQ_DGRAM_HEADER); } else { struct sock *sp = v; __u16 srcp = inet_sk(sp)->inet_num; ip6_dgram_sock_seq_show(seq, v, srcp, 0, raw_seq_private(seq)->bucket); } |
1da177e4c Linux-2.6.12-rc2 |
1244 1245 |
return 0; } |
56b3d975b [NET]: Make all i... |
1246 |
static const struct seq_operations raw6_seq_ops = { |
42a73808e [RAW]: Consolidat... |
1247 1248 1249 |
.start = raw_seq_start, .next = raw_seq_next, .stop = raw_seq_stop, |
1da177e4c Linux-2.6.12-rc2 |
1250 1251 1252 1253 1254 |
.show = raw6_seq_show, }; static int raw6_seq_open(struct inode *inode, struct file *file) { |
3046d7674 [RAW]: Wrong cont... |
1255 |
return raw_seq_open(inode, file, &raw_v6_hashinfo, &raw6_seq_ops); |
1da177e4c Linux-2.6.12-rc2 |
1256 |
} |
9a32144e9 [PATCH] mark stru... |
1257 |
static const struct file_operations raw6_seq_fops = { |
1da177e4c Linux-2.6.12-rc2 |
1258 1259 1260 1261 |
.owner = THIS_MODULE, .open = raw6_seq_open, .read = seq_read, .llseek = seq_lseek, |
f51d599fb [NETNS][RAW]: Mak... |
1262 |
.release = seq_release_net, |
1da177e4c Linux-2.6.12-rc2 |
1263 |
}; |
2c8c1e729 net: spread __net... |
1264 |
static int __net_init raw6_init_net(struct net *net) |
1da177e4c Linux-2.6.12-rc2 |
1265 |
{ |
d4beaa66a net: proc: change... |
1266 |
if (!proc_create("raw6", S_IRUGO, net->proc_net, &raw6_seq_fops)) |
1da177e4c Linux-2.6.12-rc2 |
1267 |
return -ENOMEM; |
a308da162 [NETNS][RAW]: Cre... |
1268 |
|
1da177e4c Linux-2.6.12-rc2 |
1269 1270 |
return 0; } |
2c8c1e729 net: spread __net... |
1271 |
static void __net_exit raw6_exit_net(struct net *net) |
a308da162 [NETNS][RAW]: Cre... |
1272 |
{ |
ece31ffd5 net: proc: change... |
1273 |
remove_proc_entry("raw6", net->proc_net); |
a308da162 [NETNS][RAW]: Cre... |
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 |
} static struct pernet_operations raw6_net_ops = { .init = raw6_init_net, .exit = raw6_exit_net, }; int __init raw6_proc_init(void) { return register_pernet_subsys(&raw6_net_ops); } |
1da177e4c Linux-2.6.12-rc2 |
1285 1286 |
void raw6_proc_exit(void) { |
a308da162 [NETNS][RAW]: Cre... |
1287 |
unregister_pernet_subsys(&raw6_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
1288 1289 |
} #endif /* CONFIG_PROC_FS */ |
7f4e4868f [IPV6]: make the ... |
1290 1291 |
/* Same as inet6_dgram_ops, sans udp_poll. */ |
77d4b1d36 net: ping: do not... |
1292 |
const struct proto_ops inet6_sockraw_ops = { |
7f4e4868f [IPV6]: make the ... |
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 |
.family = PF_INET6, .owner = THIS_MODULE, .release = inet6_release, .bind = inet6_bind, .connect = inet_dgram_connect, /* ok */ .socketpair = sock_no_socketpair, /* a do nothing */ .accept = sock_no_accept, /* a do nothing */ .getname = inet6_getname, .poll = datagram_poll, /* ok */ .ioctl = inet6_ioctl, /* must change */ .listen = sock_no_listen, /* ok */ .shutdown = inet_shutdown, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */ .sendmsg = inet_sendmsg, /* ok */ .recvmsg = sock_common_recvmsg, /* ok */ .mmap = sock_no_mmap, .sendpage = sock_no_sendpage, #ifdef CONFIG_COMPAT .compat_setsockopt = compat_sock_common_setsockopt, .compat_getsockopt = compat_sock_common_getsockopt, #endif }; static struct inet_protosw rawv6_protosw = { .type = SOCK_RAW, .protocol = IPPROTO_IP, /* wild card */ .prot = &rawv6_prot, .ops = &inet6_sockraw_ops, |
7f4e4868f [IPV6]: make the ... |
1322 1323 1324 1325 1326 |
.flags = INET_PROTOSW_REUSE, }; int __init rawv6_init(void) { |
3d2f6d41d ipv6: drop unneed... |
1327 |
return inet6_register_protosw(&rawv6_protosw); |
7f4e4868f [IPV6]: make the ... |
1328 |
} |
09f7709f4 [IPV6]: fix secti... |
1329 |
void rawv6_exit(void) |
7f4e4868f [IPV6]: make the ... |
1330 1331 1332 |
{ inet6_unregister_protosw(&rawv6_protosw); } |