File Index
Files and directories
Sign in
FILE

ipv6_sockglue.c

File preview with syntax highlighting.

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