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