ipv6_sockglue.c revision 793b14731686595a741d9f47726ad8b9a235385a
1/* 2 * IPv6 BSD socket options interface 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/net/ipv4/ip_sockglue.c 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 13 * 2 of the License, or (at your option) any later version. 14 * 15 * FIXME: Make the setsockopt code POSIX compliant: That is 16 * 17 * o Truncate getsockopt returns 18 * o Return an optlen of the truncated length if need be 19 * 20 * Changes: 21 * David L Stevens <dlstevens@us.ibm.com>: 22 * - added multicast source filtering API for MLDv2 23 */ 24 25#include <linux/module.h> 26#include <linux/capability.h> 27#include <linux/errno.h> 28#include <linux/types.h> 29#include <linux/socket.h> 30#include <linux/sockios.h> 31#include <linux/net.h> 32#include <linux/in6.h> 33#include <linux/mroute6.h> 34#include <linux/netdevice.h> 35#include <linux/if_arp.h> 36#include <linux/init.h> 37#include <linux/sysctl.h> 38#include <linux/netfilter.h> 39#include <linux/slab.h> 40 41#include <net/sock.h> 42#include <net/snmp.h> 43#include <net/ipv6.h> 44#include <net/ndisc.h> 45#include <net/protocol.h> 46#include <net/transp_v6.h> 47#include <net/ip6_route.h> 48#include <net/addrconf.h> 49#include <net/inet_common.h> 50#include <net/tcp.h> 51#include <net/udp.h> 52#include <net/udplite.h> 53#include <net/xfrm.h> 54#include <net/compat.h> 55 56#include <asm/uaccess.h> 57 58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly; 59 60struct ip6_ra_chain *ip6_ra_chain; 61DEFINE_RWLOCK(ip6_ra_lock); 62 63int ip6_ra_control(struct sock *sk, int sel) 64{ 65 struct ip6_ra_chain *ra, *new_ra, **rap; 66 67 /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ 68 if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW) 69 return -ENOPROTOOPT; 70 71 new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; 72 73 write_lock_bh(&ip6_ra_lock); 74 for (rap = &ip6_ra_chain; (ra=*rap) != NULL; rap = &ra->next) { 75 if (ra->sk == sk) { 76 if (sel>=0) { 77 write_unlock_bh(&ip6_ra_lock); 78 kfree(new_ra); 79 return -EADDRINUSE; 80 } 81 82 *rap = ra->next; 83 write_unlock_bh(&ip6_ra_lock); 84 85 sock_put(sk); 86 kfree(ra); 87 return 0; 88 } 89 } 90 if (new_ra == NULL) { 91 write_unlock_bh(&ip6_ra_lock); 92 return -ENOBUFS; 93 } 94 new_ra->sk = sk; 95 new_ra->sel = sel; 96 new_ra->next = ra; 97 *rap = new_ra; 98 sock_hold(sk); 99 write_unlock_bh(&ip6_ra_lock); 100 return 0; 101} 102 103static 104struct ipv6_txoptions *ipv6_update_options(struct sock *sk, 105 struct ipv6_txoptions *opt) 106{ 107 if (inet_sk(sk)->is_icsk) { 108 if (opt && 109 !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) && 110 inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) { 111 struct inet_connection_sock *icsk = inet_csk(sk); 112 icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; 113 icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); 114 } 115 opt = xchg(&inet6_sk(sk)->opt, opt); 116 } else { 117 spin_lock(&sk->sk_dst_lock); 118 opt = xchg(&inet6_sk(sk)->opt, opt); 119 spin_unlock(&sk->sk_dst_lock); 120 } 121 sk_dst_reset(sk); 122 123 return opt; 124} 125 126static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, 127 char __user *optval, unsigned int optlen) 128{ 129 struct ipv6_pinfo *np = inet6_sk(sk); 130 struct net *net = sock_net(sk); 131 int val, valbool; 132 int retv = -ENOPROTOOPT; 133 134 if (optval == NULL) 135 val=0; 136 else { 137 if (optlen >= sizeof(int)) { 138 if (get_user(val, (int __user *) optval)) 139 return -EFAULT; 140 } else 141 val = 0; 142 } 143 144 valbool = (val!=0); 145 146 if (ip6_mroute_opt(optname)) 147 return ip6_mroute_setsockopt(sk, optname, optval, optlen); 148 149 lock_sock(sk); 150 151 switch (optname) { 152 153 case IPV6_ADDRFORM: 154 if (optlen < sizeof(int)) 155 goto e_inval; 156 if (val == PF_INET) { 157 struct ipv6_txoptions *opt; 158 struct sk_buff *pktopt; 159 160 if (sk->sk_type == SOCK_RAW) 161 break; 162 163 if (sk->sk_protocol == IPPROTO_UDP || 164 sk->sk_protocol == IPPROTO_UDPLITE) { 165 struct udp_sock *up = udp_sk(sk); 166 if (up->pending == AF_INET6) { 167 retv = -EBUSY; 168 break; 169 } 170 } else if (sk->sk_protocol != IPPROTO_TCP) 171 break; 172 173 if (sk->sk_state != TCP_ESTABLISHED) { 174 retv = -ENOTCONN; 175 break; 176 } 177 178 if (ipv6_only_sock(sk) || 179 !ipv6_addr_v4mapped(&np->daddr)) { 180 retv = -EADDRNOTAVAIL; 181 break; 182 } 183 184 fl6_free_socklist(sk); 185 ipv6_sock_mc_close(sk); 186 187 /* 188 * Sock is moving from IPv6 to IPv4 (sk_prot), so 189 * remove it from the refcnt debug socks count in the 190 * original family... 191 */ 192 sk_refcnt_debug_dec(sk); 193 194 if (sk->sk_protocol == IPPROTO_TCP) { 195 struct inet_connection_sock *icsk = inet_csk(sk); 196 local_bh_disable(); 197 sock_prot_inuse_add(net, sk->sk_prot, -1); 198 sock_prot_inuse_add(net, &tcp_prot, 1); 199 local_bh_enable(); 200 sk->sk_prot = &tcp_prot; 201 icsk->icsk_af_ops = &ipv4_specific; 202 sk->sk_socket->ops = &inet_stream_ops; 203 sk->sk_family = PF_INET; 204 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 205 } else { 206 struct proto *prot = &udp_prot; 207 208 if (sk->sk_protocol == IPPROTO_UDPLITE) 209 prot = &udplite_prot; 210 local_bh_disable(); 211 sock_prot_inuse_add(net, sk->sk_prot, -1); 212 sock_prot_inuse_add(net, prot, 1); 213 local_bh_enable(); 214 sk->sk_prot = prot; 215 sk->sk_socket->ops = &inet_dgram_ops; 216 sk->sk_family = PF_INET; 217 } 218 opt = xchg(&np->opt, NULL); 219 if (opt) 220 sock_kfree_s(sk, opt, opt->tot_len); 221 pktopt = xchg(&np->pktoptions, NULL); 222 kfree_skb(pktopt); 223 224 sk->sk_destruct = inet_sock_destruct; 225 /* 226 * ... and add it to the refcnt debug socks count 227 * in the new family. -acme 228 */ 229 sk_refcnt_debug_inc(sk); 230 module_put(THIS_MODULE); 231 retv = 0; 232 break; 233 } 234 goto e_inval; 235 236 case IPV6_V6ONLY: 237 if (optlen < sizeof(int) || 238 inet_sk(sk)->inet_num) 239 goto e_inval; 240 np->ipv6only = valbool; 241 retv = 0; 242 break; 243 244 case IPV6_RECVPKTINFO: 245 if (optlen < sizeof(int)) 246 goto e_inval; 247 np->rxopt.bits.rxinfo = valbool; 248 retv = 0; 249 break; 250 251 case IPV6_2292PKTINFO: 252 if (optlen < sizeof(int)) 253 goto e_inval; 254 np->rxopt.bits.rxoinfo = valbool; 255 retv = 0; 256 break; 257 258 case IPV6_RECVHOPLIMIT: 259 if (optlen < sizeof(int)) 260 goto e_inval; 261 np->rxopt.bits.rxhlim = valbool; 262 retv = 0; 263 break; 264 265 case IPV6_2292HOPLIMIT: 266 if (optlen < sizeof(int)) 267 goto e_inval; 268 np->rxopt.bits.rxohlim = valbool; 269 retv = 0; 270 break; 271 272 case IPV6_RECVRTHDR: 273 if (optlen < sizeof(int)) 274 goto e_inval; 275 np->rxopt.bits.srcrt = valbool; 276 retv = 0; 277 break; 278 279 case IPV6_2292RTHDR: 280 if (optlen < sizeof(int)) 281 goto e_inval; 282 np->rxopt.bits.osrcrt = valbool; 283 retv = 0; 284 break; 285 286 case IPV6_RECVHOPOPTS: 287 if (optlen < sizeof(int)) 288 goto e_inval; 289 np->rxopt.bits.hopopts = valbool; 290 retv = 0; 291 break; 292 293 case IPV6_2292HOPOPTS: 294 if (optlen < sizeof(int)) 295 goto e_inval; 296 np->rxopt.bits.ohopopts = valbool; 297 retv = 0; 298 break; 299 300 case IPV6_RECVDSTOPTS: 301 if (optlen < sizeof(int)) 302 goto e_inval; 303 np->rxopt.bits.dstopts = valbool; 304 retv = 0; 305 break; 306 307 case IPV6_2292DSTOPTS: 308 if (optlen < sizeof(int)) 309 goto e_inval; 310 np->rxopt.bits.odstopts = valbool; 311 retv = 0; 312 break; 313 314 case IPV6_TCLASS: 315 if (optlen < sizeof(int)) 316 goto e_inval; 317 if (val < -1 || val > 0xff) 318 goto e_inval; 319 /* RFC 3542, 6.5: default traffic class of 0x0 */ 320 if (val == -1) 321 val = 0; 322 np->tclass = val; 323 retv = 0; 324 break; 325 326 case IPV6_RECVTCLASS: 327 if (optlen < sizeof(int)) 328 goto e_inval; 329 np->rxopt.bits.rxtclass = valbool; 330 retv = 0; 331 break; 332 333 case IPV6_FLOWINFO: 334 if (optlen < sizeof(int)) 335 goto e_inval; 336 np->rxopt.bits.rxflow = valbool; 337 retv = 0; 338 break; 339 340 case IPV6_RECVPATHMTU: 341 if (optlen < sizeof(int)) 342 goto e_inval; 343 np->rxopt.bits.rxpmtu = valbool; 344 retv = 0; 345 break; 346 347 case IPV6_HOPOPTS: 348 case IPV6_RTHDRDSTOPTS: 349 case IPV6_RTHDR: 350 case IPV6_DSTOPTS: 351 { 352 struct ipv6_txoptions *opt; 353 354 /* remove any sticky options header with a zero option 355 * length, per RFC3542. 356 */ 357 if (optlen == 0) 358 optval = NULL; 359 else if (optval == NULL) 360 goto e_inval; 361 else if (optlen < sizeof(struct ipv6_opt_hdr) || 362 optlen & 0x7 || optlen > 8 * 255) 363 goto e_inval; 364 365 /* hop-by-hop / destination options are privileged option */ 366 retv = -EPERM; 367 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) 368 break; 369 370 opt = ipv6_renew_options(sk, np->opt, optname, 371 (struct ipv6_opt_hdr __user *)optval, 372 optlen); 373 if (IS_ERR(opt)) { 374 retv = PTR_ERR(opt); 375 break; 376 } 377 378 /* routing header option needs extra check */ 379 retv = -EINVAL; 380 if (optname == IPV6_RTHDR && opt && opt->srcrt) { 381 struct ipv6_rt_hdr *rthdr = opt->srcrt; 382 switch (rthdr->type) { 383#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 384 case IPV6_SRCRT_TYPE_2: 385 if (rthdr->hdrlen != 2 || 386 rthdr->segments_left != 1) 387 goto sticky_done; 388 389 break; 390#endif 391 default: 392 goto sticky_done; 393 } 394 } 395 396 retv = 0; 397 opt = ipv6_update_options(sk, opt); 398sticky_done: 399 if (opt) 400 sock_kfree_s(sk, opt, opt->tot_len); 401 break; 402 } 403 404 case IPV6_PKTINFO: 405 { 406 struct in6_pktinfo pkt; 407 408 if (optlen == 0) 409 goto e_inval; 410 else if (optlen < sizeof(struct in6_pktinfo) || optval == NULL) 411 goto e_inval; 412 413 if (copy_from_user(&pkt, optval, sizeof(struct in6_pktinfo))) { 414 retv = -EFAULT; 415 break; 416 } 417 if (sk->sk_bound_dev_if && pkt.ipi6_ifindex != sk->sk_bound_dev_if) 418 goto e_inval; 419 420 np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex; 421 ipv6_addr_copy(&np->sticky_pktinfo.ipi6_addr, &pkt.ipi6_addr); 422 retv = 0; 423 break; 424 } 425 426 case IPV6_2292PKTOPTIONS: 427 { 428 struct ipv6_txoptions *opt = NULL; 429 struct msghdr msg; 430 struct flowi fl; 431 int junk; 432 433 fl.fl6_flowlabel = 0; 434 fl.oif = sk->sk_bound_dev_if; 435 fl.mark = sk->sk_mark; 436 437 if (optlen == 0) 438 goto update; 439 440 /* 1K is probably excessive 441 * 1K is surely not enough, 2K per standard header is 16K. 442 */ 443 retv = -EINVAL; 444 if (optlen > 64*1024) 445 break; 446 447 opt = sock_kmalloc(sk, sizeof(*opt) + optlen, GFP_KERNEL); 448 retv = -ENOBUFS; 449 if (opt == NULL) 450 break; 451 452 memset(opt, 0, sizeof(*opt)); 453 opt->tot_len = sizeof(*opt) + optlen; 454 retv = -EFAULT; 455 if (copy_from_user(opt+1, optval, optlen)) 456 goto done; 457 458 msg.msg_controllen = optlen; 459 msg.msg_control = (void*)(opt+1); 460 461 retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk); 462 if (retv) 463 goto done; 464update: 465 retv = 0; 466 opt = ipv6_update_options(sk, opt); 467done: 468 if (opt) 469 sock_kfree_s(sk, opt, opt->tot_len); 470 break; 471 } 472 case IPV6_UNICAST_HOPS: 473 if (optlen < sizeof(int)) 474 goto e_inval; 475 if (val > 255 || val < -1) 476 goto e_inval; 477 np->hop_limit = val; 478 retv = 0; 479 break; 480 481 case IPV6_MULTICAST_HOPS: 482 if (sk->sk_type == SOCK_STREAM) 483 break; 484 if (optlen < sizeof(int)) 485 goto e_inval; 486 if (val > 255 || val < -1) 487 goto e_inval; 488 np->mcast_hops = val; 489 retv = 0; 490 break; 491 492 case IPV6_MULTICAST_LOOP: 493 if (optlen < sizeof(int)) 494 goto e_inval; 495 if (val != valbool) 496 goto e_inval; 497 np->mc_loop = valbool; 498 retv = 0; 499 break; 500 501 case IPV6_MULTICAST_IF: 502 if (sk->sk_type == SOCK_STREAM) 503 break; 504 if (optlen < sizeof(int)) 505 goto e_inval; 506 507 if (val) { 508 struct net_device *dev; 509 510 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) 511 goto e_inval; 512 513 dev = dev_get_by_index(net, val); 514 if (!dev) { 515 retv = -ENODEV; 516 break; 517 } 518 dev_put(dev); 519 } 520 np->mcast_oif = val; 521 retv = 0; 522 break; 523 case IPV6_ADD_MEMBERSHIP: 524 case IPV6_DROP_MEMBERSHIP: 525 { 526 struct ipv6_mreq mreq; 527 528 if (optlen < sizeof(struct ipv6_mreq)) 529 goto e_inval; 530 531 retv = -EPROTO; 532 if (inet_sk(sk)->is_icsk) 533 break; 534 535 retv = -EFAULT; 536 if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq))) 537 break; 538 539 if (optname == IPV6_ADD_MEMBERSHIP) 540 retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); 541 else 542 retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); 543 break; 544 } 545 case IPV6_JOIN_ANYCAST: 546 case IPV6_LEAVE_ANYCAST: 547 { 548 struct ipv6_mreq mreq; 549 550 if (optlen < sizeof(struct ipv6_mreq)) 551 goto e_inval; 552 553 retv = -EFAULT; 554 if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq))) 555 break; 556 557 if (optname == IPV6_JOIN_ANYCAST) 558 retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr); 559 else 560 retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr); 561 break; 562 } 563 case MCAST_JOIN_GROUP: 564 case MCAST_LEAVE_GROUP: 565 { 566 struct group_req greq; 567 struct sockaddr_in6 *psin6; 568 569 if (optlen < sizeof(struct group_req)) 570 goto e_inval; 571 572 retv = -EFAULT; 573 if (copy_from_user(&greq, optval, sizeof(struct group_req))) 574 break; 575 if (greq.gr_group.ss_family != AF_INET6) { 576 retv = -EADDRNOTAVAIL; 577 break; 578 } 579 psin6 = (struct sockaddr_in6 *)&greq.gr_group; 580 if (optname == MCAST_JOIN_GROUP) 581 retv = ipv6_sock_mc_join(sk, greq.gr_interface, 582 &psin6->sin6_addr); 583 else 584 retv = ipv6_sock_mc_drop(sk, greq.gr_interface, 585 &psin6->sin6_addr); 586 break; 587 } 588 case MCAST_JOIN_SOURCE_GROUP: 589 case MCAST_LEAVE_SOURCE_GROUP: 590 case MCAST_BLOCK_SOURCE: 591 case MCAST_UNBLOCK_SOURCE: 592 { 593 struct group_source_req greqs; 594 int omode, add; 595 596 if (optlen < sizeof(struct group_source_req)) 597 goto e_inval; 598 if (copy_from_user(&greqs, optval, sizeof(greqs))) { 599 retv = -EFAULT; 600 break; 601 } 602 if (greqs.gsr_group.ss_family != AF_INET6 || 603 greqs.gsr_source.ss_family != AF_INET6) { 604 retv = -EADDRNOTAVAIL; 605 break; 606 } 607 if (optname == MCAST_BLOCK_SOURCE) { 608 omode = MCAST_EXCLUDE; 609 add = 1; 610 } else if (optname == MCAST_UNBLOCK_SOURCE) { 611 omode = MCAST_EXCLUDE; 612 add = 0; 613 } else if (optname == MCAST_JOIN_SOURCE_GROUP) { 614 struct sockaddr_in6 *psin6; 615 616 psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; 617 retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, 618 &psin6->sin6_addr); 619 /* prior join w/ different source is ok */ 620 if (retv && retv != -EADDRINUSE) 621 break; 622 omode = MCAST_INCLUDE; 623 add = 1; 624 } else /* MCAST_LEAVE_SOURCE_GROUP */ { 625 omode = MCAST_INCLUDE; 626 add = 0; 627 } 628 retv = ip6_mc_source(add, omode, sk, &greqs); 629 break; 630 } 631 case MCAST_MSFILTER: 632 { 633 extern int sysctl_mld_max_msf; 634 struct group_filter *gsf; 635 636 if (optlen < GROUP_FILTER_SIZE(0)) 637 goto e_inval; 638 if (optlen > sysctl_optmem_max) { 639 retv = -ENOBUFS; 640 break; 641 } 642 gsf = kmalloc(optlen,GFP_KERNEL); 643 if (!gsf) { 644 retv = -ENOBUFS; 645 break; 646 } 647 retv = -EFAULT; 648 if (copy_from_user(gsf, optval, optlen)) { 649 kfree(gsf); 650 break; 651 } 652 /* numsrc >= (4G-140)/128 overflow in 32 bits */ 653 if (gsf->gf_numsrc >= 0x1ffffffU || 654 gsf->gf_numsrc > sysctl_mld_max_msf) { 655 kfree(gsf); 656 retv = -ENOBUFS; 657 break; 658 } 659 if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) { 660 kfree(gsf); 661 retv = -EINVAL; 662 break; 663 } 664 retv = ip6_mc_msfilter(sk, gsf); 665 kfree(gsf); 666 667 break; 668 } 669 case IPV6_ROUTER_ALERT: 670 if (optlen < sizeof(int)) 671 goto e_inval; 672 retv = ip6_ra_control(sk, val); 673 break; 674 case IPV6_MTU_DISCOVER: 675 if (optlen < sizeof(int)) 676 goto e_inval; 677 if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE) 678 goto e_inval; 679 np->pmtudisc = val; 680 retv = 0; 681 break; 682 case IPV6_MTU: 683 if (optlen < sizeof(int)) 684 goto e_inval; 685 if (val && val < IPV6_MIN_MTU) 686 goto e_inval; 687 np->frag_size = val; 688 retv = 0; 689 break; 690 case IPV6_RECVERR: 691 if (optlen < sizeof(int)) 692 goto e_inval; 693 np->recverr = valbool; 694 if (!val) 695 skb_queue_purge(&sk->sk_error_queue); 696 retv = 0; 697 break; 698 case IPV6_FLOWINFO_SEND: 699 if (optlen < sizeof(int)) 700 goto e_inval; 701 np->sndflow = valbool; 702 retv = 0; 703 break; 704 case IPV6_FLOWLABEL_MGR: 705 retv = ipv6_flowlabel_opt(sk, optval, optlen); 706 break; 707 case IPV6_IPSEC_POLICY: 708 case IPV6_XFRM_POLICY: 709 retv = -EPERM; 710 if (!capable(CAP_NET_ADMIN)) 711 break; 712 retv = xfrm_user_policy(sk, optname, optval, optlen); 713 break; 714 715 case IPV6_ADDR_PREFERENCES: 716 { 717 unsigned int pref = 0; 718 unsigned int prefmask = ~0; 719 720 if (optlen < sizeof(int)) 721 goto e_inval; 722 723 retv = -EINVAL; 724 725 /* check PUBLIC/TMP/PUBTMP_DEFAULT conflicts */ 726 switch (val & (IPV6_PREFER_SRC_PUBLIC| 727 IPV6_PREFER_SRC_TMP| 728 IPV6_PREFER_SRC_PUBTMP_DEFAULT)) { 729 case IPV6_PREFER_SRC_PUBLIC: 730 pref |= IPV6_PREFER_SRC_PUBLIC; 731 break; 732 case IPV6_PREFER_SRC_TMP: 733 pref |= IPV6_PREFER_SRC_TMP; 734 break; 735 case IPV6_PREFER_SRC_PUBTMP_DEFAULT: 736 break; 737 case 0: 738 goto pref_skip_pubtmp; 739 default: 740 goto e_inval; 741 } 742 743 prefmask &= ~(IPV6_PREFER_SRC_PUBLIC| 744 IPV6_PREFER_SRC_TMP); 745pref_skip_pubtmp: 746 747 /* check HOME/COA conflicts */ 748 switch (val & (IPV6_PREFER_SRC_HOME|IPV6_PREFER_SRC_COA)) { 749 case IPV6_PREFER_SRC_HOME: 750 break; 751 case IPV6_PREFER_SRC_COA: 752 pref |= IPV6_PREFER_SRC_COA; 753 case 0: 754 goto pref_skip_coa; 755 default: 756 goto e_inval; 757 } 758 759 prefmask &= ~IPV6_PREFER_SRC_COA; 760pref_skip_coa: 761 762 /* check CGA/NONCGA conflicts */ 763 switch (val & (IPV6_PREFER_SRC_CGA|IPV6_PREFER_SRC_NONCGA)) { 764 case IPV6_PREFER_SRC_CGA: 765 case IPV6_PREFER_SRC_NONCGA: 766 case 0: 767 break; 768 default: 769 goto e_inval; 770 } 771 772 np->srcprefs = (np->srcprefs & prefmask) | pref; 773 retv = 0; 774 775 break; 776 } 777 case IPV6_MINHOPCOUNT: 778 if (optlen < sizeof(int)) 779 goto e_inval; 780 if (val < 0 || val > 255) 781 goto e_inval; 782 np->min_hopcount = val; 783 break; 784 case IPV6_DONTFRAG: 785 np->dontfrag = valbool; 786 retv = 0; 787 break; 788 } 789 790 release_sock(sk); 791 792 return retv; 793 794e_inval: 795 release_sock(sk); 796 return -EINVAL; 797} 798 799int ipv6_setsockopt(struct sock *sk, int level, int optname, 800 char __user *optval, unsigned int optlen) 801{ 802 int err; 803 804 if (level == SOL_IP && sk->sk_type != SOCK_RAW) 805 return udp_prot.setsockopt(sk, level, optname, optval, optlen); 806 807 if (level != SOL_IPV6) 808 return -ENOPROTOOPT; 809 810 err = do_ipv6_setsockopt(sk, level, optname, optval, optlen); 811#ifdef CONFIG_NETFILTER 812 /* we need to exclude all possible ENOPROTOOPTs except default case */ 813 if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY && 814 optname != IPV6_XFRM_POLICY) { 815 lock_sock(sk); 816 err = nf_setsockopt(sk, PF_INET6, optname, optval, 817 optlen); 818 release_sock(sk); 819 } 820#endif 821 return err; 822} 823 824EXPORT_SYMBOL(ipv6_setsockopt); 825 826#ifdef CONFIG_COMPAT 827int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, 828 char __user *optval, unsigned int optlen) 829{ 830 int err; 831 832 if (level == SOL_IP && sk->sk_type != SOCK_RAW) { 833 if (udp_prot.compat_setsockopt != NULL) 834 return udp_prot.compat_setsockopt(sk, level, optname, 835 optval, optlen); 836 return udp_prot.setsockopt(sk, level, optname, optval, optlen); 837 } 838 839 if (level != SOL_IPV6) 840 return -ENOPROTOOPT; 841 842 if (optname >= MCAST_JOIN_GROUP && optname <= MCAST_MSFILTER) 843 return compat_mc_setsockopt(sk, level, optname, optval, optlen, 844 ipv6_setsockopt); 845 846 err = do_ipv6_setsockopt(sk, level, optname, optval, optlen); 847#ifdef CONFIG_NETFILTER 848 /* we need to exclude all possible ENOPROTOOPTs except default case */ 849 if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY && 850 optname != IPV6_XFRM_POLICY) { 851 lock_sock(sk); 852 err = compat_nf_setsockopt(sk, PF_INET6, optname, 853 optval, optlen); 854 release_sock(sk); 855 } 856#endif 857 return err; 858} 859 860EXPORT_SYMBOL(compat_ipv6_setsockopt); 861#endif 862 863static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt, 864 int optname, char __user *optval, int len) 865{ 866 struct ipv6_opt_hdr *hdr; 867 868 if (!opt) 869 return 0; 870 871 switch(optname) { 872 case IPV6_HOPOPTS: 873 hdr = opt->hopopt; 874 break; 875 case IPV6_RTHDRDSTOPTS: 876 hdr = opt->dst0opt; 877 break; 878 case IPV6_RTHDR: 879 hdr = (struct ipv6_opt_hdr *)opt->srcrt; 880 break; 881 case IPV6_DSTOPTS: 882 hdr = opt->dst1opt; 883 break; 884 default: 885 return -EINVAL; /* should not happen */ 886 } 887 888 if (!hdr) 889 return 0; 890 891 len = min_t(unsigned int, len, ipv6_optlen(hdr)); 892 if (copy_to_user(optval, hdr, len)) 893 return -EFAULT; 894 return len; 895} 896 897static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, 898 char __user *optval, int __user *optlen) 899{ 900 struct ipv6_pinfo *np = inet6_sk(sk); 901 int len; 902 int val; 903 904 if (ip6_mroute_opt(optname)) 905 return ip6_mroute_getsockopt(sk, optname, optval, optlen); 906 907 if (get_user(len, optlen)) 908 return -EFAULT; 909 switch (optname) { 910 case IPV6_ADDRFORM: 911 if (sk->sk_protocol != IPPROTO_UDP && 912 sk->sk_protocol != IPPROTO_UDPLITE && 913 sk->sk_protocol != IPPROTO_TCP) 914 return -ENOPROTOOPT; 915 if (sk->sk_state != TCP_ESTABLISHED) 916 return -ENOTCONN; 917 val = sk->sk_family; 918 break; 919 case MCAST_MSFILTER: 920 { 921 struct group_filter gsf; 922 int err; 923 924 if (len < GROUP_FILTER_SIZE(0)) 925 return -EINVAL; 926 if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) 927 return -EFAULT; 928 if (gsf.gf_group.ss_family != AF_INET6) 929 return -EADDRNOTAVAIL; 930 lock_sock(sk); 931 err = ip6_mc_msfget(sk, &gsf, 932 (struct group_filter __user *)optval, optlen); 933 release_sock(sk); 934 return err; 935 } 936 937 case IPV6_2292PKTOPTIONS: 938 { 939 struct msghdr msg; 940 struct sk_buff *skb; 941 942 if (sk->sk_type != SOCK_STREAM) 943 return -ENOPROTOOPT; 944 945 msg.msg_control = optval; 946 msg.msg_controllen = len; 947 msg.msg_flags = 0; 948 949 lock_sock(sk); 950 skb = np->pktoptions; 951 if (skb) 952 atomic_inc(&skb->users); 953 release_sock(sk); 954 955 if (skb) { 956 int err = datagram_recv_ctl(sk, &msg, skb); 957 kfree_skb(skb); 958 if (err) 959 return err; 960 } else { 961 if (np->rxopt.bits.rxinfo) { 962 struct in6_pktinfo src_info; 963 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : 964 np->sticky_pktinfo.ipi6_ifindex; 965 np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) : 966 ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr)); 967 put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); 968 } 969 if (np->rxopt.bits.rxhlim) { 970 int hlim = np->mcast_hops; 971 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim); 972 } 973 if (np->rxopt.bits.rxoinfo) { 974 struct in6_pktinfo src_info; 975 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : 976 np->sticky_pktinfo.ipi6_ifindex; 977 np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) : 978 ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr)); 979 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); 980 } 981 if (np->rxopt.bits.rxohlim) { 982 int hlim = np->mcast_hops; 983 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim); 984 } 985 } 986 len -= msg.msg_controllen; 987 return put_user(len, optlen); 988 } 989 case IPV6_MTU: 990 { 991 struct dst_entry *dst; 992 993 val = 0; 994 rcu_read_lock(); 995 dst = __sk_dst_get(sk); 996 if (dst) 997 val = dst_mtu(dst); 998 rcu_read_unlock(); 999 if (!val) 1000 return -ENOTCONN; 1001 break; 1002 } 1003 1004 case IPV6_V6ONLY: 1005 val = np->ipv6only; 1006 break; 1007 1008 case IPV6_RECVPKTINFO: 1009 val = np->rxopt.bits.rxinfo; 1010 break; 1011 1012 case IPV6_2292PKTINFO: 1013 val = np->rxopt.bits.rxoinfo; 1014 break; 1015 1016 case IPV6_RECVHOPLIMIT: 1017 val = np->rxopt.bits.rxhlim; 1018 break; 1019 1020 case IPV6_2292HOPLIMIT: 1021 val = np->rxopt.bits.rxohlim; 1022 break; 1023 1024 case IPV6_RECVRTHDR: 1025 val = np->rxopt.bits.srcrt; 1026 break; 1027 1028 case IPV6_2292RTHDR: 1029 val = np->rxopt.bits.osrcrt; 1030 break; 1031 1032 case IPV6_HOPOPTS: 1033 case IPV6_RTHDRDSTOPTS: 1034 case IPV6_RTHDR: 1035 case IPV6_DSTOPTS: 1036 { 1037 1038 lock_sock(sk); 1039 len = ipv6_getsockopt_sticky(sk, np->opt, 1040 optname, optval, len); 1041 release_sock(sk); 1042 /* check if ipv6_getsockopt_sticky() returns err code */ 1043 if (len < 0) 1044 return len; 1045 return put_user(len, optlen); 1046 } 1047 1048 case IPV6_RECVHOPOPTS: 1049 val = np->rxopt.bits.hopopts; 1050 break; 1051 1052 case IPV6_2292HOPOPTS: 1053 val = np->rxopt.bits.ohopopts; 1054 break; 1055 1056 case IPV6_RECVDSTOPTS: 1057 val = np->rxopt.bits.dstopts; 1058 break; 1059 1060 case IPV6_2292DSTOPTS: 1061 val = np->rxopt.bits.odstopts; 1062 break; 1063 1064 case IPV6_TCLASS: 1065 val = np->tclass; 1066 break; 1067 1068 case IPV6_RECVTCLASS: 1069 val = np->rxopt.bits.rxtclass; 1070 break; 1071 1072 case IPV6_FLOWINFO: 1073 val = np->rxopt.bits.rxflow; 1074 break; 1075 1076 case IPV6_RECVPATHMTU: 1077 val = np->rxopt.bits.rxpmtu; 1078 break; 1079 1080 case IPV6_PATHMTU: 1081 { 1082 struct dst_entry *dst; 1083 struct ip6_mtuinfo mtuinfo; 1084 1085 if (len < sizeof(mtuinfo)) 1086 return -EINVAL; 1087 1088 len = sizeof(mtuinfo); 1089 memset(&mtuinfo, 0, sizeof(mtuinfo)); 1090 1091 rcu_read_lock(); 1092 dst = __sk_dst_get(sk); 1093 if (dst) 1094 mtuinfo.ip6m_mtu = dst_mtu(dst); 1095 rcu_read_unlock(); 1096 if (!mtuinfo.ip6m_mtu) 1097 return -ENOTCONN; 1098 1099 if (put_user(len, optlen)) 1100 return -EFAULT; 1101 if (copy_to_user(optval, &mtuinfo, len)) 1102 return -EFAULT; 1103 1104 return 0; 1105 break; 1106 } 1107 1108 case IPV6_UNICAST_HOPS: 1109 case IPV6_MULTICAST_HOPS: 1110 { 1111 struct dst_entry *dst; 1112 1113 if (optname == IPV6_UNICAST_HOPS) 1114 val = np->hop_limit; 1115 else 1116 val = np->mcast_hops; 1117 1118 if (val < 0) { 1119 rcu_read_lock(); 1120 dst = __sk_dst_get(sk); 1121 if (dst) 1122 val = ip6_dst_hoplimit(dst); 1123 rcu_read_unlock(); 1124 } 1125 1126 if (val < 0) 1127 val = sock_net(sk)->ipv6.devconf_all->hop_limit; 1128 break; 1129 } 1130 1131 case IPV6_MULTICAST_LOOP: 1132 val = np->mc_loop; 1133 break; 1134 1135 case IPV6_MULTICAST_IF: 1136 val = np->mcast_oif; 1137 break; 1138 1139 case IPV6_MTU_DISCOVER: 1140 val = np->pmtudisc; 1141 break; 1142 1143 case IPV6_RECVERR: 1144 val = np->recverr; 1145 break; 1146 1147 case IPV6_FLOWINFO_SEND: 1148 val = np->sndflow; 1149 break; 1150 1151 case IPV6_ADDR_PREFERENCES: 1152 val = 0; 1153 1154 if (np->srcprefs & IPV6_PREFER_SRC_TMP) 1155 val |= IPV6_PREFER_SRC_TMP; 1156 else if (np->srcprefs & IPV6_PREFER_SRC_PUBLIC) 1157 val |= IPV6_PREFER_SRC_PUBLIC; 1158 else { 1159 /* XXX: should we return system default? */ 1160 val |= IPV6_PREFER_SRC_PUBTMP_DEFAULT; 1161 } 1162 1163 if (np->srcprefs & IPV6_PREFER_SRC_COA) 1164 val |= IPV6_PREFER_SRC_COA; 1165 else 1166 val |= IPV6_PREFER_SRC_HOME; 1167 break; 1168 1169 case IPV6_MINHOPCOUNT: 1170 val = np->min_hopcount; 1171 break; 1172 1173 case IPV6_DONTFRAG: 1174 val = np->dontfrag; 1175 break; 1176 1177 default: 1178 return -ENOPROTOOPT; 1179 } 1180 len = min_t(unsigned int, sizeof(int), len); 1181 if(put_user(len, optlen)) 1182 return -EFAULT; 1183 if(copy_to_user(optval,&val,len)) 1184 return -EFAULT; 1185 return 0; 1186} 1187 1188int ipv6_getsockopt(struct sock *sk, int level, int optname, 1189 char __user *optval, int __user *optlen) 1190{ 1191 int err; 1192 1193 if (level == SOL_IP && sk->sk_type != SOCK_RAW) 1194 return udp_prot.getsockopt(sk, level, optname, optval, optlen); 1195 1196 if(level != SOL_IPV6) 1197 return -ENOPROTOOPT; 1198 1199 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 1200#ifdef CONFIG_NETFILTER 1201 /* we need to exclude all possible ENOPROTOOPTs except default case */ 1202 if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { 1203 int len; 1204 1205 if (get_user(len, optlen)) 1206 return -EFAULT; 1207 1208 lock_sock(sk); 1209 err = nf_getsockopt(sk, PF_INET6, optname, optval, 1210 &len); 1211 release_sock(sk); 1212 if (err >= 0) 1213 err = put_user(len, optlen); 1214 } 1215#endif 1216 return err; 1217} 1218 1219EXPORT_SYMBOL(ipv6_getsockopt); 1220 1221#ifdef CONFIG_COMPAT 1222int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, 1223 char __user *optval, int __user *optlen) 1224{ 1225 int err; 1226 1227 if (level == SOL_IP && sk->sk_type != SOCK_RAW) { 1228 if (udp_prot.compat_getsockopt != NULL) 1229 return udp_prot.compat_getsockopt(sk, level, optname, 1230 optval, optlen); 1231 return udp_prot.getsockopt(sk, level, optname, optval, optlen); 1232 } 1233 1234 if (level != SOL_IPV6) 1235 return -ENOPROTOOPT; 1236 1237 if (optname == MCAST_MSFILTER) 1238 return compat_mc_getsockopt(sk, level, optname, optval, optlen, 1239 ipv6_getsockopt); 1240 1241 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 1242#ifdef CONFIG_NETFILTER 1243 /* we need to exclude all possible ENOPROTOOPTs except default case */ 1244 if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { 1245 int len; 1246 1247 if (get_user(len, optlen)) 1248 return -EFAULT; 1249 1250 lock_sock(sk); 1251 err = compat_nf_getsockopt(sk, PF_INET6, 1252 optname, optval, &len); 1253 release_sock(sk); 1254 if (err >= 0) 1255 err = put_user(len, optlen); 1256 } 1257#endif 1258 return err; 1259} 1260 1261EXPORT_SYMBOL(compat_ipv6_getsockopt); 1262#endif 1263 1264