linux/net/ipv6/tcp_ipv6.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	TCP over IPv6
 *	Linux INET6 implementation
 *
 *	Authors:
 *	Pedro Roque		<[email protected]>
 *
 *	Based on:
 *	linux/net/ipv4/tcp.c
 *	linux/net/ipv4/tcp_input.c
 *	linux/net/ipv4/tcp_output.c
 *
 *	Fixes:
 *	Hideaki YOSHIFUJI	:	sin6_scope_id support
 *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
 *	Alexey Kuznetsov		allow both IPv4 and IPv6 sockets to bind
 *					a single port at the same time.
 *	YOSHIFUJI Hideaki @USAGI:	convert /proc/net/tcp6 to seq_file.
 */

#include <linux/bottom_half.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/jiffies.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/netdevice.h>
#include <linux/init.h>
#include <linux/jhash.h>
#include <linux/ipsec.h>
#include <linux/times.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/random.h>
#include <linux/indirect_call_wrapper.h>

#include <net/tcp.h>
#include <net/ndisc.h>
#include <net/inet6_hashtables.h>
#include <net/inet6_connection_sock.h>
#include <net/ipv6.h>
#include <net/transp_v6.h>
#include <net/addrconf.h>
#include <net/ip6_route.h>
#include <net/ip6_checksum.h>
#include <net/inet_ecn.h>
#include <net/protocol.h>
#include <net/xfrm.h>
#include <net/snmp.h>
#include <net/dsfield.h>
#include <net/timewait_sock.h>
#include <net/inet_common.h>
#include <net/secure_seq.h>
#include <net/hotdata.h>
#include <net/busy_poll.h>
#include <net/rstreason.h>

#include <linux/proc_fs.h>
#include <linux/seq_file.h>

#include <crypto/hash.h>
#include <linux/scatterlist.h>

#include <trace/events/tcp.h>

static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb,
			      enum sk_rst_reason reason);
static void	tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
				      struct request_sock *req);

INDIRECT_CALLABLE_SCOPE int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);

static const struct inet_connection_sock_af_ops ipv6_mapped;
const struct inet_connection_sock_af_ops ipv6_specific;
#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
static const struct tcp_sock_af_ops tcp_sock_ipv6_specific;
static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
#endif

/* Helper returning the inet6 address from a given tcp socket.
 * It can be used in TCP stack instead of inet6_sk(sk).
 * This avoids a dereference and allow compiler optimizations.
 * It is a specialized version of inet6_sk_generic().
 */
#define tcp_inet6_sk(sk)

static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
{}

static u32 tcp_v6_init_seq(const struct sk_buff *skb)
{}

static u32 tcp_v6_init_ts_off(const struct net *net, const struct sk_buff *skb)
{}

static int tcp_v6_pre_connect(struct sock *sk, struct sockaddr *uaddr,
			      int addr_len)
{}

static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
			  int addr_len)
{}

static void tcp_v6_mtu_reduced(struct sock *sk)
{}

static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
		u8 type, u8 code, int offset, __be32 info)
{}


static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
			      struct flowi *fl,
			      struct request_sock *req,
			      struct tcp_fastopen_cookie *foc,
			      enum tcp_synack_type synack_type,
			      struct sk_buff *syn_skb)
{}


static void tcp_v6_reqsk_destructor(struct request_sock *req)
{}

#ifdef CONFIG_TCP_MD5SIG
static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(const struct sock *sk,
						   const struct in6_addr *addr,
						   int l3index)
{}

static struct tcp_md5sig_key *tcp_v6_md5_lookup(const struct sock *sk,
						const struct sock *addr_sk)
{}

static int tcp_v6_parse_md5_keys(struct sock *sk, int optname,
				 sockptr_t optval, int optlen)
{}

static int tcp_v6_md5_hash_headers(struct tcp_sigpool *hp,
				   const struct in6_addr *daddr,
				   const struct in6_addr *saddr,
				   const struct tcphdr *th, int nbytes)
{}

static int tcp_v6_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
			       const struct in6_addr *daddr, struct in6_addr *saddr,
			       const struct tcphdr *th)
{}

static int tcp_v6_md5_hash_skb(char *md5_hash,
			       const struct tcp_md5sig_key *key,
			       const struct sock *sk,
			       const struct sk_buff *skb)
{}
#endif

static void tcp_v6_init_req(struct request_sock *req,
			    const struct sock *sk_listener,
			    struct sk_buff *skb,
			    u32 tw_isn)
{}

static struct dst_entry *tcp_v6_route_req(const struct sock *sk,
					  struct sk_buff *skb,
					  struct flowi *fl,
					  struct request_sock *req,
					  u32 tw_isn)
{}

struct request_sock_ops tcp6_request_sock_ops __read_mostly =;

const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops =;

static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq,
				 u32 ack, u32 win, u32 tsval, u32 tsecr,
				 int oif, int rst, u8 tclass, __be32 label,
				 u32 priority, u32 txhash, struct tcp_key *key)
{}

static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb,
			      enum sk_rst_reason reason)
{}

static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq,
			    u32 ack, u32 win, u32 tsval, u32 tsecr, int oif,
			    struct tcp_key *key, u8 tclass,
			    __be32 label, u32 priority, u32 txhash)
{}

static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
{}

static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
				  struct request_sock *req)
{}


static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb)
{}

u16 tcp_v6_get_syncookie(struct sock *sk, struct ipv6hdr *iph,
			 struct tcphdr *th, u32 *cookie)
{}

static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
{}

static void tcp_v6_restore_cb(struct sk_buff *skb)
{}

static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
					 struct request_sock *req,
					 struct dst_entry *dst,
					 struct request_sock *req_unhash,
					 bool *own_req)
{}

INDIRECT_CALLABLE_DECLARE();
/* The socket must have it's spinlock held when we get
 * here, unless it is a TCP_LISTEN socket.
 *
 * We have a potential double-lock case here, so even when
 * doing backlog processing we use the BH locking scheme.
 * This is because we cannot sleep with the original spinlock
 * held.
 */
INDIRECT_CALLABLE_SCOPE
int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
{}

static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
			   const struct tcphdr *th)
{}

INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
{}

void tcp_v6_early_demux(struct sk_buff *skb)
{}

static struct timewait_sock_ops tcp6_timewait_sock_ops =;

INDIRECT_CALLABLE_SCOPE void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
{}

const struct inet_connection_sock_af_ops ipv6_specific =;

#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
static const struct tcp_sock_af_ops tcp_sock_ipv6_specific =;
#endif

/*
 *	TCP over IPv4 via INET6 API
 */
static const struct inet_connection_sock_af_ops ipv6_mapped =;

#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific =;
#endif

/* NOTE: A lot of things set to zero explicitly by call to
 *       sk_alloc() so need not be done here.
 */
static int tcp_v6_init_sock(struct sock *sk)
{}

#ifdef CONFIG_PROC_FS
/* Proc filesystem TCPv6 sock list dumping. */
static void get_openreq6(struct seq_file *seq,
			 const struct request_sock *req, int i)
{}

static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
{}

static void get_timewait6_sock(struct seq_file *seq,
			       struct inet_timewait_sock *tw, int i)
{}

static int tcp6_seq_show(struct seq_file *seq, void *v)
{}

static const struct seq_operations tcp6_seq_ops =;

static struct tcp_seq_afinfo tcp6_seq_afinfo =;

int __net_init tcp6_proc_init(struct net *net)
{}

void tcp6_proc_exit(struct net *net)
{}
#endif

struct proto tcpv6_prot =;
EXPORT_SYMBOL_GPL();


static struct inet_protosw tcpv6_protosw =;

static int __net_init tcpv6_net_init(struct net *net)
{}

static void __net_exit tcpv6_net_exit(struct net *net)
{}

static struct pernet_operations tcpv6_net_ops =;

int __init tcpv6_init(void)
{}

void tcpv6_exit(void)
{}