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