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