162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * INET		An implementation of the TCP/IP protocol suite for the LINUX
462306a36Sopenharmony_ci *		operating system.  INET is implemented using the  BSD Socket
562306a36Sopenharmony_ci *		interface as the means of communication with the user level.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *		PF_INET protocol family socket handler.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Authors:	Ross Biro
1062306a36Sopenharmony_ci *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
1162306a36Sopenharmony_ci *		Florian La Roche, <flla@stud.uni-sb.de>
1262306a36Sopenharmony_ci *		Alan Cox, <A.Cox@swansea.ac.uk>
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * Changes (see also sock.c)
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *		piggy,
1762306a36Sopenharmony_ci *		Karl Knutson	:	Socket protocol table
1862306a36Sopenharmony_ci *		A.N.Kuznetsov	:	Socket death error in accept().
1962306a36Sopenharmony_ci *		John Richardson :	Fix non blocking error in connect()
2062306a36Sopenharmony_ci *					so sockets that fail to connect
2162306a36Sopenharmony_ci *					don't return -EINPROGRESS.
2262306a36Sopenharmony_ci *		Alan Cox	:	Asynchronous I/O support
2362306a36Sopenharmony_ci *		Alan Cox	:	Keep correct socket pointer on sock
2462306a36Sopenharmony_ci *					structures
2562306a36Sopenharmony_ci *					when accept() ed
2662306a36Sopenharmony_ci *		Alan Cox	:	Semantics of SO_LINGER aren't state
2762306a36Sopenharmony_ci *					moved to close when you look carefully.
2862306a36Sopenharmony_ci *					With this fixed and the accept bug fixed
2962306a36Sopenharmony_ci *					some RPC stuff seems happier.
3062306a36Sopenharmony_ci *		Niibe Yutaka	:	4.4BSD style write async I/O
3162306a36Sopenharmony_ci *		Alan Cox,
3262306a36Sopenharmony_ci *		Tony Gale 	:	Fixed reuse semantics.
3362306a36Sopenharmony_ci *		Alan Cox	:	bind() shouldn't abort existing but dead
3462306a36Sopenharmony_ci *					sockets. Stops FTP netin:.. I hope.
3562306a36Sopenharmony_ci *		Alan Cox	:	bind() works correctly for RAW sockets.
3662306a36Sopenharmony_ci *					Note that FreeBSD at least was broken
3762306a36Sopenharmony_ci *					in this respect so be careful with
3862306a36Sopenharmony_ci *					compatibility tests...
3962306a36Sopenharmony_ci *		Alan Cox	:	routing cache support
4062306a36Sopenharmony_ci *		Alan Cox	:	memzero the socket structure for
4162306a36Sopenharmony_ci *					compactness.
4262306a36Sopenharmony_ci *		Matt Day	:	nonblock connect error handler
4362306a36Sopenharmony_ci *		Alan Cox	:	Allow large numbers of pending sockets
4462306a36Sopenharmony_ci *					(eg for big web sites), but only if
4562306a36Sopenharmony_ci *					specifically application requested.
4662306a36Sopenharmony_ci *		Alan Cox	:	New buffering throughout IP. Used
4762306a36Sopenharmony_ci *					dumbly.
4862306a36Sopenharmony_ci *		Alan Cox	:	New buffering now used smartly.
4962306a36Sopenharmony_ci *		Alan Cox	:	BSD rather than common sense
5062306a36Sopenharmony_ci *					interpretation of listen.
5162306a36Sopenharmony_ci *		Germano Caronni	:	Assorted small races.
5262306a36Sopenharmony_ci *		Alan Cox	:	sendmsg/recvmsg basic support.
5362306a36Sopenharmony_ci *		Alan Cox	:	Only sendmsg/recvmsg now supported.
5462306a36Sopenharmony_ci *		Alan Cox	:	Locked down bind (see security list).
5562306a36Sopenharmony_ci *		Alan Cox	:	Loosened bind a little.
5662306a36Sopenharmony_ci *		Mike McLagan	:	ADD/DEL DLCI Ioctls
5762306a36Sopenharmony_ci *	Willy Konynenberg	:	Transparent proxying support.
5862306a36Sopenharmony_ci *		David S. Miller	:	New socket lookup architecture.
5962306a36Sopenharmony_ci *					Some other random speedups.
6062306a36Sopenharmony_ci *		Cyrus Durgin	:	Cleaned up file for kmod hacks.
6162306a36Sopenharmony_ci *		Andi Kleen	:	Fix inet_stream_connect TCP race.
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#define pr_fmt(fmt) "IPv4: " fmt
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#include <linux/err.h>
6762306a36Sopenharmony_ci#include <linux/errno.h>
6862306a36Sopenharmony_ci#include <linux/types.h>
6962306a36Sopenharmony_ci#include <linux/socket.h>
7062306a36Sopenharmony_ci#include <linux/in.h>
7162306a36Sopenharmony_ci#include <linux/kernel.h>
7262306a36Sopenharmony_ci#include <linux/kmod.h>
7362306a36Sopenharmony_ci#include <linux/sched.h>
7462306a36Sopenharmony_ci#include <linux/timer.h>
7562306a36Sopenharmony_ci#include <linux/string.h>
7662306a36Sopenharmony_ci#include <linux/sockios.h>
7762306a36Sopenharmony_ci#include <linux/net.h>
7862306a36Sopenharmony_ci#include <linux/capability.h>
7962306a36Sopenharmony_ci#include <linux/fcntl.h>
8062306a36Sopenharmony_ci#include <linux/mm.h>
8162306a36Sopenharmony_ci#include <linux/interrupt.h>
8262306a36Sopenharmony_ci#include <linux/stat.h>
8362306a36Sopenharmony_ci#include <linux/init.h>
8462306a36Sopenharmony_ci#include <linux/poll.h>
8562306a36Sopenharmony_ci#include <linux/netfilter_ipv4.h>
8662306a36Sopenharmony_ci#include <linux/random.h>
8762306a36Sopenharmony_ci#include <linux/slab.h>
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#include <linux/uaccess.h>
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#include <linux/inet.h>
9262306a36Sopenharmony_ci#include <linux/igmp.h>
9362306a36Sopenharmony_ci#include <linux/inetdevice.h>
9462306a36Sopenharmony_ci#include <linux/netdevice.h>
9562306a36Sopenharmony_ci#include <net/checksum.h>
9662306a36Sopenharmony_ci#include <net/ip.h>
9762306a36Sopenharmony_ci#include <net/protocol.h>
9862306a36Sopenharmony_ci#include <net/arp.h>
9962306a36Sopenharmony_ci#include <net/route.h>
10062306a36Sopenharmony_ci#include <net/ip_fib.h>
10162306a36Sopenharmony_ci#include <net/inet_connection_sock.h>
10262306a36Sopenharmony_ci#include <net/gro.h>
10362306a36Sopenharmony_ci#include <net/gso.h>
10462306a36Sopenharmony_ci#include <net/tcp.h>
10562306a36Sopenharmony_ci#include <net/udp.h>
10662306a36Sopenharmony_ci#include <net/udplite.h>
10762306a36Sopenharmony_ci#include <net/ping.h>
10862306a36Sopenharmony_ci#include <linux/skbuff.h>
10962306a36Sopenharmony_ci#include <net/sock.h>
11062306a36Sopenharmony_ci#include <net/raw.h>
11162306a36Sopenharmony_ci#include <net/icmp.h>
11262306a36Sopenharmony_ci#include <net/inet_common.h>
11362306a36Sopenharmony_ci#include <net/ip_tunnels.h>
11462306a36Sopenharmony_ci#include <net/xfrm.h>
11562306a36Sopenharmony_ci#include <net/net_namespace.h>
11662306a36Sopenharmony_ci#include <net/secure_seq.h>
11762306a36Sopenharmony_ci#ifdef CONFIG_IP_MROUTE
11862306a36Sopenharmony_ci#include <linux/mroute.h>
11962306a36Sopenharmony_ci#endif
12062306a36Sopenharmony_ci#include <net/l3mdev.h>
12162306a36Sopenharmony_ci#include <net/compat.h>
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#include <trace/events/sock.h>
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/* The inetsw table contains everything that inet_create needs to
12662306a36Sopenharmony_ci * build a new socket.
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_cistatic struct list_head inetsw[SOCK_MAX];
12962306a36Sopenharmony_cistatic DEFINE_SPINLOCK(inetsw_lock);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci/* New destruction routine */
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_civoid inet_sock_destruct(struct sock *sk)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	struct inet_sock *inet = inet_sk(sk);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	__skb_queue_purge(&sk->sk_receive_queue);
13862306a36Sopenharmony_ci	__skb_queue_purge(&sk->sk_error_queue);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	sk_mem_reclaim_final(sk);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	if (sk->sk_type == SOCK_STREAM && sk->sk_state != TCP_CLOSE) {
14362306a36Sopenharmony_ci		pr_err("Attempt to release TCP socket in state %d %p\n",
14462306a36Sopenharmony_ci		       sk->sk_state, sk);
14562306a36Sopenharmony_ci		return;
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci	if (!sock_flag(sk, SOCK_DEAD)) {
14862306a36Sopenharmony_ci		pr_err("Attempt to release alive inet socket %p\n", sk);
14962306a36Sopenharmony_ci		return;
15062306a36Sopenharmony_ci	}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	WARN_ON_ONCE(atomic_read(&sk->sk_rmem_alloc));
15362306a36Sopenharmony_ci	WARN_ON_ONCE(refcount_read(&sk->sk_wmem_alloc));
15462306a36Sopenharmony_ci	WARN_ON_ONCE(sk->sk_wmem_queued);
15562306a36Sopenharmony_ci	WARN_ON_ONCE(sk_forward_alloc_get(sk));
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	kfree(rcu_dereference_protected(inet->inet_opt, 1));
15862306a36Sopenharmony_ci	dst_release(rcu_dereference_protected(sk->sk_dst_cache, 1));
15962306a36Sopenharmony_ci	dst_release(rcu_dereference_protected(sk->sk_rx_dst, 1));
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ciEXPORT_SYMBOL(inet_sock_destruct);
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*
16462306a36Sopenharmony_ci *	The routines beyond this point handle the behaviour of an AF_INET
16562306a36Sopenharmony_ci *	socket object. Mostly it punts to the subprotocols of IP to do
16662306a36Sopenharmony_ci *	the work.
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/*
17062306a36Sopenharmony_ci *	Automatically bind an unbound socket.
17162306a36Sopenharmony_ci */
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic int inet_autobind(struct sock *sk)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	struct inet_sock *inet;
17662306a36Sopenharmony_ci	/* We may need to bind the socket. */
17762306a36Sopenharmony_ci	lock_sock(sk);
17862306a36Sopenharmony_ci	inet = inet_sk(sk);
17962306a36Sopenharmony_ci	if (!inet->inet_num) {
18062306a36Sopenharmony_ci		if (sk->sk_prot->get_port(sk, 0)) {
18162306a36Sopenharmony_ci			release_sock(sk);
18262306a36Sopenharmony_ci			return -EAGAIN;
18362306a36Sopenharmony_ci		}
18462306a36Sopenharmony_ci		inet->inet_sport = htons(inet->inet_num);
18562306a36Sopenharmony_ci	}
18662306a36Sopenharmony_ci	release_sock(sk);
18762306a36Sopenharmony_ci	return 0;
18862306a36Sopenharmony_ci}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciint __inet_listen_sk(struct sock *sk, int backlog)
19162306a36Sopenharmony_ci{
19262306a36Sopenharmony_ci	unsigned char old_state = sk->sk_state;
19362306a36Sopenharmony_ci	int err, tcp_fastopen;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	if (!((1 << old_state) & (TCPF_CLOSE | TCPF_LISTEN)))
19662306a36Sopenharmony_ci		return -EINVAL;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	WRITE_ONCE(sk->sk_max_ack_backlog, backlog);
19962306a36Sopenharmony_ci	/* Really, if the socket is already in listen state
20062306a36Sopenharmony_ci	 * we can only allow the backlog to be adjusted.
20162306a36Sopenharmony_ci	 */
20262306a36Sopenharmony_ci	if (old_state != TCP_LISTEN) {
20362306a36Sopenharmony_ci		/* Enable TFO w/o requiring TCP_FASTOPEN socket option.
20462306a36Sopenharmony_ci		 * Note that only TCP sockets (SOCK_STREAM) will reach here.
20562306a36Sopenharmony_ci		 * Also fastopen backlog may already been set via the option
20662306a36Sopenharmony_ci		 * because the socket was in TCP_LISTEN state previously but
20762306a36Sopenharmony_ci		 * was shutdown() rather than close().
20862306a36Sopenharmony_ci		 */
20962306a36Sopenharmony_ci		tcp_fastopen = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen);
21062306a36Sopenharmony_ci		if ((tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
21162306a36Sopenharmony_ci		    (tcp_fastopen & TFO_SERVER_ENABLE) &&
21262306a36Sopenharmony_ci		    !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) {
21362306a36Sopenharmony_ci			fastopen_queue_tune(sk, backlog);
21462306a36Sopenharmony_ci			tcp_fastopen_init_key_once(sock_net(sk));
21562306a36Sopenharmony_ci		}
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci		err = inet_csk_listen_start(sk);
21862306a36Sopenharmony_ci		if (err)
21962306a36Sopenharmony_ci			return err;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci		tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_LISTEN_CB, 0, NULL);
22262306a36Sopenharmony_ci	}
22362306a36Sopenharmony_ci	return 0;
22462306a36Sopenharmony_ci}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci/*
22762306a36Sopenharmony_ci *	Move a socket into listening state.
22862306a36Sopenharmony_ci */
22962306a36Sopenharmony_ciint inet_listen(struct socket *sock, int backlog)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	struct sock *sk = sock->sk;
23262306a36Sopenharmony_ci	int err = -EINVAL;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	lock_sock(sk);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM)
23762306a36Sopenharmony_ci		goto out;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	err = __inet_listen_sk(sk, backlog);
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ciout:
24262306a36Sopenharmony_ci	release_sock(sk);
24362306a36Sopenharmony_ci	return err;
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ciEXPORT_SYMBOL(inet_listen);
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci/*
24862306a36Sopenharmony_ci *	Create an inet socket.
24962306a36Sopenharmony_ci */
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic int inet_create(struct net *net, struct socket *sock, int protocol,
25262306a36Sopenharmony_ci		       int kern)
25362306a36Sopenharmony_ci{
25462306a36Sopenharmony_ci	struct sock *sk;
25562306a36Sopenharmony_ci	struct inet_protosw *answer;
25662306a36Sopenharmony_ci	struct inet_sock *inet;
25762306a36Sopenharmony_ci	struct proto *answer_prot;
25862306a36Sopenharmony_ci	unsigned char answer_flags;
25962306a36Sopenharmony_ci	int try_loading_module = 0;
26062306a36Sopenharmony_ci	int err;
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	if (protocol < 0 || protocol >= IPPROTO_MAX)
26362306a36Sopenharmony_ci		return -EINVAL;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	sock->state = SS_UNCONNECTED;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	/* Look for the requested type/protocol pair. */
26862306a36Sopenharmony_cilookup_protocol:
26962306a36Sopenharmony_ci	err = -ESOCKTNOSUPPORT;
27062306a36Sopenharmony_ci	rcu_read_lock();
27162306a36Sopenharmony_ci	list_for_each_entry_rcu(answer, &inetsw[sock->type], list) {
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci		err = 0;
27462306a36Sopenharmony_ci		/* Check the non-wild match. */
27562306a36Sopenharmony_ci		if (protocol == answer->protocol) {
27662306a36Sopenharmony_ci			if (protocol != IPPROTO_IP)
27762306a36Sopenharmony_ci				break;
27862306a36Sopenharmony_ci		} else {
27962306a36Sopenharmony_ci			/* Check for the two wild cases. */
28062306a36Sopenharmony_ci			if (IPPROTO_IP == protocol) {
28162306a36Sopenharmony_ci				protocol = answer->protocol;
28262306a36Sopenharmony_ci				break;
28362306a36Sopenharmony_ci			}
28462306a36Sopenharmony_ci			if (IPPROTO_IP == answer->protocol)
28562306a36Sopenharmony_ci				break;
28662306a36Sopenharmony_ci		}
28762306a36Sopenharmony_ci		err = -EPROTONOSUPPORT;
28862306a36Sopenharmony_ci	}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	if (unlikely(err)) {
29162306a36Sopenharmony_ci		if (try_loading_module < 2) {
29262306a36Sopenharmony_ci			rcu_read_unlock();
29362306a36Sopenharmony_ci			/*
29462306a36Sopenharmony_ci			 * Be more specific, e.g. net-pf-2-proto-132-type-1
29562306a36Sopenharmony_ci			 * (net-pf-PF_INET-proto-IPPROTO_SCTP-type-SOCK_STREAM)
29662306a36Sopenharmony_ci			 */
29762306a36Sopenharmony_ci			if (++try_loading_module == 1)
29862306a36Sopenharmony_ci				request_module("net-pf-%d-proto-%d-type-%d",
29962306a36Sopenharmony_ci					       PF_INET, protocol, sock->type);
30062306a36Sopenharmony_ci			/*
30162306a36Sopenharmony_ci			 * Fall back to generic, e.g. net-pf-2-proto-132
30262306a36Sopenharmony_ci			 * (net-pf-PF_INET-proto-IPPROTO_SCTP)
30362306a36Sopenharmony_ci			 */
30462306a36Sopenharmony_ci			else
30562306a36Sopenharmony_ci				request_module("net-pf-%d-proto-%d",
30662306a36Sopenharmony_ci					       PF_INET, protocol);
30762306a36Sopenharmony_ci			goto lookup_protocol;
30862306a36Sopenharmony_ci		} else
30962306a36Sopenharmony_ci			goto out_rcu_unlock;
31062306a36Sopenharmony_ci	}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	err = -EPERM;
31362306a36Sopenharmony_ci	if (sock->type == SOCK_RAW && !kern &&
31462306a36Sopenharmony_ci	    !ns_capable(net->user_ns, CAP_NET_RAW))
31562306a36Sopenharmony_ci		goto out_rcu_unlock;
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	sock->ops = answer->ops;
31862306a36Sopenharmony_ci	answer_prot = answer->prot;
31962306a36Sopenharmony_ci	answer_flags = answer->flags;
32062306a36Sopenharmony_ci	rcu_read_unlock();
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	WARN_ON(!answer_prot->slab);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	err = -ENOMEM;
32562306a36Sopenharmony_ci	sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, kern);
32662306a36Sopenharmony_ci	if (!sk)
32762306a36Sopenharmony_ci		goto out;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	err = 0;
33062306a36Sopenharmony_ci	if (INET_PROTOSW_REUSE & answer_flags)
33162306a36Sopenharmony_ci		sk->sk_reuse = SK_CAN_REUSE;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	if (INET_PROTOSW_ICSK & answer_flags)
33462306a36Sopenharmony_ci		inet_init_csk_locks(sk);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	inet = inet_sk(sk);
33762306a36Sopenharmony_ci	inet_assign_bit(IS_ICSK, sk, INET_PROTOSW_ICSK & answer_flags);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	inet_clear_bit(NODEFRAG, sk);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	if (SOCK_RAW == sock->type) {
34262306a36Sopenharmony_ci		inet->inet_num = protocol;
34362306a36Sopenharmony_ci		if (IPPROTO_RAW == protocol)
34462306a36Sopenharmony_ci			inet_set_bit(HDRINCL, sk);
34562306a36Sopenharmony_ci	}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	if (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc))
34862306a36Sopenharmony_ci		inet->pmtudisc = IP_PMTUDISC_DONT;
34962306a36Sopenharmony_ci	else
35062306a36Sopenharmony_ci		inet->pmtudisc = IP_PMTUDISC_WANT;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	atomic_set(&inet->inet_id, 0);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	sock_init_data(sock, sk);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	sk->sk_destruct	   = inet_sock_destruct;
35762306a36Sopenharmony_ci	sk->sk_protocol	   = protocol;
35862306a36Sopenharmony_ci	sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
35962306a36Sopenharmony_ci	sk->sk_txrehash = READ_ONCE(net->core.sysctl_txrehash);
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	inet->uc_ttl	= -1;
36262306a36Sopenharmony_ci	inet_set_bit(MC_LOOP, sk);
36362306a36Sopenharmony_ci	inet->mc_ttl	= 1;
36462306a36Sopenharmony_ci	inet_set_bit(MC_ALL, sk);
36562306a36Sopenharmony_ci	inet->mc_index	= 0;
36662306a36Sopenharmony_ci	inet->mc_list	= NULL;
36762306a36Sopenharmony_ci	inet->rcv_tos	= 0;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	if (inet->inet_num) {
37062306a36Sopenharmony_ci		/* It assumes that any protocol which allows
37162306a36Sopenharmony_ci		 * the user to assign a number at socket
37262306a36Sopenharmony_ci		 * creation time automatically
37362306a36Sopenharmony_ci		 * shares.
37462306a36Sopenharmony_ci		 */
37562306a36Sopenharmony_ci		inet->inet_sport = htons(inet->inet_num);
37662306a36Sopenharmony_ci		/* Add to protocol hash chains. */
37762306a36Sopenharmony_ci		err = sk->sk_prot->hash(sk);
37862306a36Sopenharmony_ci		if (err) {
37962306a36Sopenharmony_ci			sk_common_release(sk);
38062306a36Sopenharmony_ci			goto out;
38162306a36Sopenharmony_ci		}
38262306a36Sopenharmony_ci	}
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	if (sk->sk_prot->init) {
38562306a36Sopenharmony_ci		err = sk->sk_prot->init(sk);
38662306a36Sopenharmony_ci		if (err) {
38762306a36Sopenharmony_ci			sk_common_release(sk);
38862306a36Sopenharmony_ci			goto out;
38962306a36Sopenharmony_ci		}
39062306a36Sopenharmony_ci	}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	if (!kern) {
39362306a36Sopenharmony_ci		err = BPF_CGROUP_RUN_PROG_INET_SOCK(sk);
39462306a36Sopenharmony_ci		if (err) {
39562306a36Sopenharmony_ci			sk_common_release(sk);
39662306a36Sopenharmony_ci			goto out;
39762306a36Sopenharmony_ci		}
39862306a36Sopenharmony_ci	}
39962306a36Sopenharmony_ciout:
40062306a36Sopenharmony_ci	return err;
40162306a36Sopenharmony_ciout_rcu_unlock:
40262306a36Sopenharmony_ci	rcu_read_unlock();
40362306a36Sopenharmony_ci	goto out;
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci/*
40862306a36Sopenharmony_ci *	The peer socket should always be NULL (or else). When we call this
40962306a36Sopenharmony_ci *	function we are destroying the object and from then on nobody
41062306a36Sopenharmony_ci *	should refer to it.
41162306a36Sopenharmony_ci */
41262306a36Sopenharmony_ciint inet_release(struct socket *sock)
41362306a36Sopenharmony_ci{
41462306a36Sopenharmony_ci	struct sock *sk = sock->sk;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	if (sk) {
41762306a36Sopenharmony_ci		long timeout;
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci		if (!sk->sk_kern_sock)
42062306a36Sopenharmony_ci			BPF_CGROUP_RUN_PROG_INET_SOCK_RELEASE(sk);
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci		/* Applications forget to leave groups before exiting */
42362306a36Sopenharmony_ci		ip_mc_drop_socket(sk);
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci		/* If linger is set, we don't return until the close
42662306a36Sopenharmony_ci		 * is complete.  Otherwise we return immediately. The
42762306a36Sopenharmony_ci		 * actually closing is done the same either way.
42862306a36Sopenharmony_ci		 *
42962306a36Sopenharmony_ci		 * If the close is due to the process exiting, we never
43062306a36Sopenharmony_ci		 * linger..
43162306a36Sopenharmony_ci		 */
43262306a36Sopenharmony_ci		timeout = 0;
43362306a36Sopenharmony_ci		if (sock_flag(sk, SOCK_LINGER) &&
43462306a36Sopenharmony_ci		    !(current->flags & PF_EXITING))
43562306a36Sopenharmony_ci			timeout = sk->sk_lingertime;
43662306a36Sopenharmony_ci		sk->sk_prot->close(sk, timeout);
43762306a36Sopenharmony_ci		sock->sk = NULL;
43862306a36Sopenharmony_ci	}
43962306a36Sopenharmony_ci	return 0;
44062306a36Sopenharmony_ci}
44162306a36Sopenharmony_ciEXPORT_SYMBOL(inet_release);
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ciint inet_bind_sk(struct sock *sk, struct sockaddr *uaddr, int addr_len)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	u32 flags = BIND_WITH_LOCK;
44662306a36Sopenharmony_ci	int err;
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	/* If the socket has its own bind function then use it. (RAW) */
44962306a36Sopenharmony_ci	if (sk->sk_prot->bind) {
45062306a36Sopenharmony_ci		return sk->sk_prot->bind(sk, uaddr, addr_len);
45162306a36Sopenharmony_ci	}
45262306a36Sopenharmony_ci	if (addr_len < sizeof(struct sockaddr_in))
45362306a36Sopenharmony_ci		return -EINVAL;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	/* BPF prog is run before any checks are done so that if the prog
45662306a36Sopenharmony_ci	 * changes context in a wrong way it will be caught.
45762306a36Sopenharmony_ci	 */
45862306a36Sopenharmony_ci	err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, &addr_len,
45962306a36Sopenharmony_ci						 CGROUP_INET4_BIND, &flags);
46062306a36Sopenharmony_ci	if (err)
46162306a36Sopenharmony_ci		return err;
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	return __inet_bind(sk, uaddr, addr_len, flags);
46462306a36Sopenharmony_ci}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ciint inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
46762306a36Sopenharmony_ci{
46862306a36Sopenharmony_ci	return inet_bind_sk(sock->sk, uaddr, addr_len);
46962306a36Sopenharmony_ci}
47062306a36Sopenharmony_ciEXPORT_SYMBOL(inet_bind);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ciint __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
47362306a36Sopenharmony_ci		u32 flags)
47462306a36Sopenharmony_ci{
47562306a36Sopenharmony_ci	struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
47662306a36Sopenharmony_ci	struct inet_sock *inet = inet_sk(sk);
47762306a36Sopenharmony_ci	struct net *net = sock_net(sk);
47862306a36Sopenharmony_ci	unsigned short snum;
47962306a36Sopenharmony_ci	int chk_addr_ret;
48062306a36Sopenharmony_ci	u32 tb_id = RT_TABLE_LOCAL;
48162306a36Sopenharmony_ci	int err;
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	if (addr->sin_family != AF_INET) {
48462306a36Sopenharmony_ci		/* Compatibility games : accept AF_UNSPEC (mapped to AF_INET)
48562306a36Sopenharmony_ci		 * only if s_addr is INADDR_ANY.
48662306a36Sopenharmony_ci		 */
48762306a36Sopenharmony_ci		err = -EAFNOSUPPORT;
48862306a36Sopenharmony_ci		if (addr->sin_family != AF_UNSPEC ||
48962306a36Sopenharmony_ci		    addr->sin_addr.s_addr != htonl(INADDR_ANY))
49062306a36Sopenharmony_ci			goto out;
49162306a36Sopenharmony_ci	}
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id;
49462306a36Sopenharmony_ci	chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id);
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	/* Not specified by any standard per-se, however it breaks too
49762306a36Sopenharmony_ci	 * many applications when removed.  It is unfortunate since
49862306a36Sopenharmony_ci	 * allowing applications to make a non-local bind solves
49962306a36Sopenharmony_ci	 * several problems with systems using dynamic addressing.
50062306a36Sopenharmony_ci	 * (ie. your servers still start up even if your ISDN link
50162306a36Sopenharmony_ci	 *  is temporarily down)
50262306a36Sopenharmony_ci	 */
50362306a36Sopenharmony_ci	err = -EADDRNOTAVAIL;
50462306a36Sopenharmony_ci	if (!inet_addr_valid_or_nonlocal(net, inet, addr->sin_addr.s_addr,
50562306a36Sopenharmony_ci	                                 chk_addr_ret))
50662306a36Sopenharmony_ci		goto out;
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	snum = ntohs(addr->sin_port);
50962306a36Sopenharmony_ci	err = -EACCES;
51062306a36Sopenharmony_ci	if (!(flags & BIND_NO_CAP_NET_BIND_SERVICE) &&
51162306a36Sopenharmony_ci	    snum && inet_port_requires_bind_service(net, snum) &&
51262306a36Sopenharmony_ci	    !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
51362306a36Sopenharmony_ci		goto out;
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	/*      We keep a pair of addresses. rcv_saddr is the one
51662306a36Sopenharmony_ci	 *      used by hash lookups, and saddr is used for transmit.
51762306a36Sopenharmony_ci	 *
51862306a36Sopenharmony_ci	 *      In the BSD API these are the same except where it
51962306a36Sopenharmony_ci	 *      would be illegal to use them (multicast/broadcast) in
52062306a36Sopenharmony_ci	 *      which case the sending device address is used.
52162306a36Sopenharmony_ci	 */
52262306a36Sopenharmony_ci	if (flags & BIND_WITH_LOCK)
52362306a36Sopenharmony_ci		lock_sock(sk);
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	/* Check these errors (active socket, double bind). */
52662306a36Sopenharmony_ci	err = -EINVAL;
52762306a36Sopenharmony_ci	if (sk->sk_state != TCP_CLOSE || inet->inet_num)
52862306a36Sopenharmony_ci		goto out_release_sock;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
53162306a36Sopenharmony_ci	if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
53262306a36Sopenharmony_ci		inet->inet_saddr = 0;  /* Use device */
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	/* Make sure we are allowed to bind here. */
53562306a36Sopenharmony_ci	if (snum || !(inet_test_bit(BIND_ADDRESS_NO_PORT, sk) ||
53662306a36Sopenharmony_ci		      (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
53762306a36Sopenharmony_ci		err = sk->sk_prot->get_port(sk, snum);
53862306a36Sopenharmony_ci		if (err) {
53962306a36Sopenharmony_ci			inet->inet_saddr = inet->inet_rcv_saddr = 0;
54062306a36Sopenharmony_ci			goto out_release_sock;
54162306a36Sopenharmony_ci		}
54262306a36Sopenharmony_ci		if (!(flags & BIND_FROM_BPF)) {
54362306a36Sopenharmony_ci			err = BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk);
54462306a36Sopenharmony_ci			if (err) {
54562306a36Sopenharmony_ci				inet->inet_saddr = inet->inet_rcv_saddr = 0;
54662306a36Sopenharmony_ci				if (sk->sk_prot->put_port)
54762306a36Sopenharmony_ci					sk->sk_prot->put_port(sk);
54862306a36Sopenharmony_ci				goto out_release_sock;
54962306a36Sopenharmony_ci			}
55062306a36Sopenharmony_ci		}
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	if (inet->inet_rcv_saddr)
55462306a36Sopenharmony_ci		sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
55562306a36Sopenharmony_ci	if (snum)
55662306a36Sopenharmony_ci		sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
55762306a36Sopenharmony_ci	inet->inet_sport = htons(inet->inet_num);
55862306a36Sopenharmony_ci	inet->inet_daddr = 0;
55962306a36Sopenharmony_ci	inet->inet_dport = 0;
56062306a36Sopenharmony_ci	sk_dst_reset(sk);
56162306a36Sopenharmony_ci	err = 0;
56262306a36Sopenharmony_ciout_release_sock:
56362306a36Sopenharmony_ci	if (flags & BIND_WITH_LOCK)
56462306a36Sopenharmony_ci		release_sock(sk);
56562306a36Sopenharmony_ciout:
56662306a36Sopenharmony_ci	return err;
56762306a36Sopenharmony_ci}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ciint inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr,
57062306a36Sopenharmony_ci		       int addr_len, int flags)
57162306a36Sopenharmony_ci{
57262306a36Sopenharmony_ci	struct sock *sk = sock->sk;
57362306a36Sopenharmony_ci	const struct proto *prot;
57462306a36Sopenharmony_ci	int err;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	if (addr_len < sizeof(uaddr->sa_family))
57762306a36Sopenharmony_ci		return -EINVAL;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	/* IPV6_ADDRFORM can change sk->sk_prot under us. */
58062306a36Sopenharmony_ci	prot = READ_ONCE(sk->sk_prot);
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	if (uaddr->sa_family == AF_UNSPEC)
58362306a36Sopenharmony_ci		return prot->disconnect(sk, flags);
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	if (BPF_CGROUP_PRE_CONNECT_ENABLED(sk)) {
58662306a36Sopenharmony_ci		err = prot->pre_connect(sk, uaddr, addr_len);
58762306a36Sopenharmony_ci		if (err)
58862306a36Sopenharmony_ci			return err;
58962306a36Sopenharmony_ci	}
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci	if (data_race(!inet_sk(sk)->inet_num) && inet_autobind(sk))
59262306a36Sopenharmony_ci		return -EAGAIN;
59362306a36Sopenharmony_ci	return prot->connect(sk, uaddr, addr_len);
59462306a36Sopenharmony_ci}
59562306a36Sopenharmony_ciEXPORT_SYMBOL(inet_dgram_connect);
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_cistatic long inet_wait_for_connect(struct sock *sk, long timeo, int writebias)
59862306a36Sopenharmony_ci{
59962306a36Sopenharmony_ci	DEFINE_WAIT_FUNC(wait, woken_wake_function);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	add_wait_queue(sk_sleep(sk), &wait);
60262306a36Sopenharmony_ci	sk->sk_write_pending += writebias;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	/* Basic assumption: if someone sets sk->sk_err, he _must_
60562306a36Sopenharmony_ci	 * change state of the socket from TCP_SYN_*.
60662306a36Sopenharmony_ci	 * Connect() does not allow to get error notifications
60762306a36Sopenharmony_ci	 * without closing the socket.
60862306a36Sopenharmony_ci	 */
60962306a36Sopenharmony_ci	while ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
61062306a36Sopenharmony_ci		release_sock(sk);
61162306a36Sopenharmony_ci		timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
61262306a36Sopenharmony_ci		lock_sock(sk);
61362306a36Sopenharmony_ci		if (signal_pending(current) || !timeo)
61462306a36Sopenharmony_ci			break;
61562306a36Sopenharmony_ci	}
61662306a36Sopenharmony_ci	remove_wait_queue(sk_sleep(sk), &wait);
61762306a36Sopenharmony_ci	sk->sk_write_pending -= writebias;
61862306a36Sopenharmony_ci	return timeo;
61962306a36Sopenharmony_ci}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci/*
62262306a36Sopenharmony_ci *	Connect to a remote host. There is regrettably still a little
62362306a36Sopenharmony_ci *	TCP 'magic' in here.
62462306a36Sopenharmony_ci */
62562306a36Sopenharmony_ciint __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
62662306a36Sopenharmony_ci			  int addr_len, int flags, int is_sendmsg)
62762306a36Sopenharmony_ci{
62862306a36Sopenharmony_ci	struct sock *sk = sock->sk;
62962306a36Sopenharmony_ci	int err;
63062306a36Sopenharmony_ci	long timeo;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	/*
63362306a36Sopenharmony_ci	 * uaddr can be NULL and addr_len can be 0 if:
63462306a36Sopenharmony_ci	 * sk is a TCP fastopen active socket and
63562306a36Sopenharmony_ci	 * TCP_FASTOPEN_CONNECT sockopt is set and
63662306a36Sopenharmony_ci	 * we already have a valid cookie for this socket.
63762306a36Sopenharmony_ci	 * In this case, user can call write() after connect().
63862306a36Sopenharmony_ci	 * write() will invoke tcp_sendmsg_fastopen() which calls
63962306a36Sopenharmony_ci	 * __inet_stream_connect().
64062306a36Sopenharmony_ci	 */
64162306a36Sopenharmony_ci	if (uaddr) {
64262306a36Sopenharmony_ci		if (addr_len < sizeof(uaddr->sa_family))
64362306a36Sopenharmony_ci			return -EINVAL;
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci		if (uaddr->sa_family == AF_UNSPEC) {
64662306a36Sopenharmony_ci			sk->sk_disconnects++;
64762306a36Sopenharmony_ci			err = sk->sk_prot->disconnect(sk, flags);
64862306a36Sopenharmony_ci			sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
64962306a36Sopenharmony_ci			goto out;
65062306a36Sopenharmony_ci		}
65162306a36Sopenharmony_ci	}
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	switch (sock->state) {
65462306a36Sopenharmony_ci	default:
65562306a36Sopenharmony_ci		err = -EINVAL;
65662306a36Sopenharmony_ci		goto out;
65762306a36Sopenharmony_ci	case SS_CONNECTED:
65862306a36Sopenharmony_ci		err = -EISCONN;
65962306a36Sopenharmony_ci		goto out;
66062306a36Sopenharmony_ci	case SS_CONNECTING:
66162306a36Sopenharmony_ci		if (inet_test_bit(DEFER_CONNECT, sk))
66262306a36Sopenharmony_ci			err = is_sendmsg ? -EINPROGRESS : -EISCONN;
66362306a36Sopenharmony_ci		else
66462306a36Sopenharmony_ci			err = -EALREADY;
66562306a36Sopenharmony_ci		/* Fall out of switch with err, set for this state */
66662306a36Sopenharmony_ci		break;
66762306a36Sopenharmony_ci	case SS_UNCONNECTED:
66862306a36Sopenharmony_ci		err = -EISCONN;
66962306a36Sopenharmony_ci		if (sk->sk_state != TCP_CLOSE)
67062306a36Sopenharmony_ci			goto out;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci		if (BPF_CGROUP_PRE_CONNECT_ENABLED(sk)) {
67362306a36Sopenharmony_ci			err = sk->sk_prot->pre_connect(sk, uaddr, addr_len);
67462306a36Sopenharmony_ci			if (err)
67562306a36Sopenharmony_ci				goto out;
67662306a36Sopenharmony_ci		}
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci		err = sk->sk_prot->connect(sk, uaddr, addr_len);
67962306a36Sopenharmony_ci		if (err < 0)
68062306a36Sopenharmony_ci			goto out;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci		sock->state = SS_CONNECTING;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci		if (!err && inet_test_bit(DEFER_CONNECT, sk))
68562306a36Sopenharmony_ci			goto out;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci		/* Just entered SS_CONNECTING state; the only
68862306a36Sopenharmony_ci		 * difference is that return value in non-blocking
68962306a36Sopenharmony_ci		 * case is EINPROGRESS, rather than EALREADY.
69062306a36Sopenharmony_ci		 */
69162306a36Sopenharmony_ci		err = -EINPROGRESS;
69262306a36Sopenharmony_ci		break;
69362306a36Sopenharmony_ci	}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci	timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
69862306a36Sopenharmony_ci		int writebias = (sk->sk_protocol == IPPROTO_TCP) &&
69962306a36Sopenharmony_ci				tcp_sk(sk)->fastopen_req &&
70062306a36Sopenharmony_ci				tcp_sk(sk)->fastopen_req->data ? 1 : 0;
70162306a36Sopenharmony_ci		int dis = sk->sk_disconnects;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci		/* Error code is set above */
70462306a36Sopenharmony_ci		if (!timeo || !inet_wait_for_connect(sk, timeo, writebias))
70562306a36Sopenharmony_ci			goto out;
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci		err = sock_intr_errno(timeo);
70862306a36Sopenharmony_ci		if (signal_pending(current))
70962306a36Sopenharmony_ci			goto out;
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci		if (dis != sk->sk_disconnects) {
71262306a36Sopenharmony_ci			err = -EPIPE;
71362306a36Sopenharmony_ci			goto out;
71462306a36Sopenharmony_ci		}
71562306a36Sopenharmony_ci	}
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	/* Connection was closed by RST, timeout, ICMP error
71862306a36Sopenharmony_ci	 * or another process disconnected us.
71962306a36Sopenharmony_ci	 */
72062306a36Sopenharmony_ci	if (sk->sk_state == TCP_CLOSE)
72162306a36Sopenharmony_ci		goto sock_error;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	/* sk->sk_err may be not zero now, if RECVERR was ordered by user
72462306a36Sopenharmony_ci	 * and error was received after socket entered established state.
72562306a36Sopenharmony_ci	 * Hence, it is handled normally after connect() return successfully.
72662306a36Sopenharmony_ci	 */
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	sock->state = SS_CONNECTED;
72962306a36Sopenharmony_ci	err = 0;
73062306a36Sopenharmony_ciout:
73162306a36Sopenharmony_ci	return err;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_cisock_error:
73462306a36Sopenharmony_ci	err = sock_error(sk) ? : -ECONNABORTED;
73562306a36Sopenharmony_ci	sock->state = SS_UNCONNECTED;
73662306a36Sopenharmony_ci	sk->sk_disconnects++;
73762306a36Sopenharmony_ci	if (sk->sk_prot->disconnect(sk, flags))
73862306a36Sopenharmony_ci		sock->state = SS_DISCONNECTING;
73962306a36Sopenharmony_ci	goto out;
74062306a36Sopenharmony_ci}
74162306a36Sopenharmony_ciEXPORT_SYMBOL(__inet_stream_connect);
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ciint inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
74462306a36Sopenharmony_ci			int addr_len, int flags)
74562306a36Sopenharmony_ci{
74662306a36Sopenharmony_ci	int err;
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci	lock_sock(sock->sk);
74962306a36Sopenharmony_ci	err = __inet_stream_connect(sock, uaddr, addr_len, flags, 0);
75062306a36Sopenharmony_ci	release_sock(sock->sk);
75162306a36Sopenharmony_ci	return err;
75262306a36Sopenharmony_ci}
75362306a36Sopenharmony_ciEXPORT_SYMBOL(inet_stream_connect);
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_civoid __inet_accept(struct socket *sock, struct socket *newsock, struct sock *newsk)
75662306a36Sopenharmony_ci{
75762306a36Sopenharmony_ci	sock_rps_record_flow(newsk);
75862306a36Sopenharmony_ci	WARN_ON(!((1 << newsk->sk_state) &
75962306a36Sopenharmony_ci		  (TCPF_ESTABLISHED | TCPF_SYN_RECV |
76062306a36Sopenharmony_ci		  TCPF_CLOSE_WAIT | TCPF_CLOSE)));
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	if (test_bit(SOCK_SUPPORT_ZC, &sock->flags))
76362306a36Sopenharmony_ci		set_bit(SOCK_SUPPORT_ZC, &newsock->flags);
76462306a36Sopenharmony_ci	sock_graft(newsk, newsock);
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_ci	newsock->state = SS_CONNECTED;
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci/*
77062306a36Sopenharmony_ci *	Accept a pending connection. The TCP layer now gives BSD semantics.
77162306a36Sopenharmony_ci */
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ciint inet_accept(struct socket *sock, struct socket *newsock, int flags,
77462306a36Sopenharmony_ci		bool kern)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	struct sock *sk1 = sock->sk, *sk2;
77762306a36Sopenharmony_ci	int err = -EINVAL;
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci	/* IPV6_ADDRFORM can change sk->sk_prot under us. */
78062306a36Sopenharmony_ci	sk2 = READ_ONCE(sk1->sk_prot)->accept(sk1, flags, &err, kern);
78162306a36Sopenharmony_ci	if (!sk2)
78262306a36Sopenharmony_ci		return err;
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci	lock_sock(sk2);
78562306a36Sopenharmony_ci	__inet_accept(sock, newsock, sk2);
78662306a36Sopenharmony_ci	release_sock(sk2);
78762306a36Sopenharmony_ci	return 0;
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ciEXPORT_SYMBOL(inet_accept);
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci/*
79262306a36Sopenharmony_ci *	This does both peername and sockname.
79362306a36Sopenharmony_ci */
79462306a36Sopenharmony_ciint inet_getname(struct socket *sock, struct sockaddr *uaddr,
79562306a36Sopenharmony_ci		 int peer)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	struct sock *sk		= sock->sk;
79862306a36Sopenharmony_ci	struct inet_sock *inet	= inet_sk(sk);
79962306a36Sopenharmony_ci	DECLARE_SOCKADDR(struct sockaddr_in *, sin, uaddr);
80062306a36Sopenharmony_ci	int sin_addr_len = sizeof(*sin);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	sin->sin_family = AF_INET;
80362306a36Sopenharmony_ci	lock_sock(sk);
80462306a36Sopenharmony_ci	if (peer) {
80562306a36Sopenharmony_ci		if (!inet->inet_dport ||
80662306a36Sopenharmony_ci		    (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) &&
80762306a36Sopenharmony_ci		     peer == 1)) {
80862306a36Sopenharmony_ci			release_sock(sk);
80962306a36Sopenharmony_ci			return -ENOTCONN;
81062306a36Sopenharmony_ci		}
81162306a36Sopenharmony_ci		sin->sin_port = inet->inet_dport;
81262306a36Sopenharmony_ci		sin->sin_addr.s_addr = inet->inet_daddr;
81362306a36Sopenharmony_ci		BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len,
81462306a36Sopenharmony_ci				       CGROUP_INET4_GETPEERNAME);
81562306a36Sopenharmony_ci	} else {
81662306a36Sopenharmony_ci		__be32 addr = inet->inet_rcv_saddr;
81762306a36Sopenharmony_ci		if (!addr)
81862306a36Sopenharmony_ci			addr = inet->inet_saddr;
81962306a36Sopenharmony_ci		sin->sin_port = inet->inet_sport;
82062306a36Sopenharmony_ci		sin->sin_addr.s_addr = addr;
82162306a36Sopenharmony_ci		BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len,
82262306a36Sopenharmony_ci				       CGROUP_INET4_GETSOCKNAME);
82362306a36Sopenharmony_ci	}
82462306a36Sopenharmony_ci	release_sock(sk);
82562306a36Sopenharmony_ci	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
82662306a36Sopenharmony_ci	return sin_addr_len;
82762306a36Sopenharmony_ci}
82862306a36Sopenharmony_ciEXPORT_SYMBOL(inet_getname);
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ciint inet_send_prepare(struct sock *sk)
83162306a36Sopenharmony_ci{
83262306a36Sopenharmony_ci	sock_rps_record_flow(sk);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	/* We may need to bind the socket. */
83562306a36Sopenharmony_ci	if (data_race(!inet_sk(sk)->inet_num) && !sk->sk_prot->no_autobind &&
83662306a36Sopenharmony_ci	    inet_autobind(sk))
83762306a36Sopenharmony_ci		return -EAGAIN;
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci	return 0;
84062306a36Sopenharmony_ci}
84162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(inet_send_prepare);
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ciint inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
84462306a36Sopenharmony_ci{
84562306a36Sopenharmony_ci	struct sock *sk = sock->sk;
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	if (unlikely(inet_send_prepare(sk)))
84862306a36Sopenharmony_ci		return -EAGAIN;
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci	return INDIRECT_CALL_2(sk->sk_prot->sendmsg, tcp_sendmsg, udp_sendmsg,
85162306a36Sopenharmony_ci			       sk, msg, size);
85262306a36Sopenharmony_ci}
85362306a36Sopenharmony_ciEXPORT_SYMBOL(inet_sendmsg);
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_civoid inet_splice_eof(struct socket *sock)
85662306a36Sopenharmony_ci{
85762306a36Sopenharmony_ci	const struct proto *prot;
85862306a36Sopenharmony_ci	struct sock *sk = sock->sk;
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	if (unlikely(inet_send_prepare(sk)))
86162306a36Sopenharmony_ci		return;
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	/* IPV6_ADDRFORM can change sk->sk_prot under us. */
86462306a36Sopenharmony_ci	prot = READ_ONCE(sk->sk_prot);
86562306a36Sopenharmony_ci	if (prot->splice_eof)
86662306a36Sopenharmony_ci		prot->splice_eof(sock);
86762306a36Sopenharmony_ci}
86862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(inet_splice_eof);
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ciINDIRECT_CALLABLE_DECLARE(int udp_recvmsg(struct sock *, struct msghdr *,
87162306a36Sopenharmony_ci					  size_t, int, int *));
87262306a36Sopenharmony_ciint inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
87362306a36Sopenharmony_ci		 int flags)
87462306a36Sopenharmony_ci{
87562306a36Sopenharmony_ci	struct sock *sk = sock->sk;
87662306a36Sopenharmony_ci	int addr_len = 0;
87762306a36Sopenharmony_ci	int err;
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	if (likely(!(flags & MSG_ERRQUEUE)))
88062306a36Sopenharmony_ci		sock_rps_record_flow(sk);
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci	err = INDIRECT_CALL_2(sk->sk_prot->recvmsg, tcp_recvmsg, udp_recvmsg,
88362306a36Sopenharmony_ci			      sk, msg, size, flags, &addr_len);
88462306a36Sopenharmony_ci	if (err >= 0)
88562306a36Sopenharmony_ci		msg->msg_namelen = addr_len;
88662306a36Sopenharmony_ci	return err;
88762306a36Sopenharmony_ci}
88862306a36Sopenharmony_ciEXPORT_SYMBOL(inet_recvmsg);
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_ciint inet_shutdown(struct socket *sock, int how)
89162306a36Sopenharmony_ci{
89262306a36Sopenharmony_ci	struct sock *sk = sock->sk;
89362306a36Sopenharmony_ci	int err = 0;
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	/* This should really check to make sure
89662306a36Sopenharmony_ci	 * the socket is a TCP socket. (WHY AC...)
89762306a36Sopenharmony_ci	 */
89862306a36Sopenharmony_ci	how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
89962306a36Sopenharmony_ci		       1->2 bit 2 snds.
90062306a36Sopenharmony_ci		       2->3 */
90162306a36Sopenharmony_ci	if ((how & ~SHUTDOWN_MASK) || !how)	/* MAXINT->0 */
90262306a36Sopenharmony_ci		return -EINVAL;
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	lock_sock(sk);
90562306a36Sopenharmony_ci	if (sock->state == SS_CONNECTING) {
90662306a36Sopenharmony_ci		if ((1 << sk->sk_state) &
90762306a36Sopenharmony_ci		    (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
90862306a36Sopenharmony_ci			sock->state = SS_DISCONNECTING;
90962306a36Sopenharmony_ci		else
91062306a36Sopenharmony_ci			sock->state = SS_CONNECTED;
91162306a36Sopenharmony_ci	}
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	switch (sk->sk_state) {
91462306a36Sopenharmony_ci	case TCP_CLOSE:
91562306a36Sopenharmony_ci		err = -ENOTCONN;
91662306a36Sopenharmony_ci		/* Hack to wake up other listeners, who can poll for
91762306a36Sopenharmony_ci		   EPOLLHUP, even on eg. unconnected UDP sockets -- RR */
91862306a36Sopenharmony_ci		fallthrough;
91962306a36Sopenharmony_ci	default:
92062306a36Sopenharmony_ci		WRITE_ONCE(sk->sk_shutdown, sk->sk_shutdown | how);
92162306a36Sopenharmony_ci		if (sk->sk_prot->shutdown)
92262306a36Sopenharmony_ci			sk->sk_prot->shutdown(sk, how);
92362306a36Sopenharmony_ci		break;
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	/* Remaining two branches are temporary solution for missing
92662306a36Sopenharmony_ci	 * close() in multithreaded environment. It is _not_ a good idea,
92762306a36Sopenharmony_ci	 * but we have no choice until close() is repaired at VFS level.
92862306a36Sopenharmony_ci	 */
92962306a36Sopenharmony_ci	case TCP_LISTEN:
93062306a36Sopenharmony_ci		if (!(how & RCV_SHUTDOWN))
93162306a36Sopenharmony_ci			break;
93262306a36Sopenharmony_ci		fallthrough;
93362306a36Sopenharmony_ci	case TCP_SYN_SENT:
93462306a36Sopenharmony_ci		err = sk->sk_prot->disconnect(sk, O_NONBLOCK);
93562306a36Sopenharmony_ci		sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
93662306a36Sopenharmony_ci		break;
93762306a36Sopenharmony_ci	}
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	/* Wake up anyone sleeping in poll. */
94062306a36Sopenharmony_ci	sk->sk_state_change(sk);
94162306a36Sopenharmony_ci	release_sock(sk);
94262306a36Sopenharmony_ci	return err;
94362306a36Sopenharmony_ci}
94462306a36Sopenharmony_ciEXPORT_SYMBOL(inet_shutdown);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci/*
94762306a36Sopenharmony_ci *	ioctl() calls you can issue on an INET socket. Most of these are
94862306a36Sopenharmony_ci *	device configuration and stuff and very rarely used. Some ioctls
94962306a36Sopenharmony_ci *	pass on to the socket itself.
95062306a36Sopenharmony_ci *
95162306a36Sopenharmony_ci *	NOTE: I like the idea of a module for the config stuff. ie ifconfig
95262306a36Sopenharmony_ci *	loads the devconfigure module does its configuring and unloads it.
95362306a36Sopenharmony_ci *	There's a good 20K of config code hanging around the kernel.
95462306a36Sopenharmony_ci */
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ciint inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
95762306a36Sopenharmony_ci{
95862306a36Sopenharmony_ci	struct sock *sk = sock->sk;
95962306a36Sopenharmony_ci	int err = 0;
96062306a36Sopenharmony_ci	struct net *net = sock_net(sk);
96162306a36Sopenharmony_ci	void __user *p = (void __user *)arg;
96262306a36Sopenharmony_ci	struct ifreq ifr;
96362306a36Sopenharmony_ci	struct rtentry rt;
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci	switch (cmd) {
96662306a36Sopenharmony_ci	case SIOCADDRT:
96762306a36Sopenharmony_ci	case SIOCDELRT:
96862306a36Sopenharmony_ci		if (copy_from_user(&rt, p, sizeof(struct rtentry)))
96962306a36Sopenharmony_ci			return -EFAULT;
97062306a36Sopenharmony_ci		err = ip_rt_ioctl(net, cmd, &rt);
97162306a36Sopenharmony_ci		break;
97262306a36Sopenharmony_ci	case SIOCRTMSG:
97362306a36Sopenharmony_ci		err = -EINVAL;
97462306a36Sopenharmony_ci		break;
97562306a36Sopenharmony_ci	case SIOCDARP:
97662306a36Sopenharmony_ci	case SIOCGARP:
97762306a36Sopenharmony_ci	case SIOCSARP:
97862306a36Sopenharmony_ci		err = arp_ioctl(net, cmd, (void __user *)arg);
97962306a36Sopenharmony_ci		break;
98062306a36Sopenharmony_ci	case SIOCGIFADDR:
98162306a36Sopenharmony_ci	case SIOCGIFBRDADDR:
98262306a36Sopenharmony_ci	case SIOCGIFNETMASK:
98362306a36Sopenharmony_ci	case SIOCGIFDSTADDR:
98462306a36Sopenharmony_ci	case SIOCGIFPFLAGS:
98562306a36Sopenharmony_ci		if (get_user_ifreq(&ifr, NULL, p))
98662306a36Sopenharmony_ci			return -EFAULT;
98762306a36Sopenharmony_ci		err = devinet_ioctl(net, cmd, &ifr);
98862306a36Sopenharmony_ci		if (!err && put_user_ifreq(&ifr, p))
98962306a36Sopenharmony_ci			err = -EFAULT;
99062306a36Sopenharmony_ci		break;
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	case SIOCSIFADDR:
99362306a36Sopenharmony_ci	case SIOCSIFBRDADDR:
99462306a36Sopenharmony_ci	case SIOCSIFNETMASK:
99562306a36Sopenharmony_ci	case SIOCSIFDSTADDR:
99662306a36Sopenharmony_ci	case SIOCSIFPFLAGS:
99762306a36Sopenharmony_ci	case SIOCSIFFLAGS:
99862306a36Sopenharmony_ci		if (get_user_ifreq(&ifr, NULL, p))
99962306a36Sopenharmony_ci			return -EFAULT;
100062306a36Sopenharmony_ci		err = devinet_ioctl(net, cmd, &ifr);
100162306a36Sopenharmony_ci		break;
100262306a36Sopenharmony_ci	default:
100362306a36Sopenharmony_ci		if (sk->sk_prot->ioctl)
100462306a36Sopenharmony_ci			err = sk_ioctl(sk, cmd, (void __user *)arg);
100562306a36Sopenharmony_ci		else
100662306a36Sopenharmony_ci			err = -ENOIOCTLCMD;
100762306a36Sopenharmony_ci		break;
100862306a36Sopenharmony_ci	}
100962306a36Sopenharmony_ci	return err;
101062306a36Sopenharmony_ci}
101162306a36Sopenharmony_ciEXPORT_SYMBOL(inet_ioctl);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
101462306a36Sopenharmony_cistatic int inet_compat_routing_ioctl(struct sock *sk, unsigned int cmd,
101562306a36Sopenharmony_ci		struct compat_rtentry __user *ur)
101662306a36Sopenharmony_ci{
101762306a36Sopenharmony_ci	compat_uptr_t rtdev;
101862306a36Sopenharmony_ci	struct rtentry rt;
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci	if (copy_from_user(&rt.rt_dst, &ur->rt_dst,
102162306a36Sopenharmony_ci			3 * sizeof(struct sockaddr)) ||
102262306a36Sopenharmony_ci	    get_user(rt.rt_flags, &ur->rt_flags) ||
102362306a36Sopenharmony_ci	    get_user(rt.rt_metric, &ur->rt_metric) ||
102462306a36Sopenharmony_ci	    get_user(rt.rt_mtu, &ur->rt_mtu) ||
102562306a36Sopenharmony_ci	    get_user(rt.rt_window, &ur->rt_window) ||
102662306a36Sopenharmony_ci	    get_user(rt.rt_irtt, &ur->rt_irtt) ||
102762306a36Sopenharmony_ci	    get_user(rtdev, &ur->rt_dev))
102862306a36Sopenharmony_ci		return -EFAULT;
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	rt.rt_dev = compat_ptr(rtdev);
103162306a36Sopenharmony_ci	return ip_rt_ioctl(sock_net(sk), cmd, &rt);
103262306a36Sopenharmony_ci}
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_cistatic int inet_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
103562306a36Sopenharmony_ci{
103662306a36Sopenharmony_ci	void __user *argp = compat_ptr(arg);
103762306a36Sopenharmony_ci	struct sock *sk = sock->sk;
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	switch (cmd) {
104062306a36Sopenharmony_ci	case SIOCADDRT:
104162306a36Sopenharmony_ci	case SIOCDELRT:
104262306a36Sopenharmony_ci		return inet_compat_routing_ioctl(sk, cmd, argp);
104362306a36Sopenharmony_ci	default:
104462306a36Sopenharmony_ci		if (!sk->sk_prot->compat_ioctl)
104562306a36Sopenharmony_ci			return -ENOIOCTLCMD;
104662306a36Sopenharmony_ci		return sk->sk_prot->compat_ioctl(sk, cmd, arg);
104762306a36Sopenharmony_ci	}
104862306a36Sopenharmony_ci}
104962306a36Sopenharmony_ci#endif /* CONFIG_COMPAT */
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ciconst struct proto_ops inet_stream_ops = {
105262306a36Sopenharmony_ci	.family		   = PF_INET,
105362306a36Sopenharmony_ci	.owner		   = THIS_MODULE,
105462306a36Sopenharmony_ci	.release	   = inet_release,
105562306a36Sopenharmony_ci	.bind		   = inet_bind,
105662306a36Sopenharmony_ci	.connect	   = inet_stream_connect,
105762306a36Sopenharmony_ci	.socketpair	   = sock_no_socketpair,
105862306a36Sopenharmony_ci	.accept		   = inet_accept,
105962306a36Sopenharmony_ci	.getname	   = inet_getname,
106062306a36Sopenharmony_ci	.poll		   = tcp_poll,
106162306a36Sopenharmony_ci	.ioctl		   = inet_ioctl,
106262306a36Sopenharmony_ci	.gettstamp	   = sock_gettstamp,
106362306a36Sopenharmony_ci	.listen		   = inet_listen,
106462306a36Sopenharmony_ci	.shutdown	   = inet_shutdown,
106562306a36Sopenharmony_ci	.setsockopt	   = sock_common_setsockopt,
106662306a36Sopenharmony_ci	.getsockopt	   = sock_common_getsockopt,
106762306a36Sopenharmony_ci	.sendmsg	   = inet_sendmsg,
106862306a36Sopenharmony_ci	.recvmsg	   = inet_recvmsg,
106962306a36Sopenharmony_ci#ifdef CONFIG_MMU
107062306a36Sopenharmony_ci	.mmap		   = tcp_mmap,
107162306a36Sopenharmony_ci#endif
107262306a36Sopenharmony_ci	.splice_eof	   = inet_splice_eof,
107362306a36Sopenharmony_ci	.splice_read	   = tcp_splice_read,
107462306a36Sopenharmony_ci	.read_sock	   = tcp_read_sock,
107562306a36Sopenharmony_ci	.read_skb	   = tcp_read_skb,
107662306a36Sopenharmony_ci	.sendmsg_locked    = tcp_sendmsg_locked,
107762306a36Sopenharmony_ci	.peek_len	   = tcp_peek_len,
107862306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
107962306a36Sopenharmony_ci	.compat_ioctl	   = inet_compat_ioctl,
108062306a36Sopenharmony_ci#endif
108162306a36Sopenharmony_ci	.set_rcvlowat	   = tcp_set_rcvlowat,
108262306a36Sopenharmony_ci};
108362306a36Sopenharmony_ciEXPORT_SYMBOL(inet_stream_ops);
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ciconst struct proto_ops inet_dgram_ops = {
108662306a36Sopenharmony_ci	.family		   = PF_INET,
108762306a36Sopenharmony_ci	.owner		   = THIS_MODULE,
108862306a36Sopenharmony_ci	.release	   = inet_release,
108962306a36Sopenharmony_ci	.bind		   = inet_bind,
109062306a36Sopenharmony_ci	.connect	   = inet_dgram_connect,
109162306a36Sopenharmony_ci	.socketpair	   = sock_no_socketpair,
109262306a36Sopenharmony_ci	.accept		   = sock_no_accept,
109362306a36Sopenharmony_ci	.getname	   = inet_getname,
109462306a36Sopenharmony_ci	.poll		   = udp_poll,
109562306a36Sopenharmony_ci	.ioctl		   = inet_ioctl,
109662306a36Sopenharmony_ci	.gettstamp	   = sock_gettstamp,
109762306a36Sopenharmony_ci	.listen		   = sock_no_listen,
109862306a36Sopenharmony_ci	.shutdown	   = inet_shutdown,
109962306a36Sopenharmony_ci	.setsockopt	   = sock_common_setsockopt,
110062306a36Sopenharmony_ci	.getsockopt	   = sock_common_getsockopt,
110162306a36Sopenharmony_ci	.sendmsg	   = inet_sendmsg,
110262306a36Sopenharmony_ci	.read_skb	   = udp_read_skb,
110362306a36Sopenharmony_ci	.recvmsg	   = inet_recvmsg,
110462306a36Sopenharmony_ci	.mmap		   = sock_no_mmap,
110562306a36Sopenharmony_ci	.splice_eof	   = inet_splice_eof,
110662306a36Sopenharmony_ci	.set_peek_off	   = sk_set_peek_off,
110762306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
110862306a36Sopenharmony_ci	.compat_ioctl	   = inet_compat_ioctl,
110962306a36Sopenharmony_ci#endif
111062306a36Sopenharmony_ci};
111162306a36Sopenharmony_ciEXPORT_SYMBOL(inet_dgram_ops);
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci/*
111462306a36Sopenharmony_ci * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
111562306a36Sopenharmony_ci * udp_poll
111662306a36Sopenharmony_ci */
111762306a36Sopenharmony_cistatic const struct proto_ops inet_sockraw_ops = {
111862306a36Sopenharmony_ci	.family		   = PF_INET,
111962306a36Sopenharmony_ci	.owner		   = THIS_MODULE,
112062306a36Sopenharmony_ci	.release	   = inet_release,
112162306a36Sopenharmony_ci	.bind		   = inet_bind,
112262306a36Sopenharmony_ci	.connect	   = inet_dgram_connect,
112362306a36Sopenharmony_ci	.socketpair	   = sock_no_socketpair,
112462306a36Sopenharmony_ci	.accept		   = sock_no_accept,
112562306a36Sopenharmony_ci	.getname	   = inet_getname,
112662306a36Sopenharmony_ci	.poll		   = datagram_poll,
112762306a36Sopenharmony_ci	.ioctl		   = inet_ioctl,
112862306a36Sopenharmony_ci	.gettstamp	   = sock_gettstamp,
112962306a36Sopenharmony_ci	.listen		   = sock_no_listen,
113062306a36Sopenharmony_ci	.shutdown	   = inet_shutdown,
113162306a36Sopenharmony_ci	.setsockopt	   = sock_common_setsockopt,
113262306a36Sopenharmony_ci	.getsockopt	   = sock_common_getsockopt,
113362306a36Sopenharmony_ci	.sendmsg	   = inet_sendmsg,
113462306a36Sopenharmony_ci	.recvmsg	   = inet_recvmsg,
113562306a36Sopenharmony_ci	.mmap		   = sock_no_mmap,
113662306a36Sopenharmony_ci	.splice_eof	   = inet_splice_eof,
113762306a36Sopenharmony_ci#ifdef CONFIG_COMPAT
113862306a36Sopenharmony_ci	.compat_ioctl	   = inet_compat_ioctl,
113962306a36Sopenharmony_ci#endif
114062306a36Sopenharmony_ci};
114162306a36Sopenharmony_ci
114262306a36Sopenharmony_cistatic const struct net_proto_family inet_family_ops = {
114362306a36Sopenharmony_ci	.family = PF_INET,
114462306a36Sopenharmony_ci	.create = inet_create,
114562306a36Sopenharmony_ci	.owner	= THIS_MODULE,
114662306a36Sopenharmony_ci};
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_ci/* Upon startup we insert all the elements in inetsw_array[] into
114962306a36Sopenharmony_ci * the linked list inetsw.
115062306a36Sopenharmony_ci */
115162306a36Sopenharmony_cistatic struct inet_protosw inetsw_array[] =
115262306a36Sopenharmony_ci{
115362306a36Sopenharmony_ci	{
115462306a36Sopenharmony_ci		.type =       SOCK_STREAM,
115562306a36Sopenharmony_ci		.protocol =   IPPROTO_TCP,
115662306a36Sopenharmony_ci		.prot =       &tcp_prot,
115762306a36Sopenharmony_ci		.ops =        &inet_stream_ops,
115862306a36Sopenharmony_ci		.flags =      INET_PROTOSW_PERMANENT |
115962306a36Sopenharmony_ci			      INET_PROTOSW_ICSK,
116062306a36Sopenharmony_ci	},
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	{
116362306a36Sopenharmony_ci		.type =       SOCK_DGRAM,
116462306a36Sopenharmony_ci		.protocol =   IPPROTO_UDP,
116562306a36Sopenharmony_ci		.prot =       &udp_prot,
116662306a36Sopenharmony_ci		.ops =        &inet_dgram_ops,
116762306a36Sopenharmony_ci		.flags =      INET_PROTOSW_PERMANENT,
116862306a36Sopenharmony_ci       },
116962306a36Sopenharmony_ci
117062306a36Sopenharmony_ci       {
117162306a36Sopenharmony_ci		.type =       SOCK_DGRAM,
117262306a36Sopenharmony_ci		.protocol =   IPPROTO_ICMP,
117362306a36Sopenharmony_ci		.prot =       &ping_prot,
117462306a36Sopenharmony_ci		.ops =        &inet_sockraw_ops,
117562306a36Sopenharmony_ci		.flags =      INET_PROTOSW_REUSE,
117662306a36Sopenharmony_ci       },
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci       {
117962306a36Sopenharmony_ci	       .type =       SOCK_RAW,
118062306a36Sopenharmony_ci	       .protocol =   IPPROTO_IP,	/* wild card */
118162306a36Sopenharmony_ci	       .prot =       &raw_prot,
118262306a36Sopenharmony_ci	       .ops =        &inet_sockraw_ops,
118362306a36Sopenharmony_ci	       .flags =      INET_PROTOSW_REUSE,
118462306a36Sopenharmony_ci       }
118562306a36Sopenharmony_ci};
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_ci#define INETSW_ARRAY_LEN ARRAY_SIZE(inetsw_array)
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_civoid inet_register_protosw(struct inet_protosw *p)
119062306a36Sopenharmony_ci{
119162306a36Sopenharmony_ci	struct list_head *lh;
119262306a36Sopenharmony_ci	struct inet_protosw *answer;
119362306a36Sopenharmony_ci	int protocol = p->protocol;
119462306a36Sopenharmony_ci	struct list_head *last_perm;
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci	spin_lock_bh(&inetsw_lock);
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	if (p->type >= SOCK_MAX)
119962306a36Sopenharmony_ci		goto out_illegal;
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci	/* If we are trying to override a permanent protocol, bail. */
120262306a36Sopenharmony_ci	last_perm = &inetsw[p->type];
120362306a36Sopenharmony_ci	list_for_each(lh, &inetsw[p->type]) {
120462306a36Sopenharmony_ci		answer = list_entry(lh, struct inet_protosw, list);
120562306a36Sopenharmony_ci		/* Check only the non-wild match. */
120662306a36Sopenharmony_ci		if ((INET_PROTOSW_PERMANENT & answer->flags) == 0)
120762306a36Sopenharmony_ci			break;
120862306a36Sopenharmony_ci		if (protocol == answer->protocol)
120962306a36Sopenharmony_ci			goto out_permanent;
121062306a36Sopenharmony_ci		last_perm = lh;
121162306a36Sopenharmony_ci	}
121262306a36Sopenharmony_ci
121362306a36Sopenharmony_ci	/* Add the new entry after the last permanent entry if any, so that
121462306a36Sopenharmony_ci	 * the new entry does not override a permanent entry when matched with
121562306a36Sopenharmony_ci	 * a wild-card protocol. But it is allowed to override any existing
121662306a36Sopenharmony_ci	 * non-permanent entry.  This means that when we remove this entry, the
121762306a36Sopenharmony_ci	 * system automatically returns to the old behavior.
121862306a36Sopenharmony_ci	 */
121962306a36Sopenharmony_ci	list_add_rcu(&p->list, last_perm);
122062306a36Sopenharmony_ciout:
122162306a36Sopenharmony_ci	spin_unlock_bh(&inetsw_lock);
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci	return;
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ciout_permanent:
122662306a36Sopenharmony_ci	pr_err("Attempt to override permanent protocol %d\n", protocol);
122762306a36Sopenharmony_ci	goto out;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ciout_illegal:
123062306a36Sopenharmony_ci	pr_err("Ignoring attempt to register invalid socket type %d\n",
123162306a36Sopenharmony_ci	       p->type);
123262306a36Sopenharmony_ci	goto out;
123362306a36Sopenharmony_ci}
123462306a36Sopenharmony_ciEXPORT_SYMBOL(inet_register_protosw);
123562306a36Sopenharmony_ci
123662306a36Sopenharmony_civoid inet_unregister_protosw(struct inet_protosw *p)
123762306a36Sopenharmony_ci{
123862306a36Sopenharmony_ci	if (INET_PROTOSW_PERMANENT & p->flags) {
123962306a36Sopenharmony_ci		pr_err("Attempt to unregister permanent protocol %d\n",
124062306a36Sopenharmony_ci		       p->protocol);
124162306a36Sopenharmony_ci	} else {
124262306a36Sopenharmony_ci		spin_lock_bh(&inetsw_lock);
124362306a36Sopenharmony_ci		list_del_rcu(&p->list);
124462306a36Sopenharmony_ci		spin_unlock_bh(&inetsw_lock);
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci		synchronize_net();
124762306a36Sopenharmony_ci	}
124862306a36Sopenharmony_ci}
124962306a36Sopenharmony_ciEXPORT_SYMBOL(inet_unregister_protosw);
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_cistatic int inet_sk_reselect_saddr(struct sock *sk)
125262306a36Sopenharmony_ci{
125362306a36Sopenharmony_ci	struct inet_sock *inet = inet_sk(sk);
125462306a36Sopenharmony_ci	__be32 old_saddr = inet->inet_saddr;
125562306a36Sopenharmony_ci	__be32 daddr = inet->inet_daddr;
125662306a36Sopenharmony_ci	struct flowi4 *fl4;
125762306a36Sopenharmony_ci	struct rtable *rt;
125862306a36Sopenharmony_ci	__be32 new_saddr;
125962306a36Sopenharmony_ci	struct ip_options_rcu *inet_opt;
126062306a36Sopenharmony_ci	int err;
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci	inet_opt = rcu_dereference_protected(inet->inet_opt,
126362306a36Sopenharmony_ci					     lockdep_sock_is_held(sk));
126462306a36Sopenharmony_ci	if (inet_opt && inet_opt->opt.srr)
126562306a36Sopenharmony_ci		daddr = inet_opt->opt.faddr;
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	/* Query new route. */
126862306a36Sopenharmony_ci	fl4 = &inet->cork.fl.u.ip4;
126962306a36Sopenharmony_ci	rt = ip_route_connect(fl4, daddr, 0, sk->sk_bound_dev_if,
127062306a36Sopenharmony_ci			      sk->sk_protocol, inet->inet_sport,
127162306a36Sopenharmony_ci			      inet->inet_dport, sk);
127262306a36Sopenharmony_ci	if (IS_ERR(rt))
127362306a36Sopenharmony_ci		return PTR_ERR(rt);
127462306a36Sopenharmony_ci
127562306a36Sopenharmony_ci	new_saddr = fl4->saddr;
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci	if (new_saddr == old_saddr) {
127862306a36Sopenharmony_ci		sk_setup_caps(sk, &rt->dst);
127962306a36Sopenharmony_ci		return 0;
128062306a36Sopenharmony_ci	}
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_ci	err = inet_bhash2_update_saddr(sk, &new_saddr, AF_INET);
128362306a36Sopenharmony_ci	if (err) {
128462306a36Sopenharmony_ci		ip_rt_put(rt);
128562306a36Sopenharmony_ci		return err;
128662306a36Sopenharmony_ci	}
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci	sk_setup_caps(sk, &rt->dst);
128962306a36Sopenharmony_ci
129062306a36Sopenharmony_ci	if (READ_ONCE(sock_net(sk)->ipv4.sysctl_ip_dynaddr) > 1) {
129162306a36Sopenharmony_ci		pr_info("%s(): shifting inet->saddr from %pI4 to %pI4\n",
129262306a36Sopenharmony_ci			__func__, &old_saddr, &new_saddr);
129362306a36Sopenharmony_ci	}
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	/*
129662306a36Sopenharmony_ci	 * XXX The only one ugly spot where we need to
129762306a36Sopenharmony_ci	 * XXX really change the sockets identity after
129862306a36Sopenharmony_ci	 * XXX it has entered the hashes. -DaveM
129962306a36Sopenharmony_ci	 *
130062306a36Sopenharmony_ci	 * Besides that, it does not check for connection
130162306a36Sopenharmony_ci	 * uniqueness. Wait for troubles.
130262306a36Sopenharmony_ci	 */
130362306a36Sopenharmony_ci	return __sk_prot_rehash(sk);
130462306a36Sopenharmony_ci}
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ciint inet_sk_rebuild_header(struct sock *sk)
130762306a36Sopenharmony_ci{
130862306a36Sopenharmony_ci	struct inet_sock *inet = inet_sk(sk);
130962306a36Sopenharmony_ci	struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
131062306a36Sopenharmony_ci	__be32 daddr;
131162306a36Sopenharmony_ci	struct ip_options_rcu *inet_opt;
131262306a36Sopenharmony_ci	struct flowi4 *fl4;
131362306a36Sopenharmony_ci	int err;
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci	/* Route is OK, nothing to do. */
131662306a36Sopenharmony_ci	if (rt)
131762306a36Sopenharmony_ci		return 0;
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	/* Reroute. */
132062306a36Sopenharmony_ci	rcu_read_lock();
132162306a36Sopenharmony_ci	inet_opt = rcu_dereference(inet->inet_opt);
132262306a36Sopenharmony_ci	daddr = inet->inet_daddr;
132362306a36Sopenharmony_ci	if (inet_opt && inet_opt->opt.srr)
132462306a36Sopenharmony_ci		daddr = inet_opt->opt.faddr;
132562306a36Sopenharmony_ci	rcu_read_unlock();
132662306a36Sopenharmony_ci	fl4 = &inet->cork.fl.u.ip4;
132762306a36Sopenharmony_ci	rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr, inet->inet_saddr,
132862306a36Sopenharmony_ci				   inet->inet_dport, inet->inet_sport,
132962306a36Sopenharmony_ci				   sk->sk_protocol, RT_CONN_FLAGS(sk),
133062306a36Sopenharmony_ci				   sk->sk_bound_dev_if);
133162306a36Sopenharmony_ci	if (!IS_ERR(rt)) {
133262306a36Sopenharmony_ci		err = 0;
133362306a36Sopenharmony_ci		sk_setup_caps(sk, &rt->dst);
133462306a36Sopenharmony_ci	} else {
133562306a36Sopenharmony_ci		err = PTR_ERR(rt);
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_ci		/* Routing failed... */
133862306a36Sopenharmony_ci		sk->sk_route_caps = 0;
133962306a36Sopenharmony_ci		/*
134062306a36Sopenharmony_ci		 * Other protocols have to map its equivalent state to TCP_SYN_SENT.
134162306a36Sopenharmony_ci		 * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme
134262306a36Sopenharmony_ci		 */
134362306a36Sopenharmony_ci		if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_ip_dynaddr) ||
134462306a36Sopenharmony_ci		    sk->sk_state != TCP_SYN_SENT ||
134562306a36Sopenharmony_ci		    (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||
134662306a36Sopenharmony_ci		    (err = inet_sk_reselect_saddr(sk)) != 0)
134762306a36Sopenharmony_ci			WRITE_ONCE(sk->sk_err_soft, -err);
134862306a36Sopenharmony_ci	}
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci	return err;
135162306a36Sopenharmony_ci}
135262306a36Sopenharmony_ciEXPORT_SYMBOL(inet_sk_rebuild_header);
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_civoid inet_sk_set_state(struct sock *sk, int state)
135562306a36Sopenharmony_ci{
135662306a36Sopenharmony_ci	trace_inet_sock_set_state(sk, sk->sk_state, state);
135762306a36Sopenharmony_ci	sk->sk_state = state;
135862306a36Sopenharmony_ci}
135962306a36Sopenharmony_ciEXPORT_SYMBOL(inet_sk_set_state);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_civoid inet_sk_state_store(struct sock *sk, int newstate)
136262306a36Sopenharmony_ci{
136362306a36Sopenharmony_ci	trace_inet_sock_set_state(sk, sk->sk_state, newstate);
136462306a36Sopenharmony_ci	smp_store_release(&sk->sk_state, newstate);
136562306a36Sopenharmony_ci}
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_cistruct sk_buff *inet_gso_segment(struct sk_buff *skb,
136862306a36Sopenharmony_ci				 netdev_features_t features)
136962306a36Sopenharmony_ci{
137062306a36Sopenharmony_ci	bool udpfrag = false, fixedid = false, gso_partial, encap;
137162306a36Sopenharmony_ci	struct sk_buff *segs = ERR_PTR(-EINVAL);
137262306a36Sopenharmony_ci	const struct net_offload *ops;
137362306a36Sopenharmony_ci	unsigned int offset = 0;
137462306a36Sopenharmony_ci	struct iphdr *iph;
137562306a36Sopenharmony_ci	int proto, tot_len;
137662306a36Sopenharmony_ci	int nhoff;
137762306a36Sopenharmony_ci	int ihl;
137862306a36Sopenharmony_ci	int id;
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci	skb_reset_network_header(skb);
138162306a36Sopenharmony_ci	nhoff = skb_network_header(skb) - skb_mac_header(skb);
138262306a36Sopenharmony_ci	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
138362306a36Sopenharmony_ci		goto out;
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	iph = ip_hdr(skb);
138662306a36Sopenharmony_ci	ihl = iph->ihl * 4;
138762306a36Sopenharmony_ci	if (ihl < sizeof(*iph))
138862306a36Sopenharmony_ci		goto out;
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	id = ntohs(iph->id);
139162306a36Sopenharmony_ci	proto = iph->protocol;
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	/* Warning: after this point, iph might be no longer valid */
139462306a36Sopenharmony_ci	if (unlikely(!pskb_may_pull(skb, ihl)))
139562306a36Sopenharmony_ci		goto out;
139662306a36Sopenharmony_ci	__skb_pull(skb, ihl);
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	encap = SKB_GSO_CB(skb)->encap_level > 0;
139962306a36Sopenharmony_ci	if (encap)
140062306a36Sopenharmony_ci		features &= skb->dev->hw_enc_features;
140162306a36Sopenharmony_ci	SKB_GSO_CB(skb)->encap_level += ihl;
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	skb_reset_transport_header(skb);
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	segs = ERR_PTR(-EPROTONOSUPPORT);
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	if (!skb->encapsulation || encap) {
140862306a36Sopenharmony_ci		udpfrag = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP);
140962306a36Sopenharmony_ci		fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
141062306a36Sopenharmony_ci
141162306a36Sopenharmony_ci		/* fixed ID is invalid if DF bit is not set */
141262306a36Sopenharmony_ci		if (fixedid && !(ip_hdr(skb)->frag_off & htons(IP_DF)))
141362306a36Sopenharmony_ci			goto out;
141462306a36Sopenharmony_ci	}
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci	ops = rcu_dereference(inet_offloads[proto]);
141762306a36Sopenharmony_ci	if (likely(ops && ops->callbacks.gso_segment)) {
141862306a36Sopenharmony_ci		segs = ops->callbacks.gso_segment(skb, features);
141962306a36Sopenharmony_ci		if (!segs)
142062306a36Sopenharmony_ci			skb->network_header = skb_mac_header(skb) + nhoff - skb->head;
142162306a36Sopenharmony_ci	}
142262306a36Sopenharmony_ci
142362306a36Sopenharmony_ci	if (IS_ERR_OR_NULL(segs))
142462306a36Sopenharmony_ci		goto out;
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci	gso_partial = !!(skb_shinfo(segs)->gso_type & SKB_GSO_PARTIAL);
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	skb = segs;
142962306a36Sopenharmony_ci	do {
143062306a36Sopenharmony_ci		iph = (struct iphdr *)(skb_mac_header(skb) + nhoff);
143162306a36Sopenharmony_ci		if (udpfrag) {
143262306a36Sopenharmony_ci			iph->frag_off = htons(offset >> 3);
143362306a36Sopenharmony_ci			if (skb->next)
143462306a36Sopenharmony_ci				iph->frag_off |= htons(IP_MF);
143562306a36Sopenharmony_ci			offset += skb->len - nhoff - ihl;
143662306a36Sopenharmony_ci			tot_len = skb->len - nhoff;
143762306a36Sopenharmony_ci		} else if (skb_is_gso(skb)) {
143862306a36Sopenharmony_ci			if (!fixedid) {
143962306a36Sopenharmony_ci				iph->id = htons(id);
144062306a36Sopenharmony_ci				id += skb_shinfo(skb)->gso_segs;
144162306a36Sopenharmony_ci			}
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci			if (gso_partial)
144462306a36Sopenharmony_ci				tot_len = skb_shinfo(skb)->gso_size +
144562306a36Sopenharmony_ci					  SKB_GSO_CB(skb)->data_offset +
144662306a36Sopenharmony_ci					  skb->head - (unsigned char *)iph;
144762306a36Sopenharmony_ci			else
144862306a36Sopenharmony_ci				tot_len = skb->len - nhoff;
144962306a36Sopenharmony_ci		} else {
145062306a36Sopenharmony_ci			if (!fixedid)
145162306a36Sopenharmony_ci				iph->id = htons(id++);
145262306a36Sopenharmony_ci			tot_len = skb->len - nhoff;
145362306a36Sopenharmony_ci		}
145462306a36Sopenharmony_ci		iph->tot_len = htons(tot_len);
145562306a36Sopenharmony_ci		ip_send_check(iph);
145662306a36Sopenharmony_ci		if (encap)
145762306a36Sopenharmony_ci			skb_reset_inner_headers(skb);
145862306a36Sopenharmony_ci		skb->network_header = (u8 *)iph - skb->head;
145962306a36Sopenharmony_ci		skb_reset_mac_len(skb);
146062306a36Sopenharmony_ci	} while ((skb = skb->next));
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ciout:
146362306a36Sopenharmony_ci	return segs;
146462306a36Sopenharmony_ci}
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_cistatic struct sk_buff *ipip_gso_segment(struct sk_buff *skb,
146762306a36Sopenharmony_ci					netdev_features_t features)
146862306a36Sopenharmony_ci{
146962306a36Sopenharmony_ci	if (!(skb_shinfo(skb)->gso_type & SKB_GSO_IPXIP4))
147062306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
147162306a36Sopenharmony_ci
147262306a36Sopenharmony_ci	return inet_gso_segment(skb, features);
147362306a36Sopenharmony_ci}
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_cistruct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb)
147662306a36Sopenharmony_ci{
147762306a36Sopenharmony_ci	const struct net_offload *ops;
147862306a36Sopenharmony_ci	struct sk_buff *pp = NULL;
147962306a36Sopenharmony_ci	const struct iphdr *iph;
148062306a36Sopenharmony_ci	struct sk_buff *p;
148162306a36Sopenharmony_ci	unsigned int hlen;
148262306a36Sopenharmony_ci	unsigned int off;
148362306a36Sopenharmony_ci	unsigned int id;
148462306a36Sopenharmony_ci	int flush = 1;
148562306a36Sopenharmony_ci	int proto;
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci	off = skb_gro_offset(skb);
148862306a36Sopenharmony_ci	hlen = off + sizeof(*iph);
148962306a36Sopenharmony_ci	iph = skb_gro_header(skb, hlen, off);
149062306a36Sopenharmony_ci	if (unlikely(!iph))
149162306a36Sopenharmony_ci		goto out;
149262306a36Sopenharmony_ci
149362306a36Sopenharmony_ci	proto = iph->protocol;
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_ci	ops = rcu_dereference(inet_offloads[proto]);
149662306a36Sopenharmony_ci	if (!ops || !ops->callbacks.gro_receive)
149762306a36Sopenharmony_ci		goto out;
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ci	if (*(u8 *)iph != 0x45)
150062306a36Sopenharmony_ci		goto out;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	if (ip_is_fragment(iph))
150362306a36Sopenharmony_ci		goto out;
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci	if (unlikely(ip_fast_csum((u8 *)iph, 5)))
150662306a36Sopenharmony_ci		goto out;
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_ci	NAPI_GRO_CB(skb)->proto = proto;
150962306a36Sopenharmony_ci	id = ntohl(*(__be32 *)&iph->id);
151062306a36Sopenharmony_ci	flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF));
151162306a36Sopenharmony_ci	id >>= 16;
151262306a36Sopenharmony_ci
151362306a36Sopenharmony_ci	list_for_each_entry(p, head, list) {
151462306a36Sopenharmony_ci		struct iphdr *iph2;
151562306a36Sopenharmony_ci		u16 flush_id;
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_ci		if (!NAPI_GRO_CB(p)->same_flow)
151862306a36Sopenharmony_ci			continue;
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_ci		iph2 = (struct iphdr *)(p->data + off);
152162306a36Sopenharmony_ci		/* The above works because, with the exception of the top
152262306a36Sopenharmony_ci		 * (inner most) layer, we only aggregate pkts with the same
152362306a36Sopenharmony_ci		 * hdr length so all the hdrs we'll need to verify will start
152462306a36Sopenharmony_ci		 * at the same offset.
152562306a36Sopenharmony_ci		 */
152662306a36Sopenharmony_ci		if ((iph->protocol ^ iph2->protocol) |
152762306a36Sopenharmony_ci		    ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) |
152862306a36Sopenharmony_ci		    ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) {
152962306a36Sopenharmony_ci			NAPI_GRO_CB(p)->same_flow = 0;
153062306a36Sopenharmony_ci			continue;
153162306a36Sopenharmony_ci		}
153262306a36Sopenharmony_ci
153362306a36Sopenharmony_ci		/* All fields must match except length and checksum. */
153462306a36Sopenharmony_ci		NAPI_GRO_CB(p)->flush |=
153562306a36Sopenharmony_ci			(iph->ttl ^ iph2->ttl) |
153662306a36Sopenharmony_ci			(iph->tos ^ iph2->tos) |
153762306a36Sopenharmony_ci			((iph->frag_off ^ iph2->frag_off) & htons(IP_DF));
153862306a36Sopenharmony_ci
153962306a36Sopenharmony_ci		NAPI_GRO_CB(p)->flush |= flush;
154062306a36Sopenharmony_ci
154162306a36Sopenharmony_ci		/* We need to store of the IP ID check to be included later
154262306a36Sopenharmony_ci		 * when we can verify that this packet does in fact belong
154362306a36Sopenharmony_ci		 * to a given flow.
154462306a36Sopenharmony_ci		 */
154562306a36Sopenharmony_ci		flush_id = (u16)(id - ntohs(iph2->id));
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_ci		/* This bit of code makes it much easier for us to identify
154862306a36Sopenharmony_ci		 * the cases where we are doing atomic vs non-atomic IP ID
154962306a36Sopenharmony_ci		 * checks.  Specifically an atomic check can return IP ID
155062306a36Sopenharmony_ci		 * values 0 - 0xFFFF, while a non-atomic check can only
155162306a36Sopenharmony_ci		 * return 0 or 0xFFFF.
155262306a36Sopenharmony_ci		 */
155362306a36Sopenharmony_ci		if (!NAPI_GRO_CB(p)->is_atomic ||
155462306a36Sopenharmony_ci		    !(iph->frag_off & htons(IP_DF))) {
155562306a36Sopenharmony_ci			flush_id ^= NAPI_GRO_CB(p)->count;
155662306a36Sopenharmony_ci			flush_id = flush_id ? 0xFFFF : 0;
155762306a36Sopenharmony_ci		}
155862306a36Sopenharmony_ci
155962306a36Sopenharmony_ci		/* If the previous IP ID value was based on an atomic
156062306a36Sopenharmony_ci		 * datagram we can overwrite the value and ignore it.
156162306a36Sopenharmony_ci		 */
156262306a36Sopenharmony_ci		if (NAPI_GRO_CB(skb)->is_atomic)
156362306a36Sopenharmony_ci			NAPI_GRO_CB(p)->flush_id = flush_id;
156462306a36Sopenharmony_ci		else
156562306a36Sopenharmony_ci			NAPI_GRO_CB(p)->flush_id |= flush_id;
156662306a36Sopenharmony_ci	}
156762306a36Sopenharmony_ci
156862306a36Sopenharmony_ci	NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF));
156962306a36Sopenharmony_ci	NAPI_GRO_CB(skb)->flush |= flush;
157062306a36Sopenharmony_ci	skb_set_network_header(skb, off);
157162306a36Sopenharmony_ci	/* The above will be needed by the transport layer if there is one
157262306a36Sopenharmony_ci	 * immediately following this IP hdr.
157362306a36Sopenharmony_ci	 */
157462306a36Sopenharmony_ci
157562306a36Sopenharmony_ci	/* Note : No need to call skb_gro_postpull_rcsum() here,
157662306a36Sopenharmony_ci	 * as we already checked checksum over ipv4 header was 0
157762306a36Sopenharmony_ci	 */
157862306a36Sopenharmony_ci	skb_gro_pull(skb, sizeof(*iph));
157962306a36Sopenharmony_ci	skb_set_transport_header(skb, skb_gro_offset(skb));
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_ci	pp = indirect_call_gro_receive(tcp4_gro_receive, udp4_gro_receive,
158262306a36Sopenharmony_ci				       ops->callbacks.gro_receive, head, skb);
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ciout:
158562306a36Sopenharmony_ci	skb_gro_flush_final(skb, pp, flush);
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ci	return pp;
158862306a36Sopenharmony_ci}
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_cistatic struct sk_buff *ipip_gro_receive(struct list_head *head,
159162306a36Sopenharmony_ci					struct sk_buff *skb)
159262306a36Sopenharmony_ci{
159362306a36Sopenharmony_ci	if (NAPI_GRO_CB(skb)->encap_mark) {
159462306a36Sopenharmony_ci		NAPI_GRO_CB(skb)->flush = 1;
159562306a36Sopenharmony_ci		return NULL;
159662306a36Sopenharmony_ci	}
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	NAPI_GRO_CB(skb)->encap_mark = 1;
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_ci	return inet_gro_receive(head, skb);
160162306a36Sopenharmony_ci}
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_ci#define SECONDS_PER_DAY	86400
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_ci/* inet_current_timestamp - Return IP network timestamp
160662306a36Sopenharmony_ci *
160762306a36Sopenharmony_ci * Return milliseconds since midnight in network byte order.
160862306a36Sopenharmony_ci */
160962306a36Sopenharmony_ci__be32 inet_current_timestamp(void)
161062306a36Sopenharmony_ci{
161162306a36Sopenharmony_ci	u32 secs;
161262306a36Sopenharmony_ci	u32 msecs;
161362306a36Sopenharmony_ci	struct timespec64 ts;
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	ktime_get_real_ts64(&ts);
161662306a36Sopenharmony_ci
161762306a36Sopenharmony_ci	/* Get secs since midnight. */
161862306a36Sopenharmony_ci	(void)div_u64_rem(ts.tv_sec, SECONDS_PER_DAY, &secs);
161962306a36Sopenharmony_ci	/* Convert to msecs. */
162062306a36Sopenharmony_ci	msecs = secs * MSEC_PER_SEC;
162162306a36Sopenharmony_ci	/* Convert nsec to msec. */
162262306a36Sopenharmony_ci	msecs += (u32)ts.tv_nsec / NSEC_PER_MSEC;
162362306a36Sopenharmony_ci
162462306a36Sopenharmony_ci	/* Convert to network byte order. */
162562306a36Sopenharmony_ci	return htonl(msecs);
162662306a36Sopenharmony_ci}
162762306a36Sopenharmony_ciEXPORT_SYMBOL(inet_current_timestamp);
162862306a36Sopenharmony_ci
162962306a36Sopenharmony_ciint inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
163062306a36Sopenharmony_ci{
163162306a36Sopenharmony_ci	unsigned int family = READ_ONCE(sk->sk_family);
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci	if (family == AF_INET)
163462306a36Sopenharmony_ci		return ip_recv_error(sk, msg, len, addr_len);
163562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
163662306a36Sopenharmony_ci	if (family == AF_INET6)
163762306a36Sopenharmony_ci		return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len);
163862306a36Sopenharmony_ci#endif
163962306a36Sopenharmony_ci	return -EINVAL;
164062306a36Sopenharmony_ci}
164162306a36Sopenharmony_ciEXPORT_SYMBOL(inet_recv_error);
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ciint inet_gro_complete(struct sk_buff *skb, int nhoff)
164462306a36Sopenharmony_ci{
164562306a36Sopenharmony_ci	struct iphdr *iph = (struct iphdr *)(skb->data + nhoff);
164662306a36Sopenharmony_ci	const struct net_offload *ops;
164762306a36Sopenharmony_ci	__be16 totlen = iph->tot_len;
164862306a36Sopenharmony_ci	int proto = iph->protocol;
164962306a36Sopenharmony_ci	int err = -ENOSYS;
165062306a36Sopenharmony_ci
165162306a36Sopenharmony_ci	if (skb->encapsulation) {
165262306a36Sopenharmony_ci		skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IP));
165362306a36Sopenharmony_ci		skb_set_inner_network_header(skb, nhoff);
165462306a36Sopenharmony_ci	}
165562306a36Sopenharmony_ci
165662306a36Sopenharmony_ci	iph_set_totlen(iph, skb->len - nhoff);
165762306a36Sopenharmony_ci	csum_replace2(&iph->check, totlen, iph->tot_len);
165862306a36Sopenharmony_ci
165962306a36Sopenharmony_ci	ops = rcu_dereference(inet_offloads[proto]);
166062306a36Sopenharmony_ci	if (WARN_ON(!ops || !ops->callbacks.gro_complete))
166162306a36Sopenharmony_ci		goto out;
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci	/* Only need to add sizeof(*iph) to get to the next hdr below
166462306a36Sopenharmony_ci	 * because any hdr with option will have been flushed in
166562306a36Sopenharmony_ci	 * inet_gro_receive().
166662306a36Sopenharmony_ci	 */
166762306a36Sopenharmony_ci	err = INDIRECT_CALL_2(ops->callbacks.gro_complete,
166862306a36Sopenharmony_ci			      tcp4_gro_complete, udp4_gro_complete,
166962306a36Sopenharmony_ci			      skb, nhoff + sizeof(*iph));
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ciout:
167262306a36Sopenharmony_ci	return err;
167362306a36Sopenharmony_ci}
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_cistatic int ipip_gro_complete(struct sk_buff *skb, int nhoff)
167662306a36Sopenharmony_ci{
167762306a36Sopenharmony_ci	skb->encapsulation = 1;
167862306a36Sopenharmony_ci	skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP4;
167962306a36Sopenharmony_ci	return inet_gro_complete(skb, nhoff);
168062306a36Sopenharmony_ci}
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ciint inet_ctl_sock_create(struct sock **sk, unsigned short family,
168362306a36Sopenharmony_ci			 unsigned short type, unsigned char protocol,
168462306a36Sopenharmony_ci			 struct net *net)
168562306a36Sopenharmony_ci{
168662306a36Sopenharmony_ci	struct socket *sock;
168762306a36Sopenharmony_ci	int rc = sock_create_kern(net, family, type, protocol, &sock);
168862306a36Sopenharmony_ci
168962306a36Sopenharmony_ci	if (rc == 0) {
169062306a36Sopenharmony_ci		*sk = sock->sk;
169162306a36Sopenharmony_ci		(*sk)->sk_allocation = GFP_ATOMIC;
169262306a36Sopenharmony_ci		(*sk)->sk_use_task_frag = false;
169362306a36Sopenharmony_ci		/*
169462306a36Sopenharmony_ci		 * Unhash it so that IP input processing does not even see it,
169562306a36Sopenharmony_ci		 * we do not wish this socket to see incoming packets.
169662306a36Sopenharmony_ci		 */
169762306a36Sopenharmony_ci		(*sk)->sk_prot->unhash(*sk);
169862306a36Sopenharmony_ci	}
169962306a36Sopenharmony_ci	return rc;
170062306a36Sopenharmony_ci}
170162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(inet_ctl_sock_create);
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ciunsigned long snmp_fold_field(void __percpu *mib, int offt)
170462306a36Sopenharmony_ci{
170562306a36Sopenharmony_ci	unsigned long res = 0;
170662306a36Sopenharmony_ci	int i;
170762306a36Sopenharmony_ci
170862306a36Sopenharmony_ci	for_each_possible_cpu(i)
170962306a36Sopenharmony_ci		res += snmp_get_cpu_field(mib, i, offt);
171062306a36Sopenharmony_ci	return res;
171162306a36Sopenharmony_ci}
171262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(snmp_fold_field);
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci#if BITS_PER_LONG==32
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_ciu64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offt,
171762306a36Sopenharmony_ci			 size_t syncp_offset)
171862306a36Sopenharmony_ci{
171962306a36Sopenharmony_ci	void *bhptr;
172062306a36Sopenharmony_ci	struct u64_stats_sync *syncp;
172162306a36Sopenharmony_ci	u64 v;
172262306a36Sopenharmony_ci	unsigned int start;
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	bhptr = per_cpu_ptr(mib, cpu);
172562306a36Sopenharmony_ci	syncp = (struct u64_stats_sync *)(bhptr + syncp_offset);
172662306a36Sopenharmony_ci	do {
172762306a36Sopenharmony_ci		start = u64_stats_fetch_begin(syncp);
172862306a36Sopenharmony_ci		v = *(((u64 *)bhptr) + offt);
172962306a36Sopenharmony_ci	} while (u64_stats_fetch_retry(syncp, start));
173062306a36Sopenharmony_ci
173162306a36Sopenharmony_ci	return v;
173262306a36Sopenharmony_ci}
173362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(snmp_get_cpu_field64);
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_ciu64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_offset)
173662306a36Sopenharmony_ci{
173762306a36Sopenharmony_ci	u64 res = 0;
173862306a36Sopenharmony_ci	int cpu;
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_ci	for_each_possible_cpu(cpu) {
174162306a36Sopenharmony_ci		res += snmp_get_cpu_field64(mib, cpu, offt, syncp_offset);
174262306a36Sopenharmony_ci	}
174362306a36Sopenharmony_ci	return res;
174462306a36Sopenharmony_ci}
174562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(snmp_fold_field64);
174662306a36Sopenharmony_ci#endif
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci#ifdef CONFIG_IP_MULTICAST
174962306a36Sopenharmony_cistatic const struct net_protocol igmp_protocol = {
175062306a36Sopenharmony_ci	.handler =	igmp_rcv,
175162306a36Sopenharmony_ci};
175262306a36Sopenharmony_ci#endif
175362306a36Sopenharmony_ci
175462306a36Sopenharmony_cistatic const struct net_protocol tcp_protocol = {
175562306a36Sopenharmony_ci	.handler	=	tcp_v4_rcv,
175662306a36Sopenharmony_ci	.err_handler	=	tcp_v4_err,
175762306a36Sopenharmony_ci	.no_policy	=	1,
175862306a36Sopenharmony_ci	.icmp_strict_tag_validation = 1,
175962306a36Sopenharmony_ci};
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_cistatic const struct net_protocol udp_protocol = {
176262306a36Sopenharmony_ci	.handler =	udp_rcv,
176362306a36Sopenharmony_ci	.err_handler =	udp_err,
176462306a36Sopenharmony_ci	.no_policy =	1,
176562306a36Sopenharmony_ci};
176662306a36Sopenharmony_ci
176762306a36Sopenharmony_cistatic const struct net_protocol icmp_protocol = {
176862306a36Sopenharmony_ci	.handler =	icmp_rcv,
176962306a36Sopenharmony_ci	.err_handler =	icmp_err,
177062306a36Sopenharmony_ci	.no_policy =	1,
177162306a36Sopenharmony_ci};
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_cistatic __net_init int ipv4_mib_init_net(struct net *net)
177462306a36Sopenharmony_ci{
177562306a36Sopenharmony_ci	int i;
177662306a36Sopenharmony_ci
177762306a36Sopenharmony_ci	net->mib.tcp_statistics = alloc_percpu(struct tcp_mib);
177862306a36Sopenharmony_ci	if (!net->mib.tcp_statistics)
177962306a36Sopenharmony_ci		goto err_tcp_mib;
178062306a36Sopenharmony_ci	net->mib.ip_statistics = alloc_percpu(struct ipstats_mib);
178162306a36Sopenharmony_ci	if (!net->mib.ip_statistics)
178262306a36Sopenharmony_ci		goto err_ip_mib;
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_ci	for_each_possible_cpu(i) {
178562306a36Sopenharmony_ci		struct ipstats_mib *af_inet_stats;
178662306a36Sopenharmony_ci		af_inet_stats = per_cpu_ptr(net->mib.ip_statistics, i);
178762306a36Sopenharmony_ci		u64_stats_init(&af_inet_stats->syncp);
178862306a36Sopenharmony_ci	}
178962306a36Sopenharmony_ci
179062306a36Sopenharmony_ci	net->mib.net_statistics = alloc_percpu(struct linux_mib);
179162306a36Sopenharmony_ci	if (!net->mib.net_statistics)
179262306a36Sopenharmony_ci		goto err_net_mib;
179362306a36Sopenharmony_ci	net->mib.udp_statistics = alloc_percpu(struct udp_mib);
179462306a36Sopenharmony_ci	if (!net->mib.udp_statistics)
179562306a36Sopenharmony_ci		goto err_udp_mib;
179662306a36Sopenharmony_ci	net->mib.udplite_statistics = alloc_percpu(struct udp_mib);
179762306a36Sopenharmony_ci	if (!net->mib.udplite_statistics)
179862306a36Sopenharmony_ci		goto err_udplite_mib;
179962306a36Sopenharmony_ci	net->mib.icmp_statistics = alloc_percpu(struct icmp_mib);
180062306a36Sopenharmony_ci	if (!net->mib.icmp_statistics)
180162306a36Sopenharmony_ci		goto err_icmp_mib;
180262306a36Sopenharmony_ci	net->mib.icmpmsg_statistics = kzalloc(sizeof(struct icmpmsg_mib),
180362306a36Sopenharmony_ci					      GFP_KERNEL);
180462306a36Sopenharmony_ci	if (!net->mib.icmpmsg_statistics)
180562306a36Sopenharmony_ci		goto err_icmpmsg_mib;
180662306a36Sopenharmony_ci
180762306a36Sopenharmony_ci	tcp_mib_init(net);
180862306a36Sopenharmony_ci	return 0;
180962306a36Sopenharmony_ci
181062306a36Sopenharmony_cierr_icmpmsg_mib:
181162306a36Sopenharmony_ci	free_percpu(net->mib.icmp_statistics);
181262306a36Sopenharmony_cierr_icmp_mib:
181362306a36Sopenharmony_ci	free_percpu(net->mib.udplite_statistics);
181462306a36Sopenharmony_cierr_udplite_mib:
181562306a36Sopenharmony_ci	free_percpu(net->mib.udp_statistics);
181662306a36Sopenharmony_cierr_udp_mib:
181762306a36Sopenharmony_ci	free_percpu(net->mib.net_statistics);
181862306a36Sopenharmony_cierr_net_mib:
181962306a36Sopenharmony_ci	free_percpu(net->mib.ip_statistics);
182062306a36Sopenharmony_cierr_ip_mib:
182162306a36Sopenharmony_ci	free_percpu(net->mib.tcp_statistics);
182262306a36Sopenharmony_cierr_tcp_mib:
182362306a36Sopenharmony_ci	return -ENOMEM;
182462306a36Sopenharmony_ci}
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_cistatic __net_exit void ipv4_mib_exit_net(struct net *net)
182762306a36Sopenharmony_ci{
182862306a36Sopenharmony_ci	kfree(net->mib.icmpmsg_statistics);
182962306a36Sopenharmony_ci	free_percpu(net->mib.icmp_statistics);
183062306a36Sopenharmony_ci	free_percpu(net->mib.udplite_statistics);
183162306a36Sopenharmony_ci	free_percpu(net->mib.udp_statistics);
183262306a36Sopenharmony_ci	free_percpu(net->mib.net_statistics);
183362306a36Sopenharmony_ci	free_percpu(net->mib.ip_statistics);
183462306a36Sopenharmony_ci	free_percpu(net->mib.tcp_statistics);
183562306a36Sopenharmony_ci#ifdef CONFIG_MPTCP
183662306a36Sopenharmony_ci	/* allocated on demand, see mptcp_init_sock() */
183762306a36Sopenharmony_ci	free_percpu(net->mib.mptcp_statistics);
183862306a36Sopenharmony_ci#endif
183962306a36Sopenharmony_ci}
184062306a36Sopenharmony_ci
184162306a36Sopenharmony_cistatic __net_initdata struct pernet_operations ipv4_mib_ops = {
184262306a36Sopenharmony_ci	.init = ipv4_mib_init_net,
184362306a36Sopenharmony_ci	.exit = ipv4_mib_exit_net,
184462306a36Sopenharmony_ci};
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_cistatic int __init init_ipv4_mibs(void)
184762306a36Sopenharmony_ci{
184862306a36Sopenharmony_ci	return register_pernet_subsys(&ipv4_mib_ops);
184962306a36Sopenharmony_ci}
185062306a36Sopenharmony_ci
185162306a36Sopenharmony_cistatic __net_init int inet_init_net(struct net *net)
185262306a36Sopenharmony_ci{
185362306a36Sopenharmony_ci	/*
185462306a36Sopenharmony_ci	 * Set defaults for local port range
185562306a36Sopenharmony_ci	 */
185662306a36Sopenharmony_ci	seqlock_init(&net->ipv4.ip_local_ports.lock);
185762306a36Sopenharmony_ci	net->ipv4.ip_local_ports.range[0] =  32768;
185862306a36Sopenharmony_ci	net->ipv4.ip_local_ports.range[1] =  60999;
185962306a36Sopenharmony_ci
186062306a36Sopenharmony_ci	seqlock_init(&net->ipv4.ping_group_range.lock);
186162306a36Sopenharmony_ci	/*
186262306a36Sopenharmony_ci	 * Sane defaults - nobody may create ping sockets.
186362306a36Sopenharmony_ci	 * Boot scripts should set this to distro-specific group.
186462306a36Sopenharmony_ci	 */
186562306a36Sopenharmony_ci	net->ipv4.ping_group_range.range[0] = make_kgid(&init_user_ns, 1);
186662306a36Sopenharmony_ci	net->ipv4.ping_group_range.range[1] = make_kgid(&init_user_ns, 0);
186762306a36Sopenharmony_ci
186862306a36Sopenharmony_ci	/* Default values for sysctl-controlled parameters.
186962306a36Sopenharmony_ci	 * We set them here, in case sysctl is not compiled.
187062306a36Sopenharmony_ci	 */
187162306a36Sopenharmony_ci	net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
187262306a36Sopenharmony_ci	net->ipv4.sysctl_ip_fwd_update_priority = 1;
187362306a36Sopenharmony_ci	net->ipv4.sysctl_ip_dynaddr = 0;
187462306a36Sopenharmony_ci	net->ipv4.sysctl_ip_early_demux = 1;
187562306a36Sopenharmony_ci	net->ipv4.sysctl_udp_early_demux = 1;
187662306a36Sopenharmony_ci	net->ipv4.sysctl_tcp_early_demux = 1;
187762306a36Sopenharmony_ci	net->ipv4.sysctl_nexthop_compat_mode = 1;
187862306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
187962306a36Sopenharmony_ci	net->ipv4.sysctl_ip_prot_sock = PROT_SOCK;
188062306a36Sopenharmony_ci#endif
188162306a36Sopenharmony_ci
188262306a36Sopenharmony_ci	/* Some igmp sysctl, whose values are always used */
188362306a36Sopenharmony_ci	net->ipv4.sysctl_igmp_max_memberships = 20;
188462306a36Sopenharmony_ci	net->ipv4.sysctl_igmp_max_msf = 10;
188562306a36Sopenharmony_ci	/* IGMP reports for link-local multicast groups are enabled by default */
188662306a36Sopenharmony_ci	net->ipv4.sysctl_igmp_llm_reports = 1;
188762306a36Sopenharmony_ci	net->ipv4.sysctl_igmp_qrv = 2;
188862306a36Sopenharmony_ci
188962306a36Sopenharmony_ci	net->ipv4.sysctl_fib_notify_on_flag_change = 0;
189062306a36Sopenharmony_ci
189162306a36Sopenharmony_ci	return 0;
189262306a36Sopenharmony_ci}
189362306a36Sopenharmony_ci
189462306a36Sopenharmony_cistatic __net_initdata struct pernet_operations af_inet_ops = {
189562306a36Sopenharmony_ci	.init = inet_init_net,
189662306a36Sopenharmony_ci};
189762306a36Sopenharmony_ci
189862306a36Sopenharmony_cistatic int __init init_inet_pernet_ops(void)
189962306a36Sopenharmony_ci{
190062306a36Sopenharmony_ci	return register_pernet_subsys(&af_inet_ops);
190162306a36Sopenharmony_ci}
190262306a36Sopenharmony_ci
190362306a36Sopenharmony_cistatic int ipv4_proc_init(void);
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci/*
190662306a36Sopenharmony_ci *	IP protocol layer initialiser
190762306a36Sopenharmony_ci */
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_cistatic struct packet_offload ip_packet_offload __read_mostly = {
191062306a36Sopenharmony_ci	.type = cpu_to_be16(ETH_P_IP),
191162306a36Sopenharmony_ci	.callbacks = {
191262306a36Sopenharmony_ci		.gso_segment = inet_gso_segment,
191362306a36Sopenharmony_ci		.gro_receive = inet_gro_receive,
191462306a36Sopenharmony_ci		.gro_complete = inet_gro_complete,
191562306a36Sopenharmony_ci	},
191662306a36Sopenharmony_ci};
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_cistatic const struct net_offload ipip_offload = {
191962306a36Sopenharmony_ci	.callbacks = {
192062306a36Sopenharmony_ci		.gso_segment	= ipip_gso_segment,
192162306a36Sopenharmony_ci		.gro_receive	= ipip_gro_receive,
192262306a36Sopenharmony_ci		.gro_complete	= ipip_gro_complete,
192362306a36Sopenharmony_ci	},
192462306a36Sopenharmony_ci};
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_cistatic int __init ipip_offload_init(void)
192762306a36Sopenharmony_ci{
192862306a36Sopenharmony_ci	return inet_add_offload(&ipip_offload, IPPROTO_IPIP);
192962306a36Sopenharmony_ci}
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_cistatic int __init ipv4_offload_init(void)
193262306a36Sopenharmony_ci{
193362306a36Sopenharmony_ci	/*
193462306a36Sopenharmony_ci	 * Add offloads
193562306a36Sopenharmony_ci	 */
193662306a36Sopenharmony_ci	if (udpv4_offload_init() < 0)
193762306a36Sopenharmony_ci		pr_crit("%s: Cannot add UDP protocol offload\n", __func__);
193862306a36Sopenharmony_ci	if (tcpv4_offload_init() < 0)
193962306a36Sopenharmony_ci		pr_crit("%s: Cannot add TCP protocol offload\n", __func__);
194062306a36Sopenharmony_ci	if (ipip_offload_init() < 0)
194162306a36Sopenharmony_ci		pr_crit("%s: Cannot add IPIP protocol offload\n", __func__);
194262306a36Sopenharmony_ci
194362306a36Sopenharmony_ci	dev_add_offload(&ip_packet_offload);
194462306a36Sopenharmony_ci	return 0;
194562306a36Sopenharmony_ci}
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_cifs_initcall(ipv4_offload_init);
194862306a36Sopenharmony_ci
194962306a36Sopenharmony_cistatic struct packet_type ip_packet_type __read_mostly = {
195062306a36Sopenharmony_ci	.type = cpu_to_be16(ETH_P_IP),
195162306a36Sopenharmony_ci	.func = ip_rcv,
195262306a36Sopenharmony_ci	.list_func = ip_list_rcv,
195362306a36Sopenharmony_ci};
195462306a36Sopenharmony_ci
195562306a36Sopenharmony_cistatic int __init inet_init(void)
195662306a36Sopenharmony_ci{
195762306a36Sopenharmony_ci	struct inet_protosw *q;
195862306a36Sopenharmony_ci	struct list_head *r;
195962306a36Sopenharmony_ci	int rc;
196062306a36Sopenharmony_ci
196162306a36Sopenharmony_ci	sock_skb_cb_check_size(sizeof(struct inet_skb_parm));
196262306a36Sopenharmony_ci
196362306a36Sopenharmony_ci	raw_hashinfo_init(&raw_v4_hashinfo);
196462306a36Sopenharmony_ci
196562306a36Sopenharmony_ci	rc = proto_register(&tcp_prot, 1);
196662306a36Sopenharmony_ci	if (rc)
196762306a36Sopenharmony_ci		goto out;
196862306a36Sopenharmony_ci
196962306a36Sopenharmony_ci	rc = proto_register(&udp_prot, 1);
197062306a36Sopenharmony_ci	if (rc)
197162306a36Sopenharmony_ci		goto out_unregister_tcp_proto;
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_ci	rc = proto_register(&raw_prot, 1);
197462306a36Sopenharmony_ci	if (rc)
197562306a36Sopenharmony_ci		goto out_unregister_udp_proto;
197662306a36Sopenharmony_ci
197762306a36Sopenharmony_ci	rc = proto_register(&ping_prot, 1);
197862306a36Sopenharmony_ci	if (rc)
197962306a36Sopenharmony_ci		goto out_unregister_raw_proto;
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci	/*
198262306a36Sopenharmony_ci	 *	Tell SOCKET that we are alive...
198362306a36Sopenharmony_ci	 */
198462306a36Sopenharmony_ci
198562306a36Sopenharmony_ci	(void)sock_register(&inet_family_ops);
198662306a36Sopenharmony_ci
198762306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
198862306a36Sopenharmony_ci	ip_static_sysctl_init();
198962306a36Sopenharmony_ci#endif
199062306a36Sopenharmony_ci
199162306a36Sopenharmony_ci	/*
199262306a36Sopenharmony_ci	 *	Add all the base protocols.
199362306a36Sopenharmony_ci	 */
199462306a36Sopenharmony_ci
199562306a36Sopenharmony_ci	if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)
199662306a36Sopenharmony_ci		pr_crit("%s: Cannot add ICMP protocol\n", __func__);
199762306a36Sopenharmony_ci	if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)
199862306a36Sopenharmony_ci		pr_crit("%s: Cannot add UDP protocol\n", __func__);
199962306a36Sopenharmony_ci	if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)
200062306a36Sopenharmony_ci		pr_crit("%s: Cannot add TCP protocol\n", __func__);
200162306a36Sopenharmony_ci#ifdef CONFIG_IP_MULTICAST
200262306a36Sopenharmony_ci	if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)
200362306a36Sopenharmony_ci		pr_crit("%s: Cannot add IGMP protocol\n", __func__);
200462306a36Sopenharmony_ci#endif
200562306a36Sopenharmony_ci
200662306a36Sopenharmony_ci	/* Register the socket-side information for inet_create. */
200762306a36Sopenharmony_ci	for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)
200862306a36Sopenharmony_ci		INIT_LIST_HEAD(r);
200962306a36Sopenharmony_ci
201062306a36Sopenharmony_ci	for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
201162306a36Sopenharmony_ci		inet_register_protosw(q);
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_ci	/*
201462306a36Sopenharmony_ci	 *	Set the ARP module up
201562306a36Sopenharmony_ci	 */
201662306a36Sopenharmony_ci
201762306a36Sopenharmony_ci	arp_init();
201862306a36Sopenharmony_ci
201962306a36Sopenharmony_ci	/*
202062306a36Sopenharmony_ci	 *	Set the IP module up
202162306a36Sopenharmony_ci	 */
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ci	ip_init();
202462306a36Sopenharmony_ci
202562306a36Sopenharmony_ci	/* Initialise per-cpu ipv4 mibs */
202662306a36Sopenharmony_ci	if (init_ipv4_mibs())
202762306a36Sopenharmony_ci		panic("%s: Cannot init ipv4 mibs\n", __func__);
202862306a36Sopenharmony_ci
202962306a36Sopenharmony_ci	/* Setup TCP slab cache for open requests. */
203062306a36Sopenharmony_ci	tcp_init();
203162306a36Sopenharmony_ci
203262306a36Sopenharmony_ci	/* Setup UDP memory threshold */
203362306a36Sopenharmony_ci	udp_init();
203462306a36Sopenharmony_ci
203562306a36Sopenharmony_ci	/* Add UDP-Lite (RFC 3828) */
203662306a36Sopenharmony_ci	udplite4_register();
203762306a36Sopenharmony_ci
203862306a36Sopenharmony_ci	raw_init();
203962306a36Sopenharmony_ci
204062306a36Sopenharmony_ci	ping_init();
204162306a36Sopenharmony_ci
204262306a36Sopenharmony_ci	/*
204362306a36Sopenharmony_ci	 *	Set the ICMP layer up
204462306a36Sopenharmony_ci	 */
204562306a36Sopenharmony_ci
204662306a36Sopenharmony_ci	if (icmp_init() < 0)
204762306a36Sopenharmony_ci		panic("Failed to create the ICMP control socket.\n");
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_ci	/*
205062306a36Sopenharmony_ci	 *	Initialise the multicast router
205162306a36Sopenharmony_ci	 */
205262306a36Sopenharmony_ci#if defined(CONFIG_IP_MROUTE)
205362306a36Sopenharmony_ci	if (ip_mr_init())
205462306a36Sopenharmony_ci		pr_crit("%s: Cannot init ipv4 mroute\n", __func__);
205562306a36Sopenharmony_ci#endif
205662306a36Sopenharmony_ci
205762306a36Sopenharmony_ci	if (init_inet_pernet_ops())
205862306a36Sopenharmony_ci		pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__);
205962306a36Sopenharmony_ci
206062306a36Sopenharmony_ci	ipv4_proc_init();
206162306a36Sopenharmony_ci
206262306a36Sopenharmony_ci	ipfrag_init();
206362306a36Sopenharmony_ci
206462306a36Sopenharmony_ci	dev_add_pack(&ip_packet_type);
206562306a36Sopenharmony_ci
206662306a36Sopenharmony_ci	ip_tunnel_core_init();
206762306a36Sopenharmony_ci
206862306a36Sopenharmony_ci	rc = 0;
206962306a36Sopenharmony_ciout:
207062306a36Sopenharmony_ci	return rc;
207162306a36Sopenharmony_ciout_unregister_raw_proto:
207262306a36Sopenharmony_ci	proto_unregister(&raw_prot);
207362306a36Sopenharmony_ciout_unregister_udp_proto:
207462306a36Sopenharmony_ci	proto_unregister(&udp_prot);
207562306a36Sopenharmony_ciout_unregister_tcp_proto:
207662306a36Sopenharmony_ci	proto_unregister(&tcp_prot);
207762306a36Sopenharmony_ci	goto out;
207862306a36Sopenharmony_ci}
207962306a36Sopenharmony_ci
208062306a36Sopenharmony_cifs_initcall(inet_init);
208162306a36Sopenharmony_ci
208262306a36Sopenharmony_ci/* ------------------------------------------------------------------------ */
208362306a36Sopenharmony_ci
208462306a36Sopenharmony_ci#ifdef CONFIG_PROC_FS
208562306a36Sopenharmony_cistatic int __init ipv4_proc_init(void)
208662306a36Sopenharmony_ci{
208762306a36Sopenharmony_ci	int rc = 0;
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci	if (raw_proc_init())
209062306a36Sopenharmony_ci		goto out_raw;
209162306a36Sopenharmony_ci	if (tcp4_proc_init())
209262306a36Sopenharmony_ci		goto out_tcp;
209362306a36Sopenharmony_ci	if (udp4_proc_init())
209462306a36Sopenharmony_ci		goto out_udp;
209562306a36Sopenharmony_ci	if (ping_proc_init())
209662306a36Sopenharmony_ci		goto out_ping;
209762306a36Sopenharmony_ci	if (ip_misc_proc_init())
209862306a36Sopenharmony_ci		goto out_misc;
209962306a36Sopenharmony_ciout:
210062306a36Sopenharmony_ci	return rc;
210162306a36Sopenharmony_ciout_misc:
210262306a36Sopenharmony_ci	ping_proc_exit();
210362306a36Sopenharmony_ciout_ping:
210462306a36Sopenharmony_ci	udp4_proc_exit();
210562306a36Sopenharmony_ciout_udp:
210662306a36Sopenharmony_ci	tcp4_proc_exit();
210762306a36Sopenharmony_ciout_tcp:
210862306a36Sopenharmony_ci	raw_proc_exit();
210962306a36Sopenharmony_ciout_raw:
211062306a36Sopenharmony_ci	rc = -ENOMEM;
211162306a36Sopenharmony_ci	goto out;
211262306a36Sopenharmony_ci}
211362306a36Sopenharmony_ci
211462306a36Sopenharmony_ci#else /* CONFIG_PROC_FS */
211562306a36Sopenharmony_cistatic int __init ipv4_proc_init(void)
211662306a36Sopenharmony_ci{
211762306a36Sopenharmony_ci	return 0;
211862306a36Sopenharmony_ci}
211962306a36Sopenharmony_ci#endif /* CONFIG_PROC_FS */
2120