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