Unreachable code

File: net/ipv6/.tmp_ipv6_sockglue.o.preproc
Full description: The code is unreachable by any path. Superfluous semicolon, break or return statement.
Importance: 3
Checker: ReachabilityChecker
Trace:
line 1066: This node is unreachable
line 1066: This node is unreachable
This one is:
False positive index (the lower the better): 0
File contents (this file is distributed under the terms specified in the original file):
    1|struct ip6_ra_chain *ip6_ra_chain;
    2|rwlock_t ip6_ra_lock = (rwlock_t) { .raw_lock = { 0x01000000 }, .magic = 0xdeaf1eed, .owner = ((void *)-1L), .owner_cpu = -1, .dep_map = { .name = "ip6_ra_lock" } };
    3|
    4|int ip6_ra_control(struct sock *sk, int sel)
    5|{
    6| struct ip6_ra_chain *ra, *new_ra, **rap;
    7|
    8|
    9| if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW)
   10|  return -92;
   11|
   12| new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), __st_GFP_KERNEL_st__) : ((void *)0);
   13|
   14| __st_write_lock_bh_st__(&ip6_ra_lock);
   15| for (rap = &ip6_ra_chain; (ra=*rap) != ((void *)0); rap = &ra->next) {
   16|  if (ra->sk == sk) {
   17|   if (sel>=0) {
   18|    __st_write_unlock_bh_st__(&ip6_ra_lock);
   19|    kfree(new_ra);
   20|    return -98;
   21|   }
   22|
   23|   *rap = ra->next;
   24|   __st_write_unlock_bh_st__(&ip6_ra_lock);
   25|
   26|   sock_put(sk);
   27|   kfree(ra);
   28|   return 0;
   29|  }
   30| }
   31| if (new_ra == ((void *)0)) {
   32|  __st_write_unlock_bh_st__(&ip6_ra_lock);
   33|  return -105;
   34| }
   35| new_ra->sk = sk;
   36| new_ra->sel = sel;
   37| new_ra->next = ra;
   38| *rap = new_ra;
   39| sock_hold(sk);
   40| __st_write_unlock_bh_st__(&ip6_ra_lock);
   41| return 0;
   42|}
   43|
   44|static
   45|struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
   46|        struct ipv6_txoptions *opt)
   47|{
   48| if (inet_sk(sk)->is_icsk) {
   49|  if (opt &&
   50|      !((1 << sk->__sk_common.skc_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
   51|      inet_sk(sk)->inet_daddr != (( __be32)(__builtin_constant_p((__u32)((0x7f000006))) ? ((__u32)( (((__u32)((0x7f000006)) & (__u32)0x000000ffUL) << 24) | (((__u32)((0x7f000006)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((0x7f000006)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((0x7f000006)) & (__u32)0xff000000UL) >> 24))) : __fswab32((0x7f000006))))) {
   52|   struct inet_connection_sock *icsk = inet_csk(sk);
   53|   icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
   54|   icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
   55|  }
   56|  opt = ({ __typeof(*((&inet6_sk(sk)->opt))) __x = ((opt)); switch (sizeof(*&inet6_sk(sk)->opt)) { case 1: { volatile u8 *__ptr = (volatile u8 *)((&inet6_sk(sk)->opt)); asm volatile("xchgb %0,%1" : "=q" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 2: { volatile u16 *__ptr = (volatile u16 *)((&inet6_sk(sk)->opt)); asm volatile("xchgw %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 4: { volatile u32 *__ptr = (volatile u32 *)((&inet6_sk(sk)->opt)); asm volatile("xchgl %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 8: { volatile u64 *__ptr = (volatile u64 *)((&inet6_sk(sk)->opt)); asm volatile("xchgq %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } default: __xchg_wrong_size(); } __x; });
   57| } else {
   58|  __st_spin_lock_st__(&sk->sk_dst_lock);
   59|  opt = ({ __typeof(*((&inet6_sk(sk)->opt))) __x = ((opt)); switch (sizeof(*&inet6_sk(sk)->opt)) { case 1: { volatile u8 *__ptr = (volatile u8 *)((&inet6_sk(sk)->opt)); asm volatile("xchgb %0,%1" : "=q" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 2: { volatile u16 *__ptr = (volatile u16 *)((&inet6_sk(sk)->opt)); asm volatile("xchgw %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 4: { volatile u32 *__ptr = (volatile u32 *)((&inet6_sk(sk)->opt)); asm volatile("xchgl %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 8: { volatile u64 *__ptr = (volatile u64 *)((&inet6_sk(sk)->opt)); asm volatile("xchgq %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } default: __xchg_wrong_size(); } __x; });
   60|  __st_spin_unlock_st__(&sk->sk_dst_lock);
   61| }
   62| sk_dst_reset(sk);
   63|
   64| return opt;
   65|}
   66|
   67|static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
   68|      char *optval, unsigned int optlen)
   69|{
   70| struct ipv6_pinfo *np = inet6_sk(sk);
   71| struct net *net = sock_net(sk);
   72| int val, valbool;
   73| int retv = -92;
   74|
   75| if (optval == ((void *)0))
   76|  val=0;
   77| else {
   78|  if (optlen >= sizeof(int)) {
   79|   if (__st_get_user_st__(val, (int *) optval))
   80|    return -14;
   81|  } else
   82|   val = 0;
   83| }
   84|
   85| valbool = (val!=0);
   86|
   87| if (ip6_mroute_opt(optname))
   88|  return ip6_mroute_setsockopt(sk, optname, optval, optlen);
   89|
   90| lock_sock(sk);
   91|
   92| switch (optname) {
   93|
   94| case 1:
   95|  if (optlen < sizeof(int))
   96|   goto e_inval;
   97|  if (val == 2) {
   98|   struct ipv6_txoptions *opt;
   99|   struct sk_buff *pktopt;
  100|
  101|   if (sk->sk_type == SOCK_RAW)
  102|    break;
  103|
  104|   if (sk->sk_protocol == IPPROTO_UDP ||
  105|       sk->sk_protocol == IPPROTO_UDPLITE) {
  106|    struct udp_sock *up = udp_sk(sk);
  107|    if (up->pending == 10) {
  108|     retv = -16;
  109|     break;
  110|    }
  111|   } else if (sk->sk_protocol != IPPROTO_TCP)
  112|    break;
  113|
  114|   if (sk->__sk_common.skc_state != TCP_ESTABLISHED) {
  115|    retv = -107;
  116|    break;
  117|   }
  118|
  119|   if (((sk)->__sk_common.skc_family == 10 && (inet6_sk(sk)->ipv6only)) ||
  120|       !ipv6_addr_v4mapped(&np->daddr)) {
  121|    retv = -99;
  122|    break;
  123|   }
  124|
  125|   fl6_free_socklist(sk);
  126|   ipv6_sock_mc_close(sk);
  127|
  128|
  129|
  130|
  131|
  132|
  133|   do { } while (0);
  134|
  135|   if (sk->sk_protocol == IPPROTO_TCP) {
  136|    struct inet_connection_sock *icsk = inet_csk(sk);
  137|    local_bh_disable();
  138|    sock_prot_inuse_add(net, sk->__sk_common.skc_prot, -1);
  139|    sock_prot_inuse_add(net, &tcp_prot, 1);
  140|    local_bh_enable();
  141|    sk->__sk_common.skc_prot = &tcp_prot;
  142|    icsk->icsk_af_ops = &ipv4_specific;
  143|    sk->sk_socket->ops = &inet_stream_ops;
  144|    sk->__sk_common.skc_family = 2;
  145|    tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
  146|   } else {
  147|    struct proto *prot = &udp_prot;
  148|
  149|    if (sk->sk_protocol == IPPROTO_UDPLITE)
  150|     prot = &udplite_prot;
  151|    local_bh_disable();
  152|    sock_prot_inuse_add(net, sk->__sk_common.skc_prot, -1);
  153|    sock_prot_inuse_add(net, prot, 1);
  154|    local_bh_enable();
  155|    sk->__sk_common.skc_prot = prot;
  156|    sk->sk_socket->ops = &inet_dgram_ops;
  157|    sk->__sk_common.skc_family = 2;
  158|   }
  159|   opt = ({ __typeof(*((&np->opt))) __x = ((((void *)0))); switch (sizeof(*&np->opt)) { case 1: { volatile u8 *__ptr = (volatile u8 *)((&np->opt)); asm volatile("xchgb %0,%1" : "=q" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 2: { volatile u16 *__ptr = (volatile u16 *)((&np->opt)); asm volatile("xchgw %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 4: { volatile u32 *__ptr = (volatile u32 *)((&np->opt)); asm volatile("xchgl %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 8: { volatile u64 *__ptr = (volatile u64 *)((&np->opt)); asm volatile("xchgq %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } default: __xchg_wrong_size(); } __x; });
  160|   if (opt)
  161|    sock_kfree_s(sk, opt, opt->tot_len);
  162|   pktopt = ({ __typeof(*((&np->pktoptions))) __x = ((((void *)0))); switch (sizeof(*&np->pktoptions)) { case 1: { volatile u8 *__ptr = (volatile u8 *)((&np->pktoptions)); asm volatile("xchgb %0,%1" : "=q" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 2: { volatile u16 *__ptr = (volatile u16 *)((&np->pktoptions)); asm volatile("xchgw %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 4: { volatile u32 *__ptr = (volatile u32 *)((&np->pktoptions)); asm volatile("xchgl %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } case 8: { volatile u64 *__ptr = (volatile u64 *)((&np->pktoptions)); asm volatile("xchgq %0,%1" : "=r" (__x), "+m" (*__ptr) : "0" (__x) : "memory"); break; } default: __xchg_wrong_size(); } __x; });
  163|   kfree_skb(pktopt);
  164|
  165|   sk->sk_destruct = inet_sock_destruct;
  166|
  167|
  168|
  169|
  170|   do { } while (0);
  171|   module_put((&__this_module));
  172|   retv = 0;
  173|   break;
  174|  }
  175|  goto e_inval;
  176|
  177| case 26:
  178|  if (optlen < sizeof(int) ||
  179|      inet_sk(sk)->inet_num)
  180|   goto e_inval;
  181|  np->ipv6only = valbool;
  182|  retv = 0;
  183|  break;
  184|
  185| case 49:
  186|  if (optlen < sizeof(int))
  187|   goto e_inval;
  188|  np->rxopt.bits.rxinfo = valbool;
  189|  retv = 0;
  190|  break;
  191|
  192| case 2:
  193|  if (optlen < sizeof(int))
  194|   goto e_inval;
  195|  np->rxopt.bits.rxoinfo = valbool;
  196|  retv = 0;
  197|  break;
  198|
  199| case 51:
  200|  if (optlen < sizeof(int))
  201|   goto e_inval;
  202|  np->rxopt.bits.rxhlim = valbool;
  203|  retv = 0;
  204|  break;
  205|
  206| case 8:
  207|  if (optlen < sizeof(int))
  208|   goto e_inval;
  209|  np->rxopt.bits.rxohlim = valbool;
  210|  retv = 0;
  211|  break;
  212|
  213| case 56:
  214|  if (optlen < sizeof(int))
  215|   goto e_inval;
  216|  np->rxopt.bits.srcrt = valbool;
  217|  retv = 0;
  218|  break;
  219|
  220| case 5:
  221|  if (optlen < sizeof(int))
  222|   goto e_inval;
  223|  np->rxopt.bits.osrcrt = valbool;
  224|  retv = 0;
  225|  break;
  226|
  227| case 53:
  228|  if (optlen < sizeof(int))
  229|   goto e_inval;
  230|  np->rxopt.bits.hopopts = valbool;
  231|  retv = 0;
  232|  break;
  233|
  234| case 3:
  235|  if (optlen < sizeof(int))
  236|   goto e_inval;
  237|  np->rxopt.bits.ohopopts = valbool;
  238|  retv = 0;
  239|  break;
  240|
  241| case 58:
  242|  if (optlen < sizeof(int))
  243|   goto e_inval;
  244|  np->rxopt.bits.dstopts = valbool;
  245|  retv = 0;
  246|  break;
  247|
  248| case 4:
  249|  if (optlen < sizeof(int))
  250|   goto e_inval;
  251|  np->rxopt.bits.odstopts = valbool;
  252|  retv = 0;
  253|  break;
  254|
  255| case 67:
  256|  if (optlen < sizeof(int))
  257|   goto e_inval;
  258|  if (val < -1 || val > 0xff)
  259|   goto e_inval;
  260|
  261|  if (val == -1)
  262|   val = 0;
  263|  np->tclass = val;
  264|  retv = 0;
  265|  break;
  266|
  267| case 66:
  268|  if (optlen < sizeof(int))
  269|   goto e_inval;
  270|  np->rxopt.bits.rxtclass = valbool;
  271|  retv = 0;
  272|  break;
  273|
  274| case 11:
  275|  if (optlen < sizeof(int))
  276|   goto e_inval;
  277|  np->rxopt.bits.rxflow = valbool;
  278|  retv = 0;
  279|  break;
  280|
  281| case 60:
  282|  if (optlen < sizeof(int))
  283|   goto e_inval;
  284|  np->rxopt.bits.rxpmtu = valbool;
  285|  retv = 0;
  286|  break;
  287|
  288| case 75:
  289|  if (!capable(12)) {
  290|   retv = -1;
  291|   break;
  292|  }
  293|  if (optlen < sizeof(int))
  294|   goto e_inval;
  295|
  296|  inet_sk(sk)->transparent = valbool;
  297|  retv = 0;
  298|  break;
  299|
  300| case 74:
  301|  if (optlen < sizeof(int))
  302|   goto e_inval;
  303|  np->rxopt.bits.rxorigdstaddr = valbool;
  304|  retv = 0;
  305|  break;
  306|
  307| case 54:
  308| case 55:
  309| case 57:
  310| case 59:
  311| {
  312|  struct ipv6_txoptions *opt;
  313|
  314|
  315|
  316|
  317|  if (optlen == 0)
  318|   optval = ((void *)0);
  319|  else if (optval == ((void *)0))
  320|   goto e_inval;
  321|  else if (optlen < sizeof(struct ipv6_opt_hdr) ||
  322|    optlen & 0x7 || optlen > 8 * 255)
  323|   goto e_inval;
  324|
  325|
  326|  retv = -1;
  327|  if (optname != 57 && !capable(13))
  328|   break;
  329|
  330|  opt = ipv6_renew_options(sk, np->opt, optname,
  331|      (struct ipv6_opt_hdr *)optval,
  332|      optlen);
  333|  if (IS_ERR(opt)) {
  334|   retv = PTR_ERR(opt);
  335|   break;
  336|  }
  337|
  338|
  339|  retv = -22;
  340|  if (optname == 57 && opt && opt->srcrt) {
  341|   struct ipv6_rt_hdr *rthdr = opt->srcrt;
  342|   switch (rthdr->type) {
  343|
  344|   case 2:
  345|    if (rthdr->hdrlen != 2 ||
  346|        rthdr->segments_left != 1)
  347|     goto sticky_done;
  348|
  349|    break;
  350|
  351|   default:
  352|    goto sticky_done;
  353|   }
  354|  }
  355|
  356|  retv = 0;
  357|  opt = ipv6_update_options(sk, opt);
  358|sticky_done:
  359|  if (opt)
  360|   sock_kfree_s(sk, opt, opt->tot_len);
  361|  break;
  362| }
  363|
  364| case 50:
  365| {
  366|  struct in6_pktinfo pkt;
  367|
  368|  if (optlen == 0)
  369|   goto e_inval;
  370|  else if (optlen < sizeof(struct in6_pktinfo) || optval == ((void *)0))
  371|   goto e_inval;
  372|
  373|  if (copy_from_user(&pkt, optval, sizeof(struct in6_pktinfo))) {
  374|    retv = -14;
  375|    break;
  376|  }
  377|  if (sk->__sk_common.skc_bound_dev_if && pkt.ipi6_ifindex != sk->__sk_common.skc_bound_dev_if)
  378|   goto e_inval;
  379|
  380|  np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex;
  381|  ipv6_addr_copy(&np->sticky_pktinfo.ipi6_addr, &pkt.ipi6_addr);
  382|  retv = 0;
  383|  break;
  384| }
  385|
  386| case 6:
  387| {
  388|  struct ipv6_txoptions *opt = ((void *)0);
  389|  struct msghdr msg;
  390|  struct flowi fl;
  391|  int junk;
  392|
  393|  fl.nl_u.ip6_u.flowlabel = 0;
  394|  fl.oif = sk->__sk_common.skc_bound_dev_if;
  395|  fl.mark = sk->sk_mark;
  396|
  397|  if (optlen == 0)
  398|   goto update;
  399|
  400|
  401|
  402|
  403|  retv = -22;
  404|  if (optlen > 64*1024)
  405|   break;
  406|
  407|  opt = sock_kmalloc(sk, sizeof(*opt) + optlen, __st_GFP_KERNEL_st__);
  408|  retv = -105;
  409|  if (opt == ((void *)0))
  410|   break;
  411|
  412|  __st_memset_st__(opt, 0, sizeof(*opt));
  413|  opt->tot_len = sizeof(*opt) + optlen;
  414|  retv = -14;
  415|  if (copy_from_user(opt+1, optval, optlen))
  416|   goto done;
  417|
  418|  msg.msg_controllen = optlen;
  419|  msg.msg_control = (void*)(opt+1);
  420|
  421|  retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk,
  422|      &junk);
  423|  if (retv)
  424|   goto done;
  425|update:
  426|  retv = 0;
  427|  opt = ipv6_update_options(sk, opt);
  428|done:
  429|  if (opt)
  430|   sock_kfree_s(sk, opt, opt->tot_len);
  431|  break;
  432| }
  433| case 16:
  434|  if (optlen < sizeof(int))
  435|   goto e_inval;
  436|  if (val > 255 || val < -1)
  437|   goto e_inval;
  438|  np->hop_limit = val;
  439|  retv = 0;
  440|  break;
  441|
  442| case 18:
  443|  if (sk->sk_type == SOCK_STREAM)
  444|   break;
  445|  if (optlen < sizeof(int))
  446|   goto e_inval;
  447|  if (val > 255 || val < -1)
  448|   goto e_inval;
  449|  np->mcast_hops = val;
  450|  retv = 0;
  451|  break;
  452|
  453| case 19:
  454|  if (optlen < sizeof(int))
  455|   goto e_inval;
  456|  if (val != valbool)
  457|   goto e_inval;
  458|  np->mc_loop = valbool;
  459|  retv = 0;
  460|  break;
  461|
  462| case 17:
  463|  if (sk->sk_type == SOCK_STREAM)
  464|   break;
  465|  if (optlen < sizeof(int))
  466|   goto e_inval;
  467|
  468|  if (val) {
  469|   struct net_device *dev;
  470|
  471|   if (sk->__sk_common.skc_bound_dev_if && sk->__sk_common.skc_bound_dev_if != val)
  472|    goto e_inval;
  473|
  474|   dev = dev_get_by_index(net, val);
  475|   if (!dev) {
  476|    retv = -19;
  477|    break;
  478|   }
  479|   dev_put(dev);
  480|  }
  481|  np->mcast_oif = val;
  482|  retv = 0;
  483|  break;
  484| case 20:
  485| case 21:
  486| {
  487|  struct ipv6_mreq mreq;
  488|
  489|  if (optlen < sizeof(struct ipv6_mreq))
  490|   goto e_inval;
  491|
  492|  retv = -71;
  493|  if (inet_sk(sk)->is_icsk)
  494|   break;
  495|
  496|  retv = -14;
  497|  if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq)))
  498|   break;
  499|
  500|  if (optname == 20)
  501|   retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
  502|  else
  503|   retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
  504|  break;
  505| }
  506| case 27:
  507| case 28:
  508| {
  509|  struct ipv6_mreq mreq;
  510|
  511|  if (optlen < sizeof(struct ipv6_mreq))
  512|   goto e_inval;
  513|
  514|  retv = -14;
  515|  if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq)))
  516|   break;
  517|
  518|  if (optname == 27)
  519|   retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
  520|  else
  521|   retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
  522|  break;
  523| }
  524| case 42:
  525| case 45:
  526| {
  527|  struct group_req greq;
  528|  struct sockaddr_in6 *psin6;
  529|
  530|  if (optlen < sizeof(struct group_req))
  531|   goto e_inval;
  532|
  533|  retv = -14;
  534|  if (copy_from_user(&greq, optval, sizeof(struct group_req)))
  535|   break;
  536|  if (greq.gr_group.ss_family != 10) {
  537|   retv = -99;
  538|   break;
  539|  }
  540|  psin6 = (struct sockaddr_in6 *)&greq.gr_group;
  541|  if (optname == 42)
  542|   retv = ipv6_sock_mc_join(sk, greq.gr_interface,
  543|    &psin6->sin6_addr);
  544|  else
  545|   retv = ipv6_sock_mc_drop(sk, greq.gr_interface,
  546|    &psin6->sin6_addr);
  547|  break;
  548| }
  549| case 46:
  550| case 47:
  551| case 43:
  552| case 44:
  553| {
  554|  struct group_source_req greqs;
  555|  int omode, add;
  556|
  557|  if (optlen < sizeof(struct group_source_req))
  558|   goto e_inval;
  559|  if (copy_from_user(&greqs, optval, sizeof(greqs))) {
  560|   retv = -14;
  561|   break;
  562|  }
  563|  if (greqs.gsr_group.ss_family != 10 ||
  564|      greqs.gsr_source.ss_family != 10) {
  565|   retv = -99;
  566|   break;
  567|  }
  568|  if (optname == 43) {
  569|   omode = 0;
  570|   add = 1;
  571|  } else if (optname == 44) {
  572|   omode = 0;
  573|   add = 0;
  574|  } else if (optname == 46) {
  575|   struct sockaddr_in6 *psin6;
  576|
  577|   psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
  578|   retv = ipv6_sock_mc_join(sk, greqs.gsr_interface,
  579|    &psin6->sin6_addr);
  580|
  581|   if (retv && retv != -98)
  582|    break;
  583|   omode = 1;
  584|   add = 1;
  585|  } else {
  586|   omode = 1;
  587|   add = 0;
  588|  }
  589|  retv = ip6_mc_source(add, omode, sk, &greqs);
  590|  break;
  591| }
  592| case 48:
  593| {
  594|  extern int sysctl_mld_max_msf;
  595|  struct group_filter *gsf;
  596|
  597|  if (optlen < (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (0) * sizeof(struct __kernel_sockaddr_storage)))
  598|   goto e_inval;
  599|  if (optlen > sysctl_optmem_max) {
  600|   retv = -105;
  601|   break;
  602|  }
  603|  gsf = kmalloc(optlen,__st_GFP_KERNEL_st__);
  604|  if (!gsf) {
  605|   retv = -105;
  606|   break;
  607|  }
  608|  retv = -14;
  609|  if (copy_from_user(gsf, optval, optlen)) {
  610|   kfree(gsf);
  611|   break;
  612|  }
  613|
  614|  if (gsf->gf_numsrc >= 0x1ffffffU ||
  615|      gsf->gf_numsrc > sysctl_mld_max_msf) {
  616|   kfree(gsf);
  617|   retv = -105;
  618|   break;
  619|  }
  620|  if ((sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (gsf->gf_numsrc) * sizeof(struct __kernel_sockaddr_storage)) > optlen) {
  621|   kfree(gsf);
  622|   retv = -22;
  623|   break;
  624|  }
  625|  retv = ip6_mc_msfilter(sk, gsf);
  626|  kfree(gsf);
  627|
  628|  break;
  629| }
  630| case 22:
  631|  if (optlen < sizeof(int))
  632|   goto e_inval;
  633|  retv = ip6_ra_control(sk, val);
  634|  break;
  635| case 23:
  636|  if (optlen < sizeof(int))
  637|   goto e_inval;
  638|  if (val < 0 || val > 3)
  639|   goto e_inval;
  640|  np->pmtudisc = val;
  641|  retv = 0;
  642|  break;
  643| case 24:
  644|  if (optlen < sizeof(int))
  645|   goto e_inval;
  646|  if (val && val < 1280)
  647|   goto e_inval;
  648|  np->frag_size = val;
  649|  retv = 0;
  650|  break;
  651| case 25:
  652|  if (optlen < sizeof(int))
  653|   goto e_inval;
  654|  np->recverr = valbool;
  655|  if (!val)
  656|   skb_queue_purge(&sk->sk_error_queue);
  657|  retv = 0;
  658|  break;
  659| case 33:
  660|  if (optlen < sizeof(int))
  661|   goto e_inval;
  662|  np->sndflow = valbool;
  663|  retv = 0;
  664|  break;
  665| case 32:
  666|  retv = ipv6_flowlabel_opt(sk, optval, optlen);
  667|  break;
  668| case 34:
  669| case 35:
  670|  retv = -1;
  671|  if (!capable(12))
  672|   break;
  673|  retv = xfrm_user_policy(sk, optname, optval, optlen);
  674|  break;
  675|
  676| case 72:
  677|     {
  678|  unsigned int pref = 0;
  679|  unsigned int prefmask = ~0;
  680|
  681|  if (optlen < sizeof(int))
  682|   goto e_inval;
  683|
  684|  retv = -22;
  685|
  686|
  687|  switch (val & (0x0002|
  688|          0x0001|
  689|          0x0100)) {
  690|  case 0x0002:
  691|   pref |= 0x0002;
  692|   break;
  693|  case 0x0001:
  694|   pref |= 0x0001;
  695|   break;
  696|  case 0x0100:
  697|   break;
  698|  case 0:
  699|   goto pref_skip_pubtmp;
  700|  default:
  701|   goto e_inval;
  702|  }
  703|
  704|  prefmask &= ~(0x0002|
  705|         0x0001);
  706|pref_skip_pubtmp:
  707|
  708|
  709|  switch (val & (0x0400|0x0004)) {
  710|  case 0x0400:
  711|   break;
  712|  case 0x0004:
  713|   pref |= 0x0004;
  714|  case 0:
  715|   goto pref_skip_coa;
  716|  default:
  717|   goto e_inval;
  718|  }
  719|
  720|  prefmask &= ~0x0004;
  721|pref_skip_coa:
  722|
  723|
  724|  switch (val & (0x0008|0x0800)) {
  725|  case 0x0008:
  726|  case 0x0800:
  727|  case 0:
  728|   break;
  729|  default:
  730|   goto e_inval;
  731|  }
  732|
  733|  np->srcprefs = (np->srcprefs & prefmask) | pref;
  734|  retv = 0;
  735|
  736|  break;
  737|     }
  738| case 73:
  739|  if (optlen < sizeof(int))
  740|   goto e_inval;
  741|  if (val < 0 || val > 255)
  742|   goto e_inval;
  743|  np->min_hopcount = val;
  744|  break;
  745| case 62:
  746|  np->dontfrag = valbool;
  747|  retv = 0;
  748|  break;
  749| }
  750|
  751| release_sock(sk);
  752|
  753| return retv;
  754|
  755|e_inval:
  756| release_sock(sk);
  757| return -22;
  758|}
  759|
  760|int ipv6_setsockopt(struct sock *sk, int level, int optname,
  761|      char *optval, unsigned int optlen)
  762|{
  763| int err;
  764|
  765| if (level == 0 && sk->sk_type != SOCK_RAW)
  766|  return udp_prot.setsockopt(sk, level, optname, optval, optlen);
  767|
  768| if (level != 41)
  769|  return -92;
  770|
  771| err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
  772|
  773|
  774| if (err == -92 && optname != 34 &&
  775|   optname != 35) {
  776|  lock_sock(sk);
  777|  err = nf_setsockopt(sk, 10, optname, optval,
  778|    optlen);
  779|  release_sock(sk);
  780| }
  781|
  782| return err;
  783|}
  784|
  785|extern typeof(ipv6_setsockopt) ipv6_setsockopt; extern void *__crc_ipv6_setsockopt ; static const unsigned long __kcrctab_ipv6_setsockopt = (unsigned long) &__crc_ipv6_setsockopt; static const char __kstrtab_ipv6_setsockopt[] = "" "ipv6_setsockopt"; static const struct kernel_symbol __ksymtab_ipv6_setsockopt = { (unsigned long)&ipv6_setsockopt, __kstrtab_ipv6_setsockopt };
  786|
  787|
  788|int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
  789|      char *optval, unsigned int optlen)
  790|{
  791| int err;
  792|
  793| if (level == 0 && sk->sk_type != SOCK_RAW) {
  794|  if (udp_prot.compat_setsockopt != ((void *)0))
  795|   return udp_prot.compat_setsockopt(sk, level, optname,
  796|         optval, optlen);
  797|  return udp_prot.setsockopt(sk, level, optname, optval, optlen);
  798| }
  799|
  800| if (level != 41)
  801|  return -92;
  802|
  803| if (optname >= 42 && optname <= 48)
  804|  return compat_mc_setsockopt(sk, level, optname, optval, optlen,
  805|   ipv6_setsockopt);
  806|
  807| err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
  808|
  809|
  810| if (err == -92 && optname != 34 &&
  811|     optname != 35) {
  812|  lock_sock(sk);
  813|  err = compat_nf_setsockopt(sk, 10, optname,
  814|        optval, optlen);
  815|  release_sock(sk);
  816| }
  817|
  818| return err;
  819|}
  820|
  821|extern typeof(compat_ipv6_setsockopt) compat_ipv6_setsockopt; extern void *__crc_compat_ipv6_setsockopt ; static const unsigned long __kcrctab_compat_ipv6_setsockopt = (unsigned long) &__crc_compat_ipv6_setsockopt; static const char __kstrtab_compat_ipv6_setsockopt[] = "" "compat_ipv6_setsockopt"; static const struct kernel_symbol __ksymtab_compat_ipv6_setsockopt = { (unsigned long)&compat_ipv6_setsockopt, __kstrtab_compat_ipv6_setsockopt };
  822|
  823|
  824|static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
  825|      int optname, char *optval, int len)
  826|{
  827| struct ipv6_opt_hdr *hdr;
  828|
  829| if (!opt)
  830|  return 0;
  831|
  832| switch(optname) {
  833| case 54:
  834|  hdr = opt->hopopt;
  835|  break;
  836| case 55:
  837|  hdr = opt->dst0opt;
  838|  break;
  839| case 57:
  840|  hdr = (struct ipv6_opt_hdr *)opt->srcrt;
  841|  break;
  842| case 59:
  843|  hdr = opt->dst1opt;
  844|  break;
  845| default:
  846|  return -22;
  847| }
  848|
  849| if (!hdr)
  850|  return 0;
  851|
  852| len = ({ unsigned int __min1 = (len); unsigned int __min2 = ((((hdr)->hdrlen+1) << 3)); __min1 < __min2 ? __min1: __min2; });
  853| if (copy_to_user(optval, hdr, len))
  854|  return -14;
  855| return len;
  856|}
  857|
  858|static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
  859|      char *optval, int *optlen)
  860|{
  861| struct ipv6_pinfo *np = inet6_sk(sk);
  862| int len;
  863| int val;
  864|
  865| if (ip6_mroute_opt(optname))
  866|  return ip6_mroute_getsockopt(sk, optname, optval, optlen);
  867|
  868| if (__st_get_user_st__(len, optlen))
  869|  return -14;
  870| switch (optname) {
  871| case 1:
  872|  if (sk->sk_protocol != IPPROTO_UDP &&
  873|      sk->sk_protocol != IPPROTO_UDPLITE &&
  874|      sk->sk_protocol != IPPROTO_TCP)
  875|   return -92;
  876|  if (sk->__sk_common.skc_state != TCP_ESTABLISHED)
  877|   return -107;
  878|  val = sk->__sk_common.skc_family;
  879|  break;
  880| case 48:
  881| {
  882|  struct group_filter gsf;
  883|  int err;
  884|
  885|  if (len < (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (0) * sizeof(struct __kernel_sockaddr_storage)))
  886|   return -22;
  887|  if (copy_from_user(&gsf, optval, (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (0) * sizeof(struct __kernel_sockaddr_storage))))
  888|   return -14;
  889|  if (gsf.gf_group.ss_family != 10)
  890|   return -99;
  891|  lock_sock(sk);
  892|  err = ip6_mc_msfget(sk, &gsf,
  893|   (struct group_filter *)optval, optlen);
  894|  release_sock(sk);
  895|  return err;
  896| }
  897|
  898| case 6:
  899| {
  900|  struct msghdr msg;
  901|  struct sk_buff *skb;
  902|
  903|  if (sk->sk_type != SOCK_STREAM)
  904|   return -92;
  905|
  906|  msg.msg_control = optval;
  907|  msg.msg_controllen = len;
  908|  msg.msg_flags = 0;
  909|
  910|  lock_sock(sk);
  911|  skb = np->pktoptions;
  912|  if (skb)
  913|   atomic_inc(&skb->users);
  914|  release_sock(sk);
  915|
  916|  if (skb) {
  917|   int err = datagram_recv_ctl(sk, &msg, skb);
  918|   kfree_skb(skb);
  919|   if (err)
  920|    return err;
  921|  } else {
  922|   if (np->rxopt.bits.rxinfo) {
  923|    struct in6_pktinfo src_info;
  924|    src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
  925|     np->sticky_pktinfo.ipi6_ifindex;
  926|    np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) :
  927|     ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr));
  928|    put_cmsg(&msg, 41, 50, sizeof(src_info), &src_info);
  929|   }
  930|   if (np->rxopt.bits.rxhlim) {
  931|    int hlim = np->mcast_hops;
  932|    put_cmsg(&msg, 41, 52, sizeof(hlim), &hlim);
  933|   }
  934|   if (np->rxopt.bits.rxoinfo) {
  935|    struct in6_pktinfo src_info;
  936|    src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
  937|     np->sticky_pktinfo.ipi6_ifindex;
  938|    np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) :
  939|     ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr));
  940|    put_cmsg(&msg, 41, 2, sizeof(src_info), &src_info);
  941|   }
  942|   if (np->rxopt.bits.rxohlim) {
  943|    int hlim = np->mcast_hops;
  944|    put_cmsg(&msg, 41, 8, sizeof(hlim), &hlim);
  945|   }
  946|  }
  947|  len -= msg.msg_controllen;
  948|  return __st_put_user_st__(len, optlen);
  949| }
  950| case 24:
  951| {
  952|  struct dst_entry *dst;
  953|
  954|  val = 0;
  955|  __st_rcu_read_lock_st__();
  956|  dst = __sk_dst_get(sk);
  957|  if (dst)
  958|   val = dst_mtu(dst);
  959|  __st_rcu_read_unlock_st__();
  960|  if (!val)
  961|   return -107;
  962|  break;
  963| }
  964|
  965| case 26:
  966|  val = np->ipv6only;
  967|  break;
  968|
  969| case 49:
  970|  val = np->rxopt.bits.rxinfo;
  971|  break;
  972|
  973| case 2:
  974|  val = np->rxopt.bits.rxoinfo;
  975|  break;
  976|
  977| case 51:
  978|  val = np->rxopt.bits.rxhlim;
  979|  break;
  980|
  981| case 8:
  982|  val = np->rxopt.bits.rxohlim;
  983|  break;
  984|
  985| case 56:
  986|  val = np->rxopt.bits.srcrt;
  987|  break;
  988|
  989| case 5:
  990|  val = np->rxopt.bits.osrcrt;
  991|  break;
  992|
  993| case 54:
  994| case 55:
  995| case 57:
  996| case 59:
  997| {
  998|
  999|  lock_sock(sk);
 1000|  len = ipv6_getsockopt_sticky(sk, np->opt,
 1001|          optname, optval, len);
 1002|  release_sock(sk);
 1003|
 1004|  if (len < 0)
 1005|   return len;
 1006|  return __st_put_user_st__(len, optlen);
 1007| }
 1008|
 1009| case 53:
 1010|  val = np->rxopt.bits.hopopts;
 1011|  break;
 1012|
 1013| case 3:
 1014|  val = np->rxopt.bits.ohopopts;
 1015|  break;
 1016|
 1017| case 58:
 1018|  val = np->rxopt.bits.dstopts;
 1019|  break;
 1020|
 1021| case 4:
 1022|  val = np->rxopt.bits.odstopts;
 1023|  break;
 1024|
 1025| case 67:
 1026|  val = np->tclass;
 1027|  break;
 1028|
 1029| case 66:
 1030|  val = np->rxopt.bits.rxtclass;
 1031|  break;
 1032|
 1033| case 11:
 1034|  val = np->rxopt.bits.rxflow;
 1035|  break;
 1036|
 1037| case 60:
 1038|  val = np->rxopt.bits.rxpmtu;
 1039|  break;
 1040|
 1041| case 61:
 1042| {
 1043|  struct dst_entry *dst;
 1044|  struct ip6_mtuinfo mtuinfo;
 1045|
 1046|  if (len < sizeof(mtuinfo))
 1047|   return -22;
 1048|
 1049|  len = sizeof(mtuinfo);
 1050|  __st_memset_st__(&mtuinfo, 0, sizeof(mtuinfo));
 1051|
 1052|  __st_rcu_read_lock_st__();
 1053|  dst = __sk_dst_get(sk);
 1054|  if (dst)
 1055|   mtuinfo.ip6m_mtu = dst_mtu(dst);
 1056|  __st_rcu_read_unlock_st__();
 1057|  if (!mtuinfo.ip6m_mtu)
 1058|   return -107;
 1059|
 1060|  if (__st_put_user_st__(len, optlen))
 1061|   return -14;
 1062|  if (copy_to_user(optval, &mtuinfo, len))
 1063|   return -14;
 1064|
 1065|  return 0;
 1066|  break;
     |This node is unreachable prev next
 1067| }
 1068|
 1069| case 75:
 1070|  val = inet_sk(sk)->transparent;
 1071|  break;
 1072|
 1073| case 74:
 1074|  val = np->rxopt.bits.rxorigdstaddr;
 1075|  break;
 1076|
 1077| case 16:
 1078| case 18:
 1079| {
 1080|  struct dst_entry *dst;
 1081|
 1082|  if (optname == 16)
 1083|   val = np->hop_limit;
 1084|  else
 1085|   val = np->mcast_hops;
 1086|
 1087|  if (val < 0) {
 1088|   __st_rcu_read_lock_st__();
 1089|   dst = __sk_dst_get(sk);
 1090|   if (dst)
 1091|    val = ip6_dst_hoplimit(dst);
 1092|   __st_rcu_read_unlock_st__();
 1093|  }
 1094|
 1095|  if (val < 0)
 1096|   val = sock_net(sk)->ipv6.devconf_all->hop_limit;
 1097|  break;
 1098| }
 1099|
 1100| case 19:
 1101|  val = np->mc_loop;
 1102|  break;
 1103|
 1104| case 17:
 1105|  val = np->mcast_oif;
 1106|  break;
 1107|
 1108| case 23:
 1109|  val = np->pmtudisc;
 1110|  break;
 1111|
 1112| case 25:
 1113|  val = np->recverr;
 1114|  break;
 1115|
 1116| case 33:
 1117|  val = np->sndflow;
 1118|  break;
 1119|
 1120| case 72:
 1121|  val = 0;
 1122|
 1123|  if (np->srcprefs & 0x0001)
 1124|   val |= 0x0001;
 1125|  else if (np->srcprefs & 0x0002)
 1126|   val |= 0x0002;
 1127|  else {
 1128|
 1129|   val |= 0x0100;
 1130|  }
 1131|
 1132|  if (np->srcprefs & 0x0004)
 1133|   val |= 0x0004;
 1134|  else
 1135|   val |= 0x0400;
 1136|  break;
 1137|
 1138| case 73:
 1139|  val = np->min_hopcount;
 1140|  break;
 1141|
 1142| case 62:
 1143|  val = np->dontfrag;
 1144|  break;
 1145|
 1146| default:
 1147|  return -92;
 1148| }
 1149| len = ({ unsigned int __min1 = (sizeof(int)); unsigned int __min2 = (len); __min1 < __min2 ? __min1: __min2; });
 1150| if(__st_put_user_st__(len, optlen))
 1151|  return -14;
 1152| if(copy_to_user(optval,&val,len))
 1153|  return -14;
 1154| return 0;
 1155|}
 1156|
 1157|int ipv6_getsockopt(struct sock *sk, int level, int optname,
 1158|      char *optval, int *optlen)
 1159|{
 1160| int err;
 1161|
 1162| if (level == 0 && sk->sk_type != SOCK_RAW)
 1163|  return udp_prot.getsockopt(sk, level, optname, optval, optlen);
 1164|
 1165| if(level != 41)
 1166|  return -92;
 1167|
 1168| err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
 1169|
 1170|
 1171| if (err == -92 && optname != 6) {
 1172|  int len;
 1173|
 1174|  if (__st_get_user_st__(len, optlen))
 1175|   return -14;
 1176|
 1177|  lock_sock(sk);
 1178|  err = nf_getsockopt(sk, 10, optname, optval,
 1179|    &len);
 1180|  release_sock(sk);
 1181|  if (err >= 0)
 1182|   err = __st_put_user_st__(len, optlen);
 1183| }
 1184|
 1185| return err;
 1186|}
 1187|
 1188|extern typeof(ipv6_getsockopt) ipv6_getsockopt; extern void *__crc_ipv6_getsockopt ; static const unsigned long __kcrctab_ipv6_getsockopt = (unsigned long) &__crc_ipv6_getsockopt; static const char __kstrtab_ipv6_getsockopt[] = "" "ipv6_getsockopt"; static const struct kernel_symbol __ksymtab_ipv6_getsockopt = { (unsigned long)&ipv6_getsockopt, __kstrtab_ipv6_getsockopt };
 1189|
 1190|
 1191|int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
 1192|      char *optval, int *optlen)
 1193|{
 1194| int err;
 1195|
 1196| if (level == 0 && sk->sk_type != SOCK_RAW) {
 1197|  if (udp_prot.compat_getsockopt != ((void *)0))
 1198|   return udp_prot.compat_getsockopt(sk, level, optname,
 1199|         optval, optlen);
 1200|  return udp_prot.getsockopt(sk, level, optname, optval, optlen);
 1201| }
 1202|
 1203| if (level != 41)
 1204|  return -92;
 1205|
 1206| if (optname == 48)
 1207|  return compat_mc_getsockopt(sk, level, optname, optval, optlen,
 1208|   ipv6_getsockopt);
 1209|
 1210| err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
 1211|
 1212|
 1213| if (err == -92 && optname != 6) {
 1214|  int len;
 1215|
 1216|  if (__st_get_user_st__(len, optlen))
 1217|   return -14;
 1218|
 1219|  lock_sock(sk);
 1220|  err = compat_nf_getsockopt(sk, 10,
 1221|        optname, optval, &len);
 1222|  release_sock(sk);
 1223|  if (err >= 0)
 1224|   err = __st_put_user_st__(len, optlen);
 1225| }
 1226|
 1227| return err;
 1228|}
 1229|
 1230|extern typeof(compat_ipv6_getsockopt) compat_ipv6_getsockopt; extern void *__crc_compat_ipv6_getsockopt ; static const unsigned long __kcrctab_compat_ipv6_getsockopt = (unsigned long) &__crc_compat_ipv6_getsockopt; static const char __kstrtab_compat_ipv6_getsockopt[] = "" "compat_ipv6_getsockopt"; static const struct kernel_symbol __ksymtab_compat_ipv6_getsockopt = { (unsigned long)&compat_ipv6_getsockopt, __kstrtab_compat_ipv6_getsockopt };