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