drm/vc4: hdmi: Fix hotplug extcon uevent to works
[platform/kernel/linux-rpi.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 > READ_ONCE(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 > READ_ONCE(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         /* Another thread has converted the socket into IPv4 with
421          * IPV6_ADDRFORM concurrently.
422          */
423         if (unlikely(sk->sk_family != AF_INET6))
424                 goto unlock;
425
426         switch (optname) {
427
428         case IPV6_ADDRFORM:
429                 if (optlen < sizeof(int))
430                         goto e_inval;
431                 if (val == PF_INET) {
432                         struct ipv6_txoptions *opt;
433                         struct sk_buff *pktopt;
434
435                         if (sk->sk_type == SOCK_RAW)
436                                 break;
437
438                         if (sk->sk_protocol == IPPROTO_UDP ||
439                             sk->sk_protocol == IPPROTO_UDPLITE) {
440                                 struct udp_sock *up = udp_sk(sk);
441                                 if (up->pending == AF_INET6) {
442                                         retv = -EBUSY;
443                                         break;
444                                 }
445                         } else if (sk->sk_protocol == IPPROTO_TCP) {
446                                 if (sk->sk_prot != &tcpv6_prot) {
447                                         retv = -EBUSY;
448                                         break;
449                                 }
450                         } else {
451                                 break;
452                         }
453
454                         if (sk->sk_state != TCP_ESTABLISHED) {
455                                 retv = -ENOTCONN;
456                                 break;
457                         }
458
459                         if (ipv6_only_sock(sk) ||
460                             !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
461                                 retv = -EADDRNOTAVAIL;
462                                 break;
463                         }
464
465                         fl6_free_socklist(sk);
466                         __ipv6_sock_mc_close(sk);
467                         __ipv6_sock_ac_close(sk);
468
469                         /*
470                          * Sock is moving from IPv6 to IPv4 (sk_prot), so
471                          * remove it from the refcnt debug socks count in the
472                          * original family...
473                          */
474                         sk_refcnt_debug_dec(sk);
475
476                         if (sk->sk_protocol == IPPROTO_TCP) {
477                                 struct inet_connection_sock *icsk = inet_csk(sk);
478                                 local_bh_disable();
479                                 sock_prot_inuse_add(net, sk->sk_prot, -1);
480                                 sock_prot_inuse_add(net, &tcp_prot, 1);
481                                 local_bh_enable();
482                                 sk->sk_prot = &tcp_prot;
483                                 icsk->icsk_af_ops = &ipv4_specific;
484                                 sk->sk_socket->ops = &inet_stream_ops;
485                                 sk->sk_family = PF_INET;
486                                 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
487                         } else {
488                                 struct proto *prot = &udp_prot;
489
490                                 if (sk->sk_protocol == IPPROTO_UDPLITE)
491                                         prot = &udplite_prot;
492                                 local_bh_disable();
493                                 sock_prot_inuse_add(net, sk->sk_prot, -1);
494                                 sock_prot_inuse_add(net, prot, 1);
495                                 local_bh_enable();
496                                 sk->sk_prot = prot;
497                                 sk->sk_socket->ops = &inet_dgram_ops;
498                                 sk->sk_family = PF_INET;
499                         }
500                         opt = xchg((__force struct ipv6_txoptions **)&np->opt,
501                                    NULL);
502                         if (opt) {
503                                 atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
504                                 txopt_put(opt);
505                         }
506                         pktopt = xchg(&np->pktoptions, NULL);
507                         kfree_skb(pktopt);
508
509                         /*
510                          * ... and add it to the refcnt debug socks count
511                          * in the new family. -acme
512                          */
513                         sk_refcnt_debug_inc(sk);
514                         module_put(THIS_MODULE);
515                         retv = 0;
516                         break;
517                 }
518                 goto e_inval;
519
520         case IPV6_V6ONLY:
521                 if (optlen < sizeof(int) ||
522                     inet_sk(sk)->inet_num)
523                         goto e_inval;
524                 sk->sk_ipv6only = valbool;
525                 retv = 0;
526                 break;
527
528         case IPV6_RECVPKTINFO:
529                 if (optlen < sizeof(int))
530                         goto e_inval;
531                 np->rxopt.bits.rxinfo = valbool;
532                 retv = 0;
533                 break;
534
535         case IPV6_2292PKTINFO:
536                 if (optlen < sizeof(int))
537                         goto e_inval;
538                 np->rxopt.bits.rxoinfo = valbool;
539                 retv = 0;
540                 break;
541
542         case IPV6_RECVHOPLIMIT:
543                 if (optlen < sizeof(int))
544                         goto e_inval;
545                 np->rxopt.bits.rxhlim = valbool;
546                 retv = 0;
547                 break;
548
549         case IPV6_2292HOPLIMIT:
550                 if (optlen < sizeof(int))
551                         goto e_inval;
552                 np->rxopt.bits.rxohlim = valbool;
553                 retv = 0;
554                 break;
555
556         case IPV6_RECVRTHDR:
557                 if (optlen < sizeof(int))
558                         goto e_inval;
559                 np->rxopt.bits.srcrt = valbool;
560                 retv = 0;
561                 break;
562
563         case IPV6_2292RTHDR:
564                 if (optlen < sizeof(int))
565                         goto e_inval;
566                 np->rxopt.bits.osrcrt = valbool;
567                 retv = 0;
568                 break;
569
570         case IPV6_RECVHOPOPTS:
571                 if (optlen < sizeof(int))
572                         goto e_inval;
573                 np->rxopt.bits.hopopts = valbool;
574                 retv = 0;
575                 break;
576
577         case IPV6_2292HOPOPTS:
578                 if (optlen < sizeof(int))
579                         goto e_inval;
580                 np->rxopt.bits.ohopopts = valbool;
581                 retv = 0;
582                 break;
583
584         case IPV6_RECVDSTOPTS:
585                 if (optlen < sizeof(int))
586                         goto e_inval;
587                 np->rxopt.bits.dstopts = valbool;
588                 retv = 0;
589                 break;
590
591         case IPV6_2292DSTOPTS:
592                 if (optlen < sizeof(int))
593                         goto e_inval;
594                 np->rxopt.bits.odstopts = valbool;
595                 retv = 0;
596                 break;
597
598         case IPV6_TCLASS:
599                 if (optlen < sizeof(int))
600                         goto e_inval;
601                 if (val < -1 || val > 0xff)
602                         goto e_inval;
603                 /* RFC 3542, 6.5: default traffic class of 0x0 */
604                 if (val == -1)
605                         val = 0;
606                 np->tclass = val;
607                 retv = 0;
608                 break;
609
610         case IPV6_RECVTCLASS:
611                 if (optlen < sizeof(int))
612                         goto e_inval;
613                 np->rxopt.bits.rxtclass = valbool;
614                 retv = 0;
615                 break;
616
617         case IPV6_FLOWINFO:
618                 if (optlen < sizeof(int))
619                         goto e_inval;
620                 np->rxopt.bits.rxflow = valbool;
621                 retv = 0;
622                 break;
623
624         case IPV6_RECVPATHMTU:
625                 if (optlen < sizeof(int))
626                         goto e_inval;
627                 np->rxopt.bits.rxpmtu = valbool;
628                 retv = 0;
629                 break;
630
631         case IPV6_TRANSPARENT:
632                 if (valbool && !ns_capable(net->user_ns, CAP_NET_RAW) &&
633                     !ns_capable(net->user_ns, CAP_NET_ADMIN)) {
634                         retv = -EPERM;
635                         break;
636                 }
637                 if (optlen < sizeof(int))
638                         goto e_inval;
639                 /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */
640                 inet_sk(sk)->transparent = valbool;
641                 retv = 0;
642                 break;
643
644         case IPV6_FREEBIND:
645                 if (optlen < sizeof(int))
646                         goto e_inval;
647                 /* we also don't have a separate freebind bit for IPV6 */
648                 inet_sk(sk)->freebind = valbool;
649                 retv = 0;
650                 break;
651
652         case IPV6_RECVORIGDSTADDR:
653                 if (optlen < sizeof(int))
654                         goto e_inval;
655                 np->rxopt.bits.rxorigdstaddr = valbool;
656                 retv = 0;
657                 break;
658
659         case IPV6_HOPOPTS:
660         case IPV6_RTHDRDSTOPTS:
661         case IPV6_RTHDR:
662         case IPV6_DSTOPTS:
663                 retv = ipv6_set_opt_hdr(sk, optname, optval, optlen);
664                 break;
665
666         case IPV6_PKTINFO:
667         {
668                 struct in6_pktinfo pkt;
669
670                 if (optlen == 0)
671                         goto e_inval;
672                 else if (optlen < sizeof(struct in6_pktinfo) ||
673                          sockptr_is_null(optval))
674                         goto e_inval;
675
676                 if (copy_from_sockptr(&pkt, optval, sizeof(pkt))) {
677                         retv = -EFAULT;
678                         break;
679                 }
680                 if (!sk_dev_equal_l3scope(sk, pkt.ipi6_ifindex))
681                         goto e_inval;
682
683                 np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex;
684                 np->sticky_pktinfo.ipi6_addr = pkt.ipi6_addr;
685                 retv = 0;
686                 break;
687         }
688
689         case IPV6_2292PKTOPTIONS:
690         {
691                 struct ipv6_txoptions *opt = NULL;
692                 struct msghdr msg;
693                 struct flowi6 fl6;
694                 struct ipcm6_cookie ipc6;
695
696                 memset(&fl6, 0, sizeof(fl6));
697                 fl6.flowi6_oif = sk->sk_bound_dev_if;
698                 fl6.flowi6_mark = sk->sk_mark;
699
700                 if (optlen == 0)
701                         goto update;
702
703                 /* 1K is probably excessive
704                  * 1K is surely not enough, 2K per standard header is 16K.
705                  */
706                 retv = -EINVAL;
707                 if (optlen > 64*1024)
708                         break;
709
710                 opt = sock_kmalloc(sk, sizeof(*opt) + optlen, GFP_KERNEL);
711                 retv = -ENOBUFS;
712                 if (!opt)
713                         break;
714
715                 memset(opt, 0, sizeof(*opt));
716                 refcount_set(&opt->refcnt, 1);
717                 opt->tot_len = sizeof(*opt) + optlen;
718                 retv = -EFAULT;
719                 if (copy_from_sockptr(opt + 1, optval, optlen))
720                         goto done;
721
722                 msg.msg_controllen = optlen;
723                 msg.msg_control = (void *)(opt+1);
724                 ipc6.opt = opt;
725
726                 retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6);
727                 if (retv)
728                         goto done;
729 update:
730                 retv = 0;
731                 opt = ipv6_update_options(sk, opt);
732 done:
733                 if (opt) {
734                         atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
735                         txopt_put(opt);
736                 }
737                 break;
738         }
739         case IPV6_UNICAST_HOPS:
740                 if (optlen < sizeof(int))
741                         goto e_inval;
742                 if (val > 255 || val < -1)
743                         goto e_inval;
744                 np->hop_limit = val;
745                 retv = 0;
746                 break;
747
748         case IPV6_MULTICAST_HOPS:
749                 if (sk->sk_type == SOCK_STREAM)
750                         break;
751                 if (optlen < sizeof(int))
752                         goto e_inval;
753                 if (val > 255 || val < -1)
754                         goto e_inval;
755                 np->mcast_hops = (val == -1 ? IPV6_DEFAULT_MCASTHOPS : val);
756                 retv = 0;
757                 break;
758
759         case IPV6_MULTICAST_LOOP:
760                 if (optlen < sizeof(int))
761                         goto e_inval;
762                 if (val != valbool)
763                         goto e_inval;
764                 np->mc_loop = valbool;
765                 retv = 0;
766                 break;
767
768         case IPV6_UNICAST_IF:
769         {
770                 struct net_device *dev = NULL;
771                 int ifindex;
772
773                 if (optlen != sizeof(int))
774                         goto e_inval;
775
776                 ifindex = (__force int)ntohl((__force __be32)val);
777                 if (ifindex == 0) {
778                         np->ucast_oif = 0;
779                         retv = 0;
780                         break;
781                 }
782
783                 dev = dev_get_by_index(net, ifindex);
784                 retv = -EADDRNOTAVAIL;
785                 if (!dev)
786                         break;
787                 dev_put(dev);
788
789                 retv = -EINVAL;
790                 if (sk->sk_bound_dev_if)
791                         break;
792
793                 np->ucast_oif = ifindex;
794                 retv = 0;
795                 break;
796         }
797
798         case IPV6_MULTICAST_IF:
799                 if (sk->sk_type == SOCK_STREAM)
800                         break;
801                 if (optlen < sizeof(int))
802                         goto e_inval;
803
804                 if (val) {
805                         struct net_device *dev;
806                         int midx;
807
808                         rcu_read_lock();
809
810                         dev = dev_get_by_index_rcu(net, val);
811                         if (!dev) {
812                                 rcu_read_unlock();
813                                 retv = -ENODEV;
814                                 break;
815                         }
816                         midx = l3mdev_master_ifindex_rcu(dev);
817
818                         rcu_read_unlock();
819
820                         if (sk->sk_bound_dev_if &&
821                             sk->sk_bound_dev_if != val &&
822                             (!midx || midx != sk->sk_bound_dev_if))
823                                 goto e_inval;
824                 }
825                 np->mcast_oif = val;
826                 retv = 0;
827                 break;
828         case IPV6_ADD_MEMBERSHIP:
829         case IPV6_DROP_MEMBERSHIP:
830         {
831                 struct ipv6_mreq mreq;
832
833                 if (optlen < sizeof(struct ipv6_mreq))
834                         goto e_inval;
835
836                 retv = -EPROTO;
837                 if (inet_sk(sk)->is_icsk)
838                         break;
839
840                 retv = -EFAULT;
841                 if (copy_from_sockptr(&mreq, optval, sizeof(struct ipv6_mreq)))
842                         break;
843
844                 if (optname == IPV6_ADD_MEMBERSHIP)
845                         retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
846                 else
847                         retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
848                 break;
849         }
850         case IPV6_JOIN_ANYCAST:
851         case IPV6_LEAVE_ANYCAST:
852         {
853                 struct ipv6_mreq mreq;
854
855                 if (optlen < sizeof(struct ipv6_mreq))
856                         goto e_inval;
857
858                 retv = -EFAULT;
859                 if (copy_from_sockptr(&mreq, optval, sizeof(struct ipv6_mreq)))
860                         break;
861
862                 if (optname == IPV6_JOIN_ANYCAST)
863                         retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
864                 else
865                         retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
866                 break;
867         }
868         case IPV6_MULTICAST_ALL:
869                 if (optlen < sizeof(int))
870                         goto e_inval;
871                 np->mc_all = valbool;
872                 retv = 0;
873                 break;
874
875         case MCAST_JOIN_GROUP:
876         case MCAST_LEAVE_GROUP:
877                 if (in_compat_syscall())
878                         retv = compat_ipv6_mcast_join_leave(sk, optname, optval,
879                                                             optlen);
880                 else
881                         retv = ipv6_mcast_join_leave(sk, optname, optval,
882                                                      optlen);
883                 break;
884         case MCAST_JOIN_SOURCE_GROUP:
885         case MCAST_LEAVE_SOURCE_GROUP:
886         case MCAST_BLOCK_SOURCE:
887         case MCAST_UNBLOCK_SOURCE:
888                 retv = do_ipv6_mcast_group_source(sk, optname, optval, optlen);
889                 break;
890         case MCAST_MSFILTER:
891                 if (in_compat_syscall())
892                         retv = compat_ipv6_set_mcast_msfilter(sk, optval,
893                                                               optlen);
894                 else
895                         retv = ipv6_set_mcast_msfilter(sk, optval, optlen);
896                 break;
897         case IPV6_ROUTER_ALERT:
898                 if (optlen < sizeof(int))
899                         goto e_inval;
900                 retv = ip6_ra_control(sk, val);
901                 break;
902         case IPV6_ROUTER_ALERT_ISOLATE:
903                 if (optlen < sizeof(int))
904                         goto e_inval;
905                 np->rtalert_isolate = valbool;
906                 retv = 0;
907                 break;
908         case IPV6_MTU_DISCOVER:
909                 if (optlen < sizeof(int))
910                         goto e_inval;
911                 if (val < IPV6_PMTUDISC_DONT || val > IPV6_PMTUDISC_OMIT)
912                         goto e_inval;
913                 np->pmtudisc = val;
914                 retv = 0;
915                 break;
916         case IPV6_MTU:
917                 if (optlen < sizeof(int))
918                         goto e_inval;
919                 if (val && val < IPV6_MIN_MTU)
920                         goto e_inval;
921                 np->frag_size = val;
922                 retv = 0;
923                 break;
924         case IPV6_RECVERR:
925                 if (optlen < sizeof(int))
926                         goto e_inval;
927                 np->recverr = valbool;
928                 if (!val)
929                         skb_queue_purge(&sk->sk_error_queue);
930                 retv = 0;
931                 break;
932         case IPV6_FLOWINFO_SEND:
933                 if (optlen < sizeof(int))
934                         goto e_inval;
935                 np->sndflow = valbool;
936                 retv = 0;
937                 break;
938         case IPV6_FLOWLABEL_MGR:
939                 retv = ipv6_flowlabel_opt(sk, optval, optlen);
940                 break;
941         case IPV6_IPSEC_POLICY:
942         case IPV6_XFRM_POLICY:
943                 retv = -EPERM;
944                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
945                         break;
946                 retv = xfrm_user_policy(sk, optname, optval, optlen);
947                 break;
948
949         case IPV6_ADDR_PREFERENCES:
950                 if (optlen < sizeof(int))
951                         goto e_inval;
952                 retv = __ip6_sock_set_addr_preferences(sk, val);
953                 break;
954         case IPV6_MINHOPCOUNT:
955                 if (optlen < sizeof(int))
956                         goto e_inval;
957                 if (val < 0 || val > 255)
958                         goto e_inval;
959                 np->min_hopcount = val;
960                 retv = 0;
961                 break;
962         case IPV6_DONTFRAG:
963                 np->dontfrag = valbool;
964                 retv = 0;
965                 break;
966         case IPV6_AUTOFLOWLABEL:
967                 np->autoflowlabel = valbool;
968                 np->autoflowlabel_set = 1;
969                 retv = 0;
970                 break;
971         case IPV6_RECVFRAGSIZE:
972                 np->rxopt.bits.recvfragsize = valbool;
973                 retv = 0;
974                 break;
975         case IPV6_RECVERR_RFC4884:
976                 if (optlen < sizeof(int))
977                         goto e_inval;
978                 if (val < 0 || val > 1)
979                         goto e_inval;
980                 np->recverr_rfc4884 = valbool;
981                 retv = 0;
982                 break;
983         }
984
985 unlock:
986         release_sock(sk);
987         if (needs_rtnl)
988                 rtnl_unlock();
989
990         return retv;
991
992 e_inval:
993         release_sock(sk);
994         if (needs_rtnl)
995                 rtnl_unlock();
996         return -EINVAL;
997 }
998
999 int ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
1000                     unsigned int optlen)
1001 {
1002         int err;
1003
1004         if (level == SOL_IP && sk->sk_type != SOCK_RAW)
1005                 return udp_prot.setsockopt(sk, level, optname, optval, optlen);
1006
1007         if (level != SOL_IPV6)
1008                 return -ENOPROTOOPT;
1009
1010         err = do_ipv6_setsockopt(sk, level, optname, optval, optlen);
1011 #ifdef CONFIG_NETFILTER
1012         /* we need to exclude all possible ENOPROTOOPTs except default case */
1013         if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
1014                         optname != IPV6_XFRM_POLICY)
1015                 err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
1016 #endif
1017         return err;
1018 }
1019 EXPORT_SYMBOL(ipv6_setsockopt);
1020
1021 static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
1022                                   int optname, char __user *optval, int len)
1023 {
1024         struct ipv6_opt_hdr *hdr;
1025
1026         if (!opt)
1027                 return 0;
1028
1029         switch (optname) {
1030         case IPV6_HOPOPTS:
1031                 hdr = opt->hopopt;
1032                 break;
1033         case IPV6_RTHDRDSTOPTS:
1034                 hdr = opt->dst0opt;
1035                 break;
1036         case IPV6_RTHDR:
1037                 hdr = (struct ipv6_opt_hdr *)opt->srcrt;
1038                 break;
1039         case IPV6_DSTOPTS:
1040                 hdr = opt->dst1opt;
1041                 break;
1042         default:
1043                 return -EINVAL; /* should not happen */
1044         }
1045
1046         if (!hdr)
1047                 return 0;
1048
1049         len = min_t(unsigned int, len, ipv6_optlen(hdr));
1050         if (copy_to_user(optval, hdr, len))
1051                 return -EFAULT;
1052         return len;
1053 }
1054
1055 static int ipv6_get_msfilter(struct sock *sk, void __user *optval,
1056                 int __user *optlen, int len)
1057 {
1058         const int size0 = offsetof(struct group_filter, gf_slist_flex);
1059         struct group_filter __user *p = optval;
1060         struct group_filter gsf;
1061         int num;
1062         int err;
1063
1064         if (len < size0)
1065                 return -EINVAL;
1066         if (copy_from_user(&gsf, p, size0))
1067                 return -EFAULT;
1068         if (gsf.gf_group.ss_family != AF_INET6)
1069                 return -EADDRNOTAVAIL;
1070         num = gsf.gf_numsrc;
1071         lock_sock(sk);
1072         err = ip6_mc_msfget(sk, &gsf, p->gf_slist_flex);
1073         if (!err) {
1074                 if (num > gsf.gf_numsrc)
1075                         num = gsf.gf_numsrc;
1076                 if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
1077                     copy_to_user(p, &gsf, size0))
1078                         err = -EFAULT;
1079         }
1080         release_sock(sk);
1081         return err;
1082 }
1083
1084 static int compat_ipv6_get_msfilter(struct sock *sk, void __user *optval,
1085                 int __user *optlen)
1086 {
1087         const int size0 = offsetof(struct compat_group_filter, gf_slist_flex);
1088         struct compat_group_filter __user *p = optval;
1089         struct compat_group_filter gf32;
1090         struct group_filter gf;
1091         int len, err;
1092         int num;
1093
1094         if (get_user(len, optlen))
1095                 return -EFAULT;
1096         if (len < size0)
1097                 return -EINVAL;
1098
1099         if (copy_from_user(&gf32, p, size0))
1100                 return -EFAULT;
1101         gf.gf_interface = gf32.gf_interface;
1102         gf.gf_fmode = gf32.gf_fmode;
1103         num = gf.gf_numsrc = gf32.gf_numsrc;
1104         gf.gf_group = gf32.gf_group;
1105
1106         if (gf.gf_group.ss_family != AF_INET6)
1107                 return -EADDRNOTAVAIL;
1108
1109         lock_sock(sk);
1110         err = ip6_mc_msfget(sk, &gf, p->gf_slist_flex);
1111         release_sock(sk);
1112         if (err)
1113                 return err;
1114         if (num > gf.gf_numsrc)
1115                 num = gf.gf_numsrc;
1116         len = GROUP_FILTER_SIZE(num) - (sizeof(gf)-sizeof(gf32));
1117         if (put_user(len, optlen) ||
1118             put_user(gf.gf_fmode, &p->gf_fmode) ||
1119             put_user(gf.gf_numsrc, &p->gf_numsrc))
1120                 return -EFAULT;
1121         return 0;
1122 }
1123
1124 static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1125                     char __user *optval, int __user *optlen, unsigned int flags)
1126 {
1127         struct ipv6_pinfo *np = inet6_sk(sk);
1128         int len;
1129         int val;
1130
1131         if (ip6_mroute_opt(optname))
1132                 return ip6_mroute_getsockopt(sk, optname, optval, optlen);
1133
1134         if (get_user(len, optlen))
1135                 return -EFAULT;
1136         switch (optname) {
1137         case IPV6_ADDRFORM:
1138                 if (sk->sk_protocol != IPPROTO_UDP &&
1139                     sk->sk_protocol != IPPROTO_UDPLITE &&
1140                     sk->sk_protocol != IPPROTO_TCP)
1141                         return -ENOPROTOOPT;
1142                 if (sk->sk_state != TCP_ESTABLISHED)
1143                         return -ENOTCONN;
1144                 val = sk->sk_family;
1145                 break;
1146         case MCAST_MSFILTER:
1147                 if (in_compat_syscall())
1148                         return compat_ipv6_get_msfilter(sk, optval, optlen);
1149                 return ipv6_get_msfilter(sk, optval, optlen, len);
1150         case IPV6_2292PKTOPTIONS:
1151         {
1152                 struct msghdr msg;
1153                 struct sk_buff *skb;
1154
1155                 if (sk->sk_type != SOCK_STREAM)
1156                         return -ENOPROTOOPT;
1157
1158                 msg.msg_control_user = optval;
1159                 msg.msg_controllen = len;
1160                 msg.msg_flags = flags;
1161                 msg.msg_control_is_user = true;
1162
1163                 lock_sock(sk);
1164                 skb = np->pktoptions;
1165                 if (skb)
1166                         ip6_datagram_recv_ctl(sk, &msg, skb);
1167                 release_sock(sk);
1168                 if (!skb) {
1169                         if (np->rxopt.bits.rxinfo) {
1170                                 struct in6_pktinfo src_info;
1171                                 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
1172                                         np->sticky_pktinfo.ipi6_ifindex;
1173                                 src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr : np->sticky_pktinfo.ipi6_addr;
1174                                 put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
1175                         }
1176                         if (np->rxopt.bits.rxhlim) {
1177                                 int hlim = np->mcast_hops;
1178                                 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
1179                         }
1180                         if (np->rxopt.bits.rxtclass) {
1181                                 int tclass = (int)ip6_tclass(np->rcv_flowinfo);
1182
1183                                 put_cmsg(&msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
1184                         }
1185                         if (np->rxopt.bits.rxoinfo) {
1186                                 struct in6_pktinfo src_info;
1187                                 src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
1188                                         np->sticky_pktinfo.ipi6_ifindex;
1189                                 src_info.ipi6_addr = np->mcast_oif ? sk->sk_v6_daddr :
1190                                                                      np->sticky_pktinfo.ipi6_addr;
1191                                 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
1192                         }
1193                         if (np->rxopt.bits.rxohlim) {
1194                                 int hlim = np->mcast_hops;
1195                                 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
1196                         }
1197                         if (np->rxopt.bits.rxflow) {
1198                                 __be32 flowinfo = np->rcv_flowinfo;
1199
1200                                 put_cmsg(&msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
1201                         }
1202                 }
1203                 len -= msg.msg_controllen;
1204                 return put_user(len, optlen);
1205         }
1206         case IPV6_MTU:
1207         {
1208                 struct dst_entry *dst;
1209
1210                 val = 0;
1211                 rcu_read_lock();
1212                 dst = __sk_dst_get(sk);
1213                 if (dst)
1214                         val = dst_mtu(dst);
1215                 rcu_read_unlock();
1216                 if (!val)
1217                         return -ENOTCONN;
1218                 break;
1219         }
1220
1221         case IPV6_V6ONLY:
1222                 val = sk->sk_ipv6only;
1223                 break;
1224
1225         case IPV6_RECVPKTINFO:
1226                 val = np->rxopt.bits.rxinfo;
1227                 break;
1228
1229         case IPV6_2292PKTINFO:
1230                 val = np->rxopt.bits.rxoinfo;
1231                 break;
1232
1233         case IPV6_RECVHOPLIMIT:
1234                 val = np->rxopt.bits.rxhlim;
1235                 break;
1236
1237         case IPV6_2292HOPLIMIT:
1238                 val = np->rxopt.bits.rxohlim;
1239                 break;
1240
1241         case IPV6_RECVRTHDR:
1242                 val = np->rxopt.bits.srcrt;
1243                 break;
1244
1245         case IPV6_2292RTHDR:
1246                 val = np->rxopt.bits.osrcrt;
1247                 break;
1248
1249         case IPV6_HOPOPTS:
1250         case IPV6_RTHDRDSTOPTS:
1251         case IPV6_RTHDR:
1252         case IPV6_DSTOPTS:
1253         {
1254                 struct ipv6_txoptions *opt;
1255
1256                 lock_sock(sk);
1257                 opt = rcu_dereference_protected(np->opt,
1258                                                 lockdep_sock_is_held(sk));
1259                 len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
1260                 release_sock(sk);
1261                 /* check if ipv6_getsockopt_sticky() returns err code */
1262                 if (len < 0)
1263                         return len;
1264                 return put_user(len, optlen);
1265         }
1266
1267         case IPV6_RECVHOPOPTS:
1268                 val = np->rxopt.bits.hopopts;
1269                 break;
1270
1271         case IPV6_2292HOPOPTS:
1272                 val = np->rxopt.bits.ohopopts;
1273                 break;
1274
1275         case IPV6_RECVDSTOPTS:
1276                 val = np->rxopt.bits.dstopts;
1277                 break;
1278
1279         case IPV6_2292DSTOPTS:
1280                 val = np->rxopt.bits.odstopts;
1281                 break;
1282
1283         case IPV6_TCLASS:
1284                 val = np->tclass;
1285                 break;
1286
1287         case IPV6_RECVTCLASS:
1288                 val = np->rxopt.bits.rxtclass;
1289                 break;
1290
1291         case IPV6_FLOWINFO:
1292                 val = np->rxopt.bits.rxflow;
1293                 break;
1294
1295         case IPV6_RECVPATHMTU:
1296                 val = np->rxopt.bits.rxpmtu;
1297                 break;
1298
1299         case IPV6_PATHMTU:
1300         {
1301                 struct dst_entry *dst;
1302                 struct ip6_mtuinfo mtuinfo;
1303
1304                 if (len < sizeof(mtuinfo))
1305                         return -EINVAL;
1306
1307                 len = sizeof(mtuinfo);
1308                 memset(&mtuinfo, 0, sizeof(mtuinfo));
1309
1310                 rcu_read_lock();
1311                 dst = __sk_dst_get(sk);
1312                 if (dst)
1313                         mtuinfo.ip6m_mtu = dst_mtu(dst);
1314                 rcu_read_unlock();
1315                 if (!mtuinfo.ip6m_mtu)
1316                         return -ENOTCONN;
1317
1318                 if (put_user(len, optlen))
1319                         return -EFAULT;
1320                 if (copy_to_user(optval, &mtuinfo, len))
1321                         return -EFAULT;
1322
1323                 return 0;
1324         }
1325
1326         case IPV6_TRANSPARENT:
1327                 val = inet_sk(sk)->transparent;
1328                 break;
1329
1330         case IPV6_FREEBIND:
1331                 val = inet_sk(sk)->freebind;
1332                 break;
1333
1334         case IPV6_RECVORIGDSTADDR:
1335                 val = np->rxopt.bits.rxorigdstaddr;
1336                 break;
1337
1338         case IPV6_UNICAST_HOPS:
1339         case IPV6_MULTICAST_HOPS:
1340         {
1341                 struct dst_entry *dst;
1342
1343                 if (optname == IPV6_UNICAST_HOPS)
1344                         val = np->hop_limit;
1345                 else
1346                         val = np->mcast_hops;
1347
1348                 if (val < 0) {
1349                         rcu_read_lock();
1350                         dst = __sk_dst_get(sk);
1351                         if (dst)
1352                                 val = ip6_dst_hoplimit(dst);
1353                         rcu_read_unlock();
1354                 }
1355
1356                 if (val < 0)
1357                         val = sock_net(sk)->ipv6.devconf_all->hop_limit;
1358                 break;
1359         }
1360
1361         case IPV6_MULTICAST_LOOP:
1362                 val = np->mc_loop;
1363                 break;
1364
1365         case IPV6_MULTICAST_IF:
1366                 val = np->mcast_oif;
1367                 break;
1368
1369         case IPV6_MULTICAST_ALL:
1370                 val = np->mc_all;
1371                 break;
1372
1373         case IPV6_UNICAST_IF:
1374                 val = (__force int)htonl((__u32) np->ucast_oif);
1375                 break;
1376
1377         case IPV6_MTU_DISCOVER:
1378                 val = np->pmtudisc;
1379                 break;
1380
1381         case IPV6_RECVERR:
1382                 val = np->recverr;
1383                 break;
1384
1385         case IPV6_FLOWINFO_SEND:
1386                 val = np->sndflow;
1387                 break;
1388
1389         case IPV6_FLOWLABEL_MGR:
1390         {
1391                 struct in6_flowlabel_req freq;
1392                 int flags;
1393
1394                 if (len < sizeof(freq))
1395                         return -EINVAL;
1396
1397                 if (copy_from_user(&freq, optval, sizeof(freq)))
1398                         return -EFAULT;
1399
1400                 if (freq.flr_action != IPV6_FL_A_GET)
1401                         return -EINVAL;
1402
1403                 len = sizeof(freq);
1404                 flags = freq.flr_flags;
1405
1406                 memset(&freq, 0, sizeof(freq));
1407
1408                 val = ipv6_flowlabel_opt_get(sk, &freq, flags);
1409                 if (val < 0)
1410                         return val;
1411
1412                 if (put_user(len, optlen))
1413                         return -EFAULT;
1414                 if (copy_to_user(optval, &freq, len))
1415                         return -EFAULT;
1416
1417                 return 0;
1418         }
1419
1420         case IPV6_ADDR_PREFERENCES:
1421                 val = 0;
1422
1423                 if (np->srcprefs & IPV6_PREFER_SRC_TMP)
1424                         val |= IPV6_PREFER_SRC_TMP;
1425                 else if (np->srcprefs & IPV6_PREFER_SRC_PUBLIC)
1426                         val |= IPV6_PREFER_SRC_PUBLIC;
1427                 else {
1428                         /* XXX: should we return system default? */
1429                         val |= IPV6_PREFER_SRC_PUBTMP_DEFAULT;
1430                 }
1431
1432                 if (np->srcprefs & IPV6_PREFER_SRC_COA)
1433                         val |= IPV6_PREFER_SRC_COA;
1434                 else
1435                         val |= IPV6_PREFER_SRC_HOME;
1436                 break;
1437
1438         case IPV6_MINHOPCOUNT:
1439                 val = np->min_hopcount;
1440                 break;
1441
1442         case IPV6_DONTFRAG:
1443                 val = np->dontfrag;
1444                 break;
1445
1446         case IPV6_AUTOFLOWLABEL:
1447                 val = ip6_autoflowlabel(sock_net(sk), np);
1448                 break;
1449
1450         case IPV6_RECVFRAGSIZE:
1451                 val = np->rxopt.bits.recvfragsize;
1452                 break;
1453
1454         case IPV6_ROUTER_ALERT_ISOLATE:
1455                 val = np->rtalert_isolate;
1456                 break;
1457
1458         case IPV6_RECVERR_RFC4884:
1459                 val = np->recverr_rfc4884;
1460                 break;
1461
1462         default:
1463                 return -ENOPROTOOPT;
1464         }
1465         len = min_t(unsigned int, sizeof(int), len);
1466         if (put_user(len, optlen))
1467                 return -EFAULT;
1468         if (copy_to_user(optval, &val, len))
1469                 return -EFAULT;
1470         return 0;
1471 }
1472
1473 int ipv6_getsockopt(struct sock *sk, int level, int optname,
1474                     char __user *optval, int __user *optlen)
1475 {
1476         int err;
1477
1478         if (level == SOL_IP && sk->sk_type != SOCK_RAW)
1479                 return udp_prot.getsockopt(sk, level, optname, optval, optlen);
1480
1481         if (level != SOL_IPV6)
1482                 return -ENOPROTOOPT;
1483
1484         err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0);
1485 #ifdef CONFIG_NETFILTER
1486         /* we need to exclude all possible ENOPROTOOPTs except default case */
1487         if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
1488                 int len;
1489
1490                 if (get_user(len, optlen))
1491                         return -EFAULT;
1492
1493                 err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
1494                 if (err >= 0)
1495                         err = put_user(len, optlen);
1496         }
1497 #endif
1498         return err;
1499 }
1500 EXPORT_SYMBOL(ipv6_getsockopt);