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