Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  IPv6 BSD socket options interface
0004  *  Linux INET6 implementation
0005  *
0006  *  Authors:
0007  *  Pedro Roque     <roque@di.fc.ul.pt>
0008  *
0009  *  Based on linux/net/ipv4/ip_sockglue.c
0010  *
0011  *  FIXME: Make the setsockopt code POSIX compliant: That is
0012  *
0013  *  o   Truncate getsockopt returns
0014  *  o   Return an optlen of the truncated length if need be
0015  *
0016  *  Changes:
0017  *  David L Stevens <dlstevens@us.ibm.com>:
0018  *      - added multicast source filtering API for MLDv2
0019  */
0020 
0021 #include <linux/module.h>
0022 #include <linux/capability.h>
0023 #include <linux/errno.h>
0024 #include <linux/types.h>
0025 #include <linux/socket.h>
0026 #include <linux/sockios.h>
0027 #include <linux/net.h>
0028 #include <linux/in6.h>
0029 #include <linux/mroute6.h>
0030 #include <linux/netdevice.h>
0031 #include <linux/if_arp.h>
0032 #include <linux/init.h>
0033 #include <linux/sysctl.h>
0034 #include <linux/netfilter.h>
0035 #include <linux/slab.h>
0036 
0037 #include <net/sock.h>
0038 #include <net/snmp.h>
0039 #include <net/ipv6.h>
0040 #include <net/ndisc.h>
0041 #include <net/protocol.h>
0042 #include <net/transp_v6.h>
0043 #include <net/ip6_route.h>
0044 #include <net/addrconf.h>
0045 #include <net/inet_common.h>
0046 #include <net/tcp.h>
0047 #include <net/udp.h>
0048 #include <net/udplite.h>
0049 #include <net/xfrm.h>
0050 #include <net/compat.h>
0051 #include <net/seg6.h>
0052 
0053 #include <linux/uaccess.h>
0054 
0055 struct ip6_ra_chain *ip6_ra_chain;
0056 DEFINE_RWLOCK(ip6_ra_lock);
0057 
0058 DEFINE_STATIC_KEY_FALSE(ip6_min_hopcount);
0059 
0060 int ip6_ra_control(struct sock *sk, int sel)
0061 {
0062     struct ip6_ra_chain *ra, *new_ra, **rap;
0063 
0064     /* RA packet may be delivered ONLY to IPPROTO_RAW socket */
0065     if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW)
0066         return -ENOPROTOOPT;
0067 
0068     new_ra = (sel >= 0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
0069     if (sel >= 0 && !new_ra)
0070         return -ENOMEM;
0071 
0072     write_lock_bh(&ip6_ra_lock);
0073     for (rap = &ip6_ra_chain; (ra = *rap) != NULL; rap = &ra->next) {
0074         if (ra->sk == sk) {
0075             if (sel >= 0) {
0076                 write_unlock_bh(&ip6_ra_lock);
0077                 kfree(new_ra);
0078                 return -EADDRINUSE;
0079             }
0080 
0081             *rap = ra->next;
0082             write_unlock_bh(&ip6_ra_lock);
0083 
0084             sock_put(sk);
0085             kfree(ra);
0086             return 0;
0087         }
0088     }
0089     if (!new_ra) {
0090         write_unlock_bh(&ip6_ra_lock);
0091         return -ENOBUFS;
0092     }
0093     new_ra->sk = sk;
0094     new_ra->sel = sel;
0095     new_ra->next = ra;
0096     *rap = new_ra;
0097     sock_hold(sk);
0098     write_unlock_bh(&ip6_ra_lock);
0099     return 0;
0100 }
0101 
0102 struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
0103                        struct ipv6_txoptions *opt)
0104 {
0105     if (inet_sk(sk)->is_icsk) {
0106         if (opt &&
0107             !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
0108             inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) {
0109             struct inet_connection_sock *icsk = inet_csk(sk);
0110             icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
0111             icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
0112         }
0113     }
0114     opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
0115            opt);
0116     sk_dst_reset(sk);
0117 
0118     return opt;
0119 }
0120 
0121 static bool setsockopt_needs_rtnl(int optname)
0122 {
0123     switch (optname) {
0124     case IPV6_ADDRFORM:
0125     case IPV6_ADD_MEMBERSHIP:
0126     case IPV6_DROP_MEMBERSHIP:
0127     case IPV6_JOIN_ANYCAST:
0128     case IPV6_LEAVE_ANYCAST:
0129     case MCAST_JOIN_GROUP:
0130     case MCAST_LEAVE_GROUP:
0131     case MCAST_JOIN_SOURCE_GROUP:
0132     case MCAST_LEAVE_SOURCE_GROUP:
0133     case MCAST_BLOCK_SOURCE:
0134     case MCAST_UNBLOCK_SOURCE:
0135     case MCAST_MSFILTER:
0136         return true;
0137     }
0138     return false;
0139 }
0140 
0141 static int copy_group_source_from_sockptr(struct group_source_req *greqs,
0142         sockptr_t optval, int optlen)
0143 {
0144     if (in_compat_syscall()) {
0145         struct compat_group_source_req gr32;
0146 
0147         if (optlen < sizeof(gr32))
0148             return -EINVAL;
0149         if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
0150             return -EFAULT;
0151         greqs->gsr_interface = gr32.gsr_interface;
0152         greqs->gsr_group = gr32.gsr_group;
0153         greqs->gsr_source = gr32.gsr_source;
0154     } else {
0155         if (optlen < sizeof(*greqs))
0156             return -EINVAL;
0157         if (copy_from_sockptr(greqs, optval, sizeof(*greqs)))
0158             return -EFAULT;
0159     }
0160 
0161     return 0;
0162 }
0163 
0164 static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
0165         sockptr_t optval, int optlen)
0166 {
0167     struct group_source_req greqs;
0168     int omode, add;
0169     int ret;
0170 
0171     ret = copy_group_source_from_sockptr(&greqs, optval, optlen);
0172     if (ret)
0173         return ret;
0174 
0175     if (greqs.gsr_group.ss_family != AF_INET6 ||
0176         greqs.gsr_source.ss_family != AF_INET6)
0177         return -EADDRNOTAVAIL;
0178 
0179     if (optname == MCAST_BLOCK_SOURCE) {
0180         omode = MCAST_EXCLUDE;
0181         add = 1;
0182     } else if (optname == MCAST_UNBLOCK_SOURCE) {
0183         omode = MCAST_EXCLUDE;
0184         add = 0;
0185     } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
0186         struct sockaddr_in6 *psin6;
0187         int retv;
0188 
0189         psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
0190         retv = ipv6_sock_mc_join_ssm(sk, greqs.gsr_interface,
0191                          &psin6->sin6_addr,
0192                          MCAST_INCLUDE);
0193         /* prior join w/ different source is ok */
0194         if (retv && retv != -EADDRINUSE)
0195             return retv;
0196         omode = MCAST_INCLUDE;
0197         add = 1;
0198     } else /* MCAST_LEAVE_SOURCE_GROUP */ {
0199         omode = MCAST_INCLUDE;
0200         add = 0;
0201     }
0202     return ip6_mc_source(add, omode, sk, &greqs);
0203 }
0204 
0205 static int ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
0206         int optlen)
0207 {
0208     struct group_filter *gsf;
0209     int ret;
0210 
0211     if (optlen < GROUP_FILTER_SIZE(0))
0212         return -EINVAL;
0213     if (optlen > READ_ONCE(sysctl_optmem_max))
0214         return -ENOBUFS;
0215 
0216     gsf = memdup_sockptr(optval, optlen);
0217     if (IS_ERR(gsf))
0218         return PTR_ERR(gsf);
0219 
0220     /* numsrc >= (4G-140)/128 overflow in 32 bits */
0221     ret = -ENOBUFS;
0222     if (gsf->gf_numsrc >= 0x1ffffffU ||
0223         gsf->gf_numsrc > sysctl_mld_max_msf)
0224         goto out_free_gsf;
0225 
0226     ret = -EINVAL;
0227     if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
0228         goto out_free_gsf;
0229 
0230     ret = ip6_mc_msfilter(sk, gsf, gsf->gf_slist_flex);
0231 out_free_gsf:
0232     kfree(gsf);
0233     return ret;
0234 }
0235 
0236 static int compat_ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
0237         int optlen)
0238 {
0239     const int size0 = offsetof(struct compat_group_filter, gf_slist_flex);
0240     struct compat_group_filter *gf32;
0241     void *p;
0242     int ret;
0243     int n;
0244 
0245     if (optlen < size0)
0246         return -EINVAL;
0247     if (optlen > READ_ONCE(sysctl_optmem_max) - 4)
0248         return -ENOBUFS;
0249 
0250     p = kmalloc(optlen + 4, GFP_KERNEL);
0251     if (!p)
0252         return -ENOMEM;
0253 
0254     gf32 = p + 4; /* we want ->gf_group and ->gf_slist_flex aligned */
0255     ret = -EFAULT;
0256     if (copy_from_sockptr(gf32, optval, optlen))
0257         goto out_free_p;
0258 
0259     /* numsrc >= (4G-140)/128 overflow in 32 bits */
0260     ret = -ENOBUFS;
0261     n = gf32->gf_numsrc;
0262     if (n >= 0x1ffffffU || n > sysctl_mld_max_msf)
0263         goto out_free_p;
0264 
0265     ret = -EINVAL;
0266     if (offsetof(struct compat_group_filter, gf_slist_flex[n]) > optlen)
0267         goto out_free_p;
0268 
0269     ret = ip6_mc_msfilter(sk, &(struct group_filter){
0270             .gf_interface = gf32->gf_interface,
0271             .gf_group = gf32->gf_group,
0272             .gf_fmode = gf32->gf_fmode,
0273             .gf_numsrc = gf32->gf_numsrc}, gf32->gf_slist_flex);
0274 
0275 out_free_p:
0276     kfree(p);
0277     return ret;
0278 }
0279 
0280 static int ipv6_mcast_join_leave(struct sock *sk, int optname,
0281         sockptr_t optval, int optlen)
0282 {
0283     struct sockaddr_in6 *psin6;
0284     struct group_req greq;
0285 
0286     if (optlen < sizeof(greq))
0287         return -EINVAL;
0288     if (copy_from_sockptr(&greq, optval, sizeof(greq)))
0289         return -EFAULT;
0290 
0291     if (greq.gr_group.ss_family != AF_INET6)
0292         return -EADDRNOTAVAIL;
0293     psin6 = (struct sockaddr_in6 *)&greq.gr_group;
0294     if (optname == MCAST_JOIN_GROUP)
0295         return ipv6_sock_mc_join(sk, greq.gr_interface,
0296                      &psin6->sin6_addr);
0297     return ipv6_sock_mc_drop(sk, greq.gr_interface, &psin6->sin6_addr);
0298 }
0299 
0300 static int compat_ipv6_mcast_join_leave(struct sock *sk, int optname,
0301         sockptr_t optval, int optlen)
0302 {
0303     struct compat_group_req gr32;
0304     struct sockaddr_in6 *psin6;
0305 
0306     if (optlen < sizeof(gr32))
0307         return -EINVAL;
0308     if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
0309         return -EFAULT;
0310 
0311     if (gr32.gr_group.ss_family != AF_INET6)
0312         return -EADDRNOTAVAIL;
0313     psin6 = (struct sockaddr_in6 *)&gr32.gr_group;
0314     if (optname == MCAST_JOIN_GROUP)
0315         return ipv6_sock_mc_join(sk, gr32.gr_interface,
0316                     &psin6->sin6_addr);
0317     return ipv6_sock_mc_drop(sk, gr32.gr_interface, &psin6->sin6_addr);
0318 }
0319 
0320 static int ipv6_set_opt_hdr(struct sock *sk, int optname, sockptr_t optval,
0321         int optlen)
0322 {
0323     struct ipv6_pinfo *np = inet6_sk(sk);
0324     struct ipv6_opt_hdr *new = NULL;
0325     struct net *net = sock_net(sk);
0326     struct ipv6_txoptions *opt;
0327     int err;
0328 
0329     /* hop-by-hop / destination options are privileged option */
0330     if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
0331         return -EPERM;
0332 
0333     /* remove any sticky options header with a zero option
0334      * length, per RFC3542.
0335      */
0336     if (optlen > 0) {
0337         if (sockptr_is_null(optval))
0338             return -EINVAL;
0339         if (optlen < sizeof(struct ipv6_opt_hdr) ||
0340             optlen & 0x7 ||
0341             optlen > 8 * 255)
0342             return -EINVAL;
0343 
0344         new = memdup_sockptr(optval, optlen);
0345         if (IS_ERR(new))
0346             return PTR_ERR(new);
0347         if (unlikely(ipv6_optlen(new) > optlen)) {
0348             kfree(new);
0349             return -EINVAL;
0350         }
0351     }
0352 
0353     opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
0354     opt = ipv6_renew_options(sk, opt, optname, new);
0355     kfree(new);
0356     if (IS_ERR(opt))
0357         return PTR_ERR(opt);
0358 
0359     /* routing header option needs extra check */
0360     err = -EINVAL;
0361     if (optname == IPV6_RTHDR && opt && opt->srcrt) {
0362         struct ipv6_rt_hdr *rthdr = opt->srcrt;
0363         switch (rthdr->type) {
0364 #if IS_ENABLED(CONFIG_IPV6_MIP6)
0365         case IPV6_SRCRT_TYPE_2:
0366             if (rthdr->hdrlen != 2 || rthdr->segments_left != 1)
0367                 goto sticky_done;
0368             break;
0369 #endif
0370         case IPV6_SRCRT_TYPE_4:
0371         {
0372             struct ipv6_sr_hdr *srh =
0373                 (struct ipv6_sr_hdr *)opt->srcrt;
0374 
0375             if (!seg6_validate_srh(srh, optlen, false))
0376                 goto sticky_done;
0377             break;
0378         }
0379         default:
0380             goto sticky_done;
0381         }
0382     }
0383 
0384     err = 0;
0385     opt = ipv6_update_options(sk, opt);
0386 sticky_done:
0387     if (opt) {
0388         atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
0389         txopt_put(opt);
0390     }
0391     return err;
0392 }
0393 
0394 static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
0395            sockptr_t optval, unsigned int optlen)
0396 {
0397     struct ipv6_pinfo *np = inet6_sk(sk);
0398     struct net *net = sock_net(sk);
0399     int val, valbool;
0400     int retv = -ENOPROTOOPT;
0401     bool needs_rtnl = setsockopt_needs_rtnl(optname);
0402 
0403     if (sockptr_is_null(optval))
0404         val = 0;
0405     else {
0406         if (optlen >= sizeof(int)) {
0407             if (copy_from_sockptr(&val, optval, sizeof(val)))
0408                 return -EFAULT;
0409         } else
0410             val = 0;
0411     }
0412 
0413     valbool = (val != 0);
0414 
0415     if (ip6_mroute_opt(optname))
0416         return ip6_mroute_setsockopt(sk, optname, optval, optlen);
0417 
0418     if (needs_rtnl)
0419         rtnl_lock();
0420     lock_sock(sk);
0421 
0422     switch (optname) {
0423 
0424     case IPV6_ADDRFORM:
0425         if (optlen < sizeof(int))
0426             goto e_inval;
0427         if (val == PF_INET) {
0428             struct ipv6_txoptions *opt;
0429             struct sk_buff *pktopt;
0430 
0431             if (sk->sk_type == SOCK_RAW)
0432                 break;
0433 
0434             if (sk->sk_protocol == IPPROTO_UDP ||
0435                 sk->sk_protocol == IPPROTO_UDPLITE) {
0436                 struct udp_sock *up = udp_sk(sk);
0437                 if (up->pending == AF_INET6) {
0438                     retv = -EBUSY;
0439                     break;
0440                 }
0441             } else if (sk->sk_protocol == IPPROTO_TCP) {
0442                 if (sk->sk_prot != &tcpv6_prot) {
0443                     retv = -EBUSY;
0444                     break;
0445                 }
0446             } else {
0447                 break;
0448             }
0449 
0450             if (sk->sk_state != TCP_ESTABLISHED) {
0451                 retv = -ENOTCONN;
0452                 break;
0453             }
0454 
0455             if (ipv6_only_sock(sk) ||
0456                 !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
0457                 retv = -EADDRNOTAVAIL;
0458                 break;
0459             }
0460 
0461             fl6_free_socklist(sk);
0462             __ipv6_sock_mc_close(sk);
0463             __ipv6_sock_ac_close(sk);
0464 
0465             /*
0466              * Sock is moving from IPv6 to IPv4 (sk_prot), so
0467              * remove it from the refcnt debug socks count in the
0468              * original family...
0469              */
0470             sk_refcnt_debug_dec(sk);
0471 
0472             if (sk->sk_protocol == IPPROTO_TCP) {
0473                 struct inet_connection_sock *icsk = inet_csk(sk);
0474 
0475                 sock_prot_inuse_add(net, sk->sk_prot, -1);
0476                 sock_prot_inuse_add(net, &tcp_prot, 1);
0477 
0478                 /* Paired with READ_ONCE(sk->sk_prot) in net/ipv6/af_inet6.c */
0479                 WRITE_ONCE(sk->sk_prot, &tcp_prot);
0480                 icsk->icsk_af_ops = &ipv4_specific;
0481                 sk->sk_socket->ops = &inet_stream_ops;
0482                 sk->sk_family = PF_INET;
0483                 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
0484             } else {
0485                 struct proto *prot = &udp_prot;
0486 
0487                 if (sk->sk_protocol == IPPROTO_UDPLITE)
0488                     prot = &udplite_prot;
0489 
0490                 sock_prot_inuse_add(net, sk->sk_prot, -1);
0491                 sock_prot_inuse_add(net, prot, 1);
0492 
0493                 /* Paired with READ_ONCE(sk->sk_prot) in net/ipv6/af_inet6.c */
0494                 WRITE_ONCE(sk->sk_prot, prot);
0495                 sk->sk_socket->ops = &inet_dgram_ops;
0496                 sk->sk_family = PF_INET;
0497             }
0498             opt = xchg((__force struct ipv6_txoptions **)&np->opt,
0499                    NULL);
0500             if (opt) {
0501                 atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
0502                 txopt_put(opt);
0503             }
0504             pktopt = xchg(&np->pktoptions, NULL);
0505             kfree_skb(pktopt);
0506 
0507             /*
0508              * ... and add it to the refcnt debug socks count
0509              * in the new family. -acme
0510              */
0511             sk_refcnt_debug_inc(sk);
0512             module_put(THIS_MODULE);
0513             retv = 0;
0514             break;
0515         }
0516         goto e_inval;
0517 
0518     case IPV6_V6ONLY:
0519         if (optlen < sizeof(int) ||
0520             inet_sk(sk)->inet_num)
0521             goto e_inval;
0522         sk->sk_ipv6only = valbool;
0523         retv = 0;
0524         break;
0525 
0526     case IPV6_RECVPKTINFO:
0527         if (optlen < sizeof(int))
0528             goto e_inval;
0529         np->rxopt.bits.rxinfo = valbool;
0530         retv = 0;
0531         break;
0532 
0533     case IPV6_2292PKTINFO:
0534         if (optlen < sizeof(int))
0535             goto e_inval;
0536         np->rxopt.bits.rxoinfo = valbool;
0537         retv = 0;
0538         break;
0539 
0540     case IPV6_RECVHOPLIMIT:
0541         if (optlen < sizeof(int))
0542             goto e_inval;
0543         np->rxopt.bits.rxhlim = valbool;
0544         retv = 0;
0545         break;
0546 
0547     case IPV6_2292HOPLIMIT:
0548         if (optlen < sizeof(int))
0549             goto e_inval;
0550         np->rxopt.bits.rxohlim = valbool;
0551         retv = 0;
0552         break;
0553 
0554     case IPV6_RECVRTHDR:
0555         if (optlen < sizeof(int))
0556             goto e_inval;
0557         np->rxopt.bits.srcrt = valbool;
0558         retv = 0;
0559         break;
0560 
0561     case IPV6_2292RTHDR:
0562         if (optlen < sizeof(int))
0563             goto e_inval;
0564         np->rxopt.bits.osrcrt = valbool;
0565         retv = 0;
0566         break;
0567 
0568     case IPV6_RECVHOPOPTS:
0569         if (optlen < sizeof(int))
0570             goto e_inval;
0571         np->rxopt.bits.hopopts = valbool;
0572         retv = 0;
0573         break;
0574 
0575     case IPV6_2292HOPOPTS:
0576         if (optlen < sizeof(int))
0577             goto e_inval;
0578         np->rxopt.bits.ohopopts = valbool;
0579         retv = 0;
0580         break;
0581 
0582     case IPV6_RECVDSTOPTS:
0583         if (optlen < sizeof(int))
0584             goto e_inval;
0585         np->rxopt.bits.dstopts = valbool;
0586         retv = 0;
0587         break;
0588 
0589     case IPV6_2292DSTOPTS:
0590         if (optlen < sizeof(int))
0591             goto e_inval;
0592         np->rxopt.bits.odstopts = valbool;
0593         retv = 0;
0594         break;
0595 
0596     case IPV6_TCLASS:
0597         if (optlen < sizeof(int))
0598             goto e_inval;
0599         if (val < -1 || val > 0xff)
0600             goto e_inval;
0601         /* RFC 3542, 6.5: default traffic class of 0x0 */
0602         if (val == -1)
0603             val = 0;
0604         if (sk->sk_type == SOCK_STREAM) {
0605             val &= ~INET_ECN_MASK;
0606             val |= np->tclass & INET_ECN_MASK;
0607         }
0608         if (np->tclass != val) {
0609             np->tclass = val;
0610             sk_dst_reset(sk);
0611         }
0612         retv = 0;
0613         break;
0614 
0615     case IPV6_RECVTCLASS:
0616         if (optlen < sizeof(int))
0617             goto e_inval;
0618         np->rxopt.bits.rxtclass = valbool;
0619         retv = 0;
0620         break;
0621 
0622     case IPV6_FLOWINFO:
0623         if (optlen < sizeof(int))
0624             goto e_inval;
0625         np->rxopt.bits.rxflow = valbool;
0626         retv = 0;
0627         break;
0628 
0629     case IPV6_RECVPATHMTU:
0630         if (optlen < sizeof(int))
0631             goto e_inval;
0632         np->rxopt.bits.rxpmtu = valbool;
0633         retv = 0;
0634         break;
0635 
0636     case IPV6_TRANSPARENT:
0637         if (valbool && !ns_capable(net->user_ns, CAP_NET_RAW) &&
0638             !ns_capable(net->user_ns, CAP_NET_ADMIN)) {
0639             retv = -EPERM;
0640             break;
0641         }
0642         if (optlen < sizeof(int))
0643             goto e_inval;
0644         /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
0645         inet_sk(sk)->transparent = valbool;
0646         retv = 0;
0647         break;
0648 
0649     case IPV6_FREEBIND:
0650         if (optlen < sizeof(int))
0651             goto e_inval;
0652         /* we also don't have a separate freebind bit for IPV6 */
0653         inet_sk(sk)->freebind = valbool;
0654         retv = 0;
0655         break;
0656 
0657     case IPV6_RECVORIGDSTADDR:
0658         if (optlen < sizeof(int))
0659             goto e_inval;
0660         np->rxopt.bits.rxorigdstaddr = valbool;
0661         retv = 0;
0662         break;
0663 
0664     case IPV6_HOPOPTS:
0665     case IPV6_RTHDRDSTOPTS:
0666     case IPV6_RTHDR:
0667     case IPV6_DSTOPTS:
0668         retv = ipv6_set_opt_hdr(sk, optname, optval, optlen);
0669         break;
0670 
0671     case IPV6_PKTINFO:
0672     {
0673         struct in6_pktinfo pkt;
0674 
0675         if (optlen == 0)
0676             goto e_inval;
0677         else if (optlen < sizeof(struct in6_pktinfo) ||
0678              sockptr_is_null(optval))
0679             goto e_inval;
0680 
0681         if (copy_from_sockptr(&pkt, optval, sizeof(pkt))) {
0682             retv = -EFAULT;
0683             break;
0684         }
0685         if (!sk_dev_equal_l3scope(sk, pkt.ipi6_ifindex))
0686             goto e_inval;
0687 
0688         np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex;
0689         np->sticky_pktinfo.ipi6_addr = pkt.ipi6_addr;
0690         retv = 0;
0691         break;
0692     }
0693 
0694     case IPV6_2292PKTOPTIONS:
0695     {
0696         struct ipv6_txoptions *opt = NULL;
0697         struct msghdr msg;
0698         struct flowi6 fl6;
0699         struct ipcm6_cookie ipc6;
0700 
0701         memset(&fl6, 0, sizeof(fl6));
0702         fl6.flowi6_oif = sk->sk_bound_dev_if;
0703         fl6.flowi6_mark = sk->sk_mark;
0704 
0705         if (optlen == 0)
0706             goto update;
0707 
0708         /* 1K is probably excessive
0709          * 1K is surely not enough, 2K per standard header is 16K.
0710          */
0711         retv = -EINVAL;
0712         if (optlen > 64*1024)
0713             break;
0714 
0715         opt = sock_kmalloc(sk, sizeof(*opt) + optlen, GFP_KERNEL);
0716         retv = -ENOBUFS;
0717         if (!opt)
0718             break;
0719 
0720         memset(opt, 0, sizeof(*opt));
0721         refcount_set(&opt->refcnt, 1);
0722         opt->tot_len = sizeof(*opt) + optlen;
0723         retv = -EFAULT;
0724         if (copy_from_sockptr(opt + 1, optval, optlen))
0725             goto done;
0726 
0727         msg.msg_controllen = optlen;
0728         msg.msg_control = (void *)(opt+1);
0729         ipc6.opt = opt;
0730 
0731         retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6);
0732         if (retv)
0733             goto done;
0734 update:
0735         retv = 0;
0736         opt = ipv6_update_options(sk, opt);
0737 done:
0738         if (opt) {
0739             atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
0740             txopt_put(opt);
0741         }
0742         break;
0743     }
0744     case IPV6_UNICAST_HOPS:
0745         if (optlen < sizeof(int))
0746             goto e_inval;
0747         if (val > 255 || val < -1)
0748             goto e_inval;
0749         np->hop_limit = val;
0750         retv = 0;
0751         break;
0752 
0753     case IPV6_MULTICAST_HOPS:
0754         if (sk->sk_type == SOCK_STREAM)
0755             break;
0756         if (optlen < sizeof(int))
0757             goto e_inval;
0758         if (val > 255 || val < -1)
0759             goto e_inval;
0760         np->mcast_hops = (val == -1 ? IPV6_DEFAULT_MCASTHOPS : val);
0761         retv = 0;
0762         break;
0763 
0764     case IPV6_MULTICAST_LOOP:
0765         if (optlen < sizeof(int))
0766             goto e_inval;
0767         if (val != valbool)
0768             goto e_inval;
0769         np->mc_loop = valbool;
0770         retv = 0;
0771         break;
0772 
0773     case IPV6_UNICAST_IF:
0774     {
0775         struct net_device *dev = NULL;
0776         int ifindex;
0777 
0778         if (optlen != sizeof(int))
0779             goto e_inval;
0780 
0781         ifindex = (__force int)ntohl((__force __be32)val);
0782         if (ifindex == 0) {
0783             np->ucast_oif = 0;
0784             retv = 0;
0785             break;
0786         }
0787 
0788         dev = dev_get_by_index(net, ifindex);
0789         retv = -EADDRNOTAVAIL;
0790         if (!dev)
0791             break;
0792         dev_put(dev);
0793 
0794         retv = -EINVAL;
0795         if (sk->sk_bound_dev_if)
0796             break;
0797 
0798         np->ucast_oif = ifindex;
0799         retv = 0;
0800         break;
0801     }
0802 
0803     case IPV6_MULTICAST_IF:
0804         if (sk->sk_type == SOCK_STREAM)
0805             break;
0806         if (optlen < sizeof(int))
0807             goto e_inval;
0808 
0809         if (val) {
0810             struct net_device *dev;
0811             int midx;
0812 
0813             rcu_read_lock();
0814 
0815             dev = dev_get_by_index_rcu(net, val);
0816             if (!dev) {
0817                 rcu_read_unlock();
0818                 retv = -ENODEV;
0819                 break;
0820             }
0821             midx = l3mdev_master_ifindex_rcu(dev);
0822 
0823             rcu_read_unlock();
0824 
0825             if (sk->sk_bound_dev_if &&
0826                 sk->sk_bound_dev_if != val &&
0827                 (!midx || midx != sk->sk_bound_dev_if))
0828                 goto e_inval;
0829         }
0830         np->mcast_oif = val;
0831         retv = 0;
0832         break;
0833     case IPV6_ADD_MEMBERSHIP:
0834     case IPV6_DROP_MEMBERSHIP:
0835     {
0836         struct ipv6_mreq mreq;
0837 
0838         if (optlen < sizeof(struct ipv6_mreq))
0839             goto e_inval;
0840 
0841         retv = -EPROTO;
0842         if (inet_sk(sk)->is_icsk)
0843             break;
0844 
0845         retv = -EFAULT;
0846         if (copy_from_sockptr(&mreq, optval, sizeof(struct ipv6_mreq)))
0847             break;
0848 
0849         if (optname == IPV6_ADD_MEMBERSHIP)
0850             retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
0851         else
0852             retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
0853         break;
0854     }
0855     case IPV6_JOIN_ANYCAST:
0856     case IPV6_LEAVE_ANYCAST:
0857     {
0858         struct ipv6_mreq mreq;
0859 
0860         if (optlen < sizeof(struct ipv6_mreq))
0861             goto e_inval;
0862 
0863         retv = -EFAULT;
0864         if (copy_from_sockptr(&mreq, optval, sizeof(struct ipv6_mreq)))
0865             break;
0866 
0867         if (optname == IPV6_JOIN_ANYCAST)
0868             retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
0869         else
0870             retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
0871         break;
0872     }
0873     case IPV6_MULTICAST_ALL:
0874         if (optlen < sizeof(int))
0875             goto e_inval;
0876         np->mc_all = valbool;
0877         retv = 0;
0878         break;
0879 
0880     case MCAST_JOIN_GROUP:
0881     case MCAST_LEAVE_GROUP:
0882         if (in_compat_syscall())
0883             retv = compat_ipv6_mcast_join_leave(sk, optname, optval,
0884                                 optlen);
0885         else
0886             retv = ipv6_mcast_join_leave(sk, optname, optval,
0887                              optlen);
0888         break;
0889     case MCAST_JOIN_SOURCE_GROUP:
0890     case MCAST_LEAVE_SOURCE_GROUP:
0891     case MCAST_BLOCK_SOURCE:
0892     case MCAST_UNBLOCK_SOURCE:
0893         retv = do_ipv6_mcast_group_source(sk, optname, optval, optlen);
0894         break;
0895     case MCAST_MSFILTER:
0896         if (in_compat_syscall())
0897             retv = compat_ipv6_set_mcast_msfilter(sk, optval,
0898                                   optlen);
0899         else
0900             retv = ipv6_set_mcast_msfilter(sk, optval, optlen);
0901         break;
0902     case IPV6_ROUTER_ALERT:
0903         if (optlen < sizeof(int))
0904             goto e_inval;
0905         retv = ip6_ra_control(sk, val);
0906         break;
0907     case IPV6_ROUTER_ALERT_ISOLATE:
0908         if (optlen < sizeof(int))
0909             goto e_inval;
0910         np->rtalert_isolate = valbool;
0911         retv = 0;
0912         break;
0913     case IPV6_MTU_DISCOVER:
0914         if (optlen < sizeof(int))
0915             goto e_inval;
0916         if (val < IPV6_PMTUDISC_DONT || val > IPV6_PMTUDISC_OMIT)
0917             goto e_inval;
0918         np->pmtudisc = val;
0919         retv = 0;
0920         break;
0921     case IPV6_MTU:
0922         if (optlen < sizeof(int))
0923             goto e_inval;
0924         if (val && val < IPV6_MIN_MTU)
0925             goto e_inval;
0926         np->frag_size = val;
0927         retv = 0;
0928         break;
0929     case IPV6_RECVERR:
0930         if (optlen < sizeof(int))
0931             goto e_inval;
0932         np->recverr = valbool;
0933         if (!val)
0934             skb_queue_purge(&sk->sk_error_queue);
0935         retv = 0;
0936         break;
0937     case IPV6_FLOWINFO_SEND:
0938         if (optlen < sizeof(int))
0939             goto e_inval;
0940         np->sndflow = valbool;
0941         retv = 0;
0942         break;
0943     case IPV6_FLOWLABEL_MGR:
0944         retv = ipv6_flowlabel_opt(sk, optval, optlen);
0945         break;
0946     case IPV6_IPSEC_POLICY:
0947     case IPV6_XFRM_POLICY:
0948         retv = -EPERM;
0949         if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
0950             break;
0951         retv = xfrm_user_policy(sk, optname, optval, optlen);
0952         break;
0953 
0954     case IPV6_ADDR_PREFERENCES:
0955         if (optlen < sizeof(int))
0956             goto e_inval;
0957         retv = __ip6_sock_set_addr_preferences(sk, val);
0958         break;
0959     case IPV6_MINHOPCOUNT:
0960         if (optlen < sizeof(int))
0961             goto e_inval;
0962         if (val < 0 || val > 255)
0963             goto e_inval;
0964 
0965         if (val)
0966             static_branch_enable(&ip6_min_hopcount);
0967 
0968         /* tcp_v6_err() and tcp_v6_rcv() might read min_hopcount
0969          * while we are changing it.
0970          */
0971         WRITE_ONCE(np->min_hopcount, val);
0972         retv = 0;
0973         break;
0974     case IPV6_DONTFRAG:
0975         np->dontfrag = valbool;
0976         retv = 0;
0977         break;
0978     case IPV6_AUTOFLOWLABEL:
0979         np->autoflowlabel = valbool;
0980         np->autoflowlabel_set = 1;
0981         retv = 0;
0982         break;
0983     case IPV6_RECVFRAGSIZE:
0984         np->rxopt.bits.recvfragsize = valbool;
0985         retv = 0;
0986         break;
0987     case IPV6_RECVERR_RFC4884:
0988         if (optlen < sizeof(int))
0989             goto e_inval;
0990         if (val < 0 || val > 1)
0991             goto e_inval;
0992         np->recverr_rfc4884 = valbool;
0993         retv = 0;
0994         break;
0995     }
0996 
0997     release_sock(sk);
0998     if (needs_rtnl)
0999         rtnl_unlock();
1000 
1001     return retv;
1002 
1003 e_inval:
1004     release_sock(sk);
1005     if (needs_rtnl)
1006         rtnl_unlock();
1007     return -EINVAL;
1008 }
1009 
1010 int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
1011             unsigned int optlen)
1012 {
1013     int err;
1014 
1015     if (level == SOL_IP && sk->sk_type != SOCK_RAW)
1016         return udp_prot.setsockopt(sk, level, optname, optval, optlen);
1017 
1018     if (level != SOL_IPV6)
1019         return -ENOPROTOOPT;
1020 
1021     err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
1022 #ifdef CONFIG_NETFILTER
1023     /* we need to exclude all possible ENOPROTOOPTs except default case */
1024     if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
1025             optname != IPV6_XFRM_POLICY)
1026         err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
1027 #endif
1028     return err;
1029 }
1030 EXPORT_SYMBOL(ipv6_setsockopt);
1031 
1032 static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
1033                   int optname, char __user *optval, int len)
1034 {
1035     struct ipv6_opt_hdr *hdr;
1036 
1037     if (!opt)
1038         return 0;
1039 
1040     switch (optname) {
1041     case IPV6_HOPOPTS:
1042         hdr = opt->hopopt;
1043         break;
1044     case IPV6_RTHDRDSTOPTS:
1045         hdr = opt->dst0opt;
1046         break;
1047     case IPV6_RTHDR:
1048         hdr = (struct ipv6_opt_hdr *)opt->srcrt;
1049         break;
1050     case IPV6_DSTOPTS:
1051         hdr = opt->dst1opt;
1052         break;
1053     default:
1054         return -EINVAL; /* should not happen */
1055     }
1056 
1057     if (!hdr)
1058         return 0;
1059 
1060     len = min_t(unsigned int, len, ipv6_optlen(hdr));
1061     if (copy_to_user(optval, hdr, len))
1062         return -EFAULT;
1063     return len;
1064 }
1065 
1066 static int ipv6_get_msfilter(struct sock *sk, void __user *optval,
1067         int __user *optlen, int len)
1068 {
1069     const int size0 = offsetof(struct group_filter, gf_slist_flex);
1070     struct group_filter __user *p = optval;
1071     struct group_filter gsf;
1072     int num;
1073     int err;
1074 
1075     if (len < size0)
1076         return -EINVAL;
1077     if (copy_from_user(&gsf, p, size0))
1078         return -EFAULT;
1079     if (gsf.gf_group.ss_family != AF_INET6)
1080         return -EADDRNOTAVAIL;
1081     num = gsf.gf_numsrc;
1082     lock_sock(sk);
1083     err = ip6_mc_msfget(sk, &gsf, p->gf_slist_flex);
1084     if (!err) {
1085         if (num > gsf.gf_numsrc)
1086             num = gsf.gf_numsrc;
1087         if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
1088             copy_to_user(p, &gsf, size0))
1089             err = -EFAULT;
1090     }
1091     release_sock(sk);
1092     return err;
1093 }
1094 
1095 static int compat_ipv6_get_msfilter(struct sock *sk, void __user *optval,
1096         int __user *optlen)
1097 {
1098     const int size0 = offsetof(struct compat_group_filter, gf_slist_flex);
1099     struct compat_group_filter __user *p = optval;
1100     struct compat_group_filter gf32;
1101     struct group_filter gf;
1102     int len, err;
1103     int num;
1104 
1105     if (get_user(len, optlen))
1106         return -EFAULT;
1107     if (len < size0)
1108         return -EINVAL;
1109 
1110     if (copy_from_user(&gf32, p, size0))
1111         return -EFAULT;
1112     gf.gf_interface = gf32.gf_interface;
1113     gf.gf_fmode = gf32.gf_fmode;
1114     num = gf.gf_numsrc = gf32.gf_numsrc;
1115     gf.gf_group = gf32.gf_group;
1116 
1117     if (gf.gf_group.ss_family != AF_INET6)
1118         return -EADDRNOTAVAIL;
1119 
1120     lock_sock(sk);
1121     err = ip6_mc_msfget(sk, &gf, p->gf_slist_flex);
1122     release_sock(sk);
1123     if (err)
1124         return err;
1125     if (num > gf.gf_numsrc)
1126         num = gf.gf_numsrc;
1127     len = GROUP_FILTER_SIZE(num) - (sizeof(gf)-sizeof(gf32));
1128     if (put_user(len, optlen) ||
1129         put_user(gf.gf_fmode, &p->gf_fmode) ||
1130         put_user(gf.gf_numsrc, &p->gf_numsrc))
1131         return -EFAULT;
1132     return 0;
1133 }
1134 
1135 static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1136             char __user *optval, int __user *optlen, unsigned int flags)
1137 {
1138     struct ipv6_pinfo *np = inet6_sk(sk);
1139     int len;
1140     int val;
1141 
1142     if (ip6_mroute_opt(optname))
1143         return ip6_mroute_getsockopt(sk, optname, optval, optlen);
1144 
1145     if (get_user(len, optlen))
1146         return -EFAULT;
1147     switch (optname) {
1148     case IPV6_ADDRFORM:
1149         if (sk->sk_protocol != IPPROTO_UDP &&
1150             sk->sk_protocol != IPPROTO_UDPLITE &&
1151             sk->sk_protocol != IPPROTO_TCP)
1152             return -ENOPROTOOPT;
1153         if (sk->sk_state != TCP_ESTABLISHED)
1154             return -ENOTCONN;
1155         val = sk->sk_family;
1156         break;
1157     case MCAST_MSFILTER:
1158         if (in_compat_syscall())
1159             return compat_ipv6_get_msfilter(sk, optval, optlen);
1160         return ipv6_get_msfilter(sk, optval, optlen, len);
1161     case IPV6_2292PKTOPTIONS:
1162     {
1163         struct msghdr msg;
1164         struct sk_buff *skb;
1165 
1166         if (sk->sk_type != SOCK_STREAM)
1167             return -ENOPROTOOPT;
1168 
1169         msg.msg_control_user = optval;
1170         msg.msg_controllen = len;
1171         msg.msg_flags = flags;
1172         msg.msg_control_is_user = true;
1173 
1174         lock_sock(sk);
1175         skb = np->pktoptions;
1176         if (skb)
1177             ip6_datagram_recv_ctl(sk, &msg, skb);
1178         release_sock(sk);
1179         if (!skb) {
1180             if (np->rxopt.bits.rxinfo) {
1181                 struct in6_pktinfo src_info;
1182                 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
1183                     np->sticky_pktinfo.ipi6_ifindex;
1184                 src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr : np->sticky_pktinfo.ipi6_addr;
1185                 put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
1186             }
1187             if (np->rxopt.bits.rxhlim) {
1188                 int hlim = np->mcast_hops;
1189                 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
1190             }
1191             if (np->rxopt.bits.rxtclass) {
1192                 int tclass = (int)ip6_tclass(np->rcv_flowinfo);
1193 
1194                 put_cmsg(&msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
1195             }
1196             if (np->rxopt.bits.rxoinfo) {
1197                 struct in6_pktinfo src_info;
1198                 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
1199                     np->sticky_pktinfo.ipi6_ifindex;
1200                 src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr :
1201                                      np->sticky_pktinfo.ipi6_addr;
1202                 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
1203             }
1204             if (np->rxopt.bits.rxohlim) {
1205                 int hlim = np->mcast_hops;
1206                 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
1207             }
1208             if (np->rxopt.bits.rxflow) {
1209                 __be32 flowinfo = np->rcv_flowinfo;
1210 
1211                 put_cmsg(&msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
1212             }
1213         }
1214         len -= msg.msg_controllen;
1215         return put_user(len, optlen);
1216     }
1217     case IPV6_MTU:
1218     {
1219         struct dst_entry *dst;
1220 
1221         val = 0;
1222         rcu_read_lock();
1223         dst = __sk_dst_get(sk);
1224         if (dst)
1225             val = dst_mtu(dst);
1226         rcu_read_unlock();
1227         if (!val)
1228             return -ENOTCONN;
1229         break;
1230     }
1231 
1232     case IPV6_V6ONLY:
1233         val = sk->sk_ipv6only;
1234         break;
1235 
1236     case IPV6_RECVPKTINFO:
1237         val = np->rxopt.bits.rxinfo;
1238         break;
1239 
1240     case IPV6_2292PKTINFO:
1241         val = np->rxopt.bits.rxoinfo;
1242         break;
1243 
1244     case IPV6_RECVHOPLIMIT:
1245         val = np->rxopt.bits.rxhlim;
1246         break;
1247 
1248     case IPV6_2292HOPLIMIT:
1249         val = np->rxopt.bits.rxohlim;
1250         break;
1251 
1252     case IPV6_RECVRTHDR:
1253         val = np->rxopt.bits.srcrt;
1254         break;
1255 
1256     case IPV6_2292RTHDR:
1257         val = np->rxopt.bits.osrcrt;
1258         break;
1259 
1260     case IPV6_HOPOPTS:
1261     case IPV6_RTHDRDSTOPTS:
1262     case IPV6_RTHDR:
1263     case IPV6_DSTOPTS:
1264     {
1265         struct ipv6_txoptions *opt;
1266 
1267         lock_sock(sk);
1268         opt = rcu_dereference_protected(np->opt,
1269                         lockdep_sock_is_held(sk));
1270         len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
1271         release_sock(sk);
1272         /* check if ipv6_getsockopt_sticky() returns err code */
1273         if (len < 0)
1274             return len;
1275         return put_user(len, optlen);
1276     }
1277 
1278     case IPV6_RECVHOPOPTS:
1279         val = np->rxopt.bits.hopopts;
1280         break;
1281 
1282     case IPV6_2292HOPOPTS:
1283         val = np->rxopt.bits.ohopopts;
1284         break;
1285 
1286     case IPV6_RECVDSTOPTS:
1287         val = np->rxopt.bits.dstopts;
1288         break;
1289 
1290     case IPV6_2292DSTOPTS:
1291         val = np->rxopt.bits.odstopts;
1292         break;
1293 
1294     case IPV6_TCLASS:
1295         val = np->tclass;
1296         break;
1297 
1298     case IPV6_RECVTCLASS:
1299         val = np->rxopt.bits.rxtclass;
1300         break;
1301 
1302     case IPV6_FLOWINFO:
1303         val = np->rxopt.bits.rxflow;
1304         break;
1305 
1306     case IPV6_RECVPATHMTU:
1307         val = np->rxopt.bits.rxpmtu;
1308         break;
1309 
1310     case IPV6_PATHMTU:
1311     {
1312         struct dst_entry *dst;
1313         struct ip6_mtuinfo mtuinfo;
1314 
1315         if (len < sizeof(mtuinfo))
1316             return -EINVAL;
1317 
1318         len = sizeof(mtuinfo);
1319         memset(&mtuinfo, 0, sizeof(mtuinfo));
1320 
1321         rcu_read_lock();
1322         dst = __sk_dst_get(sk);
1323         if (dst)
1324             mtuinfo.ip6m_mtu = dst_mtu(dst);
1325         rcu_read_unlock();
1326         if (!mtuinfo.ip6m_mtu)
1327             return -ENOTCONN;
1328 
1329         if (put_user(len, optlen))
1330             return -EFAULT;
1331         if (copy_to_user(optval, &mtuinfo, len))
1332             return -EFAULT;
1333 
1334         return 0;
1335     }
1336 
1337     case IPV6_TRANSPARENT:
1338         val = inet_sk(sk)->transparent;
1339         break;
1340 
1341     case IPV6_FREEBIND:
1342         val = inet_sk(sk)->freebind;
1343         break;
1344 
1345     case IPV6_RECVORIGDSTADDR:
1346         val = np->rxopt.bits.rxorigdstaddr;
1347         break;
1348 
1349     case IPV6_UNICAST_HOPS:
1350     case IPV6_MULTICAST_HOPS:
1351     {
1352         struct dst_entry *dst;
1353 
1354         if (optname == IPV6_UNICAST_HOPS)
1355             val = np->hop_limit;
1356         else
1357             val = np->mcast_hops;
1358 
1359         if (val < 0) {
1360             rcu_read_lock();
1361             dst = __sk_dst_get(sk);
1362             if (dst)
1363                 val = ip6_dst_hoplimit(dst);
1364             rcu_read_unlock();
1365         }
1366 
1367         if (val < 0)
1368             val = sock_net(sk)->ipv6.devconf_all->hop_limit;
1369         break;
1370     }
1371 
1372     case IPV6_MULTICAST_LOOP:
1373         val = np->mc_loop;
1374         break;
1375 
1376     case IPV6_MULTICAST_IF:
1377         val = np->mcast_oif;
1378         break;
1379 
1380     case IPV6_MULTICAST_ALL:
1381         val = np->mc_all;
1382         break;
1383 
1384     case IPV6_UNICAST_IF:
1385         val = (__force int)htonl((__u32) np->ucast_oif);
1386         break;
1387 
1388     case IPV6_MTU_DISCOVER:
1389         val = np->pmtudisc;
1390         break;
1391 
1392     case IPV6_RECVERR:
1393         val = np->recverr;
1394         break;
1395 
1396     case IPV6_FLOWINFO_SEND:
1397         val = np->sndflow;
1398         break;
1399 
1400     case IPV6_FLOWLABEL_MGR:
1401     {
1402         struct in6_flowlabel_req freq;
1403         int flags;
1404 
1405         if (len < sizeof(freq))
1406             return -EINVAL;
1407 
1408         if (copy_from_user(&freq, optval, sizeof(freq)))
1409             return -EFAULT;
1410 
1411         if (freq.flr_action != IPV6_FL_A_GET)
1412             return -EINVAL;
1413 
1414         len = sizeof(freq);
1415         flags = freq.flr_flags;
1416 
1417         memset(&freq, 0, sizeof(freq));
1418 
1419         val = ipv6_flowlabel_opt_get(sk, &freq, flags);
1420         if (val < 0)
1421             return val;
1422 
1423         if (put_user(len, optlen))
1424             return -EFAULT;
1425         if (copy_to_user(optval, &freq, len))
1426             return -EFAULT;
1427 
1428         return 0;
1429     }
1430 
1431     case IPV6_ADDR_PREFERENCES:
1432         val = 0;
1433 
1434         if (np->srcprefs & IPV6_PREFER_SRC_TMP)
1435             val |= IPV6_PREFER_SRC_TMP;
1436         else if (np->srcprefs & IPV6_PREFER_SRC_PUBLIC)
1437             val |= IPV6_PREFER_SRC_PUBLIC;
1438         else {
1439             /* XXX: should we return system default? */
1440             val |= IPV6_PREFER_SRC_PUBTMP_DEFAULT;
1441         }
1442 
1443         if (np->srcprefs & IPV6_PREFER_SRC_COA)
1444             val |= IPV6_PREFER_SRC_COA;
1445         else
1446             val |= IPV6_PREFER_SRC_HOME;
1447         break;
1448 
1449     case IPV6_MINHOPCOUNT:
1450         val = np->min_hopcount;
1451         break;
1452 
1453     case IPV6_DONTFRAG:
1454         val = np->dontfrag;
1455         break;
1456 
1457     case IPV6_AUTOFLOWLABEL:
1458         val = ip6_autoflowlabel(sock_net(sk), np);
1459         break;
1460 
1461     case IPV6_RECVFRAGSIZE:
1462         val = np->rxopt.bits.recvfragsize;
1463         break;
1464 
1465     case IPV6_ROUTER_ALERT_ISOLATE:
1466         val = np->rtalert_isolate;
1467         break;
1468 
1469     case IPV6_RECVERR_RFC4884:
1470         val = np->recverr_rfc4884;
1471         break;
1472 
1473     default:
1474         return -ENOPROTOOPT;
1475     }
1476     len = min_t(unsigned int, sizeof(int), len);
1477     if (put_user(len, optlen))
1478         return -EFAULT;
1479     if (copy_to_user(optval, &val, len))
1480         return -EFAULT;
1481     return 0;
1482 }
1483 
1484 int ipv6_getsockopt(struct sock *sk, int level, int optname,
1485             char __user *optval, int __user *optlen)
1486 {
1487     int err;
1488 
1489     if (level == SOL_IP && sk->sk_type != SOCK_RAW)
1490         return udp_prot.getsockopt(sk, level, optname, optval, optlen);
1491 
1492     if (level != SOL_IPV6)
1493         return -ENOPROTOOPT;
1494 
1495     err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0);
1496 #ifdef CONFIG_NETFILTER
1497     /* we need to exclude all possible ENOPROTOOPTs except default case */
1498     if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
1499         int len;
1500 
1501         if (get_user(len, optlen))
1502             return -EFAULT;
1503 
1504         err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
1505         if (err >= 0)
1506             err = put_user(len, optlen);
1507     }
1508 #endif
1509     return err;
1510 }
1511 EXPORT_SYMBOL(ipv6_getsockopt);