ipv6_sockglue.c revision 881d966b48b035ab3f3aeaae0f3d3f9b584f45b2
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 58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly; 59 60static 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 95static 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 116out: 117 return err; 118} 119 120static 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 161out: 162 return segs; 163} 164 165static 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 172struct ip6_ra_chain *ip6_ra_chain; 173DEFINE_RWLOCK(ip6_ra_lock); 174 175int 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 218static 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_dec_use(sk->sk_prot); 272 sock_prot_inc_use(&tcp_prot); 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_dec_use(sk->sk_prot); 286 sock_prot_inc_use(prot); 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 } 448sticky_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; 491update: 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 513done: 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 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) 543 goto e_inval; 544 545 if (__dev_get_by_index(&init_net, val) == NULL) { 546 retv = -ENODEV; 547 break; 548 } 549 np->mcast_oif = val; 550 retv = 0; 551 break; 552 case IPV6_ADD_MEMBERSHIP: 553 case IPV6_DROP_MEMBERSHIP: 554 { 555 struct ipv6_mreq mreq; 556 557 retv = -EPROTO; 558 if (inet_sk(sk)->is_icsk) 559 break; 560 561 retv = -EFAULT; 562 if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq))) 563 break; 564 565 if (optname == IPV6_ADD_MEMBERSHIP) 566 retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); 567 else 568 retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); 569 break; 570 } 571 case IPV6_JOIN_ANYCAST: 572 case IPV6_LEAVE_ANYCAST: 573 { 574 struct ipv6_mreq mreq; 575 576 if (optlen != sizeof(struct ipv6_mreq)) 577 goto e_inval; 578 579 retv = -EFAULT; 580 if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq))) 581 break; 582 583 if (optname == IPV6_JOIN_ANYCAST) 584 retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr); 585 else 586 retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr); 587 break; 588 } 589 case MCAST_JOIN_GROUP: 590 case MCAST_LEAVE_GROUP: 591 { 592 struct group_req greq; 593 struct sockaddr_in6 *psin6; 594 595 retv = -EFAULT; 596 if (copy_from_user(&greq, optval, sizeof(struct group_req))) 597 break; 598 if (greq.gr_group.ss_family != AF_INET6) { 599 retv = -EADDRNOTAVAIL; 600 break; 601 } 602 psin6 = (struct sockaddr_in6 *)&greq.gr_group; 603 if (optname == MCAST_JOIN_GROUP) 604 retv = ipv6_sock_mc_join(sk, greq.gr_interface, 605 &psin6->sin6_addr); 606 else 607 retv = ipv6_sock_mc_drop(sk, greq.gr_interface, 608 &psin6->sin6_addr); 609 break; 610 } 611 case MCAST_JOIN_SOURCE_GROUP: 612 case MCAST_LEAVE_SOURCE_GROUP: 613 case MCAST_BLOCK_SOURCE: 614 case MCAST_UNBLOCK_SOURCE: 615 { 616 struct group_source_req greqs; 617 int omode, add; 618 619 if (optlen != sizeof(struct group_source_req)) 620 goto e_inval; 621 if (copy_from_user(&greqs, optval, sizeof(greqs))) { 622 retv = -EFAULT; 623 break; 624 } 625 if (greqs.gsr_group.ss_family != AF_INET6 || 626 greqs.gsr_source.ss_family != AF_INET6) { 627 retv = -EADDRNOTAVAIL; 628 break; 629 } 630 if (optname == MCAST_BLOCK_SOURCE) { 631 omode = MCAST_EXCLUDE; 632 add = 1; 633 } else if (optname == MCAST_UNBLOCK_SOURCE) { 634 omode = MCAST_EXCLUDE; 635 add = 0; 636 } else if (optname == MCAST_JOIN_SOURCE_GROUP) { 637 struct sockaddr_in6 *psin6; 638 639 psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; 640 retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, 641 &psin6->sin6_addr); 642 /* prior join w/ different source is ok */ 643 if (retv && retv != -EADDRINUSE) 644 break; 645 omode = MCAST_INCLUDE; 646 add = 1; 647 } else /* MCAST_LEAVE_SOURCE_GROUP */ { 648 omode = MCAST_INCLUDE; 649 add = 0; 650 } 651 retv = ip6_mc_source(add, omode, sk, &greqs); 652 break; 653 } 654 case MCAST_MSFILTER: 655 { 656 extern int sysctl_mld_max_msf; 657 struct group_filter *gsf; 658 659 if (optlen < GROUP_FILTER_SIZE(0)) 660 goto e_inval; 661 if (optlen > sysctl_optmem_max) { 662 retv = -ENOBUFS; 663 break; 664 } 665 gsf = kmalloc(optlen,GFP_KERNEL); 666 if (gsf == 0) { 667 retv = -ENOBUFS; 668 break; 669 } 670 retv = -EFAULT; 671 if (copy_from_user(gsf, optval, optlen)) { 672 kfree(gsf); 673 break; 674 } 675 /* numsrc >= (4G-140)/128 overflow in 32 bits */ 676 if (gsf->gf_numsrc >= 0x1ffffffU || 677 gsf->gf_numsrc > sysctl_mld_max_msf) { 678 kfree(gsf); 679 retv = -ENOBUFS; 680 break; 681 } 682 if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) { 683 kfree(gsf); 684 retv = -EINVAL; 685 break; 686 } 687 retv = ip6_mc_msfilter(sk, gsf); 688 kfree(gsf); 689 690 break; 691 } 692 case IPV6_ROUTER_ALERT: 693 retv = ip6_ra_control(sk, val, NULL); 694 break; 695 case IPV6_MTU_DISCOVER: 696 if (val<0 || val>3) 697 goto e_inval; 698 np->pmtudisc = val; 699 retv = 0; 700 break; 701 case IPV6_MTU: 702 if (val && val < IPV6_MIN_MTU) 703 goto e_inval; 704 np->frag_size = val; 705 retv = 0; 706 break; 707 case IPV6_RECVERR: 708 np->recverr = valbool; 709 if (!val) 710 skb_queue_purge(&sk->sk_error_queue); 711 retv = 0; 712 break; 713 case IPV6_FLOWINFO_SEND: 714 np->sndflow = valbool; 715 retv = 0; 716 break; 717 case IPV6_FLOWLABEL_MGR: 718 retv = ipv6_flowlabel_opt(sk, optval, optlen); 719 break; 720 case IPV6_IPSEC_POLICY: 721 case IPV6_XFRM_POLICY: 722 retv = -EPERM; 723 if (!capable(CAP_NET_ADMIN)) 724 break; 725 retv = xfrm_user_policy(sk, optname, optval, optlen); 726 break; 727 728 } 729 release_sock(sk); 730 731 return retv; 732 733e_inval: 734 release_sock(sk); 735 return -EINVAL; 736} 737 738int ipv6_setsockopt(struct sock *sk, int level, int optname, 739 char __user *optval, int optlen) 740{ 741 int err; 742 743 if (level == SOL_IP && sk->sk_type != SOCK_RAW) 744 return udp_prot.setsockopt(sk, level, optname, optval, optlen); 745 746 if (level != SOL_IPV6) 747 return -ENOPROTOOPT; 748 749 err = do_ipv6_setsockopt(sk, level, optname, optval, optlen); 750#ifdef CONFIG_NETFILTER 751 /* we need to exclude all possible ENOPROTOOPTs except default case */ 752 if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY && 753 optname != IPV6_XFRM_POLICY) { 754 lock_sock(sk); 755 err = nf_setsockopt(sk, PF_INET6, optname, optval, 756 optlen); 757 release_sock(sk); 758 } 759#endif 760 return err; 761} 762 763EXPORT_SYMBOL(ipv6_setsockopt); 764 765#ifdef CONFIG_COMPAT 766int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, 767 char __user *optval, int optlen) 768{ 769 int err; 770 771 if (level == SOL_IP && sk->sk_type != SOCK_RAW) { 772 if (udp_prot.compat_setsockopt != NULL) 773 return udp_prot.compat_setsockopt(sk, level, optname, 774 optval, optlen); 775 return udp_prot.setsockopt(sk, level, optname, optval, optlen); 776 } 777 778 if (level != SOL_IPV6) 779 return -ENOPROTOOPT; 780 781 err = do_ipv6_setsockopt(sk, level, optname, optval, optlen); 782#ifdef CONFIG_NETFILTER 783 /* we need to exclude all possible ENOPROTOOPTs except default case */ 784 if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY && 785 optname != IPV6_XFRM_POLICY) { 786 lock_sock(sk); 787 err = compat_nf_setsockopt(sk, PF_INET6, optname, 788 optval, optlen); 789 release_sock(sk); 790 } 791#endif 792 return err; 793} 794 795EXPORT_SYMBOL(compat_ipv6_setsockopt); 796#endif 797 798static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt, 799 int optname, char __user *optval, int len) 800{ 801 struct ipv6_opt_hdr *hdr; 802 803 if (!opt) 804 return 0; 805 806 switch(optname) { 807 case IPV6_HOPOPTS: 808 hdr = opt->hopopt; 809 break; 810 case IPV6_RTHDRDSTOPTS: 811 hdr = opt->dst0opt; 812 break; 813 case IPV6_RTHDR: 814 hdr = (struct ipv6_opt_hdr *)opt->srcrt; 815 break; 816 case IPV6_DSTOPTS: 817 hdr = opt->dst1opt; 818 break; 819 default: 820 return -EINVAL; /* should not happen */ 821 } 822 823 if (!hdr) 824 return 0; 825 826 len = min_t(unsigned int, len, ipv6_optlen(hdr)); 827 if (copy_to_user(optval, hdr, len)) 828 return -EFAULT; 829 return ipv6_optlen(hdr); 830} 831 832static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, 833 char __user *optval, int __user *optlen) 834{ 835 struct ipv6_pinfo *np = inet6_sk(sk); 836 int len; 837 int val; 838 839 if (get_user(len, optlen)) 840 return -EFAULT; 841 switch (optname) { 842 case IPV6_ADDRFORM: 843 if (sk->sk_protocol != IPPROTO_UDP && 844 sk->sk_protocol != IPPROTO_UDPLITE && 845 sk->sk_protocol != IPPROTO_TCP) 846 return -EINVAL; 847 if (sk->sk_state != TCP_ESTABLISHED) 848 return -ENOTCONN; 849 val = sk->sk_family; 850 break; 851 case MCAST_MSFILTER: 852 { 853 struct group_filter gsf; 854 int err; 855 856 if (len < GROUP_FILTER_SIZE(0)) 857 return -EINVAL; 858 if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) 859 return -EFAULT; 860 lock_sock(sk); 861 err = ip6_mc_msfget(sk, &gsf, 862 (struct group_filter __user *)optval, optlen); 863 release_sock(sk); 864 return err; 865 } 866 867 case IPV6_2292PKTOPTIONS: 868 { 869 struct msghdr msg; 870 struct sk_buff *skb; 871 872 if (sk->sk_type != SOCK_STREAM) 873 return -ENOPROTOOPT; 874 875 msg.msg_control = optval; 876 msg.msg_controllen = len; 877 msg.msg_flags = 0; 878 879 lock_sock(sk); 880 skb = np->pktoptions; 881 if (skb) 882 atomic_inc(&skb->users); 883 release_sock(sk); 884 885 if (skb) { 886 int err = datagram_recv_ctl(sk, &msg, skb); 887 kfree_skb(skb); 888 if (err) 889 return err; 890 } else { 891 if (np->rxopt.bits.rxinfo) { 892 struct in6_pktinfo src_info; 893 src_info.ipi6_ifindex = np->mcast_oif; 894 ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); 895 put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); 896 } 897 if (np->rxopt.bits.rxhlim) { 898 int hlim = np->mcast_hops; 899 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim); 900 } 901 if (np->rxopt.bits.rxoinfo) { 902 struct in6_pktinfo src_info; 903 src_info.ipi6_ifindex = np->mcast_oif; 904 ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); 905 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); 906 } 907 if (np->rxopt.bits.rxohlim) { 908 int hlim = np->mcast_hops; 909 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim); 910 } 911 } 912 len -= msg.msg_controllen; 913 return put_user(len, optlen); 914 } 915 case IPV6_MTU: 916 { 917 struct dst_entry *dst; 918 val = 0; 919 lock_sock(sk); 920 dst = sk_dst_get(sk); 921 if (dst) { 922 val = dst_mtu(dst); 923 dst_release(dst); 924 } 925 release_sock(sk); 926 if (!val) 927 return -ENOTCONN; 928 break; 929 } 930 931 case IPV6_V6ONLY: 932 val = np->ipv6only; 933 break; 934 935 case IPV6_RECVPKTINFO: 936 val = np->rxopt.bits.rxinfo; 937 break; 938 939 case IPV6_2292PKTINFO: 940 val = np->rxopt.bits.rxoinfo; 941 break; 942 943 case IPV6_RECVHOPLIMIT: 944 val = np->rxopt.bits.rxhlim; 945 break; 946 947 case IPV6_2292HOPLIMIT: 948 val = np->rxopt.bits.rxohlim; 949 break; 950 951 case IPV6_RECVRTHDR: 952 val = np->rxopt.bits.srcrt; 953 break; 954 955 case IPV6_2292RTHDR: 956 val = np->rxopt.bits.osrcrt; 957 break; 958 959 case IPV6_HOPOPTS: 960 case IPV6_RTHDRDSTOPTS: 961 case IPV6_RTHDR: 962 case IPV6_DSTOPTS: 963 { 964 965 lock_sock(sk); 966 len = ipv6_getsockopt_sticky(sk, np->opt, 967 optname, optval, len); 968 release_sock(sk); 969 return put_user(len, optlen); 970 } 971 972 case IPV6_RECVHOPOPTS: 973 val = np->rxopt.bits.hopopts; 974 break; 975 976 case IPV6_2292HOPOPTS: 977 val = np->rxopt.bits.ohopopts; 978 break; 979 980 case IPV6_RECVDSTOPTS: 981 val = np->rxopt.bits.dstopts; 982 break; 983 984 case IPV6_2292DSTOPTS: 985 val = np->rxopt.bits.odstopts; 986 break; 987 988 case IPV6_TCLASS: 989 val = np->tclass; 990 if (val < 0) 991 val = 0; 992 break; 993 994 case IPV6_RECVTCLASS: 995 val = np->rxopt.bits.rxtclass; 996 break; 997 998 case IPV6_FLOWINFO: 999 val = np->rxopt.bits.rxflow; 1000 break; 1001 1002 case IPV6_UNICAST_HOPS: 1003 case IPV6_MULTICAST_HOPS: 1004 { 1005 struct dst_entry *dst; 1006 1007 if (optname == IPV6_UNICAST_HOPS) 1008 val = np->hop_limit; 1009 else 1010 val = np->mcast_hops; 1011 1012 dst = sk_dst_get(sk); 1013 if (dst) { 1014 if (val < 0) 1015 val = dst_metric(dst, RTAX_HOPLIMIT); 1016 if (val < 0) 1017 val = ipv6_get_hoplimit(dst->dev); 1018 dst_release(dst); 1019 } 1020 if (val < 0) 1021 val = ipv6_devconf.hop_limit; 1022 break; 1023 } 1024 1025 case IPV6_MULTICAST_LOOP: 1026 val = np->mc_loop; 1027 break; 1028 1029 case IPV6_MULTICAST_IF: 1030 val = np->mcast_oif; 1031 break; 1032 1033 case IPV6_MTU_DISCOVER: 1034 val = np->pmtudisc; 1035 break; 1036 1037 case IPV6_RECVERR: 1038 val = np->recverr; 1039 break; 1040 1041 case IPV6_FLOWINFO_SEND: 1042 val = np->sndflow; 1043 break; 1044 1045 default: 1046 return -EINVAL; 1047 } 1048 len = min_t(unsigned int, sizeof(int), len); 1049 if(put_user(len, optlen)) 1050 return -EFAULT; 1051 if(copy_to_user(optval,&val,len)) 1052 return -EFAULT; 1053 return 0; 1054} 1055 1056int ipv6_getsockopt(struct sock *sk, int level, int optname, 1057 char __user *optval, int __user *optlen) 1058{ 1059 int err; 1060 1061 if (level == SOL_IP && sk->sk_type != SOCK_RAW) 1062 return udp_prot.getsockopt(sk, level, optname, optval, optlen); 1063 1064 if(level != SOL_IPV6) 1065 return -ENOPROTOOPT; 1066 1067 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 1068#ifdef CONFIG_NETFILTER 1069 /* we need to exclude all possible EINVALs except default case */ 1070 if (err == -EINVAL && optname != IPV6_ADDRFORM && 1071 optname != MCAST_MSFILTER) { 1072 int len; 1073 1074 if (get_user(len, optlen)) 1075 return -EFAULT; 1076 1077 lock_sock(sk); 1078 err = nf_getsockopt(sk, PF_INET6, optname, optval, 1079 &len); 1080 release_sock(sk); 1081 if (err >= 0) 1082 err = put_user(len, optlen); 1083 } 1084#endif 1085 return err; 1086} 1087 1088EXPORT_SYMBOL(ipv6_getsockopt); 1089 1090#ifdef CONFIG_COMPAT 1091int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, 1092 char __user *optval, int __user *optlen) 1093{ 1094 int err; 1095 1096 if (level == SOL_IP && sk->sk_type != SOCK_RAW) { 1097 if (udp_prot.compat_getsockopt != NULL) 1098 return udp_prot.compat_getsockopt(sk, level, optname, 1099 optval, optlen); 1100 return udp_prot.getsockopt(sk, level, optname, optval, optlen); 1101 } 1102 1103 if (level != SOL_IPV6) 1104 return -ENOPROTOOPT; 1105 1106 err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); 1107#ifdef CONFIG_NETFILTER 1108 /* we need to exclude all possible EINVALs except default case */ 1109 if (err == -EINVAL && optname != IPV6_ADDRFORM && 1110 optname != MCAST_MSFILTER) { 1111 int len; 1112 1113 if (get_user(len, optlen)) 1114 return -EFAULT; 1115 1116 lock_sock(sk); 1117 err = compat_nf_getsockopt(sk, PF_INET6, 1118 optname, optval, &len); 1119 release_sock(sk); 1120 if (err >= 0) 1121 err = put_user(len, optlen); 1122 } 1123#endif 1124 return err; 1125} 1126 1127EXPORT_SYMBOL(compat_ipv6_getsockopt); 1128#endif 1129 1130void __init ipv6_packet_init(void) 1131{ 1132 dev_add_pack(&ipv6_packet_type); 1133} 1134 1135void ipv6_packet_cleanup(void) 1136{ 1137 dev_remove_pack(&ipv6_packet_type); 1138} 1139