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