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