Merge tag 'sound-5.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[platform/kernel/linux-starfive.git] / net / ipv6 / ipv6_sockglue.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *      IPv6 BSD socket options interface
4  *      Linux INET6 implementation
5  *
6  *      Authors:
7  *      Pedro Roque             <roque@di.fc.ul.pt>
8  *
9  *      Based on linux/net/ipv4/ip_sockglue.c
10  *
11  *      FIXME: Make the setsockopt code POSIX compliant: That is
12  *
13  *      o       Truncate getsockopt returns
14  *      o       Return an optlen of the truncated length if need be
15  *
16  *      Changes:
17  *      David L Stevens <dlstevens@us.ibm.com>:
18  *              - added multicast source filtering API for MLDv2
19  */
20
21 #include <linux/module.h>
22 #include <linux/capability.h>
23 #include <linux/errno.h>
24 #include <linux/types.h>
25 #include <linux/socket.h>
26 #include <linux/sockios.h>
27 #include <linux/net.h>
28 #include <linux/in6.h>
29 #include <linux/mroute6.h>
30 #include <linux/netdevice.h>
31 #include <linux/if_arp.h>
32 #include <linux/init.h>
33 #include <linux/sysctl.h>
34 #include <linux/netfilter.h>
35 #include <linux/slab.h>
36
37 #include <net/sock.h>
38 #include <net/snmp.h>
39 #include <net/ipv6.h>
40 #include <net/ndisc.h>
41 #include <net/protocol.h>
42 #include <net/transp_v6.h>
43 #include <net/ip6_route.h>
44 #include <net/addrconf.h>
45 #include <net/inet_common.h>
46 #include <net/tcp.h>
47 #include <net/udp.h>
48 #include <net/udplite.h>
49 #include <net/xfrm.h>
50 #include <net/compat.h>
51 #include <net/seg6.h>
52
53 #include <linux/uaccess.h>
54
55 struct ip6_ra_chain *ip6_ra_chain;
56 DEFINE_RWLOCK(ip6_ra_lock);
57
58 int ip6_ra_control(struct sock *sk, int sel)
59 {
60         struct ip6_ra_chain *ra, *new_ra, **rap;
61
62         /* RA packet may be delivered ONLY to IPPROTO_RAW socket */
63         if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW)
64                 return -ENOPROTOOPT;
65
66         new_ra = (sel >= 0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
67         if (sel >= 0 && !new_ra)
68                 return -ENOMEM;
69
70         write_lock_bh(&ip6_ra_lock);
71         for (rap = &ip6_ra_chain; (ra = *rap) != NULL; rap = &ra->next) {
72                 if (ra->sk == sk) {
73                         if (sel >= 0) {
74                                 write_unlock_bh(&ip6_ra_lock);
75                                 kfree(new_ra);
76                                 return -EADDRINUSE;
77                         }
78
79                         *rap = ra->next;
80                         write_unlock_bh(&ip6_ra_lock);
81
82                         sock_put(sk);
83                         kfree(ra);
84                         return 0;
85                 }
86         }
87         if (!new_ra) {
88                 write_unlock_bh(&ip6_ra_lock);
89                 return -ENOBUFS;
90         }
91         new_ra->sk = sk;
92         new_ra->sel = sel;
93         new_ra->next = ra;
94         *rap = new_ra;
95         sock_hold(sk);
96         write_unlock_bh(&ip6_ra_lock);
97         return 0;
98 }
99
100 struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
101                                            struct ipv6_txoptions *opt)
102 {
103         if (inet_sk(sk)->is_icsk) {
104                 if (opt &&
105                     !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
106                     inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) {
107                         struct inet_connection_sock *icsk = inet_csk(sk);
108                         icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
109                         icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
110                 }
111         }
112         opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
113                    opt);
114         sk_dst_reset(sk);
115
116         return opt;
117 }
118
119 static bool setsockopt_needs_rtnl(int optname)
120 {
121         switch (optname) {
122         case IPV6_ADDRFORM:
123         case IPV6_ADD_MEMBERSHIP:
124         case IPV6_DROP_MEMBERSHIP:
125         case IPV6_JOIN_ANYCAST:
126         case IPV6_LEAVE_ANYCAST:
127         case MCAST_JOIN_GROUP:
128         case MCAST_LEAVE_GROUP:
129         case MCAST_JOIN_SOURCE_GROUP:
130         case MCAST_LEAVE_SOURCE_GROUP:
131         case MCAST_BLOCK_SOURCE:
132         case MCAST_UNBLOCK_SOURCE:
133         case MCAST_MSFILTER:
134                 return true;
135         }
136         return false;
137 }
138
139 static int copy_group_source_from_sockptr(struct group_source_req *greqs,
140                 sockptr_t optval, int optlen)
141 {
142         if (in_compat_syscall()) {
143                 struct compat_group_source_req gr32;
144
145                 if (optlen < sizeof(gr32))
146                         return -EINVAL;
147                 if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
148                         return -EFAULT;
149                 greqs->gsr_interface = gr32.gsr_interface;
150                 greqs->gsr_group = gr32.gsr_group;
151                 greqs->gsr_source = gr32.gsr_source;
152         } else {
153                 if (optlen < sizeof(*greqs))
154                         return -EINVAL;
155                 if (copy_from_sockptr(greqs, optval, sizeof(*greqs)))
156                         return -EFAULT;
157         }
158
159         return 0;
160 }
161
162 static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
163                 sockptr_t optval, int optlen)
164 {
165         struct group_source_req greqs;
166         int omode, add;
167         int ret;
168
169         ret = copy_group_source_from_sockptr(&greqs, optval, optlen);
170         if (ret)
171                 return ret;
172
173         if (greqs.gsr_group.ss_family != AF_INET6 ||
174             greqs.gsr_source.ss_family != AF_INET6)
175                 return -EADDRNOTAVAIL;
176
177         if (optname == MCAST_BLOCK_SOURCE) {
178                 omode = MCAST_EXCLUDE;
179                 add = 1;
180         } else if (optname == MCAST_UNBLOCK_SOURCE) {
181                 omode = MCAST_EXCLUDE;
182                 add = 0;
183         } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
184                 struct sockaddr_in6 *psin6;
185                 int retv;
186
187                 psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
188                 retv = ipv6_sock_mc_join_ssm(sk, greqs.gsr_interface,
189                                              &psin6->sin6_addr,
190                                              MCAST_INCLUDE);
191                 /* prior join w/ different source is ok */
192                 if (retv && retv != -EADDRINUSE)
193                         return retv;
194                 omode = MCAST_INCLUDE;
195                 add = 1;
196         } else /* MCAST_LEAVE_SOURCE_GROUP */ {
197                 omode = MCAST_INCLUDE;
198                 add = 0;
199         }
200         return ip6_mc_source(add, omode, sk, &greqs);
201 }
202
203 static int ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
204                 int optlen)
205 {
206         struct group_filter *gsf;
207         int ret;
208
209         if (optlen < GROUP_FILTER_SIZE(0))
210                 return -EINVAL;
211         if (optlen > sysctl_optmem_max)
212                 return -ENOBUFS;
213
214         gsf = memdup_sockptr(optval, optlen);
215         if (IS_ERR(gsf))
216                 return PTR_ERR(gsf);
217
218         /* numsrc >= (4G-140)/128 overflow in 32 bits */
219         ret = -ENOBUFS;
220         if (gsf->gf_numsrc >= 0x1ffffffU ||
221             gsf->gf_numsrc > sysctl_mld_max_msf)
222                 goto out_free_gsf;
223
224         ret = -EINVAL;
225         if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
226                 goto out_free_gsf;
227
228         ret = ip6_mc_msfilter(sk, gsf, gsf->gf_slist_flex);
229 out_free_gsf:
230         kfree(gsf);
231         return ret;
232 }
233
234 static int compat_ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
235                 int optlen)
236 {
237         const int size0 = offsetof(struct compat_group_filter, gf_slist_flex);
238         struct compat_group_filter *gf32;
239         void *p;
240         int ret;
241         int n;
242
243         if (optlen < size0)
244                 return -EINVAL;
245         if (optlen > sysctl_optmem_max - 4)
246                 return -ENOBUFS;
247
248         p = kmalloc(optlen + 4, GFP_KERNEL);
249         if (!p)
250                 return -ENOMEM;
251
252         gf32 = p + 4; /* we want ->gf_group and ->gf_slist_flex aligned */
253         ret = -EFAULT;
254         if (copy_from_sockptr(gf32, optval, optlen))
255                 goto out_free_p;
256
257         /* numsrc >= (4G-140)/128 overflow in 32 bits */
258         ret = -ENOBUFS;
259         n = gf32->gf_numsrc;
260         if (n >= 0x1ffffffU || n > sysctl_mld_max_msf)
261                 goto out_free_p;
262
263         ret = -EINVAL;
264         if (offsetof(struct compat_group_filter, gf_slist_flex[n]) > optlen)
265                 goto out_free_p;
266
267         ret = ip6_mc_msfilter(sk, &(struct group_filter){
268                         .gf_interface = gf32->gf_interface,
269                         .gf_group = gf32->gf_group,
270                         .gf_fmode = gf32->gf_fmode,
271                         .gf_numsrc = gf32->gf_numsrc}, gf32->gf_slist_flex);
272
273 out_free_p:
274         kfree(p);
275         return ret;
276 }
277
278 static int ipv6_mcast_join_leave(struct sock *sk, int optname,
279                 sockptr_t optval, int optlen)
280 {
281         struct sockaddr_in6 *psin6;
282         struct group_req greq;
283
284         if (optlen < sizeof(greq))
285                 return -EINVAL;
286         if (copy_from_sockptr(&greq, optval, sizeof(greq)))
287                 return -EFAULT;
288
289         if (greq.gr_group.ss_family != AF_INET6)
290                 return -EADDRNOTAVAIL;
291         psin6 = (struct sockaddr_in6 *)&greq.gr_group;
292         if (optname == MCAST_JOIN_GROUP)
293                 return ipv6_sock_mc_join(sk, greq.gr_interface,
294                                          &psin6->sin6_addr);
295         return ipv6_sock_mc_drop(sk, greq.gr_interface, &psin6->sin6_addr);
296 }
297
298 static int compat_ipv6_mcast_join_leave(struct sock *sk, int optname,
299                 sockptr_t optval, int optlen)
300 {
301         struct compat_group_req gr32;
302         struct sockaddr_in6 *psin6;
303
304         if (optlen < sizeof(gr32))
305                 return -EINVAL;
306         if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
307                 return -EFAULT;
308
309         if (gr32.gr_group.ss_family != AF_INET6)
310                 return -EADDRNOTAVAIL;
311         psin6 = (struct sockaddr_in6 *)&gr32.gr_group;
312         if (optname == MCAST_JOIN_GROUP)
313                 return ipv6_sock_mc_join(sk, gr32.gr_interface,
314                                         &psin6->sin6_addr);
315         return ipv6_sock_mc_drop(sk, gr32.gr_interface, &psin6->sin6_addr);
316 }
317
318 static int ipv6_set_opt_hdr(struct sock *sk, int optname, sockptr_t optval,
319                 int optlen)
320 {
321         struct ipv6_pinfo *np = inet6_sk(sk);
322         struct ipv6_opt_hdr *new = NULL;
323         struct net *net = sock_net(sk);
324         struct ipv6_txoptions *opt;
325         int err;
326
327         /* hop-by-hop / destination options are privileged option */
328         if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
329                 return -EPERM;
330
331         /* remove any sticky options header with a zero option
332          * length, per RFC3542.
333          */
334         if (optlen > 0) {
335                 if (sockptr_is_null(optval))
336                         return -EINVAL;
337                 if (optlen < sizeof(struct ipv6_opt_hdr) ||
338                     optlen & 0x7 ||
339                     optlen > 8 * 255)
340                         return -EINVAL;
341
342                 new = memdup_sockptr(optval, optlen);
343                 if (IS_ERR(new))
344                         return PTR_ERR(new);
345                 if (unlikely(ipv6_optlen(new) > optlen)) {
346                         kfree(new);
347                         return -EINVAL;
348                 }
349         }
350
351         opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
352         opt = ipv6_renew_options(sk, opt, optname, new);
353         kfree(new);
354         if (IS_ERR(opt))
355                 return PTR_ERR(opt);
356
357         /* routing header option needs extra check */
358         err = -EINVAL;
359         if (optname == IPV6_RTHDR && opt && opt->srcrt) {
360                 struct ipv6_rt_hdr *rthdr = opt->srcrt;
361                 switch (rthdr->type) {
362 #if IS_ENABLED(CONFIG_IPV6_MIP6)
363                 case IPV6_SRCRT_TYPE_2:
364                         if (rthdr->hdrlen != 2 || rthdr->segments_left != 1)
365                                 goto sticky_done;
366                         break;
367 #endif
368                 case IPV6_SRCRT_TYPE_4:
369                 {
370                         struct ipv6_sr_hdr *srh =
371                                 (struct ipv6_sr_hdr *)opt->srcrt;
372
373                         if (!seg6_validate_srh(srh, optlen, false))
374                                 goto sticky_done;
375                         break;
376                 }
377                 default:
378                         goto sticky_done;
379                 }
380         }
381
382         err = 0;
383         opt = ipv6_update_options(sk, opt);
384 sticky_done:
385         if (opt) {
386                 atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
387                 txopt_put(opt);
388         }
389         return err;
390 }
391
392 static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
393                    sockptr_t optval, unsigned int optlen)
394 {
395         struct ipv6_pinfo *np = inet6_sk(sk);
396         struct net *net = sock_net(sk);
397         int val, valbool;
398         int retv = -ENOPROTOOPT;
399         bool needs_rtnl = setsockopt_needs_rtnl(optname);
400
401         if (sockptr_is_null(optval))
402                 val = 0;
403         else {
404                 if (optlen >= sizeof(int)) {
405                         if (copy_from_sockptr(&val, optval, sizeof(val)))
406                                 return -EFAULT;
407                 } else
408                         val = 0;
409         }
410
411         valbool = (val != 0);
412
413         if (ip6_mroute_opt(optname))
414                 return ip6_mroute_setsockopt(sk, optname, optval, optlen);
415
416         if (needs_rtnl)
417                 rtnl_lock();
418         lock_sock(sk);
419
420         switch (optname) {
421
422         case IPV6_ADDRFORM:
423                 if (optlen < sizeof(int))
424                         goto e_inval;
425                 if (val == PF_INET) {
426                         struct ipv6_txoptions *opt;
427                         struct sk_buff *pktopt;
428
429                         if (sk->sk_type == SOCK_RAW)
430                                 break;
431
432                         if (sk->sk_protocol == IPPROTO_UDP ||
433                             sk->sk_protocol == IPPROTO_UDPLITE) {
434                                 struct udp_sock *up = udp_sk(sk);
435                                 if (up->pending == AF_INET6) {
436                                         retv = -EBUSY;
437                                         break;
438                                 }
439                         } else if (sk->sk_protocol == IPPROTO_TCP) {
440                                 if (sk->sk_prot != &tcpv6_prot) {
441                                         retv = -EBUSY;
442                                         break;
443                                 }
444                         } else {
445                                 break;
446                         }
447
448                         if (sk->sk_state != TCP_ESTABLISHED) {
449                                 retv = -ENOTCONN;
450                                 break;
451                         }
452
453                         if (ipv6_only_sock(sk) ||
454                             !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
455                                 retv = -EADDRNOTAVAIL;
456                                 break;
457                         }
458
459                         fl6_free_socklist(sk);
460                         __ipv6_sock_mc_close(sk);
461                         __ipv6_sock_ac_close(sk);
462
463                         /*
464                          * Sock is moving from IPv6 to IPv4 (sk_prot), so
465                          * remove it from the refcnt debug socks count in the
466                          * original family...
467                          */
468                         sk_refcnt_debug_dec(sk);
469
470                         if (sk->sk_protocol == IPPROTO_TCP) {
471                                 struct inet_connection_sock *icsk = inet_csk(sk);
472                                 local_bh_disable();
473                                 sock_prot_inuse_add(net, sk->sk_prot, -1);
474                                 sock_prot_inuse_add(net, &tcp_prot, 1);
475                                 local_bh_enable();
476                                 sk->sk_prot = &tcp_prot;
477                                 icsk->icsk_af_ops = &ipv4_specific;
478                                 sk->sk_socket->ops = &inet_stream_ops;
479                                 sk->sk_family = PF_INET;
480                                 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
481                         } else {
482                                 struct proto *prot = &udp_prot;
483
484                                 if (sk->sk_protocol == IPPROTO_UDPLITE)
485                                         prot = &udplite_prot;
486                                 local_bh_disable();
487                                 sock_prot_inuse_add(net, sk->sk_prot, -1);
488                                 sock_prot_inuse_add(net, prot, 1);
489                                 local_bh_enable();
490                                 sk->sk_prot = prot;
491                                 sk->sk_socket->ops = &inet_dgram_ops;
492                                 sk->sk_family = PF_INET;
493                         }
494                         opt = xchg((__force struct ipv6_txoptions **)&np->opt,
495                                    NULL);
496                         if (opt) {
497                                 atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
498                                 txopt_put(opt);
499                         }
500                         pktopt = xchg(&np->pktoptions, NULL);
501                         kfree_skb(pktopt);
502
503                         /*
504                          * ... and add it to the refcnt debug socks count
505                          * in the new family. -acme
506                          */
507                         sk_refcnt_debug_inc(sk);
508                         module_put(THIS_MODULE);
509                         retv = 0;
510                         break;
511                 }
512                 goto e_inval;
513
514         case IPV6_V6ONLY:
515                 if (optlen < sizeof(int) ||
516                     inet_sk(sk)->inet_num)
517                         goto e_inval;
518                 sk->sk_ipv6only = valbool;
519                 retv = 0;
520                 break;
521
522         case IPV6_RECVPKTINFO:
523                 if (optlen < sizeof(int))
524                         goto e_inval;
525                 np->rxopt.bits.rxinfo = valbool;
526                 retv = 0;
527                 break;
528
529         case IPV6_2292PKTINFO:
530                 if (optlen < sizeof(int))
531                         goto e_inval;
532                 np->rxopt.bits.rxoinfo = valbool;
533                 retv = 0;
534                 break;
535
536         case IPV6_RECVHOPLIMIT:
537                 if (optlen < sizeof(int))
538                         goto e_inval;
539                 np->rxopt.bits.rxhlim = valbool;
540                 retv = 0;
541                 break;
542
543         case IPV6_2292HOPLIMIT:
544                 if (optlen < sizeof(int))
545                         goto e_inval;
546                 np->rxopt.bits.rxohlim = valbool;
547                 retv = 0;
548                 break;
549
550         case IPV6_RECVRTHDR:
551                 if (optlen < sizeof(int))
552                         goto e_inval;
553                 np->rxopt.bits.srcrt = valbool;
554                 retv = 0;
555                 break;
556
557         case IPV6_2292RTHDR:
558                 if (optlen < sizeof(int))
559                         goto e_inval;
560                 np->rxopt.bits.osrcrt = valbool;
561                 retv = 0;
562                 break;
563
564         case IPV6_RECVHOPOPTS:
565                 if (optlen < sizeof(int))
566                         goto e_inval;
567                 np->rxopt.bits.hopopts = valbool;
568                 retv = 0;
569                 break;
570
571         case IPV6_2292HOPOPTS:
572                 if (optlen < sizeof(int))
573                         goto e_inval;
574                 np->rxopt.bits.ohopopts = valbool;
575                 retv = 0;
576                 break;
577
578         case IPV6_RECVDSTOPTS:
579                 if (optlen < sizeof(int))
580                         goto e_inval;
581                 np->rxopt.bits.dstopts = valbool;
582                 retv = 0;
583                 break;
584
585         case IPV6_2292DSTOPTS:
586                 if (optlen < sizeof(int))
587                         goto e_inval;
588                 np->rxopt.bits.odstopts = valbool;
589                 retv = 0;
590                 break;
591
592         case IPV6_TCLASS:
593                 if (optlen < sizeof(int))
594                         goto e_inval;
595                 if (val < -1 || val > 0xff)
596                         goto e_inval;
597                 /* RFC 3542, 6.5: default traffic class of 0x0 */
598                 if (val == -1)
599                         val = 0;
600                 np->tclass = val;
601                 retv = 0;
602                 break;
603
604         case IPV6_RECVTCLASS:
605                 if (optlen < sizeof(int))
606                         goto e_inval;
607                 np->rxopt.bits.rxtclass = valbool;
608                 retv = 0;
609                 break;
610
611         case IPV6_FLOWINFO:
612                 if (optlen < sizeof(int))
613                         goto e_inval;
614                 np->rxopt.bits.rxflow = valbool;
615                 retv = 0;
616                 break;
617
618         case IPV6_RECVPATHMTU:
619                 if (optlen < sizeof(int))
620                         goto e_inval;
621                 np->rxopt.bits.rxpmtu = valbool;
622                 retv = 0;
623                 break;
624
625         case IPV6_TRANSPARENT:
626                 if (valbool && !ns_capable(net->user_ns, CAP_NET_RAW) &&
627                     !ns_capable(net->user_ns, CAP_NET_ADMIN)) {
628                         retv = -EPERM;
629                         break;
630                 }
631                 if (optlen < sizeof(int))
632                         goto e_inval;
633                 /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
634                 inet_sk(sk)->transparent = valbool;
635                 retv = 0;
636                 break;
637
638         case IPV6_FREEBIND:
639                 if (optlen < sizeof(int))
640                         goto e_inval;
641                 /* we also don't have a separate freebind bit for IPV6 */
642                 inet_sk(sk)->freebind = valbool;
643                 retv = 0;
644                 break;
645
646         case IPV6_RECVORIGDSTADDR:
647                 if (optlen < sizeof(int))
648                         goto e_inval;
649                 np->rxopt.bits.rxorigdstaddr = valbool;
650                 retv = 0;
651                 break;
652
653         case IPV6_HOPOPTS:
654         case IPV6_RTHDRDSTOPTS:
655         case IPV6_RTHDR:
656         case IPV6_DSTOPTS:
657                 retv = ipv6_set_opt_hdr(sk, optname, optval, optlen);
658                 break;
659
660         case IPV6_PKTINFO:
661         {
662                 struct in6_pktinfo pkt;
663
664                 if (optlen == 0)
665                         goto e_inval;
666                 else if (optlen < sizeof(struct in6_pktinfo) ||
667                          sockptr_is_null(optval))
668                         goto e_inval;
669
670                 if (copy_from_sockptr(&pkt, optval, sizeof(pkt))) {
671                         retv = -EFAULT;
672                         break;
673                 }
674                 if (!sk_dev_equal_l3scope(sk, pkt.ipi6_ifindex))
675                         goto e_inval;
676
677                 np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex;
678                 np->sticky_pktinfo.ipi6_addr = pkt.ipi6_addr;
679                 retv = 0;
680                 break;
681         }
682
683         case IPV6_2292PKTOPTIONS:
684         {
685                 struct ipv6_txoptions *opt = NULL;
686                 struct msghdr msg;
687                 struct flowi6 fl6;
688                 struct ipcm6_cookie ipc6;
689
690                 memset(&fl6, 0, sizeof(fl6));
691                 fl6.flowi6_oif = sk->sk_bound_dev_if;
692                 fl6.flowi6_mark = sk->sk_mark;
693
694                 if (optlen == 0)
695                         goto update;
696
697                 /* 1K is probably excessive
698                  * 1K is surely not enough, 2K per standard header is 16K.
699                  */
700                 retv = -EINVAL;
701                 if (optlen > 64*1024)
702                         break;
703
704                 opt = sock_kmalloc(sk, sizeof(*opt) + optlen, GFP_KERNEL);
705                 retv = -ENOBUFS;
706                 if (!opt)
707                         break;
708
709                 memset(opt, 0, sizeof(*opt));
710                 refcount_set(&opt->refcnt, 1);
711                 opt->tot_len = sizeof(*opt) + optlen;
712                 retv = -EFAULT;
713                 if (copy_from_sockptr(opt + 1, optval, optlen))
714                         goto done;
715
716                 msg.msg_controllen = optlen;
717                 msg.msg_control = (void *)(opt+1);
718                 ipc6.opt = opt;
719
720                 retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6);
721                 if (retv)
722                         goto done;
723 update:
724                 retv = 0;
725                 opt = ipv6_update_options(sk, opt);
726 done:
727                 if (opt) {
728                         atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
729                         txopt_put(opt);
730                 }
731                 break;
732         }
733         case IPV6_UNICAST_HOPS:
734                 if (optlen < sizeof(int))
735                         goto e_inval;
736                 if (val > 255 || val < -1)
737                         goto e_inval;
738                 np->hop_limit = val;
739                 retv = 0;
740                 break;
741
742         case IPV6_MULTICAST_HOPS:
743                 if (sk->sk_type == SOCK_STREAM)
744                         break;
745                 if (optlen < sizeof(int))
746                         goto e_inval;
747                 if (val > 255 || val < -1)
748                         goto e_inval;
749                 np->mcast_hops = (val == -1 ? IPV6_DEFAULT_MCASTHOPS : val);
750                 retv = 0;
751                 break;
752
753         case IPV6_MULTICAST_LOOP:
754                 if (optlen < sizeof(int))
755                         goto e_inval;
756                 if (val != valbool)
757                         goto e_inval;
758                 np->mc_loop = valbool;
759                 retv = 0;
760                 break;
761
762         case IPV6_UNICAST_IF:
763         {
764                 struct net_device *dev = NULL;
765                 int ifindex;
766
767                 if (optlen != sizeof(int))
768                         goto e_inval;
769
770                 ifindex = (__force int)ntohl((__force __be32)val);
771                 if (ifindex == 0) {
772                         np->ucast_oif = 0;
773                         retv = 0;
774                         break;
775                 }
776
777                 dev = dev_get_by_index(net, ifindex);
778                 retv = -EADDRNOTAVAIL;
779                 if (!dev)
780                         break;
781                 dev_put(dev);
782
783                 retv = -EINVAL;
784                 if (sk->sk_bound_dev_if)
785                         break;
786
787                 np->ucast_oif = ifindex;
788                 retv = 0;
789                 break;
790         }
791
792         case IPV6_MULTICAST_IF:
793                 if (sk->sk_type == SOCK_STREAM)
794                         break;
795                 if (optlen < sizeof(int))
796                         goto e_inval;
797
798                 if (val) {
799                         struct net_device *dev;
800                         int midx;
801
802                         rcu_read_lock();
803
804                         dev = dev_get_by_index_rcu(net, val);
805                         if (!dev) {
806                                 rcu_read_unlock();
807                                 retv = -ENODEV;
808                                 break;
809                         }
810                         midx = l3mdev_master_ifindex_rcu(dev);
811
812                         rcu_read_unlock();
813
814                         if (sk->sk_bound_dev_if &&
815                             sk->sk_bound_dev_if != val &&
816                             (!midx || midx != sk->sk_bound_dev_if))
817                                 goto e_inval;
818                 }
819                 np->mcast_oif = val;
820                 retv = 0;
821                 break;
822         case IPV6_ADD_MEMBERSHIP:
823         case IPV6_DROP_MEMBERSHIP:
824         {
825                 struct ipv6_mreq mreq;
826
827                 if (optlen < sizeof(struct ipv6_mreq))
828                         goto e_inval;
829
830                 retv = -EPROTO;
831                 if (inet_sk(sk)->is_icsk)
832                         break;
833
834                 retv = -EFAULT;
835                 if (copy_from_sockptr(&mreq, optval, sizeof(struct ipv6_mreq)))
836                         break;
837
838                 if (optname == IPV6_ADD_MEMBERSHIP)
839                         retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
840                 else
841                         retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
842                 break;
843         }
844         case IPV6_JOIN_ANYCAST:
845         case IPV6_LEAVE_ANYCAST:
846         {
847                 struct ipv6_mreq mreq;
848
849                 if (optlen < sizeof(struct ipv6_mreq))
850                         goto e_inval;
851
852                 retv = -EFAULT;
853                 if (copy_from_sockptr(&mreq, optval, sizeof(struct ipv6_mreq)))
854                         break;
855
856                 if (optname == IPV6_JOIN_ANYCAST)
857                         retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
858                 else
859                         retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
860                 break;
861         }
862         case IPV6_MULTICAST_ALL:
863                 if (optlen < sizeof(int))
864                         goto e_inval;
865                 np->mc_all = valbool;
866                 retv = 0;
867                 break;
868
869         case MCAST_JOIN_GROUP:
870         case MCAST_LEAVE_GROUP:
871                 if (in_compat_syscall())
872                         retv = compat_ipv6_mcast_join_leave(sk, optname, optval,
873                                                             optlen);
874                 else
875                         retv = ipv6_mcast_join_leave(sk, optname, optval,
876                                                      optlen);
877                 break;
878         case MCAST_JOIN_SOURCE_GROUP:
879         case MCAST_LEAVE_SOURCE_GROUP:
880         case MCAST_BLOCK_SOURCE:
881         case MCAST_UNBLOCK_SOURCE:
882                 retv = do_ipv6_mcast_group_source(sk, optname, optval, optlen);
883                 break;
884         case MCAST_MSFILTER:
885                 if (in_compat_syscall())
886                         retv = compat_ipv6_set_mcast_msfilter(sk, optval,
887                                                               optlen);
888                 else
889                         retv = ipv6_set_mcast_msfilter(sk, optval, optlen);
890                 break;
891         case IPV6_ROUTER_ALERT:
892                 if (optlen < sizeof(int))
893                         goto e_inval;
894                 retv = ip6_ra_control(sk, val);
895                 break;
896         case IPV6_ROUTER_ALERT_ISOLATE:
897                 if (optlen < sizeof(int))
898                         goto e_inval;
899                 np->rtalert_isolate = valbool;
900                 retv = 0;
901                 break;
902         case IPV6_MTU_DISCOVER:
903                 if (optlen < sizeof(int))
904                         goto e_inval;
905                 if (val < IPV6_PMTUDISC_DONT || val > IPV6_PMTUDISC_OMIT)
906                         goto e_inval;
907                 np->pmtudisc = val;
908                 retv = 0;
909                 break;
910         case IPV6_MTU:
911                 if (optlen < sizeof(int))
912                         goto e_inval;
913                 if (val && val < IPV6_MIN_MTU)
914                         goto e_inval;
915                 np->frag_size = val;
916                 retv = 0;
917                 break;
918         case IPV6_RECVERR:
919                 if (optlen < sizeof(int))
920                         goto e_inval;
921                 np->recverr = valbool;
922                 if (!val)
923                         skb_queue_purge(&sk->sk_error_queue);
924                 retv = 0;
925                 break;
926         case IPV6_FLOWINFO_SEND:
927                 if (optlen < sizeof(int))
928                         goto e_inval;
929                 np->sndflow = valbool;
930                 retv = 0;
931                 break;
932         case IPV6_FLOWLABEL_MGR:
933                 retv = ipv6_flowlabel_opt(sk, optval, optlen);
934                 break;
935         case IPV6_IPSEC_POLICY:
936         case IPV6_XFRM_POLICY:
937                 retv = -EPERM;
938                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
939                         break;
940                 retv = xfrm_user_policy(sk, optname, optval, optlen);
941                 break;
942
943         case IPV6_ADDR_PREFERENCES:
944                 if (optlen < sizeof(int))
945                         goto e_inval;
946                 retv = __ip6_sock_set_addr_preferences(sk, val);
947                 break;
948         case IPV6_MINHOPCOUNT:
949                 if (optlen < sizeof(int))
950                         goto e_inval;
951                 if (val < 0 || val > 255)
952                         goto e_inval;
953                 np->min_hopcount = val;
954                 retv = 0;
955                 break;
956         case IPV6_DONTFRAG:
957                 np->dontfrag = valbool;
958                 retv = 0;
959                 break;
960         case IPV6_AUTOFLOWLABEL:
961                 np->autoflowlabel = valbool;
962                 np->autoflowlabel_set = 1;
963                 retv = 0;
964                 break;
965         case IPV6_RECVFRAGSIZE:
966                 np->rxopt.bits.recvfragsize = valbool;
967                 retv = 0;
968                 break;
969         case IPV6_RECVERR_RFC4884:
970                 if (optlen < sizeof(int))
971                         goto e_inval;
972                 if (val < 0 || val > 1)
973                         goto e_inval;
974                 np->recverr_rfc4884 = valbool;
975                 retv = 0;
976                 break;
977         }
978
979         release_sock(sk);
980         if (needs_rtnl)
981                 rtnl_unlock();
982
983         return retv;
984
985 e_inval:
986         release_sock(sk);
987         if (needs_rtnl)
988                 rtnl_unlock();
989         return -EINVAL;
990 }
991
992 int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
993                     unsigned int optlen)
994 {
995         int err;
996
997         if (level == SOL_IP && sk->sk_type != SOCK_RAW)
998                 return udp_prot.setsockopt(sk, level, optname, optval, optlen);
999
1000         if (level != SOL_IPV6)
1001                 return -ENOPROTOOPT;
1002
1003         err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
1004 #ifdef CONFIG_NETFILTER
1005         /* we need to exclude all possible ENOPROTOOPTs except default case */
1006         if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
1007                         optname != IPV6_XFRM_POLICY)
1008                 err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
1009 #endif
1010         return err;
1011 }
1012 EXPORT_SYMBOL(ipv6_setsockopt);
1013
1014 static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
1015                                   int optname, char __user *optval, int len)
1016 {
1017         struct ipv6_opt_hdr *hdr;
1018
1019         if (!opt)
1020                 return 0;
1021
1022         switch (optname) {
1023         case IPV6_HOPOPTS:
1024                 hdr = opt->hopopt;
1025                 break;
1026         case IPV6_RTHDRDSTOPTS:
1027                 hdr = opt->dst0opt;
1028                 break;
1029         case IPV6_RTHDR:
1030                 hdr = (struct ipv6_opt_hdr *)opt->srcrt;
1031                 break;
1032         case IPV6_DSTOPTS:
1033                 hdr = opt->dst1opt;
1034                 break;
1035         default:
1036                 return -EINVAL; /* should not happen */
1037         }
1038
1039         if (!hdr)
1040                 return 0;
1041
1042         len = min_t(unsigned int, len, ipv6_optlen(hdr));
1043         if (copy_to_user(optval, hdr, len))
1044                 return -EFAULT;
1045         return len;
1046 }
1047
1048 static int ipv6_get_msfilter(struct sock *sk, void __user *optval,
1049                 int __user *optlen, int len)
1050 {
1051         const int size0 = offsetof(struct group_filter, gf_slist_flex);
1052         struct group_filter __user *p = optval;
1053         struct group_filter gsf;
1054         int num;
1055         int err;
1056
1057         if (len < size0)
1058                 return -EINVAL;
1059         if (copy_from_user(&gsf, p, size0))
1060                 return -EFAULT;
1061         if (gsf.gf_group.ss_family != AF_INET6)
1062                 return -EADDRNOTAVAIL;
1063         num = gsf.gf_numsrc;
1064         lock_sock(sk);
1065         err = ip6_mc_msfget(sk, &gsf, p->gf_slist_flex);
1066         if (!err) {
1067                 if (num > gsf.gf_numsrc)
1068                         num = gsf.gf_numsrc;
1069                 if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
1070                     copy_to_user(p, &gsf, size0))
1071                         err = -EFAULT;
1072         }
1073         release_sock(sk);
1074         return err;
1075 }
1076
1077 static int compat_ipv6_get_msfilter(struct sock *sk, void __user *optval,
1078                 int __user *optlen)
1079 {
1080         const int size0 = offsetof(struct compat_group_filter, gf_slist_flex);
1081         struct compat_group_filter __user *p = optval;
1082         struct compat_group_filter gf32;
1083         struct group_filter gf;
1084         int len, err;
1085         int num;
1086
1087         if (get_user(len, optlen))
1088                 return -EFAULT;
1089         if (len < size0)
1090                 return -EINVAL;
1091
1092         if (copy_from_user(&gf32, p, size0))
1093                 return -EFAULT;
1094         gf.gf_interface = gf32.gf_interface;
1095         gf.gf_fmode = gf32.gf_fmode;
1096         num = gf.gf_numsrc = gf32.gf_numsrc;
1097         gf.gf_group = gf32.gf_group;
1098
1099         if (gf.gf_group.ss_family != AF_INET6)
1100                 return -EADDRNOTAVAIL;
1101
1102         lock_sock(sk);
1103         err = ip6_mc_msfget(sk, &gf, p->gf_slist_flex);
1104         release_sock(sk);
1105         if (err)
1106                 return err;
1107         if (num > gf.gf_numsrc)
1108                 num = gf.gf_numsrc;
1109         len = GROUP_FILTER_SIZE(num) - (sizeof(gf)-sizeof(gf32));
1110         if (put_user(len, optlen) ||
1111             put_user(gf.gf_fmode, &p->gf_fmode) ||
1112             put_user(gf.gf_numsrc, &p->gf_numsrc))
1113                 return -EFAULT;
1114         return 0;
1115 }
1116
1117 static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1118                     char __user *optval, int __user *optlen, unsigned int flags)
1119 {
1120         struct ipv6_pinfo *np = inet6_sk(sk);
1121         int len;
1122         int val;
1123
1124         if (ip6_mroute_opt(optname))
1125                 return ip6_mroute_getsockopt(sk, optname, optval, optlen);
1126
1127         if (get_user(len, optlen))
1128                 return -EFAULT;
1129         switch (optname) {
1130         case IPV6_ADDRFORM:
1131                 if (sk->sk_protocol != IPPROTO_UDP &&
1132                     sk->sk_protocol != IPPROTO_UDPLITE &&
1133                     sk->sk_protocol != IPPROTO_TCP)
1134                         return -ENOPROTOOPT;
1135                 if (sk->sk_state != TCP_ESTABLISHED)
1136                         return -ENOTCONN;
1137                 val = sk->sk_family;
1138                 break;
1139         case MCAST_MSFILTER:
1140                 if (in_compat_syscall())
1141                         return compat_ipv6_get_msfilter(sk, optval, optlen);
1142                 return ipv6_get_msfilter(sk, optval, optlen, len);
1143         case IPV6_2292PKTOPTIONS:
1144         {
1145                 struct msghdr msg;
1146                 struct sk_buff *skb;
1147
1148                 if (sk->sk_type != SOCK_STREAM)
1149                         return -ENOPROTOOPT;
1150
1151                 msg.msg_control_user = optval;
1152                 msg.msg_controllen = len;
1153                 msg.msg_flags = flags;
1154                 msg.msg_control_is_user = true;
1155
1156                 lock_sock(sk);
1157                 skb = np->pktoptions;
1158                 if (skb)
1159                         ip6_datagram_recv_ctl(sk, &msg, skb);
1160                 release_sock(sk);
1161                 if (!skb) {
1162                         if (np->rxopt.bits.rxinfo) {
1163                                 struct in6_pktinfo src_info;
1164                                 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
1165                                         np->sticky_pktinfo.ipi6_ifindex;
1166                                 src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr : np->sticky_pktinfo.ipi6_addr;
1167                                 put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
1168                         }
1169                         if (np->rxopt.bits.rxhlim) {
1170                                 int hlim = np->mcast_hops;
1171                                 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
1172                         }
1173                         if (np->rxopt.bits.rxtclass) {
1174                                 int tclass = (int)ip6_tclass(np->rcv_flowinfo);
1175
1176                                 put_cmsg(&msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
1177                         }
1178                         if (np->rxopt.bits.rxoinfo) {
1179                                 struct in6_pktinfo src_info;
1180                                 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
1181                                         np->sticky_pktinfo.ipi6_ifindex;
1182                                 src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr :
1183                                                                      np->sticky_pktinfo.ipi6_addr;
1184                                 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
1185                         }
1186                         if (np->rxopt.bits.rxohlim) {
1187                                 int hlim = np->mcast_hops;
1188                                 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
1189                         }
1190                         if (np->rxopt.bits.rxflow) {
1191                                 __be32 flowinfo = np->rcv_flowinfo;
1192
1193                                 put_cmsg(&msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
1194                         }
1195                 }
1196                 len -= msg.msg_controllen;
1197                 return put_user(len, optlen);
1198         }
1199         case IPV6_MTU:
1200         {
1201                 struct dst_entry *dst;
1202
1203                 val = 0;
1204                 rcu_read_lock();
1205                 dst = __sk_dst_get(sk);
1206                 if (dst)
1207                         val = dst_mtu(dst);
1208                 rcu_read_unlock();
1209                 if (!val)
1210                         return -ENOTCONN;
1211                 break;
1212         }
1213
1214         case IPV6_V6ONLY:
1215                 val = sk->sk_ipv6only;
1216                 break;
1217
1218         case IPV6_RECVPKTINFO:
1219                 val = np->rxopt.bits.rxinfo;
1220                 break;
1221
1222         case IPV6_2292PKTINFO:
1223                 val = np->rxopt.bits.rxoinfo;
1224                 break;
1225
1226         case IPV6_RECVHOPLIMIT:
1227                 val = np->rxopt.bits.rxhlim;
1228                 break;
1229
1230         case IPV6_2292HOPLIMIT:
1231                 val = np->rxopt.bits.rxohlim;
1232                 break;
1233
1234         case IPV6_RECVRTHDR:
1235                 val = np->rxopt.bits.srcrt;
1236                 break;
1237
1238         case IPV6_2292RTHDR:
1239                 val = np->rxopt.bits.osrcrt;
1240                 break;
1241
1242         case IPV6_HOPOPTS:
1243         case IPV6_RTHDRDSTOPTS:
1244         case IPV6_RTHDR:
1245         case IPV6_DSTOPTS:
1246         {
1247                 struct ipv6_txoptions *opt;
1248
1249                 lock_sock(sk);
1250                 opt = rcu_dereference_protected(np->opt,
1251                                                 lockdep_sock_is_held(sk));
1252                 len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
1253                 release_sock(sk);
1254                 /* check if ipv6_getsockopt_sticky() returns err code */
1255                 if (len < 0)
1256                         return len;
1257                 return put_user(len, optlen);
1258         }
1259
1260         case IPV6_RECVHOPOPTS:
1261                 val = np->rxopt.bits.hopopts;
1262                 break;
1263
1264         case IPV6_2292HOPOPTS:
1265                 val = np->rxopt.bits.ohopopts;
1266                 break;
1267
1268         case IPV6_RECVDSTOPTS:
1269                 val = np->rxopt.bits.dstopts;
1270                 break;
1271
1272         case IPV6_2292DSTOPTS:
1273                 val = np->rxopt.bits.odstopts;
1274                 break;
1275
1276         case IPV6_TCLASS:
1277                 val = np->tclass;
1278                 break;
1279
1280         case IPV6_RECVTCLASS:
1281                 val = np->rxopt.bits.rxtclass;
1282                 break;
1283
1284         case IPV6_FLOWINFO:
1285                 val = np->rxopt.bits.rxflow;
1286                 break;
1287
1288         case IPV6_RECVPATHMTU:
1289                 val = np->rxopt.bits.rxpmtu;
1290                 break;
1291
1292         case IPV6_PATHMTU:
1293         {
1294                 struct dst_entry *dst;
1295                 struct ip6_mtuinfo mtuinfo;
1296
1297                 if (len < sizeof(mtuinfo))
1298                         return -EINVAL;
1299
1300                 len = sizeof(mtuinfo);
1301                 memset(&mtuinfo, 0, sizeof(mtuinfo));
1302
1303                 rcu_read_lock();
1304                 dst = __sk_dst_get(sk);
1305                 if (dst)
1306                         mtuinfo.ip6m_mtu = dst_mtu(dst);
1307                 rcu_read_unlock();
1308                 if (!mtuinfo.ip6m_mtu)
1309                         return -ENOTCONN;
1310
1311                 if (put_user(len, optlen))
1312                         return -EFAULT;
1313                 if (copy_to_user(optval, &mtuinfo, len))
1314                         return -EFAULT;
1315
1316                 return 0;
1317         }
1318
1319         case IPV6_TRANSPARENT:
1320                 val = inet_sk(sk)->transparent;
1321                 break;
1322
1323         case IPV6_FREEBIND:
1324                 val = inet_sk(sk)->freebind;
1325                 break;
1326
1327         case IPV6_RECVORIGDSTADDR:
1328                 val = np->rxopt.bits.rxorigdstaddr;
1329                 break;
1330
1331         case IPV6_UNICAST_HOPS:
1332         case IPV6_MULTICAST_HOPS:
1333         {
1334                 struct dst_entry *dst;
1335
1336                 if (optname == IPV6_UNICAST_HOPS)
1337                         val = np->hop_limit;
1338                 else
1339                         val = np->mcast_hops;
1340
1341                 if (val < 0) {
1342                         rcu_read_lock();
1343                         dst = __sk_dst_get(sk);
1344                         if (dst)
1345                                 val = ip6_dst_hoplimit(dst);
1346                         rcu_read_unlock();
1347                 }
1348
1349                 if (val < 0)
1350                         val = sock_net(sk)->ipv6.devconf_all->hop_limit;
1351                 break;
1352         }
1353
1354         case IPV6_MULTICAST_LOOP:
1355                 val = np->mc_loop;
1356                 break;
1357
1358         case IPV6_MULTICAST_IF:
1359                 val = np->mcast_oif;
1360                 break;
1361
1362         case IPV6_MULTICAST_ALL:
1363                 val = np->mc_all;
1364                 break;
1365
1366         case IPV6_UNICAST_IF:
1367                 val = (__force int)htonl((__u32) np->ucast_oif);
1368                 break;
1369
1370         case IPV6_MTU_DISCOVER:
1371                 val = np->pmtudisc;
1372                 break;
1373
1374         case IPV6_RECVERR:
1375                 val = np->recverr;
1376                 break;
1377
1378         case IPV6_FLOWINFO_SEND:
1379                 val = np->sndflow;
1380                 break;
1381
1382         case IPV6_FLOWLABEL_MGR:
1383         {
1384                 struct in6_flowlabel_req freq;
1385                 int flags;
1386
1387                 if (len < sizeof(freq))
1388                         return -EINVAL;
1389
1390                 if (copy_from_user(&freq, optval, sizeof(freq)))
1391                         return -EFAULT;
1392
1393                 if (freq.flr_action != IPV6_FL_A_GET)
1394                         return -EINVAL;
1395
1396                 len = sizeof(freq);
1397                 flags = freq.flr_flags;
1398
1399                 memset(&freq, 0, sizeof(freq));
1400
1401                 val = ipv6_flowlabel_opt_get(sk, &freq, flags);
1402                 if (val < 0)
1403                         return val;
1404
1405                 if (put_user(len, optlen))
1406                         return -EFAULT;
1407                 if (copy_to_user(optval, &freq, len))
1408                         return -EFAULT;
1409
1410                 return 0;
1411         }
1412
1413         case IPV6_ADDR_PREFERENCES:
1414                 val = 0;
1415
1416                 if (np->srcprefs & IPV6_PREFER_SRC_TMP)
1417                         val |= IPV6_PREFER_SRC_TMP;
1418                 else if (np->srcprefs & IPV6_PREFER_SRC_PUBLIC)
1419                         val |= IPV6_PREFER_SRC_PUBLIC;
1420                 else {
1421                         /* XXX: should we return system default? */
1422                         val |= IPV6_PREFER_SRC_PUBTMP_DEFAULT;
1423                 }
1424
1425                 if (np->srcprefs & IPV6_PREFER_SRC_COA)
1426                         val |= IPV6_PREFER_SRC_COA;
1427                 else
1428                         val |= IPV6_PREFER_SRC_HOME;
1429                 break;
1430
1431         case IPV6_MINHOPCOUNT:
1432                 val = np->min_hopcount;
1433                 break;
1434
1435         case IPV6_DONTFRAG:
1436                 val = np->dontfrag;
1437                 break;
1438
1439         case IPV6_AUTOFLOWLABEL:
1440                 val = ip6_autoflowlabel(sock_net(sk), np);
1441                 break;
1442
1443         case IPV6_RECVFRAGSIZE:
1444                 val = np->rxopt.bits.recvfragsize;
1445                 break;
1446
1447         case IPV6_ROUTER_ALERT_ISOLATE:
1448                 val = np->rtalert_isolate;
1449                 break;
1450
1451         case IPV6_RECVERR_RFC4884:
1452                 val = np->recverr_rfc4884;
1453                 break;
1454
1455         default:
1456                 return -ENOPROTOOPT;
1457         }
1458         len = min_t(unsigned int, sizeof(int), len);
1459         if (put_user(len, optlen))
1460                 return -EFAULT;
1461         if (copy_to_user(optval, &val, len))
1462                 return -EFAULT;
1463         return 0;
1464 }
1465
1466 int ipv6_getsockopt(struct sock *sk, int level, int optname,
1467                     char __user *optval, int __user *optlen)
1468 {
1469         int err;
1470
1471         if (level == SOL_IP && sk->sk_type != SOCK_RAW)
1472                 return udp_prot.getsockopt(sk, level, optname, optval, optlen);
1473
1474         if (level != SOL_IPV6)
1475                 return -ENOPROTOOPT;
1476
1477         err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0);
1478 #ifdef CONFIG_NETFILTER
1479         /* we need to exclude all possible ENOPROTOOPTs except default case */
1480         if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
1481                 int len;
1482
1483                 if (get_user(len, optlen))
1484                         return -EFAULT;
1485
1486                 err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
1487                 if (err >= 0)
1488                         err = put_user(len, optlen);
1489         }
1490 #endif
1491         return err;
1492 }
1493 EXPORT_SYMBOL(ipv6_getsockopt);