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