File: /usr/src/linux/net/ipv6/udp.c

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.64 2001/09/01 00:31:50 davem 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     
51     struct 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      */
56     static 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     		}
97     gotit:
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     
134     fail:
135     	write_unlock_bh(&udp_hash_lock);
136     	return 1;
137     }
138     
139     static void udp_v6_hash(struct sock *sk)
140     {
141     	BUG();
142     }
143     
144     static 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     
159     static 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     
211     int 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     
265     ipv4_connected:
266     		if (err < 0)
267     			return err;
268     		
269     		ipv6_addr_set(&np->daddr, 0, 0, 
270     			      __constant_htonl(0x0000ffff),
271     			      sk->daddr);
272     
273     		if(ipv6_addr_any(&np->saddr)) {
274     			ipv6_addr_set(&np->saddr, 0, 0, 
275     				      __constant_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     				      __constant_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     		}
296     
297     		/* Connect to link-local address requires an interface */
298     		if (sk->bound_dev_if == 0)
299     			return -EINVAL;
300     	}
301     
302     	ipv6_addr_copy(&np->daddr, daddr);
303     	np->flow_label = fl.fl6_flowlabel;
304     
305     	sk->dport = usin->sin6_port;
306     
307     	/*
308     	 *	Check for a route to destination an obtain the
309     	 *	destination cache for it.
310     	 */
311     
312     	fl.proto = IPPROTO_UDP;
313     	fl.fl6_dst = &np->daddr;
314     	fl.fl6_src = &saddr;
315     	fl.oif = sk->bound_dev_if;
316     	fl.uli_u.ports.dport = sk->dport;
317     	fl.uli_u.ports.sport = sk->sport;
318     
319     	if (flowlabel) {
320     		if (flowlabel->opt && flowlabel->opt->srcrt) {
321     			struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
322     			fl.fl6_dst = rt0->addr;
323     		}
324     	} else if (np->opt && np->opt->srcrt) {
325     		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
326     		fl.fl6_dst = rt0->addr;
327     	}
328     
329     	dst = ip6_route_output(sk, &fl);
330     
331     	if ((err = dst->error) != 0) {
332     		dst_release(dst);
333     		fl6_sock_release(flowlabel);
334     		return err;
335     	}
336     
337     	ip6_dst_store(sk, dst, fl.fl6_dst);
338     
339     	/* get the source adddress used in the apropriate device */
340     
341     	err = ipv6_get_saddr(dst, daddr, &saddr);
342     
343     	if (err == 0) {
344     		if(ipv6_addr_any(&np->saddr))
345     			ipv6_addr_copy(&np->saddr, &saddr);
346     
347     		if(ipv6_addr_any(&np->rcv_saddr)) {
348     			ipv6_addr_copy(&np->rcv_saddr, &saddr);
349     			sk->rcv_saddr = LOOPBACK4_IPV6;
350     		}
351     		sk->state = TCP_ESTABLISHED;
352     	}
353     	fl6_sock_release(flowlabel);
354     
355     	return err;
356     }
357     
358     static void udpv6_close(struct sock *sk, long timeout)
359     {
360     	inet_sock_release(sk);
361     }
362     
363     /*
364      * 	This should be easy, if there is something there we
365      * 	return it, otherwise we block.
366      */
367     
368     int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
369     		  int noblock, int flags, int *addr_len)
370     {
371       	struct sk_buff *skb;
372       	int copied, err;
373     
374       	if (addr_len)
375       		*addr_len=sizeof(struct sockaddr_in6);
376       
377     	if (flags & MSG_ERRQUEUE)
378     		return ipv6_recv_error(sk, msg, len);
379     
380     	skb = skb_recv_datagram(sk, flags, noblock, &err);
381     	if (!skb)
382     		goto out;
383     
384      	copied = skb->len - sizeof(struct udphdr);
385       	if (copied > len) {
386       		copied = len;
387       		msg->msg_flags |= MSG_TRUNC;
388       	}
389     
390     	if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
391     		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
392     					      copied);
393     	} else if (msg->msg_flags&MSG_TRUNC) {
394     		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
395     			goto csum_copy_err;
396     		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
397     					      copied);
398     	} else {
399     		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
400     		if (err == -EINVAL)
401     			goto csum_copy_err;
402     	}
403     	if (err)
404     		goto out_free;
405     
406     	sock_recv_timestamp(msg, sk, skb);
407     
408     	/* Copy the address. */
409     	if (msg->msg_name) {
410     		struct sockaddr_in6 *sin6;
411     	  
412     		sin6 = (struct sockaddr_in6 *) msg->msg_name;
413     		sin6->sin6_family = AF_INET6;
414     		sin6->sin6_port = skb->h.uh->source;
415     		sin6->sin6_flowinfo = 0;
416     		sin6->sin6_scope_id = 0;
417     
418     		if (skb->protocol == __constant_htons(ETH_P_IP)) {
419     			ipv6_addr_set(&sin6->sin6_addr, 0, 0,
420     				      __constant_htonl(0xffff), skb->nh.iph->saddr);
421     			if (sk->protinfo.af_inet.cmsg_flags)
422     				ip_cmsg_recv(msg, skb);
423     		} else {
424     			memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
425     			       sizeof(struct in6_addr));
426     
427     			if (sk->net_pinfo.af_inet6.rxopt.all)
428     				datagram_recv_ctl(sk, msg, skb);
429     			if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
430     				struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
431     				sin6->sin6_scope_id = opt->iif;
432     			}
433     		}
434       	}
435     	err = copied;
436     
437     out_free:
438     	skb_free_datagram(sk, skb);
439     out:
440     	return err;
441     
442     csum_copy_err:
443     	/* Clear queue. */
444     	if (flags&MSG_PEEK) {
445     		int clear = 0;
446     		spin_lock_irq(&sk->receive_queue.lock);
447     		if (skb == skb_peek(&sk->receive_queue)) {
448     			__skb_unlink(skb, &sk->receive_queue);
449     			clear = 1;
450     		}
451     		spin_unlock_irq(&sk->receive_queue.lock);
452     		if (clear)
453     			kfree_skb(skb);
454     	}
455     
456     	/* Error for blocking case is chosen to masquerade
457     	   as some normal condition.
458     	 */
459     	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
460     	UDP6_INC_STATS_USER(UdpInErrors);
461     	goto out_free;
462     }
463     
464     void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
465     	       int type, int code, int offset, __u32 info)
466     {
467     	struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
468     	struct net_device *dev = skb->dev;
469     	struct in6_addr *saddr = &hdr->saddr;
470     	struct in6_addr *daddr = &hdr->daddr;
471     	struct udphdr *uh = (struct udphdr*)(skb->data+offset);
472     	struct sock *sk;
473     	int err;
474     
475     	sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
476        
477     	if (sk == NULL)
478     		return;
479     
480     	if (!icmpv6_err_convert(type, code, &err) &&
481     	    !sk->net_pinfo.af_inet6.recverr)
482     		goto out;
483     
484     	if (sk->state!=TCP_ESTABLISHED &&
485     	    !sk->net_pinfo.af_inet6.recverr)
486     		goto out;
487     
488     	if (sk->net_pinfo.af_inet6.recverr)
489     		ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
490     
491     	sk->err = err;
492     	sk->error_report(sk);
493     out:
494     	sock_put(sk);
495     }
496     
497     static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
498     {
499     #if defined(CONFIG_FILTER)
500     	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
501     		if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
502     			UDP6_INC_STATS_BH(UdpInErrors);
503     			IP6_INC_STATS_BH(Ip6InDiscards);
504     			kfree_skb(skb);
505     			return 0;
506     		}
507     		skb->ip_summed = CHECKSUM_UNNECESSARY;
508     	}
509     #endif
510     	if (sock_queue_rcv_skb(sk,skb)<0) {
511     		UDP6_INC_STATS_BH(UdpInErrors);
512     		IP6_INC_STATS_BH(Ip6InDiscards);
513     		kfree_skb(skb);
514     		return 0;
515     	}
516       	IP6_INC_STATS_BH(Ip6InDelivers);
517     	UDP6_INC_STATS_BH(UdpInDatagrams);
518     	return 0;
519     }
520     
521     static struct sock *udp_v6_mcast_next(struct sock *sk,
522     				      u16 loc_port, struct in6_addr *loc_addr,
523     				      u16 rmt_port, struct in6_addr *rmt_addr,
524     				      int dif)
525     {
526     	struct sock *s = sk;
527     	unsigned short num = ntohs(loc_port);
528     	for(; s; s = s->next) {
529     		if(s->num == num) {
530     			struct ipv6_pinfo *np = &s->net_pinfo.af_inet6;
531     			if(s->dport) {
532     				if(s->dport != rmt_port)
533     					continue;
534     			}
535     			if(!ipv6_addr_any(&np->daddr) &&
536     			   ipv6_addr_cmp(&np->daddr, rmt_addr))
537     				continue;
538     
539     			if (s->bound_dev_if && s->bound_dev_if != dif)
540     				continue;
541     
542     			if(!ipv6_addr_any(&np->rcv_saddr)) {
543     				if(ipv6_addr_cmp(&np->rcv_saddr, loc_addr) == 0)
544     					return s;
545     			}
546     			if(!inet6_mc_check(s, loc_addr))
547     				continue;
548     			return s;
549     		}
550     	}
551     	return NULL;
552     }
553     
554     /*
555      * Note: called only from the BH handler context,
556      * so we don't need to lock the hashes.
557      */
558     static void udpv6_mcast_deliver(struct udphdr *uh,
559     				struct in6_addr *saddr, struct in6_addr *daddr,
560     				struct sk_buff *skb)
561     {
562     	struct sock *sk, *sk2;
563     	struct sk_buff *buff;
564     	int dif;
565     
566     	read_lock(&udp_hash_lock);
567     	sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
568     	dif = skb->dev->ifindex;
569     	sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
570     	if (!sk)
571     		goto free_skb;
572     
573     	buff = NULL;
574     	sk2 = sk;
575     	while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
576     						  uh->source, saddr, dif))) {
577     		if (!buff) {
578     			buff = skb_clone(skb, GFP_ATOMIC);
579     			if (!buff)
580     				continue;
581     		}
582     		if (sock_queue_rcv_skb(sk2, buff) >= 0)
583     			buff = NULL;
584     	}
585     	if (buff)
586     		kfree_skb(buff);
587     	if (sock_queue_rcv_skb(sk, skb) < 0) {
588     free_skb:
589     		kfree_skb(skb);
590     	}
591     	read_unlock(&udp_hash_lock);
592     }
593     
594     int udpv6_rcv(struct sk_buff *skb)
595     {
596     	struct sock *sk;
597       	struct udphdr *uh;
598     	struct net_device *dev = skb->dev;
599     	struct in6_addr *saddr, *daddr;
600     	u32 ulen = 0;
601     
602     	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
603     		goto short_packet;
604     
605     	saddr = &skb->nh.ipv6h->saddr;
606     	daddr = &skb->nh.ipv6h->daddr;
607     	uh = skb->h.uh;
608     
609     	ulen = ntohs(uh->len);
610     
611     	/* Check for jumbo payload */
612     	if (ulen == 0)
613     		ulen = skb->len;
614     
615     	if (ulen > skb->len || ulen < sizeof(*uh))
616     		goto short_packet;
617     
618     	if (uh->check == 0) {
619     		/* IPv6 draft-v2 section 8.1 says that we SHOULD log
620     		   this error. Well, it is reasonable.
621     		 */
622     		if (net_ratelimit())
623     			printk(KERN_INFO "IPv6: udp checksum is 0\n");
624     		goto discard;
625     	}
626     
627     	if (ulen < skb->len) {
628     		if (__pskb_trim(skb, ulen))
629     			goto discard;
630     		saddr = &skb->nh.ipv6h->saddr;
631     		daddr = &skb->nh.ipv6h->daddr;
632     		uh = skb->h.uh;
633     	}
634     
635     	if (skb->ip_summed==CHECKSUM_HW) {
636     		skb->ip_summed = CHECKSUM_UNNECESSARY;
637     		if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
638     			NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.\n"));
639     			skb->ip_summed = CHECKSUM_NONE;
640     		}
641     	}
642     	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
643     		skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
644     
645     	/* 
646     	 *	Multicast receive code 
647     	 */
648     	if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
649     		udpv6_mcast_deliver(uh, saddr, daddr, skb);
650     		return 0;
651     	}
652     
653     	/* Unicast */
654     
655     	/* 
656     	 * check socket cache ... must talk to Alan about his plans
657     	 * for sock caches... i'll skip this for now.
658     	 */
659     	sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
660     
661     	if (sk == NULL) {
662     		if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
663     		    (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
664     			goto discard;
665     		UDP6_INC_STATS_BH(UdpNoPorts);
666     
667     		icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
668     
669     		kfree_skb(skb);
670     		return(0);
671     	}
672     	
673     	/* deliver */
674     	
675     	udpv6_queue_rcv_skb(sk, skb);
676     	sock_put(sk);
677     	return(0);
678     
679     short_packet:	
680     	if (net_ratelimit())
681     		printk(KERN_DEBUG "UDP: short packet: %d/%u\n", ulen, skb->len);
682     
683     discard:
684     	UDP6_INC_STATS_BH(UdpInErrors);
685     	kfree_skb(skb);
686     	return(0);	
687     }
688     
689     /*
690      *	Sending
691      */
692     
693     struct udpv6fakehdr 
694     {
695     	struct udphdr	uh;
696     	struct iovec	*iov;
697     	__u32		wcheck;
698     	__u32		pl_len;
699     	struct in6_addr *daddr;
700     };
701     
702     /*
703      *	with checksum
704      */
705     
706     static int udpv6_getfrag(const void *data, struct in6_addr *addr,
707     			 char *buff, unsigned int offset, unsigned int len)
708     {
709     	struct udpv6fakehdr *udh = (struct udpv6fakehdr *) data;
710     	char *dst;
711     	int final = 0;
712     	int clen = len;
713     
714     	dst = buff;
715     
716     	if (offset) {
717     		offset -= sizeof(struct udphdr);
718     	} else {
719     		dst += sizeof(struct udphdr);
720     		final = 1;
721     		clen -= sizeof(struct udphdr);
722     	}
723     
724     	if (csum_partial_copy_fromiovecend(dst, udh->iov, offset,
725     					   clen, &udh->wcheck))
726     		return -EFAULT;
727     
728     	if (final) {
729     		struct in6_addr *daddr;
730     		
731     		udh->wcheck = csum_partial((char *)udh, sizeof(struct udphdr),
732     					   udh->wcheck);
733     
734     		if (udh->daddr) {
735     			daddr = udh->daddr;
736     		} else {
737     			/*
738     			 *	use packet destination address
739     			 *	this should improve cache locality
740     			 */
741     			daddr = addr + 1;
742     		}
743     		udh->uh.check = csum_ipv6_magic(addr, daddr,
744     						udh->pl_len, IPPROTO_UDP,
745     						udh->wcheck);
746     		if (udh->uh.check == 0)
747     			udh->uh.check = -1;
748     
749     		memcpy(buff, udh, sizeof(struct udphdr));
750     	}
751     	return 0;
752     }
753     
754     static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
755     {
756     	struct ipv6_txoptions opt_space;
757     	struct udpv6fakehdr udh;
758     	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
759     	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
760     	struct ipv6_txoptions *opt = NULL;
761     	struct ip6_flowlabel *flowlabel = NULL;
762     	struct flowi fl;
763     	int addr_len = msg->msg_namelen;
764     	struct in6_addr *daddr;
765     	int len = ulen + sizeof(struct udphdr);
766     	int addr_type;
767     	int hlimit = -1;
768     	
769     	int err;
770     	
771     	/* Rough check on arithmetic overflow,
772     	   better check is made in ip6_build_xmit
773     	   */
774     	if (ulen < 0 || ulen > INT_MAX - sizeof(struct udphdr))
775     		return -EMSGSIZE;
776     	
777     	fl.fl6_flowlabel = 0;
778     	fl.oif = 0;
779     
780     	if (sin6) {
781     		if (sin6->sin6_family == AF_INET)
782     			return udp_sendmsg(sk, msg, ulen);
783     
784     		if (addr_len < SIN6_LEN_RFC2133)
785     			return -EINVAL;
786     
787     		if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
788     			return -EINVAL;
789     
790     		if (sin6->sin6_port == 0)
791     			return -EINVAL;
792     
793     		udh.uh.dest = sin6->sin6_port;
794     		daddr = &sin6->sin6_addr;
795     
796     		if (np->sndflow) {
797     			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
798     			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
799     				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
800     				if (flowlabel == NULL)
801     					return -EINVAL;
802     				daddr = &flowlabel->dst;
803     			}
804     		}
805     
806     		/* Otherwise it will be difficult to maintain sk->dst_cache. */
807     		if (sk->state == TCP_ESTABLISHED &&
808     		    !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
809     			daddr = &sk->net_pinfo.af_inet6.daddr;
810     
811     		if (addr_len >= sizeof(struct sockaddr_in6) &&
812     		    sin6->sin6_scope_id &&
813     		    ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
814     			fl.oif = sin6->sin6_scope_id;
815     	} else {
816     		if (sk->state != TCP_ESTABLISHED)
817     			return -ENOTCONN;
818     
819     		udh.uh.dest = sk->dport;
820     		daddr = &sk->net_pinfo.af_inet6.daddr;
821     		fl.fl6_flowlabel = np->flow_label;
822     	}
823     
824     	addr_type = ipv6_addr_type(daddr);
825     
826     	if (addr_type == IPV6_ADDR_MAPPED) {
827     		struct sockaddr_in sin;
828     
829     		sin.sin_family = AF_INET;
830     		sin.sin_addr.s_addr = daddr->s6_addr32[3];
831     		sin.sin_port = udh.uh.dest;
832     		msg->msg_name = (struct sockaddr *)(&sin);
833     		msg->msg_namelen = sizeof(sin);
834     		fl6_sock_release(flowlabel);
835     
836     		return udp_sendmsg(sk, msg, ulen);
837     	}
838     
839     	udh.daddr = NULL;
840     	if (!fl.oif)
841     		fl.oif = sk->bound_dev_if;
842     	fl.fl6_src = NULL;
843     
844     	if (msg->msg_controllen) {
845     		opt = &opt_space;
846     		memset(opt, 0, sizeof(struct ipv6_txoptions));
847     
848     		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
849     		if (err < 0) {
850     			fl6_sock_release(flowlabel);
851     			return err;
852     		}
853     		if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
854     			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
855     			if (flowlabel == NULL)
856     				return -EINVAL;
857     		}
858     		if (!(opt->opt_nflen|opt->opt_flen))
859     			opt = NULL;
860     	}
861     	if (opt == NULL)
862     		opt = np->opt;
863     	if (flowlabel)
864     		opt = fl6_merge_options(&opt_space, flowlabel, opt);
865     	if (opt && opt->srcrt)
866     		udh.daddr = daddr;
867     
868     	udh.uh.source = sk->sport;
869     	udh.uh.len = len < 0x10000 ? htons(len) : 0;
870     	udh.uh.check = 0;
871     	udh.iov = msg->msg_iov;
872     	udh.wcheck = 0;
873     	udh.pl_len = len;
874     
875     	fl.proto = IPPROTO_UDP;
876     	fl.fl6_dst = daddr;
877     	if (fl.fl6_src == NULL && !ipv6_addr_any(&np->saddr))
878     		fl.fl6_src = &np->saddr;
879     	fl.uli_u.ports.dport = udh.uh.dest;
880     	fl.uli_u.ports.sport = udh.uh.source;
881     
882     	err = ip6_build_xmit(sk, udpv6_getfrag, &udh, &fl, len, opt, hlimit,
883     			     msg->msg_flags);
884     
885     	fl6_sock_release(flowlabel);
886     
887     	if (err < 0)
888     		return err;
889     
890     	UDP6_INC_STATS_USER(UdpOutDatagrams);
891     	return ulen;
892     }
893     
894     static struct inet6_protocol udpv6_protocol = 
895     {
896     	udpv6_rcv,		/* UDP handler		*/
897     	udpv6_err,		/* UDP error control	*/
898     	NULL,			/* next			*/
899     	IPPROTO_UDP,		/* protocol ID		*/
900     	0,			/* copy			*/
901     	NULL,			/* data			*/
902     	"UDPv6"			/* name			*/
903     };
904     
905     #define LINE_LEN 190
906     #define LINE_FMT "%-190s\n"
907     
908     static void get_udp6_sock(struct sock *sp, char *tmpbuf, int i)
909     {
910     	struct in6_addr *dest, *src;
911     	__u16 destp, srcp;
912     
913     	dest  = &sp->net_pinfo.af_inet6.daddr;
914     	src   = &sp->net_pinfo.af_inet6.rcv_saddr;
915     	destp = ntohs(sp->dport);
916     	srcp  = ntohs(sp->sport);
917     	sprintf(tmpbuf,
918     		"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
919     		"%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
920     		i,
921     		src->s6_addr32[0], src->s6_addr32[1],
922     		src->s6_addr32[2], src->s6_addr32[3], srcp,
923     		dest->s6_addr32[0], dest->s6_addr32[1],
924     		dest->s6_addr32[2], dest->s6_addr32[3], destp,
925     		sp->state, 
926     		atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
927     		0, 0L, 0,
928     		sock_i_uid(sp), 0,
929     		sock_i_ino(sp),
930     		atomic_read(&sp->refcnt), sp);
931     }
932     
933     int udp6_get_info(char *buffer, char **start, off_t offset, int length)
934     {
935     	int len = 0, num = 0, i;
936     	off_t pos = 0;
937     	off_t begin;
938     	char tmpbuf[LINE_LEN+2];
939     
940     	if (offset < LINE_LEN+1)
941     		len += sprintf(buffer, LINE_FMT,
942     			       "  sl  "						/* 6 */
943     			       "local_address                         "		/* 38 */
944     			       "remote_address                        "		/* 38 */
945     			       "st tx_queue rx_queue tr tm->when retrnsmt"	/* 41 */
946     			       "   uid  timeout inode");			/* 21 */
947     										/*----*/
948     										/*144 */
949     	pos = LINE_LEN+1;
950     	read_lock(&udp_hash_lock);
951     	for (i = 0; i < UDP_HTABLE_SIZE; i++) {
952     		struct sock *sk;
953     
954     		for (sk = udp_hash[i]; sk; sk = sk->next, num++) {
955     			if (sk->family != PF_INET6)
956     				continue;
957     			pos += LINE_LEN+1;
958     			if (pos <= offset)
959     				continue;
960     			get_udp6_sock(sk, tmpbuf, i);
961     			len += sprintf(buffer+len, LINE_FMT, tmpbuf);
962     			if(len >= length)
963     				goto out;
964     		}
965     	}
966     out:
967     	read_unlock(&udp_hash_lock);
968     	begin = len - (pos - offset);
969     	*start = buffer + begin;
970     	len -= begin;
971     	if(len > length)
972     		len = length;
973     	if (len < 0)
974     		len = 0; 
975     	return len;
976     }
977     
978     struct proto udpv6_prot = {
979     	name:		"UDP",
980     	close:		udpv6_close,
981     	connect:	udpv6_connect,
982     	disconnect:	udp_disconnect,
983     	ioctl:		udp_ioctl,
984     	destroy:	inet6_destroy_sock,
985     	setsockopt:	ipv6_setsockopt,
986     	getsockopt:	ipv6_getsockopt,
987     	sendmsg:	udpv6_sendmsg,
988     	recvmsg:	udpv6_recvmsg,
989     	backlog_rcv:	udpv6_queue_rcv_skb,
990     	hash:		udp_v6_hash,
991     	unhash:		udp_v6_unhash,
992     	get_port:	udp_v6_get_port,
993     };
994     
995     extern struct proto_ops inet6_dgram_ops;
996     
997     static struct inet_protosw udpv6_protosw = {
998     	type:        SOCK_DGRAM,
999     	protocol:    IPPROTO_UDP,
1000     	prot:        &udpv6_prot,
1001     	ops:         &inet6_dgram_ops,
1002     	capability:  -1,
1003     	no_check:    UDP_CSUM_DEFAULT,
1004     	flags:       INET_PROTOSW_PERMANENT,
1005     };
1006     
1007     
1008     void __init udpv6_init(void)
1009     {
1010     	inet6_add_protocol(&udpv6_protocol);
1011     	inet6_register_protosw(&udpv6_protosw);
1012     }
1013