ipv6: datagram: Refactor dst lookup and update codes to a new function
[linux-block.git] / net / ipv6 / datagram.c
CommitLineData
1da177e4
LT
1/*
2 * common UDP/RAW code
1ab1457c 3 * Linux INET6 implementation
1da177e4
LT
4 *
5 * Authors:
1ab1457c 6 * Pedro Roque <roque@di.fc.ul.pt>
1da177e4 7 *
1da177e4
LT
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
4fc268d2 14#include <linux/capability.h>
1da177e4
LT
15#include <linux/errno.h>
16#include <linux/types.h>
17#include <linux/kernel.h>
1da177e4
LT
18#include <linux/interrupt.h>
19#include <linux/socket.h>
20#include <linux/sockios.h>
21#include <linux/in6.h>
22#include <linux/ipv6.h>
23#include <linux/route.h>
5a0e3ad6 24#include <linux/slab.h>
a495f836 25#include <linux/export.h>
1da177e4
LT
26
27#include <net/ipv6.h>
28#include <net/ndisc.h>
29#include <net/addrconf.h>
30#include <net/transp_v6.h>
31#include <net/ip6_route.h>
c752f073 32#include <net/tcp_states.h>
e7219858 33#include <net/dsfield.h>
1da177e4
LT
34
35#include <linux/errqueue.h>
36#include <asm/uaccess.h>
37
a50feda5 38static bool ipv6_mapped_addr_any(const struct in6_addr *a)
c15fea2d 39{
a50feda5 40 return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0);
c15fea2d
MM
41}
42
80fbdb20
MKL
43static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
44{
45 struct inet_sock *inet = inet_sk(sk);
46 struct ipv6_pinfo *np = inet6_sk(sk);
47
48 memset(fl6, 0, sizeof(*fl6));
49 fl6->flowi6_proto = sk->sk_protocol;
50 fl6->daddr = sk->sk_v6_daddr;
51 fl6->saddr = np->saddr;
52 fl6->flowi6_oif = sk->sk_bound_dev_if;
53 fl6->flowi6_mark = sk->sk_mark;
54 fl6->fl6_dport = inet->inet_dport;
55 fl6->fl6_sport = inet->inet_sport;
56 fl6->flowlabel = np->flow_label;
57
58 if (!fl6->flowi6_oif)
59 fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
60
61 if (!fl6->flowi6_oif && ipv6_addr_is_multicast(&fl6->daddr))
62 fl6->flowi6_oif = np->mcast_oif;
63
64 security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
65}
66
7e2040db
MKL
67static int ip6_datagram_dst_update(struct sock *sk)
68{
69 struct ip6_flowlabel *flowlabel = NULL;
70 struct in6_addr *final_p, final;
71 struct ipv6_txoptions *opt;
72 struct dst_entry *dst;
73 struct inet_sock *inet = inet_sk(sk);
74 struct ipv6_pinfo *np = inet6_sk(sk);
75 struct flowi6 fl6;
76 int err = 0;
77
78 if (np->sndflow && (np->flow_label & IPV6_FLOWLABEL_MASK)) {
79 flowlabel = fl6_sock_lookup(sk, np->flow_label);
80 if (!flowlabel)
81 return -EINVAL;
82 }
83 ip6_datagram_flow_key_init(&fl6, sk);
84
85 rcu_read_lock();
86 opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
87 final_p = fl6_update_dst(&fl6, opt, &final);
88 rcu_read_unlock();
89
90 dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
91 if (IS_ERR(dst)) {
92 err = PTR_ERR(dst);
93 goto out;
94 }
95
96 if (ipv6_addr_any(&np->saddr))
97 np->saddr = fl6.saddr;
98
99 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
100 sk->sk_v6_rcv_saddr = fl6.saddr;
101 inet->inet_rcv_saddr = LOOPBACK4_IPV6;
102 if (sk->sk_prot->rehash)
103 sk->sk_prot->rehash(sk);
104 }
105
106 ip6_dst_store(sk, dst,
107 ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
108 &sk->sk_v6_daddr : NULL,
109#ifdef CONFIG_IPV6_SUBTREES
110 ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
111 &np->saddr :
112#endif
113 NULL);
114
115out:
116 fl6_sock_release(flowlabel);
117 return err;
118}
119
03645a11 120static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
1da177e4
LT
121{
122 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
67ba4152
IM
123 struct inet_sock *inet = inet_sk(sk);
124 struct ipv6_pinfo *np = inet6_sk(sk);
7e2040db 125 struct in6_addr *daddr;
1da177e4
LT
126 int addr_type;
127 int err;
80fbdb20 128 __be32 fl6_flowlabel = 0;
1da177e4
LT
129
130 if (usin->sin6_family == AF_INET) {
131 if (__ipv6_only_sock(sk))
132 return -EAFNOSUPPORT;
03645a11 133 err = __ip4_datagram_connect(sk, uaddr, addr_len);
1da177e4
LT
134 goto ipv4_connected;
135 }
136
137 if (addr_len < SIN6_LEN_RFC2133)
1ab1457c 138 return -EINVAL;
1da177e4 139
1ab1457c
YH
140 if (usin->sin6_family != AF_INET6)
141 return -EAFNOSUPPORT;
1da177e4 142
7e2040db 143 if (np->sndflow)
80fbdb20 144 fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
1da177e4
LT
145
146 addr_type = ipv6_addr_type(&usin->sin6_addr);
147
148 if (addr_type == IPV6_ADDR_ANY) {
149 /*
150 * connect to self
151 */
152 usin->sin6_addr.s6_addr[15] = 0x01;
153 }
154
155 daddr = &usin->sin6_addr;
156
157 if (addr_type == IPV6_ADDR_MAPPED) {
158 struct sockaddr_in sin;
159
160 if (__ipv6_only_sock(sk)) {
161 err = -ENETUNREACH;
162 goto out;
163 }
164 sin.sin_family = AF_INET;
165 sin.sin_addr.s_addr = daddr->s6_addr32[3];
166 sin.sin_port = usin->sin6_port;
167
03645a11
ED
168 err = __ip4_datagram_connect(sk,
169 (struct sockaddr *) &sin,
170 sizeof(sin));
1da177e4
LT
171
172ipv4_connected:
173 if (err)
174 goto out;
1ab1457c 175
efe4208f 176 ipv6_addr_set_v4mapped(inet->inet_daddr, &sk->sk_v6_daddr);
1da177e4 177
c15fea2d
MM
178 if (ipv6_addr_any(&np->saddr) ||
179 ipv6_mapped_addr_any(&np->saddr))
c720c7e8 180 ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
b301e82c 181
efe4208f
ED
182 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr) ||
183 ipv6_mapped_addr_any(&sk->sk_v6_rcv_saddr)) {
c720c7e8 184 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
efe4208f 185 &sk->sk_v6_rcv_saddr);
719f8358
ED
186 if (sk->sk_prot->rehash)
187 sk->sk_prot->rehash(sk);
188 }
1da177e4 189
1da177e4
LT
190 goto out;
191 }
192
842df073 193 if (__ipv6_addr_needs_scope_id(addr_type)) {
1da177e4
LT
194 if (addr_len >= sizeof(struct sockaddr_in6) &&
195 usin->sin6_scope_id) {
196 if (sk->sk_bound_dev_if &&
197 sk->sk_bound_dev_if != usin->sin6_scope_id) {
198 err = -EINVAL;
199 goto out;
200 }
201 sk->sk_bound_dev_if = usin->sin6_scope_id;
1da177e4
LT
202 }
203
1ac4f008
BH
204 if (!sk->sk_bound_dev_if && (addr_type & IPV6_ADDR_MULTICAST))
205 sk->sk_bound_dev_if = np->mcast_oif;
206
1da177e4
LT
207 /* Connect to link-local address requires an interface */
208 if (!sk->sk_bound_dev_if) {
209 err = -EINVAL;
210 goto out;
211 }
212 }
213
efe4208f 214 sk->sk_v6_daddr = *daddr;
80fbdb20 215 np->flow_label = fl6_flowlabel;
1da177e4 216
c720c7e8 217 inet->inet_dport = usin->sin6_port;
1da177e4
LT
218
219 /*
220 * Check for a route to destination an obtain the
221 * destination cache for it.
222 */
223
7e2040db
MKL
224 err = ip6_datagram_dst_update(sk);
225 if (err)
1da177e4 226 goto out;
1da177e4
LT
227
228 sk->sk_state = TCP_ESTABLISHED;
877d1f62 229 sk_set_txhash(sk);
1da177e4 230out:
1da177e4
LT
231 return err;
232}
03645a11
ED
233
234int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
235{
236 int res;
237
238 lock_sock(sk);
239 res = __ip6_datagram_connect(sk, uaddr, addr_len);
240 release_sock(sk);
241 return res;
242}
a495f836 243EXPORT_SYMBOL_GPL(ip6_datagram_connect);
1da177e4 244
82b276cd
HFS
245int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *uaddr,
246 int addr_len)
247{
248 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, uaddr);
249 if (sin6->sin6_family != AF_INET6)
250 return -EAFNOSUPPORT;
251 return ip6_datagram_connect(sk, uaddr, addr_len);
252}
253EXPORT_SYMBOL_GPL(ip6_datagram_connect_v6_only);
254
1ab1457c 255void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
e69a4adc 256 __be16 port, u32 info, u8 *payload)
1da177e4
LT
257{
258 struct ipv6_pinfo *np = inet6_sk(sk);
cc70ab26 259 struct icmp6hdr *icmph = icmp6_hdr(skb);
1da177e4
LT
260 struct sock_exterr_skb *serr;
261
262 if (!np->recverr)
263 return;
264
265 skb = skb_clone(skb, GFP_ATOMIC);
266 if (!skb)
267 return;
268
d40a4de0
BH
269 skb->protocol = htons(ETH_P_IPV6);
270
1da177e4
LT
271 serr = SKB_EXT_ERR(skb);
272 serr->ee.ee_errno = err;
273 serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6;
1ab1457c 274 serr->ee.ee_type = icmph->icmp6_type;
1da177e4
LT
275 serr->ee.ee_code = icmph->icmp6_code;
276 serr->ee.ee_pad = 0;
277 serr->ee.ee_info = info;
278 serr->ee.ee_data = 0;
d56f90a7
ACM
279 serr->addr_offset = (u8 *)&(((struct ipv6hdr *)(icmph + 1))->daddr) -
280 skb_network_header(skb);
1da177e4
LT
281 serr->port = port;
282
1da177e4 283 __skb_pull(skb, payload - skb->data);
bd82393c 284 skb_reset_transport_header(skb);
1da177e4
LT
285
286 if (sock_queue_err_skb(sk, skb))
287 kfree_skb(skb);
288}
289
4c9483b2 290void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info)
1da177e4 291{
1c1e9d2b 292 const struct ipv6_pinfo *np = inet6_sk(sk);
1da177e4
LT
293 struct sock_exterr_skb *serr;
294 struct ipv6hdr *iph;
295 struct sk_buff *skb;
296
297 if (!np->recverr)
298 return;
299
300 skb = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
301 if (!skb)
302 return;
303
d40a4de0
BH
304 skb->protocol = htons(ETH_P_IPV6);
305
1ced98e8
ACM
306 skb_put(skb, sizeof(struct ipv6hdr));
307 skb_reset_network_header(skb);
0660e03f 308 iph = ipv6_hdr(skb);
4e3fd7a0 309 iph->daddr = fl6->daddr;
1da177e4
LT
310
311 serr = SKB_EXT_ERR(skb);
312 serr->ee.ee_errno = err;
313 serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
1ab1457c 314 serr->ee.ee_type = 0;
1da177e4
LT
315 serr->ee.ee_code = 0;
316 serr->ee.ee_pad = 0;
317 serr->ee.ee_info = info;
318 serr->ee.ee_data = 0;
d56f90a7 319 serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
1958b856 320 serr->port = fl6->fl6_dport;
1da177e4 321
27a884dc 322 __skb_pull(skb, skb_tail_pointer(skb) - skb->data);
bd82393c 323 skb_reset_transport_header(skb);
1da177e4
LT
324
325 if (sock_queue_err_skb(sk, skb))
326 kfree_skb(skb);
327}
328
4c9483b2 329void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
4b340ae2
BH
330{
331 struct ipv6_pinfo *np = inet6_sk(sk);
332 struct ipv6hdr *iph;
333 struct sk_buff *skb;
334 struct ip6_mtuinfo *mtu_info;
335
336 if (!np->rxopt.bits.rxpmtu)
337 return;
338
339 skb = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
340 if (!skb)
341 return;
342
343 skb_put(skb, sizeof(struct ipv6hdr));
344 skb_reset_network_header(skb);
345 iph = ipv6_hdr(skb);
4e3fd7a0 346 iph->daddr = fl6->daddr;
4b340ae2
BH
347
348 mtu_info = IP6CBMTU(skb);
4b340ae2
BH
349
350 mtu_info->ip6m_mtu = mtu;
351 mtu_info->ip6m_addr.sin6_family = AF_INET6;
352 mtu_info->ip6m_addr.sin6_port = 0;
353 mtu_info->ip6m_addr.sin6_flowinfo = 0;
4c9483b2 354 mtu_info->ip6m_addr.sin6_scope_id = fl6->flowi6_oif;
4e3fd7a0 355 mtu_info->ip6m_addr.sin6_addr = ipv6_hdr(skb)->daddr;
4b340ae2
BH
356
357 __skb_pull(skb, skb_tail_pointer(skb) - skb->data);
358 skb_reset_transport_header(skb);
359
360 skb = xchg(&np->rxpmtu, skb);
361 kfree_skb(skb);
362}
363
34b99df4
JA
364/* For some errors we have valid addr_offset even with zero payload and
365 * zero port. Also, addr_offset should be supported if port is set.
366 */
367static inline bool ipv6_datagram_support_addr(struct sock_exterr_skb *serr)
368{
369 return serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6 ||
370 serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
371 serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL || serr->port;
372}
373
c247f053
WB
374/* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL.
375 *
376 * At one point, excluding local errors was a quick test to identify icmp/icmp6
377 * errors. This is no longer true, but the test remained, so the v6 stack,
378 * unlike v4, also honors cmsg requests on all wifi and timestamp errors.
379 *
380 * Timestamp code paths do not initialize the fields expected by cmsg:
381 * the PKTINFO fields in skb->cb[]. Fill those in here.
382 */
383static bool ip6_datagram_support_cmsg(struct sk_buff *skb,
384 struct sock_exterr_skb *serr)
829ae9d6 385{
c247f053
WB
386 if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
387 serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6)
388 return true;
389
390 if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL)
391 return false;
392
393 if (!skb->dev)
394 return false;
829ae9d6
WB
395
396 if (skb->protocol == htons(ETH_P_IPV6))
c247f053 397 IP6CB(skb)->iif = skb->dev->ifindex;
829ae9d6 398 else
c247f053
WB
399 PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex;
400
401 return true;
829ae9d6
WB
402}
403
1ab1457c 404/*
1da177e4
LT
405 * Handle MSG_ERRQUEUE
406 */
85fbaa75 407int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
1da177e4
LT
408{
409 struct ipv6_pinfo *np = inet6_sk(sk);
410 struct sock_exterr_skb *serr;
364a9e93 411 struct sk_buff *skb;
342dfc30 412 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name);
1da177e4
LT
413 struct {
414 struct sock_extended_err ee;
415 struct sockaddr_in6 offender;
416 } errhdr;
417 int err;
418 int copied;
419
420 err = -EAGAIN;
364a9e93 421 skb = sock_dequeue_err_skb(sk);
63159f29 422 if (!skb)
1da177e4
LT
423 goto out;
424
425 copied = skb->len;
426 if (copied > len) {
427 msg->msg_flags |= MSG_TRUNC;
428 copied = len;
429 }
51f3d02b 430 err = skb_copy_datagram_msg(skb, 0, msg, copied);
1da177e4
LT
431 if (err)
432 goto out_free_skb;
433
434 sock_recv_timestamp(msg, sk, skb);
435
436 serr = SKB_EXT_ERR(skb);
437
34b99df4 438 if (sin && ipv6_datagram_support_addr(serr)) {
d56f90a7 439 const unsigned char *nh = skb_network_header(skb);
1da177e4
LT
440 sin->sin6_family = AF_INET6;
441 sin->sin6_flowinfo = 0;
1ab1457c 442 sin->sin6_port = serr->port;
d40a4de0 443 if (skb->protocol == htons(ETH_P_IPV6)) {
6c40d100
YH
444 const struct ipv6hdr *ip6h = container_of((struct in6_addr *)(nh + serr->addr_offset),
445 struct ipv6hdr, daddr);
446 sin->sin6_addr = ip6h->daddr;
1da177e4 447 if (np->sndflow)
6502ca52 448 sin->sin6_flowinfo = ip6_flowinfo(ip6h);
842df073
HFS
449 sin->sin6_scope_id =
450 ipv6_iface_scope_id(&sin->sin6_addr,
451 IP6CB(skb)->iif);
1da177e4 452 } else {
b301e82c
BH
453 ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
454 &sin->sin6_addr);
842df073 455 sin->sin6_scope_id = 0;
1da177e4 456 }
85fbaa75 457 *addr_len = sizeof(*sin);
1da177e4
LT
458 }
459
460 memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
461 sin = &errhdr.offender;
f812116b 462 memset(sin, 0, sizeof(*sin));
c247f053
WB
463
464 if (ip6_datagram_support_cmsg(skb, serr)) {
1da177e4 465 sin->sin6_family = AF_INET6;
c247f053 466 if (np->rxopt.all)
4b261c75 467 ip6_datagram_recv_common_ctl(sk, msg, skb);
d40a4de0 468 if (skb->protocol == htons(ETH_P_IPV6)) {
4e3fd7a0 469 sin->sin6_addr = ipv6_hdr(skb)->saddr;
1da177e4 470 if (np->rxopt.all)
4b261c75 471 ip6_datagram_recv_specific_ctl(sk, msg, skb);
842df073
HFS
472 sin->sin6_scope_id =
473 ipv6_iface_scope_id(&sin->sin6_addr,
474 IP6CB(skb)->iif);
1da177e4 475 } else {
b301e82c
BH
476 ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
477 &sin->sin6_addr);
f812116b 478 if (inet_sk(sk)->cmsg_flags)
1da177e4
LT
479 ip_cmsg_recv(msg, skb);
480 }
481 }
482
483 put_cmsg(msg, SOL_IPV6, IPV6_RECVERR, sizeof(errhdr), &errhdr);
484
485 /* Now we could try to dump offended packet options */
486
487 msg->msg_flags |= MSG_ERRQUEUE;
488 err = copied;
489
1ab1457c 490out_free_skb:
1da177e4
LT
491 kfree_skb(skb);
492out:
493 return err;
494}
a495f836 495EXPORT_SYMBOL_GPL(ipv6_recv_error);
1da177e4 496
4b340ae2
BH
497/*
498 * Handle IPV6_RECVPATHMTU
499 */
85fbaa75
HFS
500int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
501 int *addr_len)
4b340ae2
BH
502{
503 struct ipv6_pinfo *np = inet6_sk(sk);
504 struct sk_buff *skb;
4b340ae2 505 struct ip6_mtuinfo mtu_info;
342dfc30 506 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name);
4b340ae2
BH
507 int err;
508 int copied;
509
510 err = -EAGAIN;
511 skb = xchg(&np->rxpmtu, NULL);
63159f29 512 if (!skb)
4b340ae2
BH
513 goto out;
514
515 copied = skb->len;
516 if (copied > len) {
517 msg->msg_flags |= MSG_TRUNC;
518 copied = len;
519 }
51f3d02b 520 err = skb_copy_datagram_msg(skb, 0, msg, copied);
4b340ae2
BH
521 if (err)
522 goto out_free_skb;
523
524 sock_recv_timestamp(msg, sk, skb);
525
526 memcpy(&mtu_info, IP6CBMTU(skb), sizeof(mtu_info));
527
4b340ae2
BH
528 if (sin) {
529 sin->sin6_family = AF_INET6;
530 sin->sin6_flowinfo = 0;
531 sin->sin6_port = 0;
532 sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
4e3fd7a0 533 sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
85fbaa75 534 *addr_len = sizeof(*sin);
4b340ae2
BH
535 }
536
537 put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
538
539 err = copied;
540
541out_free_skb:
542 kfree_skb(skb);
543out:
544 return err;
545}
1da177e4
LT
546
547
4b261c75
HFS
548void ip6_datagram_recv_common_ctl(struct sock *sk, struct msghdr *msg,
549 struct sk_buff *skb)
1da177e4
LT
550{
551 struct ipv6_pinfo *np = inet6_sk(sk);
4b261c75 552 bool is_ipv6 = skb->protocol == htons(ETH_P_IPV6);
1da177e4
LT
553
554 if (np->rxopt.bits.rxinfo) {
555 struct in6_pktinfo src_info;
556
4b261c75
HFS
557 if (is_ipv6) {
558 src_info.ipi6_ifindex = IP6CB(skb)->iif;
559 src_info.ipi6_addr = ipv6_hdr(skb)->daddr;
560 } else {
561 src_info.ipi6_ifindex =
562 PKTINFO_SKB_CB(skb)->ipi_ifindex;
563 ipv6_addr_set_v4mapped(ip_hdr(skb)->daddr,
564 &src_info.ipi6_addr);
565 }
829ae9d6
WB
566
567 if (src_info.ipi6_ifindex >= 0)
568 put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO,
569 sizeof(src_info), &src_info);
1da177e4 570 }
4b261c75
HFS
571}
572
573void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
574 struct sk_buff *skb)
575{
576 struct ipv6_pinfo *np = inet6_sk(sk);
577 struct inet6_skb_parm *opt = IP6CB(skb);
578 unsigned char *nh = skb_network_header(skb);
1da177e4
LT
579
580 if (np->rxopt.bits.rxhlim) {
0660e03f 581 int hlim = ipv6_hdr(skb)->hop_limit;
1da177e4
LT
582 put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
583 }
584
41a1f8ea 585 if (np->rxopt.bits.rxtclass) {
e7219858 586 int tclass = ipv6_get_dsfield(ipv6_hdr(skb));
41a1f8ea
YH
587 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
588 }
589
6502ca52
YH
590 if (np->rxopt.bits.rxflow) {
591 __be32 flowinfo = ip6_flowinfo((struct ipv6hdr *)nh);
592 if (flowinfo)
593 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
1da177e4 594 }
333fad53
YH
595
596 /* HbH is allowed only once */
8b58a398
FW
597 if (np->rxopt.bits.hopopts && (opt->flags & IP6SKB_HOPBYHOP)) {
598 u8 *ptr = nh + sizeof(struct ipv6hdr);
1da177e4
LT
599 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
600 }
333fad53
YH
601
602 if (opt->lastopt &&
603 (np->rxopt.bits.dstopts || np->rxopt.bits.srcrt)) {
604 /*
605 * Silly enough, but we need to reparse in order to
606 * report extension headers (except for HbH)
607 * in order.
608 *
1ab1457c 609 * Also note that IPV6_RECVRTHDRDSTOPTS is NOT
333fad53
YH
610 * (and WILL NOT be) defined because
611 * IPV6_RECVDSTOPTS is more generic. --yoshfuji
612 */
613 unsigned int off = sizeof(struct ipv6hdr);
0660e03f 614 u8 nexthdr = ipv6_hdr(skb)->nexthdr;
333fad53
YH
615
616 while (off <= opt->lastopt) {
95c96174 617 unsigned int len;
d56f90a7 618 u8 *ptr = nh + off;
333fad53 619
b5a4257c 620 switch (nexthdr) {
333fad53
YH
621 case IPPROTO_DSTOPTS:
622 nexthdr = ptr[0];
623 len = (ptr[1] + 1) << 3;
624 if (np->rxopt.bits.dstopts)
625 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
626 break;
627 case IPPROTO_ROUTING:
628 nexthdr = ptr[0];
629 len = (ptr[1] + 1) << 3;
630 if (np->rxopt.bits.srcrt)
631 put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
632 break;
633 case IPPROTO_AH:
634 nexthdr = ptr[0];
a3059893 635 len = (ptr[1] + 2) << 2;
333fad53
YH
636 break;
637 default:
638 nexthdr = ptr[0];
639 len = (ptr[1] + 1) << 3;
640 break;
641 }
642
643 off += len;
644 }
645 }
646
647 /* socket options in old style */
648 if (np->rxopt.bits.rxoinfo) {
649 struct in6_pktinfo src_info;
650
651 src_info.ipi6_ifindex = opt->iif;
4e3fd7a0 652 src_info.ipi6_addr = ipv6_hdr(skb)->daddr;
333fad53
YH
653 put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
654 }
655 if (np->rxopt.bits.rxohlim) {
0660e03f 656 int hlim = ipv6_hdr(skb)->hop_limit;
333fad53
YH
657 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
658 }
8b58a398
FW
659 if (np->rxopt.bits.ohopopts && (opt->flags & IP6SKB_HOPBYHOP)) {
660 u8 *ptr = nh + sizeof(struct ipv6hdr);
333fad53
YH
661 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
662 }
663 if (np->rxopt.bits.odstopts && opt->dst0) {
d56f90a7 664 u8 *ptr = nh + opt->dst0;
333fad53 665 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
1da177e4 666 }
333fad53 667 if (np->rxopt.bits.osrcrt && opt->srcrt) {
d56f90a7 668 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(nh + opt->srcrt);
333fad53 669 put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
1da177e4 670 }
333fad53 671 if (np->rxopt.bits.odstopts && opt->dst1) {
d56f90a7 672 u8 *ptr = nh + opt->dst1;
333fad53 673 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
1da177e4 674 }
6c468622
BS
675 if (np->rxopt.bits.rxorigdstaddr) {
676 struct sockaddr_in6 sin6;
747465ef 677 __be16 *ports = (__be16 *) skb_transport_header(skb);
6c468622
BS
678
679 if (skb_transport_offset(skb) + 4 <= skb->len) {
680 /* All current transport protocols have the port numbers in the
681 * first four bytes of the transport header and this function is
682 * written with this assumption in mind.
683 */
684
685 sin6.sin6_family = AF_INET6;
4e3fd7a0 686 sin6.sin6_addr = ipv6_hdr(skb)->daddr;
6c468622
BS
687 sin6.sin6_port = ports[1];
688 sin6.sin6_flowinfo = 0;
3868b7aa
HFS
689 sin6.sin6_scope_id =
690 ipv6_iface_scope_id(&ipv6_hdr(skb)->daddr,
691 opt->iif);
6c468622
BS
692
693 put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
694 }
695 }
4b261c75
HFS
696}
697
698void ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
699 struct sk_buff *skb)
700{
701 ip6_datagram_recv_common_ctl(sk, msg, skb);
702 ip6_datagram_recv_specific_ctl(sk, msg, skb);
1da177e4 703}
8e72d37e 704EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
1da177e4 705
73df66f8
TP
706int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
707 struct msghdr *msg, struct flowi6 *fl6,
708 struct ipv6_txoptions *opt,
709 int *hlimit, int *tclass, int *dontfrag)
1da177e4
LT
710{
711 struct in6_pktinfo *src_info;
712 struct cmsghdr *cmsg;
713 struct ipv6_rt_hdr *rthdr;
714 struct ipv6_opt_hdr *hdr;
715 int len;
716 int err = 0;
717
f95b414e 718 for_each_cmsghdr(cmsg, msg) {
1da177e4 719 int addr_type;
1da177e4
LT
720
721 if (!CMSG_OK(msg, cmsg)) {
722 err = -EINVAL;
723 goto exit_f;
724 }
725
726 if (cmsg->cmsg_level != SOL_IPV6)
727 continue;
728
729 switch (cmsg->cmsg_type) {
1ab1457c
YH
730 case IPV6_PKTINFO:
731 case IPV6_2292PKTINFO:
187e3838
YH
732 {
733 struct net_device *dev = NULL;
734
1ab1457c 735 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
1da177e4
LT
736 err = -EINVAL;
737 goto exit_f;
738 }
739
740 src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1ab1457c 741
1da177e4 742 if (src_info->ipi6_ifindex) {
4c9483b2
DM
743 if (fl6->flowi6_oif &&
744 src_info->ipi6_ifindex != fl6->flowi6_oif)
1da177e4 745 return -EINVAL;
4c9483b2 746 fl6->flowi6_oif = src_info->ipi6_ifindex;
1da177e4
LT
747 }
748
187e3838 749 addr_type = __ipv6_addr_type(&src_info->ipi6_addr);
1da177e4 750
536b2e92 751 rcu_read_lock();
4c9483b2
DM
752 if (fl6->flowi6_oif) {
753 dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
536b2e92
ED
754 if (!dev) {
755 rcu_read_unlock();
187e3838 756 return -ENODEV;
536b2e92
ED
757 }
758 } else if (addr_type & IPV6_ADDR_LINKLOCAL) {
759 rcu_read_unlock();
187e3838 760 return -EINVAL;
536b2e92 761 }
1ab1457c 762
187e3838
YH
763 if (addr_type != IPV6_ADDR_ANY) {
764 int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL;
2563fa59 765 if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) &&
ec0506db 766 !ipv6_chk_addr(net, &src_info->ipi6_addr,
7c90cc2d
FLB
767 strict ? dev : NULL, 0) &&
768 !ipv6_chk_acast_addr_src(net, dev,
769 &src_info->ipi6_addr))
187e3838
YH
770 err = -EINVAL;
771 else
4e3fd7a0 772 fl6->saddr = src_info->ipi6_addr;
1da177e4 773 }
187e3838 774
536b2e92 775 rcu_read_unlock();
1da177e4 776
187e3838
YH
777 if (err)
778 goto exit_f;
779
1da177e4 780 break;
187e3838 781 }
1da177e4
LT
782
783 case IPV6_FLOWINFO:
1ab1457c 784 if (cmsg->cmsg_len < CMSG_LEN(4)) {
1da177e4
LT
785 err = -EINVAL;
786 goto exit_f;
787 }
788
4c9483b2
DM
789 if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
790 if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
1da177e4
LT
791 err = -EINVAL;
792 goto exit_f;
793 }
794 }
4c9483b2 795 fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
1da177e4
LT
796 break;
797
333fad53 798 case IPV6_2292HOPOPTS:
1da177e4 799 case IPV6_HOPOPTS:
1ab1457c 800 if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
1da177e4
LT
801 err = -EINVAL;
802 goto exit_f;
803 }
804
805 hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
806 len = ((hdr->hdrlen + 1) << 3);
807 if (cmsg->cmsg_len < CMSG_LEN(len)) {
808 err = -EINVAL;
809 goto exit_f;
810 }
af31f412 811 if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
1da177e4
LT
812 err = -EPERM;
813 goto exit_f;
814 }
815 opt->opt_nflen += len;
816 opt->hopopt = hdr;
817 break;
818
333fad53 819 case IPV6_2292DSTOPTS:
1ab1457c 820 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
1da177e4
LT
821 err = -EINVAL;
822 goto exit_f;
823 }
824
825 hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
826 len = ((hdr->hdrlen + 1) << 3);
827 if (cmsg->cmsg_len < CMSG_LEN(len)) {
828 err = -EINVAL;
829 goto exit_f;
830 }
af31f412 831 if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
1da177e4
LT
832 err = -EPERM;
833 goto exit_f;
834 }
835 if (opt->dst1opt) {
836 err = -EINVAL;
837 goto exit_f;
838 }
839 opt->opt_flen += len;
840 opt->dst1opt = hdr;
841 break;
842
333fad53
YH
843 case IPV6_DSTOPTS:
844 case IPV6_RTHDRDSTOPTS:
845 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
846 err = -EINVAL;
847 goto exit_f;
848 }
849
850 hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
851 len = ((hdr->hdrlen + 1) << 3);
852 if (cmsg->cmsg_len < CMSG_LEN(len)) {
853 err = -EINVAL;
854 goto exit_f;
855 }
af31f412 856 if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
333fad53
YH
857 err = -EPERM;
858 goto exit_f;
859 }
860 if (cmsg->cmsg_type == IPV6_DSTOPTS) {
861 opt->opt_flen += len;
862 opt->dst1opt = hdr;
863 } else {
864 opt->opt_nflen += len;
865 opt->dst0opt = hdr;
866 }
867 break;
868
869 case IPV6_2292RTHDR:
1da177e4 870 case IPV6_RTHDR:
1ab1457c 871 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
1da177e4
LT
872 err = -EINVAL;
873 goto exit_f;
874 }
875
876 rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
877
280a9d34 878 switch (rthdr->type) {
07a93626 879#if IS_ENABLED(CONFIG_IPV6_MIP6)
280a9d34 880 case IPV6_SRCRT_TYPE_2:
6e093d9d
BH
881 if (rthdr->hdrlen != 2 ||
882 rthdr->segments_left != 1) {
883 err = -EINVAL;
884 goto exit_f;
885 }
280a9d34 886 break;
bb4dbf9e 887#endif
280a9d34 888 default:
1da177e4
LT
889 err = -EINVAL;
890 goto exit_f;
891 }
892
893 len = ((rthdr->hdrlen + 1) << 3);
894
1ab1457c 895 if (cmsg->cmsg_len < CMSG_LEN(len)) {
1da177e4
LT
896 err = -EINVAL;
897 goto exit_f;
898 }
899
900 /* segments left must also match */
901 if ((rthdr->hdrlen >> 1) != rthdr->segments_left) {
902 err = -EINVAL;
903 goto exit_f;
904 }
905
906 opt->opt_nflen += len;
907 opt->srcrt = rthdr;
908
333fad53 909 if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {
1da177e4
LT
910 int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);
911
912 opt->opt_nflen += dsthdrlen;
913 opt->dst0opt = opt->dst1opt;
914 opt->dst1opt = NULL;
915 opt->opt_flen -= dsthdrlen;
916 }
917
918 break;
919
333fad53 920 case IPV6_2292HOPLIMIT:
1da177e4
LT
921 case IPV6_HOPLIMIT:
922 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
923 err = -EINVAL;
924 goto exit_f;
925 }
926
927 *hlimit = *(int *)CMSG_DATA(cmsg);
e8766fc8
SW
928 if (*hlimit < -1 || *hlimit > 0xff) {
929 err = -EINVAL;
930 goto exit_f;
931 }
932
1da177e4
LT
933 break;
934
41a1f8ea
YH
935 case IPV6_TCLASS:
936 {
937 int tc;
938
939 err = -EINVAL;
b5a4257c 940 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
41a1f8ea 941 goto exit_f;
41a1f8ea
YH
942
943 tc = *(int *)CMSG_DATA(cmsg);
d0ee011f 944 if (tc < -1 || tc > 0xff)
41a1f8ea
YH
945 goto exit_f;
946
947 err = 0;
948 *tclass = tc;
949
13b52cd4
BH
950 break;
951 }
952
953 case IPV6_DONTFRAG:
954 {
955 int df;
956
957 err = -EINVAL;
b5a4257c 958 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
13b52cd4 959 goto exit_f;
13b52cd4
BH
960
961 df = *(int *)CMSG_DATA(cmsg);
962 if (df < 0 || df > 1)
963 goto exit_f;
964
965 err = 0;
966 *dontfrag = df;
967
41a1f8ea
YH
968 break;
969 }
1da177e4 970 default:
ba7a46f1
JP
971 net_dbg_ratelimited("invalid cmsg type: %d\n",
972 cmsg->cmsg_type);
1da177e4 973 err = -EINVAL;
4a36702e 974 goto exit_f;
3ff50b79 975 }
1da177e4
LT
976 }
977
978exit_f:
979 return err;
980}
73df66f8 981EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl);
17ef66af
LC
982
983void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
984 __u16 srcp, __u16 destp, int bucket)
985{
17ef66af
LC
986 const struct in6_addr *dest, *src;
987
efe4208f
ED
988 dest = &sp->sk_v6_daddr;
989 src = &sp->sk_v6_rcv_saddr;
17ef66af
LC
990 seq_printf(seq,
991 "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
d14c5ab6 992 "%02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d\n",
17ef66af
LC
993 bucket,
994 src->s6_addr32[0], src->s6_addr32[1],
995 src->s6_addr32[2], src->s6_addr32[3], srcp,
996 dest->s6_addr32[0], dest->s6_addr32[1],
997 dest->s6_addr32[2], dest->s6_addr32[3], destp,
998 sp->sk_state,
999 sk_wmem_alloc_get(sp),
1000 sk_rmem_alloc_get(sp),
1001 0, 0L, 0,
1002 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1003 0,
1004 sock_i_ino(sp),
1005 atomic_read(&sp->sk_refcnt), sp,
1006 atomic_read(&sp->sk_drops));
1007}