udp.c 36.8 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
/*
 *	UDP over IPv6
3
 *	Linux INET6 implementation
Linus Torvalds's avatar
Linus Torvalds committed
4
5
 *
 *	Authors:
6
 *	Pedro Roque		<roque@di.fc.ul.pt>
Linus Torvalds's avatar
Linus Torvalds committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 *	Based on linux/ipv4/udp.c
 *
 *	Fixes:
 *	Hideaki YOSHIFUJI	:	sin6_scope_id support
 *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
 *	Alexey Kuznetsov		allow both IPv4 and IPv6 sockets to bind
 *					a single port at the same time.
 *      Kazunori MIYAZAWA @USAGI:       change process style to use ip6_append_data
 *      YOSHIFUJI Hideaki @USAGI:	convert /proc/net/udp6 to seq_file.
 *
 *	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>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/in6.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/init.h>
35
#include <linux/module.h>
36
#include <linux/skbuff.h>
37
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
38
39
40
41
42
43
44
#include <asm/uaccess.h>

#include <net/ndisc.h>
#include <net/protocol.h>
#include <net/transp_v6.h>
#include <net/ip6_route.h>
#include <net/raw.h>
45
#include <net/tcp_states.h>
Linus Torvalds's avatar
Linus Torvalds committed
46
47
#include <net/ip6_checksum.h>
#include <net/xfrm.h>
48
#include <net/inet6_hashtables.h>
49
#include <net/busy_poll.h>
Linus Torvalds's avatar
Linus Torvalds committed
50
51
52

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
53
#include <trace/events/skb.h>
54
#include "udp_impl.h"
Linus Torvalds's avatar
Linus Torvalds committed
55

56
57
58
59
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
{
	const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
	const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
60
61
	__be32 sk1_rcv_saddr = sk_rcv_saddr(sk);
	__be32 sk2_rcv_saddr = sk_rcv_saddr(sk2);
62
63
64
65
66
67
68
	int sk_ipv6only = ipv6_only_sock(sk);
	int sk2_ipv6only = inet_v6_ipv6only(sk2);
	int addr_type = ipv6_addr_type(sk_rcv_saddr6);
	int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;

	/* if both are mapped, treat as IPv4 */
	if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
69
		return (!sk2_ipv6only &&
70
71
			(!sk1_rcv_saddr || !sk2_rcv_saddr ||
			  sk1_rcv_saddr == sk2_rcv_saddr));
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

	if (addr_type2 == IPV6_ADDR_ANY &&
	    !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
		return 1;

	if (addr_type == IPV6_ADDR_ANY &&
	    !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED))
		return 1;

	if (sk2_rcv_saddr6 &&
	    ipv6_addr_equal(sk_rcv_saddr6, sk2_rcv_saddr6))
		return 1;

	return 0;
}

88
89
90
91
92
93
94
95
static unsigned int udp6_portaddr_hash(struct net *net,
				       const struct in6_addr *addr6,
				       unsigned int port)
{
	unsigned int hash, mix = net_hash_mix(net);

	if (ipv6_addr_any(addr6))
		hash = jhash_1word(0, mix);
Brian Haley's avatar
Brian Haley committed
96
	else if (ipv6_addr_v4mapped(addr6))
97
		hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix);
98
	else
99
		hash = jhash2((__force u32 *)addr6->s6_addr32, 4, mix);
100
101
102
103
104

	return hash ^ port;
}


105
int udp_v6_get_port(struct sock *sk, unsigned short snum)
Linus Torvalds's avatar
Linus Torvalds committed
106
{
Eric Dumazet's avatar
Eric Dumazet committed
107
108
	unsigned int hash2_nulladdr =
		udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum);
109
	unsigned int hash2_partial =
Eric Dumazet's avatar
Eric Dumazet committed
110
111
		udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0);

112
	/* precompute partial secondary hash */
Eric Dumazet's avatar
Eric Dumazet committed
113
114
	udp_sk(sk)->udp_portaddr_hash = hash2_partial;
	return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr);
Linus Torvalds's avatar
Linus Torvalds committed
115
116
}

Eric Dumazet's avatar
Eric Dumazet committed
117
118
119
120
121
122
123
124
125
static void udp_v6_rehash(struct sock *sk)
{
	u16 new_hash = udp6_portaddr_hash(sock_net(sk),
					  &inet6_sk(sk)->rcv_saddr,
					  inet_sk(sk)->inet_num);

	udp_lib_rehash(sk, new_hash);
}

126
127
static inline int compute_score(struct sock *sk, struct net *net,
				unsigned short hnum,
128
129
				const struct in6_addr *saddr, __be16 sport,
				const struct in6_addr *daddr, __be16 dport,
130
131
132
133
				int dif)
{
	int score = -1;

134
	if (net_eq(sock_net(sk), net) && udp_sk(sk)->udp_port_hash == hnum &&
135
136
137
138
139
			sk->sk_family == PF_INET6) {
		struct ipv6_pinfo *np = inet6_sk(sk);
		struct inet_sock *inet = inet_sk(sk);

		score = 0;
140
141
		if (inet->inet_dport) {
			if (inet->inet_dport != sport)
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
				return -1;
			score++;
		}
		if (!ipv6_addr_any(&np->rcv_saddr)) {
			if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
				return -1;
			score++;
		}
		if (!ipv6_addr_any(&np->daddr)) {
			if (!ipv6_addr_equal(&np->daddr, saddr))
				return -1;
			score++;
		}
		if (sk->sk_bound_dev_if) {
			if (sk->sk_bound_dev_if != dif)
				return -1;
			score++;
		}
	}
	return score;
}

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#define SCORE2_MAX (1 + 1 + 1)
static inline int compute_score2(struct sock *sk, struct net *net,
				const struct in6_addr *saddr, __be16 sport,
				const struct in6_addr *daddr, unsigned short hnum,
				int dif)
{
	int score = -1;

	if (net_eq(sock_net(sk), net) && udp_sk(sk)->udp_port_hash == hnum &&
			sk->sk_family == PF_INET6) {
		struct ipv6_pinfo *np = inet6_sk(sk);
		struct inet_sock *inet = inet_sk(sk);

		if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
			return -1;
		score = 0;
		if (inet->inet_dport) {
			if (inet->inet_dport != sport)
				return -1;
			score++;
		}
		if (!ipv6_addr_any(&np->daddr)) {
			if (!ipv6_addr_equal(&np->daddr, saddr))
				return -1;
			score++;
		}
		if (sk->sk_bound_dev_if) {
			if (sk->sk_bound_dev_if != dif)
				return -1;
			score++;
		}
	}
	return score;
}


/* called with read_rcu_lock() */
static struct sock *udp6_lib_lookup2(struct net *net,
		const struct in6_addr *saddr, __be16 sport,
		const struct in6_addr *daddr, unsigned int hnum, int dif,
		struct udp_hslot *hslot2, unsigned int slot2)
{
	struct sock *sk, *result;
	struct hlist_nulls_node *node;
208
209
	int score, badness, matches = 0, reuseport = 0;
	u32 hash = 0;
210
211
212
213
214
215
216
217
218
219

begin:
	result = NULL;
	badness = -1;
	udp_portaddr_for_each_entry_rcu(sk, node, &hslot2->head) {
		score = compute_score2(sk, net, saddr, sport,
				      daddr, hnum, dif);
		if (score > badness) {
			result = sk;
			badness = score;
220
221
222
223
224
225
			reuseport = sk->sk_reuseport;
			if (reuseport) {
				hash = inet6_ehashfn(net, daddr, hnum,
						     saddr, sport);
				matches = 1;
			} else if (score == SCORE2_MAX)
226
				goto exact_match;
227
228
229
230
231
		} else if (score == badness && reuseport) {
			matches++;
			if (((u64)hash * matches) >> 32 == 0)
				result = sk;
			hash = next_pseudo_random32(hash);
232
233
234
235
236
237
238
239
240
241
242
243
		}
	}
	/*
	 * if the nulls value we got at the end of this lookup is
	 * not the expected one, we must restart lookup.
	 * We probably met an item that was moved to another chain.
	 */
	if (get_nulls_value(node) != slot2)
		goto begin;

	if (result) {
exact_match:
244
		if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
245
246
247
248
249
250
251
252
253
254
			result = NULL;
		else if (unlikely(compute_score2(result, net, saddr, sport,
				  daddr, hnum, dif) < badness)) {
			sock_put(result);
			goto begin;
		}
	}
	return result;
}

255
struct sock *__udp6_lib_lookup(struct net *net,
256
257
				      const struct in6_addr *saddr, __be16 sport,
				      const struct in6_addr *daddr, __be16 dport,
258
				      int dif, struct udp_table *udptable)
Linus Torvalds's avatar
Linus Torvalds committed
259
{
260
	struct sock *sk, *result;
261
	struct hlist_nulls_node *node;
Linus Torvalds's avatar
Linus Torvalds committed
262
	unsigned short hnum = ntohs(dport);
263
264
	unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask);
	struct udp_hslot *hslot2, *hslot = &udptable->hash[slot];
265
266
	int score, badness, matches = 0, reuseport = 0;
	u32 hash = 0;
267

268
	rcu_read_lock();
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
	if (hslot->count > 10) {
		hash2 = udp6_portaddr_hash(net, daddr, hnum);
		slot2 = hash2 & udptable->mask;
		hslot2 = &udptable->hash2[slot2];
		if (hslot->count < hslot2->count)
			goto begin;

		result = udp6_lib_lookup2(net, saddr, sport,
					  daddr, hnum, dif,
					  hslot2, slot2);
		if (!result) {
			hash2 = udp6_portaddr_hash(net, &in6addr_any, hnum);
			slot2 = hash2 & udptable->mask;
			hslot2 = &udptable->hash2[slot2];
			if (hslot->count < hslot2->count)
				goto begin;

286
287
			result = udp6_lib_lookup2(net, saddr, sport,
						  &in6addr_any, hnum, dif,
288
289
290
291
292
						  hslot2, slot2);
		}
		rcu_read_unlock();
		return result;
	}
293
294
295
begin:
	result = NULL;
	badness = -1;
296
	sk_nulls_for_each_rcu(sk, node, &hslot->head) {
297
298
299
300
		score = compute_score(sk, net, hnum, saddr, sport, daddr, dport, dif);
		if (score > badness) {
			result = sk;
			badness = score;
301
302
303
304
305
306
307
308
309
310
311
			reuseport = sk->sk_reuseport;
			if (reuseport) {
				hash = inet6_ehashfn(net, daddr, hnum,
						     saddr, sport);
				matches = 1;
			}
		} else if (score == badness && reuseport) {
			matches++;
			if (((u64)hash * matches) >> 32 == 0)
				result = sk;
			hash = next_pseudo_random32(hash);
Linus Torvalds's avatar
Linus Torvalds committed
312
313
		}
	}
314
315
316
317
318
	/*
	 * if the nulls value we got at the end of this lookup is
	 * not the expected one, we must restart lookup.
	 * We probably met an item that was moved to another chain.
	 */
319
	if (get_nulls_value(node) != slot)
320
321
		goto begin;

322
	if (result) {
323
		if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
324
325
326
327
328
329
330
331
			result = NULL;
		else if (unlikely(compute_score(result, net, hnum, saddr, sport,
					daddr, dport, dif) < badness)) {
			sock_put(result);
			goto begin;
		}
	}
	rcu_read_unlock();
Linus Torvalds's avatar
Linus Torvalds committed
332
333
	return result;
}
334
EXPORT_SYMBOL_GPL(__udp6_lib_lookup);
Linus Torvalds's avatar
Linus Torvalds committed
335

336
337
static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
					  __be16 sport, __be16 dport,
338
					  struct udp_table *udptable)
339
{
340
	struct sock *sk;
341
	const struct ipv6hdr *iph = ipv6_hdr(skb);
342

343
344
	if (unlikely(sk = skb_steal_sock(skb)))
		return sk;
Eric Dumazet's avatar
Eric Dumazet committed
345
346
347
	return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport,
				 &iph->daddr, dport, inet6_iif(skb),
				 udptable);
348
349
}

350
351
352
353
354
355
356
357
struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
			     const struct in6_addr *daddr, __be16 dport, int dif)
{
	return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table);
}
EXPORT_SYMBOL_GPL(udp6_lib_lookup);


Linus Torvalds's avatar
Linus Torvalds committed
358
359
360
361
362
/*
 * 	This should be easy, if there is something there we
 * 	return it, otherwise we block.
 */

363
int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
Linus Torvalds's avatar
Linus Torvalds committed
364
365
366
367
368
		  struct msghdr *msg, size_t len,
		  int noblock, int flags, int *addr_len)
{
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct inet_sock *inet = inet_sk(sk);
369
	struct sk_buff *skb;
370
	unsigned int ulen, copied;
371
	int peeked, off = 0;
372
373
	int err;
	int is_udplite = IS_UDPLITE(sk);
374
	int is_udp4;
375
	bool slow;
Linus Torvalds's avatar
Linus Torvalds committed
376

377
	if (addr_len)
378
		*addr_len = sizeof(struct sockaddr_in6);
379

Linus Torvalds's avatar
Linus Torvalds committed
380
381
382
	if (flags & MSG_ERRQUEUE)
		return ipv6_recv_error(sk, msg, len);

383
384
385
	if (np->rxpmtu && np->rxopt.bits.rxpmtu)
		return ipv6_recv_rxpmtu(sk, msg, len);

Linus Torvalds's avatar
Linus Torvalds committed
386
try_again:
387
	skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
388
				  &peeked, &off, &err);
Linus Torvalds's avatar
Linus Torvalds committed
389
390
391
	if (!skb)
		goto out;

392
	ulen = skb->len - sizeof(struct udphdr);
393
394
395
396
	copied = len;
	if (copied > ulen)
		copied = ulen;
	else if (copied < ulen)
397
		msg->msg_flags |= MSG_TRUNC;
Linus Torvalds's avatar
Linus Torvalds committed
398

399
400
	is_udp4 = (skb->protocol == htons(ETH_P_IP));

401
	/*
402
403
404
	 * If checksum is needed at all, try to do it while copying the
	 * data.  If the data is truncated, or if we only want a partial
	 * coverage checksum (UDP-Lite), do it before the copy.
405
406
	 */

407
	if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
408
		if (udp_lib_checksum_complete(skb))
Linus Torvalds's avatar
Linus Torvalds committed
409
			goto csum_copy_err;
410
411
	}

412
	if (skb_csum_unnecessary(skb))
413
		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
414
					      msg->msg_iov, copied);
415
	else {
Linus Torvalds's avatar
Linus Torvalds committed
416
417
418
419
		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
		if (err == -EINVAL)
			goto csum_copy_err;
	}
420
421
	if (unlikely(err)) {
		trace_kfree_skb(skb, udpv6_recvmsg);
422
423
424
425
426
427
428
429
430
431
432
		if (!peeked) {
			atomic_inc(&sk->sk_drops);
			if (is_udp4)
				UDP_INC_STATS_USER(sock_net(sk),
						   UDP_MIB_INERRORS,
						   is_udplite);
			else
				UDP6_INC_STATS_USER(sock_net(sk),
						    UDP_MIB_INERRORS,
						    is_udplite);
		}
Linus Torvalds's avatar
Linus Torvalds committed
433
		goto out_free;
434
	}
435
436
437
438
439
440
441
442
	if (!peeked) {
		if (is_udp4)
			UDP_INC_STATS_USER(sock_net(sk),
					UDP_MIB_INDATAGRAMS, is_udplite);
		else
			UDP6_INC_STATS_USER(sock_net(sk),
					UDP_MIB_INDATAGRAMS, is_udplite);
	}
443

444
	sock_recv_ts_and_drops(msg, sk, skb);
Linus Torvalds's avatar
Linus Torvalds committed
445
446
447
448

	/* Copy the address. */
	if (msg->msg_name) {
		struct sockaddr_in6 *sin6;
449

Linus Torvalds's avatar
Linus Torvalds committed
450
451
		sin6 = (struct sockaddr_in6 *) msg->msg_name;
		sin6->sin6_family = AF_INET6;
452
		sin6->sin6_port = udp_hdr(skb)->source;
Linus Torvalds's avatar
Linus Torvalds committed
453
454
		sin6->sin6_flowinfo = 0;

455
		if (is_udp4) {
456
457
			ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr,
					       &sin6->sin6_addr);
458
459
			sin6->sin6_scope_id = 0;
		} else {
Alexey Dobriyan's avatar
Alexey Dobriyan committed
460
			sin6->sin6_addr = ipv6_hdr(skb)->saddr;
461
462
463
			sin6->sin6_scope_id =
				ipv6_iface_scope_id(&sin6->sin6_addr,
						    IP6CB(skb)->iif);
Linus Torvalds's avatar
Linus Torvalds committed
464
465
466
		}

	}
467
	if (is_udp4) {
Linus Torvalds's avatar
Linus Torvalds committed
468
469
470
471
		if (inet->cmsg_flags)
			ip_cmsg_recv(msg, skb);
	} else {
		if (np->rxopt.all)
472
			ip6_datagram_recv_ctl(sk, msg, skb);
473
	}
Linus Torvalds's avatar
Linus Torvalds committed
474

475
	err = copied;
Linus Torvalds's avatar
Linus Torvalds committed
476
	if (flags & MSG_TRUNC)
477
		err = ulen;
Linus Torvalds's avatar
Linus Torvalds committed
478
479

out_free:
480
	skb_free_datagram_locked(sk, skb);
Linus Torvalds's avatar
Linus Torvalds committed
481
482
483
484
out:
	return err;

csum_copy_err:
485
	slow = lock_sock_fast(sk);
486
	if (!skb_kill_datagram(sk, skb, flags)) {
487
488
489
		if (is_udp4) {
			UDP_INC_STATS_USER(sock_net(sk),
					UDP_MIB_CSUMERRORS, is_udplite);
490
491
			UDP_INC_STATS_USER(sock_net(sk),
					UDP_MIB_INERRORS, is_udplite);
492
493
494
		} else {
			UDP6_INC_STATS_USER(sock_net(sk),
					UDP_MIB_CSUMERRORS, is_udplite);
495
496
			UDP6_INC_STATS_USER(sock_net(sk),
					UDP_MIB_INERRORS, is_udplite);
497
		}
498
	}
499
	unlock_sock_fast(sk, slow);
Linus Torvalds's avatar
Linus Torvalds committed
500

501
	if (noblock)
Linus Torvalds's avatar
Linus Torvalds committed
502
		return -EAGAIN;
503
504
505

	/* starting over for a new packet */
	msg->msg_flags &= ~MSG_TRUNC;
Linus Torvalds's avatar
Linus Torvalds committed
506
507
508
	goto try_again;
}

509
void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
510
		    u8 type, u8 code, int offset, __be32 info,
511
		    struct udp_table *udptable)
Linus Torvalds's avatar
Linus Torvalds committed
512
513
{
	struct ipv6_pinfo *np;
514
515
516
	const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
	const struct in6_addr *saddr = &hdr->saddr;
	const struct in6_addr *daddr = &hdr->daddr;
Linus Torvalds's avatar
Linus Torvalds committed
517
518
519
520
	struct udphdr *uh = (struct udphdr*)(skb->data+offset);
	struct sock *sk;
	int err;

521
	sk = __udp6_lib_lookup(dev_net(skb->dev), daddr, uh->dest,
522
			       saddr, uh->source, inet6_iif(skb), udptable);
Linus Torvalds's avatar
Linus Torvalds committed
523
524
525
	if (sk == NULL)
		return;

526
527
	if (type == ICMPV6_PKT_TOOBIG)
		ip6_sk_update_pmtu(skb, sk, info);
528
529
	if (type == NDISC_REDIRECT)
		ip6_sk_redirect(skb, sk);
530

Linus Torvalds's avatar
Linus Torvalds committed
531
532
533
534
535
536
537
538
	np = inet6_sk(sk);

	if (!icmpv6_err_convert(type, code, &err) && !np->recverr)
		goto out;

	if (sk->sk_state != TCP_ESTABLISHED && !np->recverr)
		goto out;

539
	if (np->recverr)
Linus Torvalds's avatar
Linus Torvalds committed
540
		ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
541

Linus Torvalds's avatar
Linus Torvalds committed
542
543
544
545
546
547
	sk->sk_err = err;
	sk->sk_error_report(sk);
out:
	sock_put(sk);
}

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
	int rc;

	if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
		sock_rps_save_rxhash(sk, skb);

	rc = sock_queue_rcv_skb(sk, skb);
	if (rc < 0) {
		int is_udplite = IS_UDPLITE(sk);

		/* Note that an ENOMEM error is charged twice */
		if (rc == -ENOMEM)
			UDP6_INC_STATS_BH(sock_net(sk),
					UDP_MIB_RCVBUFERRORS, is_udplite);
		UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
		kfree_skb(skb);
		return -1;
	}
	return 0;
}

570
static __inline__ void udpv6_err(struct sk_buff *skb,
571
572
				 struct inet6_skb_parm *opt, u8 type,
				 u8 code, int offset, __be32 info     )
573
{
574
	__udp6_lib_err(skb, opt, type, code, offset, info, &udp_table);
575
576
}

577
578
579
580
581
582
583
584
static struct static_key udpv6_encap_needed __read_mostly;
void udpv6_encap_enable(void)
{
	if (!static_key_enabled(&udpv6_encap_needed))
		static_key_slow_inc(&udpv6_encap_needed);
}
EXPORT_SYMBOL(udpv6_encap_enable);

585
int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
Linus Torvalds's avatar
Linus Torvalds committed
586
{
587
	struct udp_sock *up = udp_sk(sk);
588
	int rc;
589
	int is_udplite = IS_UDPLITE(sk);
590

591
592
	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
		goto drop;
Linus Torvalds's avatar
Linus Torvalds committed
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
	if (static_key_false(&udpv6_encap_needed) && up->encap_type) {
		int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);

		/*
		 * This is an encapsulation socket so pass the skb to
		 * the socket's udp_encap_rcv() hook. Otherwise, just
		 * fall through and pass this up the UDP socket.
		 * up->encap_rcv() returns the following value:
		 * =0 if skb was successfully passed to the encap
		 *    handler or was discarded by it.
		 * >0 if skb should be passed on to UDP.
		 * <0 if skb should be resubmitted as proto -N
		 */

		/* if we're overly short, let UDP handle it */
		encap_rcv = ACCESS_ONCE(up->encap_rcv);
		if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {
			int ret;

			ret = encap_rcv(sk, skb);
			if (ret <= 0) {
				UDP_INC_STATS_BH(sock_net(sk),
						 UDP_MIB_INDATAGRAMS,
						 is_udplite);
				return -ret;
			}
		}

		/* FALLTHROUGH -- it's a UDP Packet */
	}

625
626
627
	/*
	 * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
	 */
628
	if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
629
630
631
632
633
634
635
636
637
638
639
640
641

		if (up->pcrlen == 0) {          /* full coverage was set  */
			LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: partial coverage"
				" %d while full coverage %d requested\n",
				UDP_SKB_CB(skb)->cscov, skb->len);
			goto drop;
		}
		if (UDP_SKB_CB(skb)->cscov  <  up->pcrlen) {
			LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: coverage %d "
						    "too small, need min %d\n",
				       UDP_SKB_CB(skb)->cscov, up->pcrlen);
			goto drop;
		}
Linus Torvalds's avatar
Linus Torvalds committed
642
643
	}

644
	if (rcu_access_pointer(sk->sk_filter)) {
645
		if (udp_lib_checksum_complete(skb))
646
			goto csum_error;
647
	}
648

649
650
651
	if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
		goto drop;

652
	skb_dst_drop(skb);
653

654
655
656
657
658
659
660
661
662
	bh_lock_sock(sk);
	rc = 0;
	if (!sock_owned_by_user(sk))
		rc = __udpv6_queue_rcv_skb(sk, skb);
	else if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) {
		bh_unlock_sock(sk);
		goto drop;
	}
	bh_unlock_sock(sk);
663
664

	return rc;
665
666
csum_error:
	UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
667
drop:
668
	UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
669
	atomic_inc(&sk->sk_drops);
670
671
	kfree_skb(skb);
	return -1;
Linus Torvalds's avatar
Linus Torvalds committed
672
673
}

674
static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
675
676
				      __be16 loc_port, const struct in6_addr *loc_addr,
				      __be16 rmt_port, const struct in6_addr *rmt_addr,
Linus Torvalds's avatar
Linus Torvalds committed
677
678
				      int dif)
{
679
	struct hlist_nulls_node *node;
Linus Torvalds's avatar
Linus Torvalds committed
680
681
682
	struct sock *s = sk;
	unsigned short num = ntohs(loc_port);

683
	sk_nulls_for_each_from(s, node) {
Linus Torvalds's avatar
Linus Torvalds committed
684
685
		struct inet_sock *inet = inet_sk(s);

686
		if (!net_eq(sock_net(s), net))
687
688
			continue;

689
690
		if (udp_sk(s)->udp_port_hash == num &&
		    s->sk_family == PF_INET6) {
Linus Torvalds's avatar
Linus Torvalds committed
691
			struct ipv6_pinfo *np = inet6_sk(s);
692
693
			if (inet->inet_dport) {
				if (inet->inet_dport != rmt_port)
Linus Torvalds's avatar
Linus Torvalds committed
694
695
696
697
698
699
700
701
702
703
					continue;
			}
			if (!ipv6_addr_any(&np->daddr) &&
			    !ipv6_addr_equal(&np->daddr, rmt_addr))
				continue;

			if (s->sk_bound_dev_if && s->sk_bound_dev_if != dif)
				continue;

			if (!ipv6_addr_any(&np->rcv_saddr)) {
704
705
				if (!ipv6_addr_equal(&np->rcv_saddr, loc_addr))
					continue;
Linus Torvalds's avatar
Linus Torvalds committed
706
			}
Stephen Hemminger's avatar
Stephen Hemminger committed
707
			if (!inet6_mc_check(s, loc_addr, rmt_addr))
Linus Torvalds's avatar
Linus Torvalds committed
708
709
710
711
712
713
714
				continue;
			return s;
		}
	}
	return NULL;
}

715
716
717
static void flush_stack(struct sock **stack, unsigned int count,
			struct sk_buff *skb, unsigned int final)
{
718
	struct sk_buff *skb1 = NULL;
719
	struct sock *sk;
720
	unsigned int i;
721
722

	for (i = 0; i < count; i++) {
723
		sk = stack[i];
724
725
726
727
728
729
730
731
		if (likely(skb1 == NULL))
			skb1 = (i == final) ? skb : skb_clone(skb, GFP_ATOMIC);
		if (!skb1) {
			atomic_inc(&sk->sk_drops);
			UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
					  IS_UDPLITE(sk));
			UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
					  IS_UDPLITE(sk));
732
		}
733
734
735

		if (skb1 && udpv6_queue_rcv_skb(sk, skb1) <= 0)
			skb1 = NULL;
736
	}
737
738
	if (unlikely(skb1))
		kfree_skb(skb1);
739
}
Linus Torvalds's avatar
Linus Torvalds committed
740
741
742
743
/*
 * Note: called only from the BH handler context,
 * so we don't need to lock the hashes.
 */
744
static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
745
		const struct in6_addr *saddr, const struct in6_addr *daddr,
746
		struct udp_table *udptable)
Linus Torvalds's avatar
Linus Torvalds committed
747
{
748
	struct sock *sk, *stack[256 / sizeof(struct sock *)];
749
	const struct udphdr *uh = udp_hdr(skb);
750
	struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest));
Linus Torvalds's avatar
Linus Torvalds committed
751
	int dif;
752
	unsigned int i, count = 0;
Linus Torvalds's avatar
Linus Torvalds committed
753

754
	spin_lock(&hslot->lock);
755
	sk = sk_nulls_head(&hslot->head);
756
	dif = inet6_iif(skb);
757
	sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
758
759
760
761
762
763
764
765
766
	while (sk) {
		stack[count++] = sk;
		sk = udp_v6_mcast_next(net, sk_nulls_next(sk), uh->dest, daddr,
				       uh->source, saddr, dif);
		if (unlikely(count == ARRAY_SIZE(stack))) {
			if (!sk)
				break;
			flush_stack(stack, count, skb, ~0);
			count = 0;
Hideo Aoki's avatar
Hideo Aoki committed
767
		}
Linus Torvalds's avatar
Linus Torvalds committed
768
	}
769
770
771
772
773
774
	/*
	 * before releasing the lock, we must take reference on sockets
	 */
	for (i = 0; i < count; i++)
		sock_hold(stack[i]);

775
	spin_unlock(&hslot->lock);
776
777
778
779
780
781
782
783
784

	if (count) {
		flush_stack(stack, count, skb, count - 1);

		for (i = 0; i < count; i++)
			sock_put(stack[i]);
	} else {
		kfree_skb(skb);
	}
785
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
786
787
}

788
int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
789
		   int proto)
Linus Torvalds's avatar
Linus Torvalds committed
790
{
791
	struct net *net = dev_net(skb->dev);
Linus Torvalds's avatar
Linus Torvalds committed
792
	struct sock *sk;
793
	struct udphdr *uh;
794
	const struct in6_addr *saddr, *daddr;
Linus Torvalds's avatar
Linus Torvalds committed
795
796
797
	u32 ulen = 0;

	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
798
		goto discard;
Linus Torvalds's avatar
Linus Torvalds committed
799

800
801
	saddr = &ipv6_hdr(skb)->saddr;
	daddr = &ipv6_hdr(skb)->daddr;
802
	uh = udp_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
803
804

	ulen = ntohs(uh->len);
805
806
	if (ulen > skb->len)
		goto short_packet;
Linus Torvalds's avatar
Linus Torvalds committed
807

808
809
	if (proto == IPPROTO_UDP) {
		/* UDP validates ulen. */
Linus Torvalds's avatar
Linus Torvalds committed
810

811
812
813
		/* Check for jumbo payload */
		if (ulen == 0)
			ulen = skb->len;
Linus Torvalds's avatar
Linus Torvalds committed
814

815
816
		if (ulen < sizeof(*uh))
			goto short_packet;
Linus Torvalds's avatar
Linus Torvalds committed
817

818
819
820
		if (ulen < skb->len) {
			if (pskb_trim_rcsum(skb, ulen))
				goto short_packet;
821
822
			saddr = &ipv6_hdr(skb)->saddr;
			daddr = &ipv6_hdr(skb)->daddr;
823
			uh = udp_hdr(skb);
824
825
		}
	}
Linus Torvalds's avatar
Linus Torvalds committed
826

827
	if (udp6_csum_init(skb, uh, proto))
828
		goto csum_error;
829

830
831
	/*
	 *	Multicast receive code
Linus Torvalds's avatar
Linus Torvalds committed
832
	 */
833
	if (ipv6_addr_is_multicast(daddr))
834
835
		return __udp6_lib_mcast_deliver(net, skb,
				saddr, daddr, udptable);
Linus Torvalds's avatar
Linus Torvalds committed
836
837
838

	/* Unicast */

839
	/*
Linus Torvalds's avatar
Linus Torvalds committed
840
841
842
	 * check socket cache ... must talk to Alan about his plans
	 * for sock caches... i'll skip this for now.
	 */
843
	sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
844
	if (sk != NULL) {
845
846
847
848
		int ret;

		sk_mark_ll(sk, skb);
		ret = udpv6_queue_rcv_skb(sk, skb);
849
		sock_put(sk);
Linus Torvalds's avatar
Linus Torvalds committed
850

851
852
853
854
855
		/* a return value > 0 means to resubmit the input, but
		 * it wants the return to be -protocol, or 0
		 */
		if (ret > 0)
			return -ret;
Linus Torvalds's avatar
Linus Torvalds committed
856

Stephen Hemminger's avatar
Stephen Hemminger committed
857
		return 0;
Linus Torvalds's avatar
Linus Torvalds committed
858
	}
859

860
	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
861
		goto discard;
862
863

	if (udp_lib_checksum_complete(skb))
864
		goto csum_error;
865
866
867
868
869

	UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);

	kfree_skb(skb);
Stephen Hemminger's avatar
Stephen Hemminger committed
870
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
871

872
short_packet:
873
	LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n",
874
		       proto == IPPROTO_UDPLITE ? "-Lite" : "",
875
876
877
878
879
880
		       saddr,
		       ntohs(uh->source),
		       ulen,
		       skb->len,
		       daddr,
		       ntohs(uh->dest));
881
882
883
	goto discard;
csum_error:
	UDP6_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
Linus Torvalds's avatar
Linus Torvalds committed
884
discard:
885
	UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
Linus Torvalds's avatar
Linus Torvalds committed
886
	kfree_skb(skb);
Stephen Hemminger's avatar
Stephen Hemminger committed
887
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
888
}
889

890
static __inline__ int udpv6_rcv(struct sk_buff *skb)
891
{
892
	return __udp6_lib_rcv(skb, &udp_table, IPPROTO_UDP);
893
894
}

Linus Torvalds's avatar
Linus Torvalds committed
895
896
897
898
899
900
901
/*
 * Throw away all pending data and cancel the corking. Socket is locked.
 */
static void udp_v6_flush_pending_frames(struct sock *sk)
{
	struct udp_sock *up = udp_sk(sk);

902
903
904
	if (up->pending == AF_INET)
		udp_flush_pending_frames(sk);
	else if (up->pending) {
Linus Torvalds's avatar
Linus Torvalds committed
905
906
907
		up->len = 0;
		up->pending = 0;
		ip6_flush_pending_frames(sk);
908
	}
Linus Torvalds's avatar
Linus Torvalds committed
909
910
}

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
/**
 * 	udp6_hwcsum_outgoing  -  handle outgoing HW checksumming
 * 	@sk: 	socket we are sending on
 * 	@skb: 	sk_buff containing the filled-in UDP header
 * 	        (checksum field must be zeroed out)
 */
static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
				 const struct in6_addr *saddr,
				 const struct in6_addr *daddr, int len)
{
	unsigned int offset;
	struct udphdr *uh = udp_hdr(skb);
	__wsum csum = 0;

	if (skb_queue_len(&sk->sk_write_queue) == 1) {
		/* Only one fragment on the socket.  */
		skb->csum_start = skb_transport_header(skb) - skb->head;
		skb->csum_offset = offsetof(struct udphdr, check);
		uh->check = ~csum_ipv6_magic(saddr, daddr, len, IPPROTO_UDP, 0);
	} else {
		/*
		 * HW-checksum won't work as there are two or more
		 * fragments on the socket so that all csums of sk_buffs
		 * should be together
		 */
		offset = skb_transport_offset(skb);
		skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);

		skb->ip_summed = CHECKSUM_NONE;

		skb_queue_walk(&sk->sk_write_queue, skb) {
			csum = csum_add(csum, skb->csum);
		}

		uh->check = csum_ipv6_magic(saddr, daddr, len, IPPROTO_UDP,
					    csum);
		if (uh->check == 0)
			uh->check = CSUM_MANGLED_0;
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
952
953
954
955
/*
 *	Sending
 */

956
static int udp_v6_push_pending_frames(struct sock *sk)
Linus Torvalds's avatar
Linus Torvalds committed
957
958
959
{
	struct sk_buff *skb;
	struct udphdr *uh;
960
	struct udp_sock  *up = udp_sk(sk);
Linus Torvalds's avatar
Linus Torvalds committed
961
	struct inet_sock *inet = inet_sk(sk);
962
	struct flowi6 *fl6;
Linus Torvalds's avatar
Linus Torvalds committed
963
	int err = 0;
964
	int is_udplite = IS_UDPLITE(sk);
965
	__wsum csum = 0;
Linus Torvalds's avatar
Linus Torvalds committed
966

967
968
969
970
971
	if (up->pending == AF_INET)
		return udp_push_pending_frames(sk);

	fl6 = &inet->cork.fl.u.ip6;

Linus Torvalds's avatar
Linus Torvalds committed
972
973
974
975
976
977
978
	/* Grab the skbuff where UDP header space exists. */
	if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
		goto out;

	/*
	 * Create a UDP header
	 */
979
	uh = udp_hdr(skb);
980
981
	uh->source = fl6->fl6_sport;
	uh->dest = fl6->fl6_dport;
Linus Torvalds's avatar
Linus Torvalds committed
982
983
984
	uh->len = htons(up->len);
	uh->check = 0;

985
	if (is_udplite)
986
		csum = udplite_csum_outgoing(sk, skb);
987
	else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
988
		udp6_hwcsum_outgoing(sk, skb, &fl6->saddr, &fl6->daddr,
989
990
991
				     up->len);
		goto send;
	} else
992
		csum = udp_csum_outgoing(sk, skb);
Linus Torvalds's avatar
Linus Torvalds committed
993

994
	/* add protocol-dependent pseudo-header */
995
996
	uh->check = csum_ipv6_magic(&fl6->saddr, &fl6->daddr,
				    up->len, fl6->flowi6_proto, csum);
Linus Torvalds's avatar
Linus Torvalds committed
997
	if (uh->check == 0)
998
		uh->check = CSUM_MANGLED_0;
Linus Torvalds's avatar
Linus Torvalds committed
999

1000
send:
Linus Torvalds's avatar
Linus Torvalds committed
1001
	err = ip6_push_pending_frames(sk);
Eric Dumazet's avatar
Eric Dumazet committed
1002
1003
1004
1005
1006
1007
1008
1009
1010
	if (err) {
		if (err == -ENOBUFS && !inet6_sk(sk)->recverr) {
			UDP6_INC_STATS_USER(sock_net(sk),
					    UDP_MIB_SNDBUFERRORS, is_udplite);
			err = 0;
		}
	} else
		UDP6_INC_STATS_USER(sock_net(sk),
				    UDP_MIB_OUTDATAGRAMS, is_udplite);
Linus Torvalds's avatar
Linus Torvalds committed
1011
1012
1013
1014
1015
1016
out:
	up->len = 0;
	up->pending = 0;
	return err;
}

1017
int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
Linus Torvalds's avatar
Linus Torvalds committed
1018
1019
1020
1021
1022
1023
1024
		  struct msghdr *msg, size_t len)
{
	struct ipv6_txoptions opt_space;
	struct udp_sock *up = udp_sk(sk);
	struct inet_sock *inet = inet_sk(sk);
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
1025
	struct in6_addr *daddr, *final_p, final;
Linus Torvalds's avatar
Linus Torvalds committed
1026
1027
	struct ipv6_txoptions *opt = NULL;
	struct ip6_flowlabel *flowlabel = NULL;
1028
	struct flowi6 fl6;
Linus Torvalds's avatar
Linus Torvalds committed
1029
1030
1031
1032
	struct dst_entry *dst;
	int addr_len = msg->msg_namelen;
	int ulen = len;
	int hlimit = -1;
1033
	int tclass = -1;
1034
	int dontfrag = -1;
Linus Torvalds's avatar
Linus Torvalds committed
1035
1036
	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
	int err;
1037
	int connected = 0;
1038
	int is_udplite = IS_UDPLITE(sk);
1039
	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
Linus Torvalds's avatar
Linus Torvalds committed
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

	/* destination address check */
	if (sin6) {
		if (addr_len < offsetof(struct sockaddr, sa_data))
			return -EINVAL;

		switch (sin6->sin6_family) {
		case AF_INET6:
			if (addr_len < SIN6_LEN_RFC2133)
				return -EINVAL;
			daddr = &sin6->sin6_addr;
			break;
		case AF_INET:
			goto do_udp_sendmsg;
		case AF_UNSPEC:
			msg->msg_name = sin6 = NULL;
			msg->msg_namelen = addr_len = 0;
			daddr = NULL;
			break;
		default:
			return -EINVAL;
		}
	} else if (!up->pending) {
		if (sk->sk_state != TCP_ESTABLISHED)
			return -EDESTADDRREQ;
		daddr = &np->daddr;
1066
	} else
Linus Torvalds's avatar
Linus Torvalds committed
1067
1068
1069
		daddr = NULL;

	if (daddr) {
1070
		if (ipv6_addr_v4mapped(daddr)) {
Linus Torvalds's avatar
Linus Torvalds committed
1071
1072
			struct sockaddr_in sin;
			sin.sin_family = AF_INET;
1073
			sin.sin_port = sin6 ? sin6->sin6_port : inet->inet_dport;
Linus Torvalds's avatar
Linus Torvalds committed
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
			sin.sin_addr.s_addr = daddr->s6_addr32[3];
			msg->msg_name = &sin;
			msg->msg_namelen = sizeof(sin);
do_udp_sendmsg:
			if (__ipv6_only_sock(sk))
				return -ENETUNREACH;
			return udp_sendmsg(iocb, sk, msg, len);
		}
	}

	if (up->pending == AF_INET)
		return udp_sendmsg(iocb, sk, msg, len);

	/* Rough check on arithmetic overflow,
1088
	   better check is made in ip6_append_data().
Linus Torvalds's avatar
Linus Torvalds committed
1089
1090
1091
	   */
	if (len > INT_MAX - sizeof(struct udphdr))
		return -EMSGSIZE;
1092

Linus Torvalds's avatar
Linus Torvalds committed
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
	if (up->pending) {
		/*
		 * There are pending frames.
		 * The socket lock must be held while it's corked.
		 */
		lock_sock(sk);
		if (likely(up->pending)) {
			if (unlikely(up->pending != AF_INET6)) {
				release_sock(sk);
				return -EAFNOSUPPORT;
			}
			dst = NULL;
			goto do_append_data;
		}
		release_sock(sk);
	}
	ulen += sizeof(struct udphdr);

1111
	memset(&fl6, 0, sizeof(fl6));
Linus Torvalds's avatar
Linus Torvalds committed
1112
1113
1114
1115
1116

	if (sin6) {
		if (sin6->sin6_port == 0)
			return -EINVAL;

1117
		fl6.fl6_dport = sin6->sin6_port;
Linus Torvalds's avatar
Linus Torvalds committed
1118
1119
1120
		daddr = &sin6->sin6_addr;

		if (np->sndflow) {
1121
1122
1123
			fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
			if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
				flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
Linus Torvalds's avatar
Linus Torvalds committed
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
				if (flowlabel == NULL)
					return -EINVAL;
				daddr = &flowlabel->dst;
			}
		}

		/*
		 * Otherwise it will be difficult to maintain
		 * sk->sk_dst_cache.
		 */
		if (sk->sk_state == TCP_ESTABLISHED &&
		    ipv6_addr_equal(daddr, &np->daddr))
			daddr = &np->daddr;

		if (addr_len >= sizeof(struct sockaddr_in6) &&
		    sin6->sin6_scope_id &&
1140
		    __ipv6_addr_needs_scope_id(__ipv6_addr_type(daddr)))
1141
			fl6.flowi6_oif = sin6->sin6_scope_id;
Linus Torvalds's avatar
Linus Torvalds committed
1142
1143
1144
1145
	} else {
		if (sk->sk_state != TCP_ESTABLISHED)
			return -EDESTADDRREQ;

1146
		fl6.fl6_dport = inet->inet_dport;
Linus Torvalds's avatar
Linus Torvalds committed
1147
		daddr = &np->daddr;
1148
		fl6.flowlabel = np->flow_label;
1149
		connected = 1;
Linus Torvalds's avatar
Linus Torvalds committed
1150
1151
	}

1152
1153
	if (!fl6.flowi6_oif)
		fl6.flowi6_oif = sk->sk_bound_dev_if;
Linus Torvalds's avatar
Linus Torvalds committed
1154

1155
1156
	if (!fl6.flowi6_oif)
		fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
1157

1158
	fl6.flowi6_mark = sk->sk_mark;
1159

Linus Torvalds's avatar
Linus Torvalds committed
1160
1161
1162
1163
1164
	if (msg->msg_controllen) {
		opt = &opt_space;
		memset(opt, 0, sizeof(struct ipv6_txoptions));
		opt->tot_len = sizeof(*opt);

1165
1166
		err = ip6_datagram_send_ctl(sock_net(