1/*
2 *	UDP over IPv6
3 *	Linux INET6 implementation
4 *
5 *	Authors:
6 *	Pedro Roque		<roque@di.fc.ul.pt>
7 *
8 *	Based on linux/ipv4/udp.c
9 *
10 *	$Id: udp.c,v 1.1.1.1 2008/10/15 03:27:34 james26_jang Exp $
11 *
12 *	Fixes:
13 *	Hideaki YOSHIFUJI	:	sin6_scope_id support
14 *
15 *	This program is free software; you can redistribute it and/or
16 *      modify it under the terms of the GNU General Public License
17 *      as published by the Free Software Foundation; either version
18 *      2 of the License, or (at your option) any later version.
19 */
20
21#include <linux/config.h>
22#include <linux/errno.h>
23#include <linux/types.h>
24#include <linux/socket.h>
25#include <linux/sockios.h>
26#include <linux/sched.h>
27#include <linux/net.h>
28#include <linux/in6.h>
29#include <linux/netdevice.h>
30#include <linux/if_arp.h>
31#include <linux/ipv6.h>
32#include <linux/icmpv6.h>
33#include <linux/init.h>
34#include <asm/uaccess.h>
35
36#include <net/sock.h>
37#include <net/snmp.h>
38
39#include <net/ipv6.h>
40#include <net/ndisc.h>
41#include <net/protocol.h>
42#include <net/transp_v6.h>
43#include <net/ip6_route.h>
44#include <net/addrconf.h>
45#include <net/ip.h>
46#include <net/udp.h>
47#include <net/inet_common.h>
48
49#include <net/checksum.h>
50
51struct udp_mib udp_stats_in6[NR_CPUS*2];
52
53/* Grrr, addr_type already calculated by caller, but I don't want
54 * to add some silly "cookie" argument to this method just for that.
55 */
56static int udp_v6_get_port(struct sock *sk, unsigned short snum)
57{
58	write_lock_bh(&udp_hash_lock);
59	if (snum == 0) {
60		int best_size_so_far, best, result, i;
61
62		if (udp_port_rover > sysctl_local_port_range[1] ||
63		    udp_port_rover < sysctl_local_port_range[0])
64			udp_port_rover = sysctl_local_port_range[0];
65		best_size_so_far = 32767;
66		best = result = udp_port_rover;
67		for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
68			struct sock *sk;
69			int size;
70
71			sk = udp_hash[result & (UDP_HTABLE_SIZE - 1)];
72			if (!sk) {
73				if (result > sysctl_local_port_range[1])
74					result = sysctl_local_port_range[0] +
75						((result - sysctl_local_port_range[0]) &
76						 (UDP_HTABLE_SIZE - 1));
77				goto gotit;
78			}
79			size = 0;
80			do {
81				if (++size >= best_size_so_far)
82					goto next;
83			} while ((sk = sk->next) != NULL);
84			best_size_so_far = size;
85			best = result;
86		next:;
87		}
88		result = best;
89		for(;; result += UDP_HTABLE_SIZE) {
90			if (result > sysctl_local_port_range[1])
91				result = sysctl_local_port_range[0]
92					+ ((result - sysctl_local_port_range[0]) &
93					   (UDP_HTABLE_SIZE - 1));
94			if (!udp_lport_inuse(result))
95				break;
96		}
97gotit:
98		udp_port_rover = snum = result;
99	} else {
100		struct sock *sk2;
101		int addr_type = ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);
102
103		for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
104		     sk2 != NULL;
105		     sk2 = sk2->next) {
106			if (sk2->num == snum &&
107			    sk2 != sk &&
108			    sk2->bound_dev_if == sk->bound_dev_if &&
109			    (!sk2->rcv_saddr ||
110			     addr_type == IPV6_ADDR_ANY ||
111			     !ipv6_addr_cmp(&sk->net_pinfo.af_inet6.rcv_saddr,
112					    &sk2->net_pinfo.af_inet6.rcv_saddr) ||
113			     (addr_type == IPV6_ADDR_MAPPED &&
114			      sk2->family == AF_INET &&
115			      sk->rcv_saddr == sk2->rcv_saddr)) &&
116			    (!sk2->reuse || !sk->reuse))
117				goto fail;
118		}
119	}
120
121	sk->num = snum;
122	if (sk->pprev == NULL) {
123		struct sock **skp = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
124		if ((sk->next = *skp) != NULL)
125			(*skp)->pprev = &sk->next;
126		*skp = sk;
127		sk->pprev = skp;
128		sock_prot_inc_use(sk->prot);
129		sock_hold(sk);
130	}
131	write_unlock_bh(&udp_hash_lock);
132	return 0;
133
134fail:
135	write_unlock_bh(&udp_hash_lock);
136	return 1;
137}
138
139static void udp_v6_hash(struct sock *sk)
140{
141	BUG();
142}
143
144static void udp_v6_unhash(struct sock *sk)
145{
146 	write_lock_bh(&udp_hash_lock);
147	if (sk->pprev) {
148		if (sk->next)
149			sk->next->pprev = sk->pprev;
150		*sk->pprev = sk->next;
151		sk->pprev = NULL;
152		sk->num = 0;
153		sock_prot_dec_use(sk->prot);
154		__sock_put(sk);
155	}
156	write_unlock_bh(&udp_hash_lock);
157}
158
159static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
160				  struct in6_addr *daddr, u16 dport, int dif)
161{
162	struct sock *sk, *result = NULL;
163	unsigned short hnum = ntohs(dport);
164	int badness = -1;
165
166 	read_lock(&udp_hash_lock);
167	for(sk = udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]; sk != NULL; sk = sk->next) {
168		if((sk->num == hnum)		&&
169		   (sk->family == PF_INET6)) {
170			struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
171			int score = 0;
172			if(sk->dport) {
173				if(sk->dport != sport)
174					continue;
175				score++;
176			}
177			if(!ipv6_addr_any(&np->rcv_saddr)) {
178				if(ipv6_addr_cmp(&np->rcv_saddr, daddr))
179					continue;
180				score++;
181			}
182			if(!ipv6_addr_any(&np->daddr)) {
183				if(ipv6_addr_cmp(&np->daddr, saddr))
184					continue;
185				score++;
186			}
187			if(sk->bound_dev_if) {
188				if(sk->bound_dev_if != dif)
189					continue;
190				score++;
191			}
192			if(score == 4) {
193				result = sk;
194				break;
195			} else if(score > badness) {
196				result = sk;
197				badness = score;
198			}
199		}
200	}
201	if (result)
202		sock_hold(result);
203 	read_unlock(&udp_hash_lock);
204	return result;
205}
206
207/*
208 *
209 */
210
211int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
212{
213	struct sockaddr_in6	*usin = (struct sockaddr_in6 *) uaddr;
214	struct ipv6_pinfo      	*np = &sk->net_pinfo.af_inet6;
215	struct in6_addr		*daddr;
216	struct in6_addr		saddr;
217	struct dst_entry	*dst;
218	struct flowi		fl;
219	struct ip6_flowlabel	*flowlabel = NULL;
220	int			addr_type;
221	int			err;
222
223	if (usin->sin6_family == AF_INET) {
224		err = udp_connect(sk, uaddr, addr_len);
225		goto ipv4_connected;
226	}
227
228	if (addr_len < SIN6_LEN_RFC2133)
229	  	return -EINVAL;
230
231	if (usin->sin6_family != AF_INET6)
232	  	return -EAFNOSUPPORT;
233
234	fl.fl6_flowlabel = 0;
235	if (np->sndflow) {
236		fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
237		if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
238			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
239			if (flowlabel == NULL)
240				return -EINVAL;
241			ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
242		}
243	}
244
245	addr_type = ipv6_addr_type(&usin->sin6_addr);
246
247	if (addr_type == IPV6_ADDR_ANY) {
248		/*
249		 *	connect to self
250		 */
251		usin->sin6_addr.s6_addr[15] = 0x01;
252	}
253
254	daddr = &usin->sin6_addr;
255
256	if (addr_type == IPV6_ADDR_MAPPED) {
257		struct sockaddr_in sin;
258
259		sin.sin_family = AF_INET;
260		sin.sin_addr.s_addr = daddr->s6_addr32[3];
261		sin.sin_port = usin->sin6_port;
262
263		err = udp_connect(sk, (struct sockaddr*) &sin, sizeof(sin));
264
265ipv4_connected:
266		if (err < 0)
267			return err;
268
269		ipv6_addr_set(&np->daddr, 0, 0,
270			      htonl(0x0000ffff),
271			      sk->daddr);
272
273		if(ipv6_addr_any(&np->saddr)) {
274			ipv6_addr_set(&np->saddr, 0, 0,
275				      htonl(0x0000ffff),
276				      sk->saddr);
277		}
278
279		if(ipv6_addr_any(&np->rcv_saddr)) {
280			ipv6_addr_set(&np->rcv_saddr, 0, 0,
281				      htonl(0x0000ffff),
282				      sk->rcv_saddr);
283		}
284		return 0;
285	}
286
287	if (addr_type&IPV6_ADDR_LINKLOCAL) {
288		if (addr_len >= sizeof(struct sockaddr_in6) &&
289		    usin->sin6_scope_id) {
290			if (sk->bound_dev_if && sk->bound_dev_if != usin->sin6_scope_id) {
291				fl6_sock_release(flowlabel);
292				return -EINVAL;
293			}
294			sk->bound_dev_if = usin->sin6_scope_id;
295			if (!sk->bound_dev_if && (addr_type&IPV6_ADDR_MULTICAST))
296				fl.oif = np->mcast_oif;
297		}
298
299		/* Connect to link-local address requires an interface */
300		if (sk->bound_dev_if == 0)
301			return -EINVAL;
302	}
303
304	ipv6_addr_copy(&np->daddr, daddr);
305	np->flow_label = fl.fl6_flowlabel;
306
307	sk->dport = usin->sin6_port;
308
309	/*
310	 *	Check for a route to destination an obtain the
311	 *	destination cache for it.
312	 */
313
314	fl.proto = IPPROTO_UDP;
315	fl.fl6_dst = &np->daddr;
316	fl.fl6_src = &saddr;
317	fl.oif = sk->bound_dev_if;
318	fl.uli_u.ports.dport = sk->dport;
319	fl.uli_u.ports.sport = sk->sport;
320
321	if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
322		fl.oif = np->mcast_oif;
323
324	if (flowlabel) {
325		if (flowlabel->opt && flowlabel->opt->srcrt) {
326			struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
327			fl.fl6_dst = rt0->addr;
328		}
329	} else if (np->opt && np->opt->srcrt) {
330		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
331		fl.fl6_dst = rt0->addr;
332	}
333
334	dst = ip6_route_output(sk, &fl);
335
336	if ((err = dst->error) != 0) {
337		dst_release(dst);
338		fl6_sock_release(flowlabel);
339		return err;
340	}
341
342	ip6_dst_store(sk, dst, fl.fl6_dst);
343
344	/* get the source adddress used in the apropriate device */
345
346	err = ipv6_get_saddr(dst, daddr, &saddr);
347
348	if (err == 0) {
349		if(ipv6_addr_any(&np->saddr))
350			ipv6_addr_copy(&np->saddr, &saddr);
351
352		if(ipv6_addr_any(&np->rcv_saddr)) {
353			ipv6_addr_copy(&np->rcv_saddr, &saddr);
354			sk->rcv_saddr = LOOPBACK4_IPV6;
355		}
356		sk->state = TCP_ESTABLISHED;
357	}
358	fl6_sock_release(flowlabel);
359
360	return err;
361}
362
363static void udpv6_close(struct sock *sk, long timeout)
364{
365	inet_sock_release(sk);
366}
367
368/*
369 * 	This should be easy, if there is something there we
370 * 	return it, otherwise we block.
371 */
372
373int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
374		  int noblock, int flags, int *addr_len)
375{
376  	struct sk_buff *skb;
377  	int copied, err;
378
379  	if (addr_len)
380  		*addr_len=sizeof(struct sockaddr_in6);
381
382	if (flags & MSG_ERRQUEUE)
383		return ipv6_recv_error(sk, msg, len);
384
385	skb = skb_recv_datagram(sk, flags, noblock, &err);
386	if (!skb)
387		goto out;
388
389 	copied = skb->len - sizeof(struct udphdr);
390  	if (copied > len) {
391  		copied = len;
392  		msg->msg_flags |= MSG_TRUNC;
393  	}
394
395	if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
396		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
397					      copied);
398	} else if (msg->msg_flags&MSG_TRUNC) {
399		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
400			goto csum_copy_err;
401		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
402					      copied);
403	} else {
404		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
405		if (err == -EINVAL)
406			goto csum_copy_err;
407	}
408	if (err)
409		goto out_free;
410
411	sock_recv_timestamp(msg, sk, skb);
412
413	/* Copy the address. */
414	if (msg->msg_name) {
415		struct sockaddr_in6 *sin6;
416
417		sin6 = (struct sockaddr_in6 *) msg->msg_name;
418		sin6->sin6_family = AF_INET6;
419		sin6->sin6_port = skb->h.uh->source;
420		sin6->sin6_flowinfo = 0;
421		sin6->sin6_scope_id = 0;
422
423		if (skb->protocol == htons(ETH_P_IP)) {
424			ipv6_addr_set(&sin6->sin6_addr, 0, 0,
425				      htonl(0xffff), skb->nh.iph->saddr);
426			if (sk->protinfo.af_inet.cmsg_flags)
427				ip_cmsg_recv(msg, skb);
428		} else {
429			memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
430			       sizeof(struct in6_addr));
431
432			if (sk->net_pinfo.af_inet6.rxopt.all)
433				datagram_recv_ctl(sk, msg, skb);
434			if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
435				struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
436				sin6->sin6_scope_id = opt->iif;
437			}
438		}
439  	}
440	err = copied;
441
442out_free:
443	skb_free_datagram(sk, skb);
444out:
445	return err;
446
447csum_copy_err:
448	/* Clear queue. */
449	if (flags&MSG_PEEK) {
450		int clear = 0;
451		spin_lock_irq(&sk->receive_queue.lock);
452		if (skb == skb_peek(&sk->receive_queue)) {
453			__skb_unlink(skb, &sk->receive_queue);
454			clear = 1;
455		}
456		spin_unlock_irq(&sk->receive_queue.lock);
457		if (clear)
458			kfree_skb(skb);
459	}
460
461	/* Error for blocking case is chosen to masquerade
462	   as some normal condition.
463	 */
464	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
465	UDP6_INC_STATS_USER(UdpInErrors);
466	goto out_free;
467}
468
469void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
470	       int type, int code, int offset, __u32 info)
471{
472	struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
473	struct net_device *dev = skb->dev;
474	struct in6_addr *saddr = &hdr->saddr;
475	struct in6_addr *daddr = &hdr->daddr;
476	struct udphdr *uh = (struct udphdr*)(skb->data+offset);
477	struct sock *sk;
478	int err;
479
480	sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
481
482	if (sk == NULL)
483		return;
484
485	if (!icmpv6_err_convert(type, code, &err) &&
486	    !sk->net_pinfo.af_inet6.recverr)
487		goto out;
488
489	if (sk->state!=TCP_ESTABLISHED &&
490	    !sk->net_pinfo.af_inet6.recverr)
491		goto out;
492
493	if (sk->net_pinfo.af_inet6.recverr)
494		ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
495
496	sk->err = err;
497	sk->error_report(sk);
498out:
499	sock_put(sk);
500}
501
502static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
503{
504#if defined(CONFIG_FILTER)
505	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
506		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
507			UDP6_INC_STATS_BH(UdpInErrors);
508			IP6_INC_STATS_BH(Ip6InDiscards);
509			kfree_skb(skb);
510			return 0;
511		}
512		skb->ip_summed = CHECKSUM_UNNECESSARY;
513	}
514#endif
515	if (sock_queue_rcv_skb(sk,skb)<0) {
516		UDP6_INC_STATS_BH(UdpInErrors);
517		IP6_INC_STATS_BH(Ip6InDiscards);
518		kfree_skb(skb);
519		return 0;
520	}
521  	IP6_INC_STATS_BH(Ip6InDelivers);
522	UDP6_INC_STATS_BH(UdpInDatagrams);
523	return 0;
524}
525
526static struct sock *udp_v6_mcast_next(struct sock *sk,
527				      u16 loc_port, struct in6_addr *loc_addr,
528				      u16 rmt_port, struct in6_addr *rmt_addr,
529				      int dif)
530{
531	struct sock *s = sk;
532	unsigned short num = ntohs(loc_port);
533	for(; s; s = s->next) {
534		if(s->num == num) {
535			struct ipv6_pinfo *np = &s->net_pinfo.af_inet6;
536			if(s->dport) {
537				if(s->dport != rmt_port)
538					continue;
539			}
540			if(!ipv6_addr_any(&np->daddr) &&
541			   ipv6_addr_cmp(&np->daddr, rmt_addr))
542				continue;
543
544			if (s->bound_dev_if && s->bound_dev_if != dif)
545				continue;
546
547			if(!ipv6_addr_any(&np->rcv_saddr)) {
548				if(ipv6_addr_cmp(&np->rcv_saddr, loc_addr) == 0)
549					return s;
550			}
551			if(!inet6_mc_check(s, loc_addr))
552				continue;
553			return s;
554		}
555	}
556	return NULL;
557}
558
559/*
560 * Note: called only from the BH handler context,
561 * so we don't need to lock the hashes.
562 */
563static void udpv6_mcast_deliver(struct udphdr *uh,
564				struct in6_addr *saddr, struct in6_addr *daddr,
565				struct sk_buff *skb)
566{
567	struct sock *sk, *sk2;
568	struct sk_buff *buff;
569	int dif;
570
571	read_lock(&udp_hash_lock);
572	sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
573	dif = skb->dev->ifindex;
574	sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
575	if (!sk)
576		goto free_skb;
577
578	buff = NULL;
579	sk2 = sk;
580	while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
581						  uh->source, saddr, dif))) {
582		if (!buff) {
583			buff = skb_clone(skb, GFP_ATOMIC);
584			if (!buff)
585				continue;
586		}
587		if (sock_queue_rcv_skb(sk2, buff) >= 0)
588			buff = NULL;
589	}
590	if (buff)
591		kfree_skb(buff);
592	if (sock_queue_rcv_skb(sk, skb) < 0) {
593free_skb:
594		kfree_skb(skb);
595	}
596	read_unlock(&udp_hash_lock);
597}
598
599int udpv6_rcv(struct sk_buff *skb)
600{
601	struct sock *sk;
602  	struct udphdr *uh;
603	struct net_device *dev = skb->dev;
604	struct in6_addr *saddr, *daddr;
605	u32 ulen = 0;
606
607	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
608		goto short_packet;
609
610	saddr = &skb->nh.ipv6h->saddr;
611	daddr = &skb->nh.ipv6h->daddr;
612	uh = skb->h.uh;
613
614	ulen = ntohs(uh->len);
615
616	/* Check for jumbo payload */
617	if (ulen == 0)
618		ulen = skb->len;
619
620	if (ulen > skb->len || ulen < sizeof(*uh))
621		goto short_packet;
622
623	if (uh->check == 0) {
624		/* IPv6 draft-v2 section 8.1 says that we SHOULD log
625		   this error. Well, it is reasonable.
626		 */
627		if (net_ratelimit())
628			printk(KERN_INFO "IPv6: udp checksum is 0\n");
629		goto discard;
630	}
631
632	if (ulen < skb->len) {
633		if (__pskb_trim(skb, ulen))
634			goto discard;
635		saddr = &skb->nh.ipv6h->saddr;
636		daddr = &skb->nh.ipv6h->daddr;
637		uh = skb->h.uh;
638	}
639
640	if (skb->ip_summed==CHECKSUM_HW) {
641		skb->ip_summed = CHECKSUM_UNNECESSARY;
642		if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
643			NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.\n"));
644			skb->ip_summed = CHECKSUM_NONE;
645		}
646	}
647	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
648		skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
649
650	/*
651	 *	Multicast receive code
652	 */
653	if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
654		udpv6_mcast_deliver(uh, saddr, daddr, skb);
655		return 0;
656	}
657
658	/* Unicast */
659
660	/*
661	 * check socket cache ... must talk to Alan about his plans
662	 * for sock caches... i'll skip this for now.
663	 */
664	sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
665
666	if (sk == NULL) {
667		if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
668		    (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
669			goto discard;
670		UDP6_INC_STATS_BH(UdpNoPorts);
671
672		icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
673
674		kfree_skb(skb);
675		return(0);
676	}
677
678	/* deliver */
679
680	udpv6_queue_rcv_skb(sk, skb);
681	sock_put(sk);
682	return(0);
683
684short_packet:
685	if (net_ratelimit())
686		printk(KERN_DEBUG "UDP: short packet: %d/%u\n", ulen, skb->len);
687
688discard:
689	UDP6_INC_STATS_BH(UdpInErrors);
690	kfree_skb(skb);
691	return(0);
692}
693
694/*
695 *	Sending
696 */
697
698struct udpv6fakehdr
699{
700	struct udphdr	uh;
701	struct iovec	*iov;
702	__u32		wcheck;
703	__u32		pl_len;
704	struct in6_addr *daddr;
705};
706
707/*
708 *	with checksum
709 */
710
711static int udpv6_getfrag(const void *data, struct in6_addr *addr,
712			 char *buff, unsigned int offset, unsigned int len)
713{
714	struct udpv6fakehdr *udh = (struct udpv6fakehdr *) data;
715	char *dst;
716	int final = 0;
717	int clen = len;
718
719	dst = buff;
720
721	if (offset) {
722		offset -= sizeof(struct udphdr);
723	} else {
724		dst += sizeof(struct udphdr);
725		final = 1;
726		clen -= sizeof(struct udphdr);
727	}
728
729	if (csum_partial_copy_fromiovecend(dst, udh->iov, offset,
730					   clen, &udh->wcheck))
731		return -EFAULT;
732
733	if (final) {
734		struct in6_addr *daddr;
735
736		udh->wcheck = csum_partial((char *)udh, sizeof(struct udphdr),
737					   udh->wcheck);
738
739		if (udh->daddr) {
740			daddr = udh->daddr;
741		} else {
742			/*
743			 *	use packet destination address
744			 *	this should improve cache locality
745			 */
746			daddr = addr + 1;
747		}
748		udh->uh.check = csum_ipv6_magic(addr, daddr,
749						udh->pl_len, IPPROTO_UDP,
750						udh->wcheck);
751		if (udh->uh.check == 0)
752			udh->uh.check = -1;
753
754		memcpy(buff, udh, sizeof(struct udphdr));
755	}
756	return 0;
757}
758
759static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
760{
761	struct ipv6_txoptions opt_space;
762	struct udpv6fakehdr udh;
763	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
764	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
765	struct ipv6_txoptions *opt = NULL;
766	struct ip6_flowlabel *flowlabel = NULL;
767	struct flowi fl;
768	int addr_len = msg->msg_namelen;
769	struct in6_addr *daddr;
770	int len = ulen + sizeof(struct udphdr);
771	int addr_type;
772	int hlimit = -1;
773
774	int err;
775
776	/* Rough check on arithmetic overflow,
777	   better check is made in ip6_build_xmit
778	   */
779	if (ulen < 0 || ulen > INT_MAX - sizeof(struct udphdr))
780		return -EMSGSIZE;
781
782	fl.fl6_flowlabel = 0;
783	fl.oif = 0;
784
785	if (sin6) {
786		if (sin6->sin6_family == AF_INET)
787			return udp_sendmsg(sk, msg, ulen);
788
789		if (addr_len < SIN6_LEN_RFC2133)
790			return -EINVAL;
791
792		if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
793			return -EINVAL;
794
795		if (sin6->sin6_port == 0)
796			return -EINVAL;
797
798		udh.uh.dest = sin6->sin6_port;
799		daddr = &sin6->sin6_addr;
800
801		if (np->sndflow) {
802			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
803			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
804				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
805				if (flowlabel == NULL)
806					return -EINVAL;
807				daddr = &flowlabel->dst;
808			}
809		}
810
811		/* Otherwise it will be difficult to maintain sk->dst_cache. */
812		if (sk->state == TCP_ESTABLISHED &&
813		    !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
814			daddr = &sk->net_pinfo.af_inet6.daddr;
815
816		if (addr_len >= sizeof(struct sockaddr_in6) &&
817		    sin6->sin6_scope_id &&
818		    ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
819			fl.oif = sin6->sin6_scope_id;
820	} else {
821		if (sk->state != TCP_ESTABLISHED)
822			return -ENOTCONN;
823
824		udh.uh.dest = sk->dport;
825		daddr = &sk->net_pinfo.af_inet6.daddr;
826		fl.fl6_flowlabel = np->flow_label;
827	}
828
829	addr_type = ipv6_addr_type(daddr);
830
831	if (addr_type == IPV6_ADDR_MAPPED) {
832		struct sockaddr_in sin;
833
834		sin.sin_family = AF_INET;
835		sin.sin_addr.s_addr = daddr->s6_addr32[3];
836		sin.sin_port = udh.uh.dest;
837		msg->msg_name = (struct sockaddr *)(&sin);
838		msg->msg_namelen = sizeof(sin);
839		fl6_sock_release(flowlabel);
840
841		return udp_sendmsg(sk, msg, ulen);
842	}
843
844	udh.daddr = NULL;
845	if (!fl.oif)
846		fl.oif = sk->bound_dev_if;
847	fl.fl6_src = NULL;
848
849	if (msg->msg_controllen) {
850		opt = &opt_space;
851		memset(opt, 0, sizeof(struct ipv6_txoptions));
852
853		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
854		if (err < 0) {
855			fl6_sock_release(flowlabel);
856			return err;
857		}
858		if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
859			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
860			if (flowlabel == NULL)
861				return -EINVAL;
862		}
863		if (!(opt->opt_nflen|opt->opt_flen))
864			opt = NULL;
865	}
866	if (opt == NULL)
867		opt = np->opt;
868	if (flowlabel)
869		opt = fl6_merge_options(&opt_space, flowlabel, opt);
870	if (opt && opt->srcrt)
871		udh.daddr = daddr;
872
873	udh.uh.source = sk->sport;
874	udh.uh.len = len < 0x10000 ? htons(len) : 0;
875	udh.uh.check = 0;
876	udh.iov = msg->msg_iov;
877	udh.wcheck = 0;
878	udh.pl_len = len;
879
880	fl.proto = IPPROTO_UDP;
881	fl.fl6_dst = daddr;
882	if (fl.fl6_src == NULL && !ipv6_addr_any(&np->saddr))
883		fl.fl6_src = &np->saddr;
884	fl.uli_u.ports.dport = udh.uh.dest;
885	fl.uli_u.ports.sport = udh.uh.source;
886
887	err = ip6_build_xmit(sk, udpv6_getfrag, &udh, &fl, len, opt, hlimit,
888			     msg->msg_flags);
889
890	fl6_sock_release(flowlabel);
891
892	if (err < 0)
893		return err;
894
895	UDP6_INC_STATS_USER(UdpOutDatagrams);
896	return ulen;
897}
898
899static struct inet6_protocol udpv6_protocol =
900{
901	udpv6_rcv,		/* UDP handler		*/
902	udpv6_err,		/* UDP error control	*/
903	NULL,			/* next			*/
904	IPPROTO_UDP,		/* protocol ID		*/
905	0,			/* copy			*/
906	NULL,			/* data			*/
907	"UDPv6"			/* name			*/
908};
909
910#define LINE_LEN 190
911#define LINE_FMT "%-190s\n"
912
913static void get_udp6_sock(struct sock *sp, char *tmpbuf, int i)
914{
915	struct in6_addr *dest, *src;
916	__u16 destp, srcp;
917
918	dest  = &sp->net_pinfo.af_inet6.daddr;
919	src   = &sp->net_pinfo.af_inet6.rcv_saddr;
920	destp = ntohs(sp->dport);
921	srcp  = ntohs(sp->sport);
922	sprintf(tmpbuf,
923		"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
924		"%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
925		i,
926		src->s6_addr32[0], src->s6_addr32[1],
927		src->s6_addr32[2], src->s6_addr32[3], srcp,
928		dest->s6_addr32[0], dest->s6_addr32[1],
929		dest->s6_addr32[2], dest->s6_addr32[3], destp,
930		sp->state,
931		atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
932		0, 0L, 0,
933		sock_i_uid(sp), 0,
934		sock_i_ino(sp),
935		atomic_read(&sp->refcnt), sp);
936}
937
938int udp6_get_info(char *buffer, char **start, off_t offset, int length)
939{
940	int len = 0, num = 0, i;
941	off_t pos = 0;
942	off_t begin;
943	char tmpbuf[LINE_LEN+2];
944
945	if (offset < LINE_LEN+1)
946		len += sprintf(buffer, LINE_FMT,
947			       "  sl  "						/* 6 */
948			       "local_address                         "		/* 38 */
949			       "remote_address                        "		/* 38 */
950			       "st tx_queue rx_queue tr tm->when retrnsmt"	/* 41 */
951			       "   uid  timeout inode");			/* 21 */
952										/*----*/
953										/*144 */
954	pos = LINE_LEN+1;
955	read_lock(&udp_hash_lock);
956	for (i = 0; i < UDP_HTABLE_SIZE; i++) {
957		struct sock *sk;
958
959		for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
960			if (sk->family != PF_INET6)
961				continue;
962			pos += LINE_LEN+1;
963			if (pos <= offset)
964				continue;
965			get_udp6_sock(sk, tmpbuf, i);
966			len += sprintf(buffer+len, LINE_FMT, tmpbuf);
967			if(len >= length)
968				goto out;
969		}
970	}
971out:
972	read_unlock(&udp_hash_lock);
973	begin = len - (pos - offset);
974	*start = buffer + begin;
975	len -= begin;
976	if(len > length)
977		len = length;
978	if (len < 0)
979		len = 0;
980	return len;
981}
982
983struct proto udpv6_prot = {
984	name:		"UDP",
985	close:		udpv6_close,
986	connect:	udpv6_connect,
987	disconnect:	udp_disconnect,
988	ioctl:		udp_ioctl,
989	destroy:	inet6_destroy_sock,
990	setsockopt:	ipv6_setsockopt,
991	getsockopt:	ipv6_getsockopt,
992	sendmsg:	udpv6_sendmsg,
993	recvmsg:	udpv6_recvmsg,
994	backlog_rcv:	udpv6_queue_rcv_skb,
995	hash:		udp_v6_hash,
996	unhash:		udp_v6_unhash,
997	get_port:	udp_v6_get_port,
998};
999
1000extern struct proto_ops inet6_dgram_ops;
1001
1002static struct inet_protosw udpv6_protosw = {
1003	type:        SOCK_DGRAM,
1004	protocol:    IPPROTO_UDP,
1005	prot:        &udpv6_prot,
1006	ops:         &inet6_dgram_ops,
1007	capability:  -1,
1008	no_check:    UDP_CSUM_DEFAULT,
1009	flags:       INET_PROTOSW_PERMANENT,
1010};
1011
1012
1013void __init udpv6_init(void)
1014{
1015	inet6_add_protocol(&udpv6_protocol);
1016	inet6_register_protosw(&udpv6_protosw);
1017}
1018