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