cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ipv6_sockglue.c (33171B)


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