xref: /linux/include/net/tcp.h (revision 2e6599cb899ba4b133f42cbf9d2b1883d2dc583a)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * INET		An implementation of the TCP/IP protocol suite for the LINUX
31da177e4SLinus Torvalds  *		operating system.  INET is implemented using the  BSD Socket
41da177e4SLinus Torvalds  *		interface as the means of communication with the user level.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *		Definitions for the TCP module.
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Version:	@(#)tcp.h	1.0.5	05/23/93
91da177e4SLinus Torvalds  *
1002c30a84SJesper Juhl  * Authors:	Ross Biro
111da177e4SLinus Torvalds  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
121da177e4SLinus Torvalds  *
131da177e4SLinus Torvalds  *		This program is free software; you can redistribute it and/or
141da177e4SLinus Torvalds  *		modify it under the terms of the GNU General Public License
151da177e4SLinus Torvalds  *		as published by the Free Software Foundation; either version
161da177e4SLinus Torvalds  *		2 of the License, or (at your option) any later version.
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds #ifndef _TCP_H
191da177e4SLinus Torvalds #define _TCP_H
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds #define TCP_DEBUG 1
221da177e4SLinus Torvalds #define FASTRETRANS_DEBUG 1
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds /* Cancel timers, when they are not required. */
251da177e4SLinus Torvalds #undef TCP_CLEAR_TIMERS
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds #include <linux/config.h>
281da177e4SLinus Torvalds #include <linux/list.h>
291da177e4SLinus Torvalds #include <linux/tcp.h>
301da177e4SLinus Torvalds #include <linux/slab.h>
311da177e4SLinus Torvalds #include <linux/cache.h>
321da177e4SLinus Torvalds #include <linux/percpu.h>
331da177e4SLinus Torvalds #include <net/checksum.h>
34*2e6599cbSArnaldo Carvalho de Melo #include <net/request_sock.h>
351da177e4SLinus Torvalds #include <net/sock.h>
361da177e4SLinus Torvalds #include <net/snmp.h>
371da177e4SLinus Torvalds #include <net/ip.h>
381da177e4SLinus Torvalds #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
391da177e4SLinus Torvalds #include <linux/ipv6.h>
401da177e4SLinus Torvalds #endif
411da177e4SLinus Torvalds #include <linux/seq_file.h>
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds /* This is for all connections with a full identity, no wildcards.
441da177e4SLinus Torvalds  * New scheme, half the table is for TIME_WAIT, the other half is
451da177e4SLinus Torvalds  * for the rest.  I'll experiment with dynamic table growth later.
461da177e4SLinus Torvalds  */
471da177e4SLinus Torvalds struct tcp_ehash_bucket {
481da177e4SLinus Torvalds 	rwlock_t	  lock;
491da177e4SLinus Torvalds 	struct hlist_head chain;
501da177e4SLinus Torvalds } __attribute__((__aligned__(8)));
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds /* This is for listening sockets, thus all sockets which possess wildcards. */
531da177e4SLinus Torvalds #define TCP_LHTABLE_SIZE	32	/* Yes, really, this is all you need. */
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds /* There are a few simple rules, which allow for local port reuse by
561da177e4SLinus Torvalds  * an application.  In essence:
571da177e4SLinus Torvalds  *
581da177e4SLinus Torvalds  *	1) Sockets bound to different interfaces may share a local port.
591da177e4SLinus Torvalds  *	   Failing that, goto test 2.
601da177e4SLinus Torvalds  *	2) If all sockets have sk->sk_reuse set, and none of them are in
611da177e4SLinus Torvalds  *	   TCP_LISTEN state, the port may be shared.
621da177e4SLinus Torvalds  *	   Failing that, goto test 3.
631da177e4SLinus Torvalds  *	3) If all sockets are bound to a specific inet_sk(sk)->rcv_saddr local
641da177e4SLinus Torvalds  *	   address, and none of them are the same, the port may be
651da177e4SLinus Torvalds  *	   shared.
661da177e4SLinus Torvalds  *	   Failing this, the port cannot be shared.
671da177e4SLinus Torvalds  *
681da177e4SLinus Torvalds  * The interesting point, is test #2.  This is what an FTP server does
691da177e4SLinus Torvalds  * all day.  To optimize this case we use a specific flag bit defined
701da177e4SLinus Torvalds  * below.  As we add sockets to a bind bucket list, we perform a
711da177e4SLinus Torvalds  * check of: (newsk->sk_reuse && (newsk->sk_state != TCP_LISTEN))
721da177e4SLinus Torvalds  * As long as all sockets added to a bind bucket pass this test,
731da177e4SLinus Torvalds  * the flag bit will be set.
741da177e4SLinus Torvalds  * The resulting situation is that tcp_v[46]_verify_bind() can just check
751da177e4SLinus Torvalds  * for this flag bit, if it is set and the socket trying to bind has
761da177e4SLinus Torvalds  * sk->sk_reuse set, we don't even have to walk the owners list at all,
771da177e4SLinus Torvalds  * we return that it is ok to bind this socket to the requested local port.
781da177e4SLinus Torvalds  *
791da177e4SLinus Torvalds  * Sounds like a lot of work, but it is worth it.  In a more naive
801da177e4SLinus Torvalds  * implementation (ie. current FreeBSD etc.) the entire list of ports
811da177e4SLinus Torvalds  * must be walked for each data port opened by an ftp server.  Needless
821da177e4SLinus Torvalds  * to say, this does not scale at all.  With a couple thousand FTP
831da177e4SLinus Torvalds  * users logged onto your box, isn't it nice to know that new data
841da177e4SLinus Torvalds  * ports are created in O(1) time?  I thought so. ;-)	-DaveM
851da177e4SLinus Torvalds  */
861da177e4SLinus Torvalds struct tcp_bind_bucket {
871da177e4SLinus Torvalds 	unsigned short		port;
881da177e4SLinus Torvalds 	signed short		fastreuse;
891da177e4SLinus Torvalds 	struct hlist_node	node;
901da177e4SLinus Torvalds 	struct hlist_head	owners;
911da177e4SLinus Torvalds };
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds #define tb_for_each(tb, node, head) hlist_for_each_entry(tb, node, head, node)
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds struct tcp_bind_hashbucket {
961da177e4SLinus Torvalds 	spinlock_t		lock;
971da177e4SLinus Torvalds 	struct hlist_head	chain;
981da177e4SLinus Torvalds };
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds static inline struct tcp_bind_bucket *__tb_head(struct tcp_bind_hashbucket *head)
1011da177e4SLinus Torvalds {
1021da177e4SLinus Torvalds 	return hlist_entry(head->chain.first, struct tcp_bind_bucket, node);
1031da177e4SLinus Torvalds }
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds static inline struct tcp_bind_bucket *tb_head(struct tcp_bind_hashbucket *head)
1061da177e4SLinus Torvalds {
1071da177e4SLinus Torvalds 	return hlist_empty(&head->chain) ? NULL : __tb_head(head);
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds extern struct tcp_hashinfo {
1111da177e4SLinus Torvalds 	/* This is for sockets with full identity only.  Sockets here will
1121da177e4SLinus Torvalds 	 * always be without wildcards and will have the following invariant:
1131da177e4SLinus Torvalds 	 *
1141da177e4SLinus Torvalds 	 *          TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE
1151da177e4SLinus Torvalds 	 *
1161da177e4SLinus Torvalds 	 * First half of the table is for sockets not in TIME_WAIT, second half
1171da177e4SLinus Torvalds 	 * is for TIME_WAIT sockets only.
1181da177e4SLinus Torvalds 	 */
1191da177e4SLinus Torvalds 	struct tcp_ehash_bucket *__tcp_ehash;
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	/* Ok, let's try this, I give up, we do need a local binding
1221da177e4SLinus Torvalds 	 * TCP hash as well as the others for fast bind/connect.
1231da177e4SLinus Torvalds 	 */
1241da177e4SLinus Torvalds 	struct tcp_bind_hashbucket *__tcp_bhash;
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds 	int __tcp_bhash_size;
1271da177e4SLinus Torvalds 	int __tcp_ehash_size;
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 	/* All sockets in TCP_LISTEN state will be in here.  This is the only
1301da177e4SLinus Torvalds 	 * table where wildcard'd TCP sockets can exist.  Hash function here
1311da177e4SLinus Torvalds 	 * is just local port number.
1321da177e4SLinus Torvalds 	 */
1331da177e4SLinus Torvalds 	struct hlist_head __tcp_listening_hash[TCP_LHTABLE_SIZE];
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	/* All the above members are written once at bootup and
1361da177e4SLinus Torvalds 	 * never written again _or_ are predominantly read-access.
1371da177e4SLinus Torvalds 	 *
1381da177e4SLinus Torvalds 	 * Now align to a new cache line as all the following members
1391da177e4SLinus Torvalds 	 * are often dirty.
1401da177e4SLinus Torvalds 	 */
1411da177e4SLinus Torvalds 	rwlock_t __tcp_lhash_lock ____cacheline_aligned;
1421da177e4SLinus Torvalds 	atomic_t __tcp_lhash_users;
1431da177e4SLinus Torvalds 	wait_queue_head_t __tcp_lhash_wait;
1441da177e4SLinus Torvalds 	spinlock_t __tcp_portalloc_lock;
1451da177e4SLinus Torvalds } tcp_hashinfo;
1461da177e4SLinus Torvalds 
1471da177e4SLinus Torvalds #define tcp_ehash	(tcp_hashinfo.__tcp_ehash)
1481da177e4SLinus Torvalds #define tcp_bhash	(tcp_hashinfo.__tcp_bhash)
1491da177e4SLinus Torvalds #define tcp_ehash_size	(tcp_hashinfo.__tcp_ehash_size)
1501da177e4SLinus Torvalds #define tcp_bhash_size	(tcp_hashinfo.__tcp_bhash_size)
1511da177e4SLinus Torvalds #define tcp_listening_hash (tcp_hashinfo.__tcp_listening_hash)
1521da177e4SLinus Torvalds #define tcp_lhash_lock	(tcp_hashinfo.__tcp_lhash_lock)
1531da177e4SLinus Torvalds #define tcp_lhash_users	(tcp_hashinfo.__tcp_lhash_users)
1541da177e4SLinus Torvalds #define tcp_lhash_wait	(tcp_hashinfo.__tcp_lhash_wait)
1551da177e4SLinus Torvalds #define tcp_portalloc_lock (tcp_hashinfo.__tcp_portalloc_lock)
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds extern kmem_cache_t *tcp_bucket_cachep;
1581da177e4SLinus Torvalds extern struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head,
1591da177e4SLinus Torvalds 						 unsigned short snum);
1601da177e4SLinus Torvalds extern void tcp_bucket_destroy(struct tcp_bind_bucket *tb);
1611da177e4SLinus Torvalds extern void tcp_bucket_unlock(struct sock *sk);
1621da177e4SLinus Torvalds extern int tcp_port_rover;
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds /* These are AF independent. */
1651da177e4SLinus Torvalds static __inline__ int tcp_bhashfn(__u16 lport)
1661da177e4SLinus Torvalds {
1671da177e4SLinus Torvalds 	return (lport & (tcp_bhash_size - 1));
1681da177e4SLinus Torvalds }
1691da177e4SLinus Torvalds 
1701da177e4SLinus Torvalds extern void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb,
1711da177e4SLinus Torvalds 			  unsigned short snum);
1721da177e4SLinus Torvalds 
1731da177e4SLinus Torvalds #if (BITS_PER_LONG == 64)
1741da177e4SLinus Torvalds #define TCP_ADDRCMP_ALIGN_BYTES 8
1751da177e4SLinus Torvalds #else
1761da177e4SLinus Torvalds #define TCP_ADDRCMP_ALIGN_BYTES 4
1771da177e4SLinus Torvalds #endif
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds /* This is a TIME_WAIT bucket.  It works around the memory consumption
1801da177e4SLinus Torvalds  * problems of sockets in such a state on heavily loaded servers, but
1811da177e4SLinus Torvalds  * without violating the protocol specification.
1821da177e4SLinus Torvalds  */
1831da177e4SLinus Torvalds struct tcp_tw_bucket {
1841da177e4SLinus Torvalds 	/*
1851da177e4SLinus Torvalds 	 * Now struct sock also uses sock_common, so please just
1861da177e4SLinus Torvalds 	 * don't add nothing before this first member (__tw_common) --acme
1871da177e4SLinus Torvalds 	 */
1881da177e4SLinus Torvalds 	struct sock_common	__tw_common;
1891da177e4SLinus Torvalds #define tw_family		__tw_common.skc_family
1901da177e4SLinus Torvalds #define tw_state		__tw_common.skc_state
1911da177e4SLinus Torvalds #define tw_reuse		__tw_common.skc_reuse
1921da177e4SLinus Torvalds #define tw_bound_dev_if		__tw_common.skc_bound_dev_if
1931da177e4SLinus Torvalds #define tw_node			__tw_common.skc_node
1941da177e4SLinus Torvalds #define tw_bind_node		__tw_common.skc_bind_node
1951da177e4SLinus Torvalds #define tw_refcnt		__tw_common.skc_refcnt
1961da177e4SLinus Torvalds 	volatile unsigned char	tw_substate;
1971da177e4SLinus Torvalds 	unsigned char		tw_rcv_wscale;
1981da177e4SLinus Torvalds 	__u16			tw_sport;
1991da177e4SLinus Torvalds 	/* Socket demultiplex comparisons on incoming packets. */
2001da177e4SLinus Torvalds 	/* these five are in inet_sock */
2011da177e4SLinus Torvalds 	__u32			tw_daddr
2021da177e4SLinus Torvalds 		__attribute__((aligned(TCP_ADDRCMP_ALIGN_BYTES)));
2031da177e4SLinus Torvalds 	__u32			tw_rcv_saddr;
2041da177e4SLinus Torvalds 	__u16			tw_dport;
2051da177e4SLinus Torvalds 	__u16			tw_num;
2061da177e4SLinus Torvalds 	/* And these are ours. */
2071da177e4SLinus Torvalds 	int			tw_hashent;
2081da177e4SLinus Torvalds 	int			tw_timeout;
2091da177e4SLinus Torvalds 	__u32			tw_rcv_nxt;
2101da177e4SLinus Torvalds 	__u32			tw_snd_nxt;
2111da177e4SLinus Torvalds 	__u32			tw_rcv_wnd;
2121da177e4SLinus Torvalds 	__u32			tw_ts_recent;
2131da177e4SLinus Torvalds 	long			tw_ts_recent_stamp;
2141da177e4SLinus Torvalds 	unsigned long		tw_ttd;
2151da177e4SLinus Torvalds 	struct tcp_bind_bucket	*tw_tb;
2161da177e4SLinus Torvalds 	struct hlist_node	tw_death_node;
2171da177e4SLinus Torvalds #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2181da177e4SLinus Torvalds 	struct in6_addr		tw_v6_daddr;
2191da177e4SLinus Torvalds 	struct in6_addr		tw_v6_rcv_saddr;
2201da177e4SLinus Torvalds 	int			tw_v6_ipv6only;
2211da177e4SLinus Torvalds #endif
2221da177e4SLinus Torvalds };
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds static __inline__ void tw_add_node(struct tcp_tw_bucket *tw,
2251da177e4SLinus Torvalds 				   struct hlist_head *list)
2261da177e4SLinus Torvalds {
2271da177e4SLinus Torvalds 	hlist_add_head(&tw->tw_node, list);
2281da177e4SLinus Torvalds }
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds static __inline__ void tw_add_bind_node(struct tcp_tw_bucket *tw,
2311da177e4SLinus Torvalds 					struct hlist_head *list)
2321da177e4SLinus Torvalds {
2331da177e4SLinus Torvalds 	hlist_add_head(&tw->tw_bind_node, list);
2341da177e4SLinus Torvalds }
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds static inline int tw_dead_hashed(struct tcp_tw_bucket *tw)
2371da177e4SLinus Torvalds {
2381da177e4SLinus Torvalds 	return tw->tw_death_node.pprev != NULL;
2391da177e4SLinus Torvalds }
2401da177e4SLinus Torvalds 
2411da177e4SLinus Torvalds static __inline__ void tw_dead_node_init(struct tcp_tw_bucket *tw)
2421da177e4SLinus Torvalds {
2431da177e4SLinus Torvalds 	tw->tw_death_node.pprev = NULL;
2441da177e4SLinus Torvalds }
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds static __inline__ void __tw_del_dead_node(struct tcp_tw_bucket *tw)
2471da177e4SLinus Torvalds {
2481da177e4SLinus Torvalds 	__hlist_del(&tw->tw_death_node);
2491da177e4SLinus Torvalds 	tw_dead_node_init(tw);
2501da177e4SLinus Torvalds }
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds static __inline__ int tw_del_dead_node(struct tcp_tw_bucket *tw)
2531da177e4SLinus Torvalds {
2541da177e4SLinus Torvalds 	if (tw_dead_hashed(tw)) {
2551da177e4SLinus Torvalds 		__tw_del_dead_node(tw);
2561da177e4SLinus Torvalds 		return 1;
2571da177e4SLinus Torvalds 	}
2581da177e4SLinus Torvalds 	return 0;
2591da177e4SLinus Torvalds }
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds #define tw_for_each(tw, node, head) \
2621da177e4SLinus Torvalds 	hlist_for_each_entry(tw, node, head, tw_node)
2631da177e4SLinus Torvalds 
2641da177e4SLinus Torvalds #define tw_for_each_inmate(tw, node, jail) \
2651da177e4SLinus Torvalds 	hlist_for_each_entry(tw, node, jail, tw_death_node)
2661da177e4SLinus Torvalds 
2671da177e4SLinus Torvalds #define tw_for_each_inmate_safe(tw, node, safe, jail) \
2681da177e4SLinus Torvalds 	hlist_for_each_entry_safe(tw, node, safe, jail, tw_death_node)
2691da177e4SLinus Torvalds 
2701da177e4SLinus Torvalds #define tcptw_sk(__sk)	((struct tcp_tw_bucket *)(__sk))
2711da177e4SLinus Torvalds 
2721da177e4SLinus Torvalds static inline u32 tcp_v4_rcv_saddr(const struct sock *sk)
2731da177e4SLinus Torvalds {
2741da177e4SLinus Torvalds 	return likely(sk->sk_state != TCP_TIME_WAIT) ?
2751da177e4SLinus Torvalds 		inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr;
2761da177e4SLinus Torvalds }
2771da177e4SLinus Torvalds 
2781da177e4SLinus Torvalds #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2791da177e4SLinus Torvalds static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
2801da177e4SLinus Torvalds {
2811da177e4SLinus Torvalds 	return likely(sk->sk_state != TCP_TIME_WAIT) ?
2821da177e4SLinus Torvalds 		&inet6_sk(sk)->rcv_saddr : &tcptw_sk(sk)->tw_v6_rcv_saddr;
2831da177e4SLinus Torvalds }
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
2861da177e4SLinus Torvalds {
2871da177e4SLinus Torvalds 	return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
2881da177e4SLinus Torvalds }
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds #define tcptw_sk_ipv6only(__sk)	(tcptw_sk(__sk)->tw_v6_ipv6only)
2911da177e4SLinus Torvalds 
2921da177e4SLinus Torvalds static inline int tcp_v6_ipv6only(const struct sock *sk)
2931da177e4SLinus Torvalds {
2941da177e4SLinus Torvalds 	return likely(sk->sk_state != TCP_TIME_WAIT) ?
2951da177e4SLinus Torvalds 		ipv6_only_sock(sk) : tcptw_sk_ipv6only(sk);
2961da177e4SLinus Torvalds }
2971da177e4SLinus Torvalds #else
2981da177e4SLinus Torvalds # define __tcp_v6_rcv_saddr(__sk)	NULL
2991da177e4SLinus Torvalds # define tcp_v6_rcv_saddr(__sk)		NULL
3001da177e4SLinus Torvalds # define tcptw_sk_ipv6only(__sk)	0
3011da177e4SLinus Torvalds # define tcp_v6_ipv6only(__sk)		0
3021da177e4SLinus Torvalds #endif
3031da177e4SLinus Torvalds 
3041da177e4SLinus Torvalds extern kmem_cache_t *tcp_timewait_cachep;
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds static inline void tcp_tw_put(struct tcp_tw_bucket *tw)
3071da177e4SLinus Torvalds {
3081da177e4SLinus Torvalds 	if (atomic_dec_and_test(&tw->tw_refcnt)) {
3091da177e4SLinus Torvalds #ifdef INET_REFCNT_DEBUG
3101da177e4SLinus Torvalds 		printk(KERN_DEBUG "tw_bucket %p released\n", tw);
3111da177e4SLinus Torvalds #endif
3121da177e4SLinus Torvalds 		kmem_cache_free(tcp_timewait_cachep, tw);
3131da177e4SLinus Torvalds 	}
3141da177e4SLinus Torvalds }
3151da177e4SLinus Torvalds 
3161da177e4SLinus Torvalds extern atomic_t tcp_orphan_count;
3171da177e4SLinus Torvalds extern int tcp_tw_count;
3181da177e4SLinus Torvalds extern void tcp_time_wait(struct sock *sk, int state, int timeo);
3191da177e4SLinus Torvalds extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw);
3201da177e4SLinus Torvalds 
3211da177e4SLinus Torvalds 
3221da177e4SLinus Torvalds /* Socket demux engine toys. */
3231da177e4SLinus Torvalds #ifdef __BIG_ENDIAN
3241da177e4SLinus Torvalds #define TCP_COMBINED_PORTS(__sport, __dport) \
3251da177e4SLinus Torvalds 	(((__u32)(__sport)<<16) | (__u32)(__dport))
3261da177e4SLinus Torvalds #else /* __LITTLE_ENDIAN */
3271da177e4SLinus Torvalds #define TCP_COMBINED_PORTS(__sport, __dport) \
3281da177e4SLinus Torvalds 	(((__u32)(__dport)<<16) | (__u32)(__sport))
3291da177e4SLinus Torvalds #endif
3301da177e4SLinus Torvalds 
3311da177e4SLinus Torvalds #if (BITS_PER_LONG == 64)
3321da177e4SLinus Torvalds #ifdef __BIG_ENDIAN
3331da177e4SLinus Torvalds #define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \
3341da177e4SLinus Torvalds 	__u64 __name = (((__u64)(__saddr))<<32)|((__u64)(__daddr));
3351da177e4SLinus Torvalds #else /* __LITTLE_ENDIAN */
3361da177e4SLinus Torvalds #define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \
3371da177e4SLinus Torvalds 	__u64 __name = (((__u64)(__daddr))<<32)|((__u64)(__saddr));
3381da177e4SLinus Torvalds #endif /* __BIG_ENDIAN */
3391da177e4SLinus Torvalds #define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\
3401da177e4SLinus Torvalds 	(((*((__u64 *)&(inet_sk(__sk)->daddr)))== (__cookie))	&&	\
3411da177e4SLinus Torvalds 	 ((*((__u32 *)&(inet_sk(__sk)->dport)))== (__ports))	&&	\
3421da177e4SLinus Torvalds 	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3431da177e4SLinus Torvalds #define TCP_IPV4_TW_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\
3441da177e4SLinus Torvalds 	(((*((__u64 *)&(tcptw_sk(__sk)->tw_daddr))) == (__cookie)) &&	\
3451da177e4SLinus Torvalds 	 ((*((__u32 *)&(tcptw_sk(__sk)->tw_dport))) == (__ports)) &&	\
3461da177e4SLinus Torvalds 	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3471da177e4SLinus Torvalds #else /* 32-bit arch */
3481da177e4SLinus Torvalds #define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr)
3491da177e4SLinus Torvalds #define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\
3501da177e4SLinus Torvalds 	((inet_sk(__sk)->daddr			== (__saddr))	&&	\
3511da177e4SLinus Torvalds 	 (inet_sk(__sk)->rcv_saddr		== (__daddr))	&&	\
3521da177e4SLinus Torvalds 	 ((*((__u32 *)&(inet_sk(__sk)->dport)))== (__ports))	&&	\
3531da177e4SLinus Torvalds 	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3541da177e4SLinus Torvalds #define TCP_IPV4_TW_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\
3551da177e4SLinus Torvalds 	((tcptw_sk(__sk)->tw_daddr		== (__saddr))	&&	\
3561da177e4SLinus Torvalds 	 (tcptw_sk(__sk)->tw_rcv_saddr		== (__daddr))	&&	\
3571da177e4SLinus Torvalds 	 ((*((__u32 *)&(tcptw_sk(__sk)->tw_dport))) == (__ports)) &&	\
3581da177e4SLinus Torvalds 	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3591da177e4SLinus Torvalds #endif /* 64-bit arch */
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds #define TCP_IPV6_MATCH(__sk, __saddr, __daddr, __ports, __dif)	   \
3621da177e4SLinus Torvalds 	(((*((__u32 *)&(inet_sk(__sk)->dport)))== (__ports))   	&& \
3631da177e4SLinus Torvalds 	 ((__sk)->sk_family		== AF_INET6)		&& \
3641da177e4SLinus Torvalds 	 ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr))	&& \
3651da177e4SLinus Torvalds 	 ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr))	&& \
3661da177e4SLinus Torvalds 	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds /* These can have wildcards, don't try too hard. */
3691da177e4SLinus Torvalds static __inline__ int tcp_lhashfn(unsigned short num)
3701da177e4SLinus Torvalds {
3711da177e4SLinus Torvalds 	return num & (TCP_LHTABLE_SIZE - 1);
3721da177e4SLinus Torvalds }
3731da177e4SLinus Torvalds 
3741da177e4SLinus Torvalds static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
3751da177e4SLinus Torvalds {
3761da177e4SLinus Torvalds 	return tcp_lhashfn(inet_sk(sk)->num);
3771da177e4SLinus Torvalds }
3781da177e4SLinus Torvalds 
3791da177e4SLinus Torvalds #define MAX_TCP_HEADER	(128 + MAX_HEADER)
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds /*
3821da177e4SLinus Torvalds  * Never offer a window over 32767 without using window scaling. Some
3831da177e4SLinus Torvalds  * poor stacks do signed 16bit maths!
3841da177e4SLinus Torvalds  */
3851da177e4SLinus Torvalds #define MAX_TCP_WINDOW		32767U
3861da177e4SLinus Torvalds 
3871da177e4SLinus Torvalds /* Minimal accepted MSS. It is (60+60+8) - (20+20). */
3881da177e4SLinus Torvalds #define TCP_MIN_MSS		88U
3891da177e4SLinus Torvalds 
3901da177e4SLinus Torvalds /* Minimal RCV_MSS. */
3911da177e4SLinus Torvalds #define TCP_MIN_RCVMSS		536U
3921da177e4SLinus Torvalds 
3931da177e4SLinus Torvalds /* After receiving this amount of duplicate ACKs fast retransmit starts. */
3941da177e4SLinus Torvalds #define TCP_FASTRETRANS_THRESH 3
3951da177e4SLinus Torvalds 
3961da177e4SLinus Torvalds /* Maximal reordering. */
3971da177e4SLinus Torvalds #define TCP_MAX_REORDERING	127
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds /* Maximal number of ACKs sent quickly to accelerate slow-start. */
4001da177e4SLinus Torvalds #define TCP_MAX_QUICKACKS	16U
4011da177e4SLinus Torvalds 
4021da177e4SLinus Torvalds /* urg_data states */
4031da177e4SLinus Torvalds #define TCP_URG_VALID	0x0100
4041da177e4SLinus Torvalds #define TCP_URG_NOTYET	0x0200
4051da177e4SLinus Torvalds #define TCP_URG_READ	0x0400
4061da177e4SLinus Torvalds 
4071da177e4SLinus Torvalds #define TCP_RETR1	3	/*
4081da177e4SLinus Torvalds 				 * This is how many retries it does before it
4091da177e4SLinus Torvalds 				 * tries to figure out if the gateway is
4101da177e4SLinus Torvalds 				 * down. Minimal RFC value is 3; it corresponds
4111da177e4SLinus Torvalds 				 * to ~3sec-8min depending on RTO.
4121da177e4SLinus Torvalds 				 */
4131da177e4SLinus Torvalds 
4141da177e4SLinus Torvalds #define TCP_RETR2	15	/*
4151da177e4SLinus Torvalds 				 * This should take at least
4161da177e4SLinus Torvalds 				 * 90 minutes to time out.
4171da177e4SLinus Torvalds 				 * RFC1122 says that the limit is 100 sec.
4181da177e4SLinus Torvalds 				 * 15 is ~13-30min depending on RTO.
4191da177e4SLinus Torvalds 				 */
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds #define TCP_SYN_RETRIES	 5	/* number of times to retry active opening a
4221da177e4SLinus Torvalds 				 * connection: ~180sec is RFC minumum	*/
4231da177e4SLinus Torvalds 
4241da177e4SLinus Torvalds #define TCP_SYNACK_RETRIES 5	/* number of times to retry passive opening a
4251da177e4SLinus Torvalds 				 * connection: ~180sec is RFC minumum	*/
4261da177e4SLinus Torvalds 
4271da177e4SLinus Torvalds 
4281da177e4SLinus Torvalds #define TCP_ORPHAN_RETRIES 7	/* number of times to retry on an orphaned
4291da177e4SLinus Torvalds 				 * socket. 7 is ~50sec-16min.
4301da177e4SLinus Torvalds 				 */
4311da177e4SLinus Torvalds 
4321da177e4SLinus Torvalds 
4331da177e4SLinus Torvalds #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
4341da177e4SLinus Torvalds 				  * state, about 60 seconds	*/
4351da177e4SLinus Torvalds #define TCP_FIN_TIMEOUT	TCP_TIMEWAIT_LEN
4361da177e4SLinus Torvalds                                  /* BSD style FIN_WAIT2 deadlock breaker.
4371da177e4SLinus Torvalds 				  * It used to be 3min, new value is 60sec,
4381da177e4SLinus Torvalds 				  * to combine FIN-WAIT-2 timeout with
4391da177e4SLinus Torvalds 				  * TIME-WAIT timer.
4401da177e4SLinus Torvalds 				  */
4411da177e4SLinus Torvalds 
4421da177e4SLinus Torvalds #define TCP_DELACK_MAX	((unsigned)(HZ/5))	/* maximal time to delay before sending an ACK */
4431da177e4SLinus Torvalds #if HZ >= 100
4441da177e4SLinus Torvalds #define TCP_DELACK_MIN	((unsigned)(HZ/25))	/* minimal time to delay before sending an ACK */
4451da177e4SLinus Torvalds #define TCP_ATO_MIN	((unsigned)(HZ/25))
4461da177e4SLinus Torvalds #else
4471da177e4SLinus Torvalds #define TCP_DELACK_MIN	4U
4481da177e4SLinus Torvalds #define TCP_ATO_MIN	4U
4491da177e4SLinus Torvalds #endif
4501da177e4SLinus Torvalds #define TCP_RTO_MAX	((unsigned)(120*HZ))
4511da177e4SLinus Torvalds #define TCP_RTO_MIN	((unsigned)(HZ/5))
4521da177e4SLinus Torvalds #define TCP_TIMEOUT_INIT ((unsigned)(3*HZ))	/* RFC 1122 initial RTO value	*/
4531da177e4SLinus Torvalds 
4541da177e4SLinus Torvalds #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes
4551da177e4SLinus Torvalds 					                 * for local resources.
4561da177e4SLinus Torvalds 					                 */
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds #define TCP_KEEPALIVE_TIME	(120*60*HZ)	/* two hours */
4591da177e4SLinus Torvalds #define TCP_KEEPALIVE_PROBES	9		/* Max of 9 keepalive probes	*/
4601da177e4SLinus Torvalds #define TCP_KEEPALIVE_INTVL	(75*HZ)
4611da177e4SLinus Torvalds 
4621da177e4SLinus Torvalds #define MAX_TCP_KEEPIDLE	32767
4631da177e4SLinus Torvalds #define MAX_TCP_KEEPINTVL	32767
4641da177e4SLinus Torvalds #define MAX_TCP_KEEPCNT		127
4651da177e4SLinus Torvalds #define MAX_TCP_SYNCNT		127
4661da177e4SLinus Torvalds 
4671da177e4SLinus Torvalds #define TCP_SYNQ_INTERVAL	(HZ/5)	/* Period of SYNACK timer */
4681da177e4SLinus Torvalds #define TCP_SYNQ_HSIZE		512	/* Size of SYNACK hash table */
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds #define TCP_PAWS_24DAYS	(60 * 60 * 24 * 24)
4711da177e4SLinus Torvalds #define TCP_PAWS_MSL	60		/* Per-host timestamps are invalidated
4721da177e4SLinus Torvalds 					 * after this time. It should be equal
4731da177e4SLinus Torvalds 					 * (or greater than) TCP_TIMEWAIT_LEN
4741da177e4SLinus Torvalds 					 * to provide reliability equal to one
4751da177e4SLinus Torvalds 					 * provided by timewait state.
4761da177e4SLinus Torvalds 					 */
4771da177e4SLinus Torvalds #define TCP_PAWS_WINDOW	1		/* Replay window for per-host
4781da177e4SLinus Torvalds 					 * timestamps. It must be less than
4791da177e4SLinus Torvalds 					 * minimal timewait lifetime.
4801da177e4SLinus Torvalds 					 */
4811da177e4SLinus Torvalds 
4821da177e4SLinus Torvalds #define TCP_TW_RECYCLE_SLOTS_LOG	5
4831da177e4SLinus Torvalds #define TCP_TW_RECYCLE_SLOTS		(1<<TCP_TW_RECYCLE_SLOTS_LOG)
4841da177e4SLinus Torvalds 
4851da177e4SLinus Torvalds /* If time > 4sec, it is "slow" path, no recycling is required,
4861da177e4SLinus Torvalds    so that we select tick to get range about 4 seconds.
4871da177e4SLinus Torvalds  */
4881da177e4SLinus Torvalds 
4891da177e4SLinus Torvalds #if HZ <= 16 || HZ > 4096
4901da177e4SLinus Torvalds # error Unsupported: HZ <= 16 or HZ > 4096
4911da177e4SLinus Torvalds #elif HZ <= 32
4921da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (5+2-TCP_TW_RECYCLE_SLOTS_LOG)
4931da177e4SLinus Torvalds #elif HZ <= 64
4941da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (6+2-TCP_TW_RECYCLE_SLOTS_LOG)
4951da177e4SLinus Torvalds #elif HZ <= 128
4961da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG)
4971da177e4SLinus Torvalds #elif HZ <= 256
4981da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (8+2-TCP_TW_RECYCLE_SLOTS_LOG)
4991da177e4SLinus Torvalds #elif HZ <= 512
5001da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (9+2-TCP_TW_RECYCLE_SLOTS_LOG)
5011da177e4SLinus Torvalds #elif HZ <= 1024
5021da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG)
5031da177e4SLinus Torvalds #elif HZ <= 2048
5041da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (11+2-TCP_TW_RECYCLE_SLOTS_LOG)
5051da177e4SLinus Torvalds #else
5061da177e4SLinus Torvalds # define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG)
5071da177e4SLinus Torvalds #endif
5081da177e4SLinus Torvalds 
5091da177e4SLinus Torvalds #define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
5101da177e4SLinus Torvalds 					 * max_cwnd = snd_cwnd * beta
5111da177e4SLinus Torvalds 					 */
5121da177e4SLinus Torvalds #define BICTCP_MAX_INCREMENT 32		/*
5131da177e4SLinus Torvalds 					 * Limit on the amount of
5141da177e4SLinus Torvalds 					 * increment allowed during
5151da177e4SLinus Torvalds 					 * binary search.
5161da177e4SLinus Torvalds 					 */
5171da177e4SLinus Torvalds #define BICTCP_FUNC_OF_MIN_INCR 11	/*
5181da177e4SLinus Torvalds 					 * log(B/Smin)/log(B/(B-1))+1,
5191da177e4SLinus Torvalds 					 * Smin:min increment
5201da177e4SLinus Torvalds 					 * B:log factor
5211da177e4SLinus Torvalds 					 */
5221da177e4SLinus Torvalds #define BICTCP_B		4	 /*
5231da177e4SLinus Torvalds 					  * In binary search,
5241da177e4SLinus Torvalds 					  * go to point (max+min)/N
5251da177e4SLinus Torvalds 					  */
5261da177e4SLinus Torvalds 
5271da177e4SLinus Torvalds /*
5281da177e4SLinus Torvalds  *	TCP option
5291da177e4SLinus Torvalds  */
5301da177e4SLinus Torvalds 
5311da177e4SLinus Torvalds #define TCPOPT_NOP		1	/* Padding */
5321da177e4SLinus Torvalds #define TCPOPT_EOL		0	/* End of options */
5331da177e4SLinus Torvalds #define TCPOPT_MSS		2	/* Segment size negotiating */
5341da177e4SLinus Torvalds #define TCPOPT_WINDOW		3	/* Window scaling */
5351da177e4SLinus Torvalds #define TCPOPT_SACK_PERM        4       /* SACK Permitted */
5361da177e4SLinus Torvalds #define TCPOPT_SACK             5       /* SACK Block */
5371da177e4SLinus Torvalds #define TCPOPT_TIMESTAMP	8	/* Better RTT estimations/PAWS */
5381da177e4SLinus Torvalds 
5391da177e4SLinus Torvalds /*
5401da177e4SLinus Torvalds  *     TCP option lengths
5411da177e4SLinus Torvalds  */
5421da177e4SLinus Torvalds 
5431da177e4SLinus Torvalds #define TCPOLEN_MSS            4
5441da177e4SLinus Torvalds #define TCPOLEN_WINDOW         3
5451da177e4SLinus Torvalds #define TCPOLEN_SACK_PERM      2
5461da177e4SLinus Torvalds #define TCPOLEN_TIMESTAMP      10
5471da177e4SLinus Torvalds 
5481da177e4SLinus Torvalds /* But this is what stacks really send out. */
5491da177e4SLinus Torvalds #define TCPOLEN_TSTAMP_ALIGNED		12
5501da177e4SLinus Torvalds #define TCPOLEN_WSCALE_ALIGNED		4
5511da177e4SLinus Torvalds #define TCPOLEN_SACKPERM_ALIGNED	4
5521da177e4SLinus Torvalds #define TCPOLEN_SACK_BASE		2
5531da177e4SLinus Torvalds #define TCPOLEN_SACK_BASE_ALIGNED	4
5541da177e4SLinus Torvalds #define TCPOLEN_SACK_PERBLOCK		8
5551da177e4SLinus Torvalds 
5561da177e4SLinus Torvalds #define TCP_TIME_RETRANS	1	/* Retransmit timer */
5571da177e4SLinus Torvalds #define TCP_TIME_DACK		2	/* Delayed ack timer */
5581da177e4SLinus Torvalds #define TCP_TIME_PROBE0		3	/* Zero window probe timer */
5591da177e4SLinus Torvalds #define TCP_TIME_KEEPOPEN	4	/* Keepalive timer */
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds /* Flags in tp->nonagle */
5621da177e4SLinus Torvalds #define TCP_NAGLE_OFF		1	/* Nagle's algo is disabled */
5631da177e4SLinus Torvalds #define TCP_NAGLE_CORK		2	/* Socket is corked	    */
5641da177e4SLinus Torvalds #define TCP_NAGLE_PUSH		4	/* Cork is overriden for already queued data */
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds /* sysctl variables for tcp */
5671da177e4SLinus Torvalds extern int sysctl_max_syn_backlog;
5681da177e4SLinus Torvalds extern int sysctl_tcp_timestamps;
5691da177e4SLinus Torvalds extern int sysctl_tcp_window_scaling;
5701da177e4SLinus Torvalds extern int sysctl_tcp_sack;
5711da177e4SLinus Torvalds extern int sysctl_tcp_fin_timeout;
5721da177e4SLinus Torvalds extern int sysctl_tcp_tw_recycle;
5731da177e4SLinus Torvalds extern int sysctl_tcp_keepalive_time;
5741da177e4SLinus Torvalds extern int sysctl_tcp_keepalive_probes;
5751da177e4SLinus Torvalds extern int sysctl_tcp_keepalive_intvl;
5761da177e4SLinus Torvalds extern int sysctl_tcp_syn_retries;
5771da177e4SLinus Torvalds extern int sysctl_tcp_synack_retries;
5781da177e4SLinus Torvalds extern int sysctl_tcp_retries1;
5791da177e4SLinus Torvalds extern int sysctl_tcp_retries2;
5801da177e4SLinus Torvalds extern int sysctl_tcp_orphan_retries;
5811da177e4SLinus Torvalds extern int sysctl_tcp_syncookies;
5821da177e4SLinus Torvalds extern int sysctl_tcp_retrans_collapse;
5831da177e4SLinus Torvalds extern int sysctl_tcp_stdurg;
5841da177e4SLinus Torvalds extern int sysctl_tcp_rfc1337;
5851da177e4SLinus Torvalds extern int sysctl_tcp_abort_on_overflow;
5861da177e4SLinus Torvalds extern int sysctl_tcp_max_orphans;
5871da177e4SLinus Torvalds extern int sysctl_tcp_max_tw_buckets;
5881da177e4SLinus Torvalds extern int sysctl_tcp_fack;
5891da177e4SLinus Torvalds extern int sysctl_tcp_reordering;
5901da177e4SLinus Torvalds extern int sysctl_tcp_ecn;
5911da177e4SLinus Torvalds extern int sysctl_tcp_dsack;
5921da177e4SLinus Torvalds extern int sysctl_tcp_mem[3];
5931da177e4SLinus Torvalds extern int sysctl_tcp_wmem[3];
5941da177e4SLinus Torvalds extern int sysctl_tcp_rmem[3];
5951da177e4SLinus Torvalds extern int sysctl_tcp_app_win;
5961da177e4SLinus Torvalds extern int sysctl_tcp_adv_win_scale;
5971da177e4SLinus Torvalds extern int sysctl_tcp_tw_reuse;
5981da177e4SLinus Torvalds extern int sysctl_tcp_frto;
5991da177e4SLinus Torvalds extern int sysctl_tcp_low_latency;
6001da177e4SLinus Torvalds extern int sysctl_tcp_westwood;
6011da177e4SLinus Torvalds extern int sysctl_tcp_vegas_cong_avoid;
6021da177e4SLinus Torvalds extern int sysctl_tcp_vegas_alpha;
6031da177e4SLinus Torvalds extern int sysctl_tcp_vegas_beta;
6041da177e4SLinus Torvalds extern int sysctl_tcp_vegas_gamma;
6051da177e4SLinus Torvalds extern int sysctl_tcp_nometrics_save;
6061da177e4SLinus Torvalds extern int sysctl_tcp_bic;
6071da177e4SLinus Torvalds extern int sysctl_tcp_bic_fast_convergence;
6081da177e4SLinus Torvalds extern int sysctl_tcp_bic_low_window;
6091da177e4SLinus Torvalds extern int sysctl_tcp_bic_beta;
6101da177e4SLinus Torvalds extern int sysctl_tcp_moderate_rcvbuf;
6111da177e4SLinus Torvalds extern int sysctl_tcp_tso_win_divisor;
6121da177e4SLinus Torvalds 
6131da177e4SLinus Torvalds extern atomic_t tcp_memory_allocated;
6141da177e4SLinus Torvalds extern atomic_t tcp_sockets_allocated;
6151da177e4SLinus Torvalds extern int tcp_memory_pressure;
6161da177e4SLinus Torvalds 
6171da177e4SLinus Torvalds #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
6181da177e4SLinus Torvalds #define TCP_INET_FAMILY(fam) ((fam) == AF_INET)
6191da177e4SLinus Torvalds #else
6201da177e4SLinus Torvalds #define TCP_INET_FAMILY(fam) 1
6211da177e4SLinus Torvalds #endif
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds /*
6241da177e4SLinus Torvalds  *	Pointers to address related TCP functions
6251da177e4SLinus Torvalds  *	(i.e. things that depend on the address family)
6261da177e4SLinus Torvalds  */
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds struct tcp_func {
6291da177e4SLinus Torvalds 	int			(*queue_xmit)		(struct sk_buff *skb,
6301da177e4SLinus Torvalds 							 int ipfragok);
6311da177e4SLinus Torvalds 
6321da177e4SLinus Torvalds 	void			(*send_check)		(struct sock *sk,
6331da177e4SLinus Torvalds 							 struct tcphdr *th,
6341da177e4SLinus Torvalds 							 int len,
6351da177e4SLinus Torvalds 							 struct sk_buff *skb);
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds 	int			(*rebuild_header)	(struct sock *sk);
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 	int			(*conn_request)		(struct sock *sk,
6401da177e4SLinus Torvalds 							 struct sk_buff *skb);
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds 	struct sock *		(*syn_recv_sock)	(struct sock *sk,
6431da177e4SLinus Torvalds 							 struct sk_buff *skb,
6441da177e4SLinus Torvalds 							 struct open_request *req,
6451da177e4SLinus Torvalds 							 struct dst_entry *dst);
6461da177e4SLinus Torvalds 
6471da177e4SLinus Torvalds 	int			(*remember_stamp)	(struct sock *sk);
6481da177e4SLinus Torvalds 
6491da177e4SLinus Torvalds 	__u16			net_header_len;
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds 	int			(*setsockopt)		(struct sock *sk,
6521da177e4SLinus Torvalds 							 int level,
6531da177e4SLinus Torvalds 							 int optname,
6541da177e4SLinus Torvalds 							 char __user *optval,
6551da177e4SLinus Torvalds 							 int optlen);
6561da177e4SLinus Torvalds 
6571da177e4SLinus Torvalds 	int			(*getsockopt)		(struct sock *sk,
6581da177e4SLinus Torvalds 							 int level,
6591da177e4SLinus Torvalds 							 int optname,
6601da177e4SLinus Torvalds 							 char __user *optval,
6611da177e4SLinus Torvalds 							 int __user *optlen);
6621da177e4SLinus Torvalds 
6631da177e4SLinus Torvalds 
6641da177e4SLinus Torvalds 	void			(*addr2sockaddr)	(struct sock *sk,
6651da177e4SLinus Torvalds 							 struct sockaddr *);
6661da177e4SLinus Torvalds 
6671da177e4SLinus Torvalds 	int sockaddr_len;
6681da177e4SLinus Torvalds };
6691da177e4SLinus Torvalds 
6701da177e4SLinus Torvalds /*
6711da177e4SLinus Torvalds  * The next routines deal with comparing 32 bit unsigned ints
6721da177e4SLinus Torvalds  * and worry about wraparound (automatic with unsigned arithmetic).
6731da177e4SLinus Torvalds  */
6741da177e4SLinus Torvalds 
6751da177e4SLinus Torvalds static inline int before(__u32 seq1, __u32 seq2)
6761da177e4SLinus Torvalds {
6771da177e4SLinus Torvalds         return (__s32)(seq1-seq2) < 0;
6781da177e4SLinus Torvalds }
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds static inline int after(__u32 seq1, __u32 seq2)
6811da177e4SLinus Torvalds {
6821da177e4SLinus Torvalds 	return (__s32)(seq2-seq1) < 0;
6831da177e4SLinus Torvalds }
6841da177e4SLinus Torvalds 
6851da177e4SLinus Torvalds 
6861da177e4SLinus Torvalds /* is s2<=s1<=s3 ? */
6871da177e4SLinus Torvalds static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
6881da177e4SLinus Torvalds {
6891da177e4SLinus Torvalds 	return seq3 - seq2 >= seq1 - seq2;
6901da177e4SLinus Torvalds }
6911da177e4SLinus Torvalds 
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds extern struct proto tcp_prot;
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds DECLARE_SNMP_STAT(struct tcp_mib, tcp_statistics);
6961da177e4SLinus Torvalds #define TCP_INC_STATS(field)		SNMP_INC_STATS(tcp_statistics, field)
6971da177e4SLinus Torvalds #define TCP_INC_STATS_BH(field)		SNMP_INC_STATS_BH(tcp_statistics, field)
6981da177e4SLinus Torvalds #define TCP_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(tcp_statistics, field)
6991da177e4SLinus Torvalds #define TCP_DEC_STATS(field)		SNMP_DEC_STATS(tcp_statistics, field)
7001da177e4SLinus Torvalds #define TCP_ADD_STATS_BH(field, val)	SNMP_ADD_STATS_BH(tcp_statistics, field, val)
7011da177e4SLinus Torvalds #define TCP_ADD_STATS_USER(field, val)	SNMP_ADD_STATS_USER(tcp_statistics, field, val)
7021da177e4SLinus Torvalds 
7031da177e4SLinus Torvalds extern void			tcp_put_port(struct sock *sk);
7041da177e4SLinus Torvalds extern void			tcp_inherit_port(struct sock *sk, struct sock *child);
7051da177e4SLinus Torvalds 
7061da177e4SLinus Torvalds extern void			tcp_v4_err(struct sk_buff *skb, u32);
7071da177e4SLinus Torvalds 
7081da177e4SLinus Torvalds extern void			tcp_shutdown (struct sock *sk, int how);
7091da177e4SLinus Torvalds 
7101da177e4SLinus Torvalds extern int			tcp_v4_rcv(struct sk_buff *skb);
7111da177e4SLinus Torvalds 
7121da177e4SLinus Torvalds extern int			tcp_v4_remember_stamp(struct sock *sk);
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds extern int		    	tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw);
7151da177e4SLinus Torvalds 
7161da177e4SLinus Torvalds extern int			tcp_sendmsg(struct kiocb *iocb, struct sock *sk,
7171da177e4SLinus Torvalds 					    struct msghdr *msg, size_t size);
7181da177e4SLinus Torvalds extern ssize_t			tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
7191da177e4SLinus Torvalds 
7201da177e4SLinus Torvalds extern int			tcp_ioctl(struct sock *sk,
7211da177e4SLinus Torvalds 					  int cmd,
7221da177e4SLinus Torvalds 					  unsigned long arg);
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds extern int			tcp_rcv_state_process(struct sock *sk,
7251da177e4SLinus Torvalds 						      struct sk_buff *skb,
7261da177e4SLinus Torvalds 						      struct tcphdr *th,
7271da177e4SLinus Torvalds 						      unsigned len);
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds extern int			tcp_rcv_established(struct sock *sk,
7301da177e4SLinus Torvalds 						    struct sk_buff *skb,
7311da177e4SLinus Torvalds 						    struct tcphdr *th,
7321da177e4SLinus Torvalds 						    unsigned len);
7331da177e4SLinus Torvalds 
7341da177e4SLinus Torvalds extern void			tcp_rcv_space_adjust(struct sock *sk);
7351da177e4SLinus Torvalds 
7361da177e4SLinus Torvalds enum tcp_ack_state_t
7371da177e4SLinus Torvalds {
7381da177e4SLinus Torvalds 	TCP_ACK_SCHED = 1,
7391da177e4SLinus Torvalds 	TCP_ACK_TIMER = 2,
7401da177e4SLinus Torvalds 	TCP_ACK_PUSHED= 4
7411da177e4SLinus Torvalds };
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds static inline void tcp_schedule_ack(struct tcp_sock *tp)
7441da177e4SLinus Torvalds {
7451da177e4SLinus Torvalds 	tp->ack.pending |= TCP_ACK_SCHED;
7461da177e4SLinus Torvalds }
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds static inline int tcp_ack_scheduled(struct tcp_sock *tp)
7491da177e4SLinus Torvalds {
7501da177e4SLinus Torvalds 	return tp->ack.pending&TCP_ACK_SCHED;
7511da177e4SLinus Torvalds }
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp)
7541da177e4SLinus Torvalds {
7551da177e4SLinus Torvalds 	if (tp->ack.quick && --tp->ack.quick == 0) {
7561da177e4SLinus Torvalds 		/* Leaving quickack mode we deflate ATO. */
7571da177e4SLinus Torvalds 		tp->ack.ato = TCP_ATO_MIN;
7581da177e4SLinus Torvalds 	}
7591da177e4SLinus Torvalds }
7601da177e4SLinus Torvalds 
7611da177e4SLinus Torvalds extern void tcp_enter_quickack_mode(struct tcp_sock *tp);
7621da177e4SLinus Torvalds 
7631da177e4SLinus Torvalds static __inline__ void tcp_delack_init(struct tcp_sock *tp)
7641da177e4SLinus Torvalds {
7651da177e4SLinus Torvalds 	memset(&tp->ack, 0, sizeof(tp->ack));
7661da177e4SLinus Torvalds }
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
7691da177e4SLinus Torvalds {
7701da177e4SLinus Torvalds  	rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0;
7711da177e4SLinus Torvalds }
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds enum tcp_tw_status
7741da177e4SLinus Torvalds {
7751da177e4SLinus Torvalds 	TCP_TW_SUCCESS = 0,
7761da177e4SLinus Torvalds 	TCP_TW_RST = 1,
7771da177e4SLinus Torvalds 	TCP_TW_ACK = 2,
7781da177e4SLinus Torvalds 	TCP_TW_SYN = 3
7791da177e4SLinus Torvalds };
7801da177e4SLinus Torvalds 
7811da177e4SLinus Torvalds 
7821da177e4SLinus Torvalds extern enum tcp_tw_status	tcp_timewait_state_process(struct tcp_tw_bucket *tw,
7831da177e4SLinus Torvalds 							   struct sk_buff *skb,
7841da177e4SLinus Torvalds 							   struct tcphdr *th,
7851da177e4SLinus Torvalds 							   unsigned len);
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds extern struct sock *		tcp_check_req(struct sock *sk,struct sk_buff *skb,
7881da177e4SLinus Torvalds 					      struct open_request *req,
7891da177e4SLinus Torvalds 					      struct open_request **prev);
7901da177e4SLinus Torvalds extern int			tcp_child_process(struct sock *parent,
7911da177e4SLinus Torvalds 						  struct sock *child,
7921da177e4SLinus Torvalds 						  struct sk_buff *skb);
7931da177e4SLinus Torvalds extern void			tcp_enter_frto(struct sock *sk);
7941da177e4SLinus Torvalds extern void			tcp_enter_loss(struct sock *sk, int how);
7951da177e4SLinus Torvalds extern void			tcp_clear_retrans(struct tcp_sock *tp);
7961da177e4SLinus Torvalds extern void			tcp_update_metrics(struct sock *sk);
7971da177e4SLinus Torvalds 
7981da177e4SLinus Torvalds extern void			tcp_close(struct sock *sk,
7991da177e4SLinus Torvalds 					  long timeout);
8001da177e4SLinus Torvalds extern struct sock *		tcp_accept(struct sock *sk, int flags, int *err);
8011da177e4SLinus Torvalds extern unsigned int		tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds extern int			tcp_getsockopt(struct sock *sk, int level,
8041da177e4SLinus Torvalds 					       int optname,
8051da177e4SLinus Torvalds 					       char __user *optval,
8061da177e4SLinus Torvalds 					       int __user *optlen);
8071da177e4SLinus Torvalds extern int			tcp_setsockopt(struct sock *sk, int level,
8081da177e4SLinus Torvalds 					       int optname, char __user *optval,
8091da177e4SLinus Torvalds 					       int optlen);
8101da177e4SLinus Torvalds extern void			tcp_set_keepalive(struct sock *sk, int val);
8111da177e4SLinus Torvalds extern int			tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
8121da177e4SLinus Torvalds 					    struct msghdr *msg,
8131da177e4SLinus Torvalds 					    size_t len, int nonblock,
8141da177e4SLinus Torvalds 					    int flags, int *addr_len);
8151da177e4SLinus Torvalds 
8161da177e4SLinus Torvalds extern int			tcp_listen_start(struct sock *sk);
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds extern void			tcp_parse_options(struct sk_buff *skb,
8191da177e4SLinus Torvalds 						  struct tcp_options_received *opt_rx,
8201da177e4SLinus Torvalds 						  int estab);
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds /*
8231da177e4SLinus Torvalds  *	TCP v4 functions exported for the inet6 API
8241da177e4SLinus Torvalds  */
8251da177e4SLinus Torvalds 
8261da177e4SLinus Torvalds extern int		       	tcp_v4_rebuild_header(struct sock *sk);
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds extern int		       	tcp_v4_build_header(struct sock *sk,
8291da177e4SLinus Torvalds 						    struct sk_buff *skb);
8301da177e4SLinus Torvalds 
8311da177e4SLinus Torvalds extern void		       	tcp_v4_send_check(struct sock *sk,
8321da177e4SLinus Torvalds 						  struct tcphdr *th, int len,
8331da177e4SLinus Torvalds 						  struct sk_buff *skb);
8341da177e4SLinus Torvalds 
8351da177e4SLinus Torvalds extern int			tcp_v4_conn_request(struct sock *sk,
8361da177e4SLinus Torvalds 						    struct sk_buff *skb);
8371da177e4SLinus Torvalds 
8381da177e4SLinus Torvalds extern struct sock *		tcp_create_openreq_child(struct sock *sk,
8391da177e4SLinus Torvalds 							 struct open_request *req,
8401da177e4SLinus Torvalds 							 struct sk_buff *skb);
8411da177e4SLinus Torvalds 
8421da177e4SLinus Torvalds extern struct sock *		tcp_v4_syn_recv_sock(struct sock *sk,
8431da177e4SLinus Torvalds 						     struct sk_buff *skb,
8441da177e4SLinus Torvalds 						     struct open_request *req,
8451da177e4SLinus Torvalds 							struct dst_entry *dst);
8461da177e4SLinus Torvalds 
8471da177e4SLinus Torvalds extern int			tcp_v4_do_rcv(struct sock *sk,
8481da177e4SLinus Torvalds 					      struct sk_buff *skb);
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds extern int			tcp_v4_connect(struct sock *sk,
8511da177e4SLinus Torvalds 					       struct sockaddr *uaddr,
8521da177e4SLinus Torvalds 					       int addr_len);
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds extern int			tcp_connect(struct sock *sk);
8551da177e4SLinus Torvalds 
8561da177e4SLinus Torvalds extern struct sk_buff *		tcp_make_synack(struct sock *sk,
8571da177e4SLinus Torvalds 						struct dst_entry *dst,
8581da177e4SLinus Torvalds 						struct open_request *req);
8591da177e4SLinus Torvalds 
8601da177e4SLinus Torvalds extern int			tcp_disconnect(struct sock *sk, int flags);
8611da177e4SLinus Torvalds 
8621da177e4SLinus Torvalds extern void			tcp_unhash(struct sock *sk);
8631da177e4SLinus Torvalds 
8641da177e4SLinus Torvalds extern int			tcp_v4_hash_connecting(struct sock *sk);
8651da177e4SLinus Torvalds 
8661da177e4SLinus Torvalds 
8671da177e4SLinus Torvalds /* From syncookies.c */
8681da177e4SLinus Torvalds extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
8691da177e4SLinus Torvalds 				    struct ip_options *opt);
8701da177e4SLinus Torvalds extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
8711da177e4SLinus Torvalds 				     __u16 *mss);
8721da177e4SLinus Torvalds 
8731da177e4SLinus Torvalds /* tcp_output.c */
8741da177e4SLinus Torvalds 
8751da177e4SLinus Torvalds extern int tcp_write_xmit(struct sock *, int nonagle);
8761da177e4SLinus Torvalds extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
8771da177e4SLinus Torvalds extern void tcp_xmit_retransmit_queue(struct sock *);
8781da177e4SLinus Torvalds extern void tcp_simple_retransmit(struct sock *);
8791da177e4SLinus Torvalds extern int tcp_trim_head(struct sock *, struct sk_buff *, u32);
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds extern void tcp_send_probe0(struct sock *);
8821da177e4SLinus Torvalds extern void tcp_send_partial(struct sock *);
8831da177e4SLinus Torvalds extern int  tcp_write_wakeup(struct sock *);
8841da177e4SLinus Torvalds extern void tcp_send_fin(struct sock *sk);
8851da177e4SLinus Torvalds extern void tcp_send_active_reset(struct sock *sk, int priority);
8861da177e4SLinus Torvalds extern int  tcp_send_synack(struct sock *);
8871da177e4SLinus Torvalds extern void tcp_push_one(struct sock *, unsigned mss_now);
8881da177e4SLinus Torvalds extern void tcp_send_ack(struct sock *sk);
8891da177e4SLinus Torvalds extern void tcp_send_delayed_ack(struct sock *sk);
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds /* tcp_timer.c */
8921da177e4SLinus Torvalds extern void tcp_init_xmit_timers(struct sock *);
8931da177e4SLinus Torvalds extern void tcp_clear_xmit_timers(struct sock *);
8941da177e4SLinus Torvalds 
8951da177e4SLinus Torvalds extern void tcp_delete_keepalive_timer(struct sock *);
8961da177e4SLinus Torvalds extern void tcp_reset_keepalive_timer(struct sock *, unsigned long);
8971da177e4SLinus Torvalds extern unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
8981da177e4SLinus Torvalds extern unsigned int tcp_current_mss(struct sock *sk, int large);
8991da177e4SLinus Torvalds 
9001da177e4SLinus Torvalds #ifdef TCP_DEBUG
9011da177e4SLinus Torvalds extern const char tcp_timer_bug_msg[];
9021da177e4SLinus Torvalds #endif
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds /* tcp_diag.c */
9051da177e4SLinus Torvalds extern void tcp_get_info(struct sock *, struct tcp_info *);
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds /* Read 'sendfile()'-style from a TCP socket */
9081da177e4SLinus Torvalds typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
9091da177e4SLinus Torvalds 				unsigned int, size_t);
9101da177e4SLinus Torvalds extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
9111da177e4SLinus Torvalds 			 sk_read_actor_t recv_actor);
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
9141da177e4SLinus Torvalds {
9151da177e4SLinus Torvalds 	struct tcp_sock *tp = tcp_sk(sk);
9161da177e4SLinus Torvalds 
9171da177e4SLinus Torvalds 	switch (what) {
9181da177e4SLinus Torvalds 	case TCP_TIME_RETRANS:
9191da177e4SLinus Torvalds 	case TCP_TIME_PROBE0:
9201da177e4SLinus Torvalds 		tp->pending = 0;
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds #ifdef TCP_CLEAR_TIMERS
9231da177e4SLinus Torvalds 		sk_stop_timer(sk, &tp->retransmit_timer);
9241da177e4SLinus Torvalds #endif
9251da177e4SLinus Torvalds 		break;
9261da177e4SLinus Torvalds 	case TCP_TIME_DACK:
9271da177e4SLinus Torvalds 		tp->ack.blocked = 0;
9281da177e4SLinus Torvalds 		tp->ack.pending = 0;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds #ifdef TCP_CLEAR_TIMERS
9311da177e4SLinus Torvalds 		sk_stop_timer(sk, &tp->delack_timer);
9321da177e4SLinus Torvalds #endif
9331da177e4SLinus Torvalds 		break;
9341da177e4SLinus Torvalds 	default:
9351da177e4SLinus Torvalds #ifdef TCP_DEBUG
9361da177e4SLinus Torvalds 		printk(tcp_timer_bug_msg);
9371da177e4SLinus Torvalds #endif
9381da177e4SLinus Torvalds 		return;
9391da177e4SLinus Torvalds 	};
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds }
9421da177e4SLinus Torvalds 
9431da177e4SLinus Torvalds /*
9441da177e4SLinus Torvalds  *	Reset the retransmission timer
9451da177e4SLinus Torvalds  */
9461da177e4SLinus Torvalds static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when)
9471da177e4SLinus Torvalds {
9481da177e4SLinus Torvalds 	struct tcp_sock *tp = tcp_sk(sk);
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds 	if (when > TCP_RTO_MAX) {
9511da177e4SLinus Torvalds #ifdef TCP_DEBUG
9521da177e4SLinus Torvalds 		printk(KERN_DEBUG "reset_xmit_timer sk=%p %d when=0x%lx, caller=%p\n", sk, what, when, current_text_addr());
9531da177e4SLinus Torvalds #endif
9541da177e4SLinus Torvalds 		when = TCP_RTO_MAX;
9551da177e4SLinus Torvalds 	}
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 	switch (what) {
9581da177e4SLinus Torvalds 	case TCP_TIME_RETRANS:
9591da177e4SLinus Torvalds 	case TCP_TIME_PROBE0:
9601da177e4SLinus Torvalds 		tp->pending = what;
9611da177e4SLinus Torvalds 		tp->timeout = jiffies+when;
9621da177e4SLinus Torvalds 		sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
9631da177e4SLinus Torvalds 		break;
9641da177e4SLinus Torvalds 
9651da177e4SLinus Torvalds 	case TCP_TIME_DACK:
9661da177e4SLinus Torvalds 		tp->ack.pending |= TCP_ACK_TIMER;
9671da177e4SLinus Torvalds 		tp->ack.timeout = jiffies+when;
9681da177e4SLinus Torvalds 		sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
9691da177e4SLinus Torvalds 		break;
9701da177e4SLinus Torvalds 
9711da177e4SLinus Torvalds 	default:
9721da177e4SLinus Torvalds #ifdef TCP_DEBUG
9731da177e4SLinus Torvalds 		printk(tcp_timer_bug_msg);
9741da177e4SLinus Torvalds #endif
9751da177e4SLinus Torvalds 		return;
9761da177e4SLinus Torvalds 	};
9771da177e4SLinus Torvalds }
9781da177e4SLinus Torvalds 
9791da177e4SLinus Torvalds /* Initialize RCV_MSS value.
9801da177e4SLinus Torvalds  * RCV_MSS is an our guess about MSS used by the peer.
9811da177e4SLinus Torvalds  * We haven't any direct information about the MSS.
9821da177e4SLinus Torvalds  * It's better to underestimate the RCV_MSS rather than overestimate.
9831da177e4SLinus Torvalds  * Overestimations make us ACKing less frequently than needed.
9841da177e4SLinus Torvalds  * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
9851da177e4SLinus Torvalds  */
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds static inline void tcp_initialize_rcv_mss(struct sock *sk)
9881da177e4SLinus Torvalds {
9891da177e4SLinus Torvalds 	struct tcp_sock *tp = tcp_sk(sk);
9901da177e4SLinus Torvalds 	unsigned int hint = min(tp->advmss, tp->mss_cache_std);
9911da177e4SLinus Torvalds 
9921da177e4SLinus Torvalds 	hint = min(hint, tp->rcv_wnd/2);
9931da177e4SLinus Torvalds 	hint = min(hint, TCP_MIN_RCVMSS);
9941da177e4SLinus Torvalds 	hint = max(hint, TCP_MIN_MSS);
9951da177e4SLinus Torvalds 
9961da177e4SLinus Torvalds 	tp->ack.rcv_mss = hint;
9971da177e4SLinus Torvalds }
9981da177e4SLinus Torvalds 
9991da177e4SLinus Torvalds static __inline__ void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
10001da177e4SLinus Torvalds {
10011da177e4SLinus Torvalds 	tp->pred_flags = htonl((tp->tcp_header_len << 26) |
10021da177e4SLinus Torvalds 			       ntohl(TCP_FLAG_ACK) |
10031da177e4SLinus Torvalds 			       snd_wnd);
10041da177e4SLinus Torvalds }
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds static __inline__ void tcp_fast_path_on(struct tcp_sock *tp)
10071da177e4SLinus Torvalds {
10081da177e4SLinus Torvalds 	__tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
10091da177e4SLinus Torvalds }
10101da177e4SLinus Torvalds 
10111da177e4SLinus Torvalds static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp)
10121da177e4SLinus Torvalds {
10131da177e4SLinus Torvalds 	if (skb_queue_len(&tp->out_of_order_queue) == 0 &&
10141da177e4SLinus Torvalds 	    tp->rcv_wnd &&
10151da177e4SLinus Torvalds 	    atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf &&
10161da177e4SLinus Torvalds 	    !tp->urg_data)
10171da177e4SLinus Torvalds 		tcp_fast_path_on(tp);
10181da177e4SLinus Torvalds }
10191da177e4SLinus Torvalds 
10201da177e4SLinus Torvalds /* Compute the actual receive window we are currently advertising.
10211da177e4SLinus Torvalds  * Rcv_nxt can be after the window if our peer push more data
10221da177e4SLinus Torvalds  * than the offered window.
10231da177e4SLinus Torvalds  */
10241da177e4SLinus Torvalds static __inline__ u32 tcp_receive_window(const struct tcp_sock *tp)
10251da177e4SLinus Torvalds {
10261da177e4SLinus Torvalds 	s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt;
10271da177e4SLinus Torvalds 
10281da177e4SLinus Torvalds 	if (win < 0)
10291da177e4SLinus Torvalds 		win = 0;
10301da177e4SLinus Torvalds 	return (u32) win;
10311da177e4SLinus Torvalds }
10321da177e4SLinus Torvalds 
10331da177e4SLinus Torvalds /* Choose a new window, without checks for shrinking, and without
10341da177e4SLinus Torvalds  * scaling applied to the result.  The caller does these things
10351da177e4SLinus Torvalds  * if necessary.  This is a "raw" window selection.
10361da177e4SLinus Torvalds  */
10371da177e4SLinus Torvalds extern u32	__tcp_select_window(struct sock *sk);
10381da177e4SLinus Torvalds 
10391da177e4SLinus Torvalds /* TCP timestamps are only 32-bits, this causes a slight
10401da177e4SLinus Torvalds  * complication on 64-bit systems since we store a snapshot
10411da177e4SLinus Torvalds  * of jiffies in the buffer control blocks below.  We decidely
10421da177e4SLinus Torvalds  * only use of the low 32-bits of jiffies and hide the ugly
10431da177e4SLinus Torvalds  * casts with the following macro.
10441da177e4SLinus Torvalds  */
10451da177e4SLinus Torvalds #define tcp_time_stamp		((__u32)(jiffies))
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds /* This is what the send packet queueing engine uses to pass
10481da177e4SLinus Torvalds  * TCP per-packet control information to the transmission
10491da177e4SLinus Torvalds  * code.  We also store the host-order sequence numbers in
10501da177e4SLinus Torvalds  * here too.  This is 36 bytes on 32-bit architectures,
10511da177e4SLinus Torvalds  * 40 bytes on 64-bit machines, if this grows please adjust
10521da177e4SLinus Torvalds  * skbuff.h:skbuff->cb[xxx] size appropriately.
10531da177e4SLinus Torvalds  */
10541da177e4SLinus Torvalds struct tcp_skb_cb {
10551da177e4SLinus Torvalds 	union {
10561da177e4SLinus Torvalds 		struct inet_skb_parm	h4;
10571da177e4SLinus Torvalds #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
10581da177e4SLinus Torvalds 		struct inet6_skb_parm	h6;
10591da177e4SLinus Torvalds #endif
10601da177e4SLinus Torvalds 	} header;	/* For incoming frames		*/
10611da177e4SLinus Torvalds 	__u32		seq;		/* Starting sequence number	*/
10621da177e4SLinus Torvalds 	__u32		end_seq;	/* SEQ + FIN + SYN + datalen	*/
10631da177e4SLinus Torvalds 	__u32		when;		/* used to compute rtt's	*/
10641da177e4SLinus Torvalds 	__u8		flags;		/* TCP header flags.		*/
10651da177e4SLinus Torvalds 
10661da177e4SLinus Torvalds 	/* NOTE: These must match up to the flags byte in a
10671da177e4SLinus Torvalds 	 *       real TCP header.
10681da177e4SLinus Torvalds 	 */
10691da177e4SLinus Torvalds #define TCPCB_FLAG_FIN		0x01
10701da177e4SLinus Torvalds #define TCPCB_FLAG_SYN		0x02
10711da177e4SLinus Torvalds #define TCPCB_FLAG_RST		0x04
10721da177e4SLinus Torvalds #define TCPCB_FLAG_PSH		0x08
10731da177e4SLinus Torvalds #define TCPCB_FLAG_ACK		0x10
10741da177e4SLinus Torvalds #define TCPCB_FLAG_URG		0x20
10751da177e4SLinus Torvalds #define TCPCB_FLAG_ECE		0x40
10761da177e4SLinus Torvalds #define TCPCB_FLAG_CWR		0x80
10771da177e4SLinus Torvalds 
10781da177e4SLinus Torvalds 	__u8		sacked;		/* State flags for SACK/FACK.	*/
10791da177e4SLinus Torvalds #define TCPCB_SACKED_ACKED	0x01	/* SKB ACK'd by a SACK block	*/
10801da177e4SLinus Torvalds #define TCPCB_SACKED_RETRANS	0x02	/* SKB retransmitted		*/
10811da177e4SLinus Torvalds #define TCPCB_LOST		0x04	/* SKB is lost			*/
10821da177e4SLinus Torvalds #define TCPCB_TAGBITS		0x07	/* All tag bits			*/
10831da177e4SLinus Torvalds 
10841da177e4SLinus Torvalds #define TCPCB_EVER_RETRANS	0x80	/* Ever retransmitted frame	*/
10851da177e4SLinus Torvalds #define TCPCB_RETRANS		(TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
10861da177e4SLinus Torvalds 
10871da177e4SLinus Torvalds #define TCPCB_URG		0x20	/* Urgent pointer advenced here	*/
10881da177e4SLinus Torvalds 
10891da177e4SLinus Torvalds #define TCPCB_AT_TAIL		(TCPCB_URG)
10901da177e4SLinus Torvalds 
10911da177e4SLinus Torvalds 	__u16		urg_ptr;	/* Valid w/URG flags is set.	*/
10921da177e4SLinus Torvalds 	__u32		ack_seq;	/* Sequence number ACK'd	*/
10931da177e4SLinus Torvalds };
10941da177e4SLinus Torvalds 
10951da177e4SLinus Torvalds #define TCP_SKB_CB(__skb)	((struct tcp_skb_cb *)&((__skb)->cb[0]))
10961da177e4SLinus Torvalds 
10971da177e4SLinus Torvalds #include <net/tcp_ecn.h>
10981da177e4SLinus Torvalds 
10991da177e4SLinus Torvalds /* Due to TSO, an SKB can be composed of multiple actual
11001da177e4SLinus Torvalds  * packets.  To keep these tracked properly, we use this.
11011da177e4SLinus Torvalds  */
11021da177e4SLinus Torvalds static inline int tcp_skb_pcount(const struct sk_buff *skb)
11031da177e4SLinus Torvalds {
11041da177e4SLinus Torvalds 	return skb_shinfo(skb)->tso_segs;
11051da177e4SLinus Torvalds }
11061da177e4SLinus Torvalds 
11071da177e4SLinus Torvalds /* This is valid iff tcp_skb_pcount() > 1. */
11081da177e4SLinus Torvalds static inline int tcp_skb_mss(const struct sk_buff *skb)
11091da177e4SLinus Torvalds {
11101da177e4SLinus Torvalds 	return skb_shinfo(skb)->tso_size;
11111da177e4SLinus Torvalds }
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds static inline void tcp_dec_pcount_approx(__u32 *count,
11141da177e4SLinus Torvalds 					 const struct sk_buff *skb)
11151da177e4SLinus Torvalds {
11161da177e4SLinus Torvalds 	if (*count) {
11171da177e4SLinus Torvalds 		*count -= tcp_skb_pcount(skb);
11181da177e4SLinus Torvalds 		if ((int)*count < 0)
11191da177e4SLinus Torvalds 			*count = 0;
11201da177e4SLinus Torvalds 	}
11211da177e4SLinus Torvalds }
11221da177e4SLinus Torvalds 
11231da177e4SLinus Torvalds static inline void tcp_packets_out_inc(struct sock *sk,
11241da177e4SLinus Torvalds 				       struct tcp_sock *tp,
11251da177e4SLinus Torvalds 				       const struct sk_buff *skb)
11261da177e4SLinus Torvalds {
11271da177e4SLinus Torvalds 	int orig = tp->packets_out;
11281da177e4SLinus Torvalds 
11291da177e4SLinus Torvalds 	tp->packets_out += tcp_skb_pcount(skb);
11301da177e4SLinus Torvalds 	if (!orig)
11311da177e4SLinus Torvalds 		tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
11321da177e4SLinus Torvalds }
11331da177e4SLinus Torvalds 
11341da177e4SLinus Torvalds static inline void tcp_packets_out_dec(struct tcp_sock *tp,
11351da177e4SLinus Torvalds 				       const struct sk_buff *skb)
11361da177e4SLinus Torvalds {
11371da177e4SLinus Torvalds 	tp->packets_out -= tcp_skb_pcount(skb);
11381da177e4SLinus Torvalds }
11391da177e4SLinus Torvalds 
11401da177e4SLinus Torvalds /* This determines how many packets are "in the network" to the best
11411da177e4SLinus Torvalds  * of our knowledge.  In many cases it is conservative, but where
11421da177e4SLinus Torvalds  * detailed information is available from the receiver (via SACK
11431da177e4SLinus Torvalds  * blocks etc.) we can make more aggressive calculations.
11441da177e4SLinus Torvalds  *
11451da177e4SLinus Torvalds  * Use this for decisions involving congestion control, use just
11461da177e4SLinus Torvalds  * tp->packets_out to determine if the send queue is empty or not.
11471da177e4SLinus Torvalds  *
11481da177e4SLinus Torvalds  * Read this equation as:
11491da177e4SLinus Torvalds  *
11501da177e4SLinus Torvalds  *	"Packets sent once on transmission queue" MINUS
11511da177e4SLinus Torvalds  *	"Packets left network, but not honestly ACKed yet" PLUS
11521da177e4SLinus Torvalds  *	"Packets fast retransmitted"
11531da177e4SLinus Torvalds  */
11541da177e4SLinus Torvalds static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
11551da177e4SLinus Torvalds {
11561da177e4SLinus Torvalds 	return (tp->packets_out - tp->left_out + tp->retrans_out);
11571da177e4SLinus Torvalds }
11581da177e4SLinus Torvalds 
11591da177e4SLinus Torvalds /*
11601da177e4SLinus Torvalds  * Which congestion algorithim is in use on the connection.
11611da177e4SLinus Torvalds  */
11621da177e4SLinus Torvalds #define tcp_is_vegas(__tp)	((__tp)->adv_cong == TCP_VEGAS)
11631da177e4SLinus Torvalds #define tcp_is_westwood(__tp)	((__tp)->adv_cong == TCP_WESTWOOD)
11641da177e4SLinus Torvalds #define tcp_is_bic(__tp)	((__tp)->adv_cong == TCP_BIC)
11651da177e4SLinus Torvalds 
11661da177e4SLinus Torvalds /* Recalculate snd_ssthresh, we want to set it to:
11671da177e4SLinus Torvalds  *
11681da177e4SLinus Torvalds  * Reno:
11691da177e4SLinus Torvalds  * 	one half the current congestion window, but no
11701da177e4SLinus Torvalds  *	less than two segments
11711da177e4SLinus Torvalds  *
11721da177e4SLinus Torvalds  * BIC:
11731da177e4SLinus Torvalds  *	behave like Reno until low_window is reached,
11741da177e4SLinus Torvalds  *	then increase congestion window slowly
11751da177e4SLinus Torvalds  */
11761da177e4SLinus Torvalds static inline __u32 tcp_recalc_ssthresh(struct tcp_sock *tp)
11771da177e4SLinus Torvalds {
11781da177e4SLinus Torvalds 	if (tcp_is_bic(tp)) {
11791da177e4SLinus Torvalds 		if (sysctl_tcp_bic_fast_convergence &&
11801da177e4SLinus Torvalds 		    tp->snd_cwnd < tp->bictcp.last_max_cwnd)
11811da177e4SLinus Torvalds 			tp->bictcp.last_max_cwnd = (tp->snd_cwnd *
11821da177e4SLinus Torvalds 						    (BICTCP_BETA_SCALE
11831da177e4SLinus Torvalds 						     + sysctl_tcp_bic_beta))
11841da177e4SLinus Torvalds 				/ (2 * BICTCP_BETA_SCALE);
11851da177e4SLinus Torvalds 		else
11861da177e4SLinus Torvalds 			tp->bictcp.last_max_cwnd = tp->snd_cwnd;
11871da177e4SLinus Torvalds 
11881da177e4SLinus Torvalds 		if (tp->snd_cwnd > sysctl_tcp_bic_low_window)
11891da177e4SLinus Torvalds 			return max((tp->snd_cwnd * sysctl_tcp_bic_beta)
11901da177e4SLinus Torvalds 				   / BICTCP_BETA_SCALE, 2U);
11911da177e4SLinus Torvalds 	}
11921da177e4SLinus Torvalds 
11931da177e4SLinus Torvalds 	return max(tp->snd_cwnd >> 1U, 2U);
11941da177e4SLinus Torvalds }
11951da177e4SLinus Torvalds 
11961da177e4SLinus Torvalds /* Stop taking Vegas samples for now. */
11971da177e4SLinus Torvalds #define tcp_vegas_disable(__tp)	((__tp)->vegas.doing_vegas_now = 0)
11981da177e4SLinus Torvalds 
11991da177e4SLinus Torvalds static inline void tcp_vegas_enable(struct tcp_sock *tp)
12001da177e4SLinus Torvalds {
12011da177e4SLinus Torvalds 	/* There are several situations when we must "re-start" Vegas:
12021da177e4SLinus Torvalds 	 *
12031da177e4SLinus Torvalds 	 *  o when a connection is established
12041da177e4SLinus Torvalds 	 *  o after an RTO
12051da177e4SLinus Torvalds 	 *  o after fast recovery
12061da177e4SLinus Torvalds 	 *  o when we send a packet and there is no outstanding
12071da177e4SLinus Torvalds 	 *    unacknowledged data (restarting an idle connection)
12081da177e4SLinus Torvalds 	 *
12091da177e4SLinus Torvalds 	 * In these circumstances we cannot do a Vegas calculation at the
12101da177e4SLinus Torvalds 	 * end of the first RTT, because any calculation we do is using
12111da177e4SLinus Torvalds 	 * stale info -- both the saved cwnd and congestion feedback are
12121da177e4SLinus Torvalds 	 * stale.
12131da177e4SLinus Torvalds 	 *
12141da177e4SLinus Torvalds 	 * Instead we must wait until the completion of an RTT during
12151da177e4SLinus Torvalds 	 * which we actually receive ACKs.
12161da177e4SLinus Torvalds 	 */
12171da177e4SLinus Torvalds 
12181da177e4SLinus Torvalds 	/* Begin taking Vegas samples next time we send something. */
12191da177e4SLinus Torvalds 	tp->vegas.doing_vegas_now = 1;
12201da177e4SLinus Torvalds 
12211da177e4SLinus Torvalds 	/* Set the beginning of the next send window. */
12221da177e4SLinus Torvalds 	tp->vegas.beg_snd_nxt = tp->snd_nxt;
12231da177e4SLinus Torvalds 
12241da177e4SLinus Torvalds 	tp->vegas.cntRTT = 0;
12251da177e4SLinus Torvalds 	tp->vegas.minRTT = 0x7fffffff;
12261da177e4SLinus Torvalds }
12271da177e4SLinus Torvalds 
12281da177e4SLinus Torvalds /* Should we be taking Vegas samples right now? */
12291da177e4SLinus Torvalds #define tcp_vegas_enabled(__tp)	((__tp)->vegas.doing_vegas_now)
12301da177e4SLinus Torvalds 
12311da177e4SLinus Torvalds extern void tcp_ca_init(struct tcp_sock *tp);
12321da177e4SLinus Torvalds 
12331da177e4SLinus Torvalds static inline void tcp_set_ca_state(struct tcp_sock *tp, u8 ca_state)
12341da177e4SLinus Torvalds {
12351da177e4SLinus Torvalds 	if (tcp_is_vegas(tp)) {
12361da177e4SLinus Torvalds 		if (ca_state == TCP_CA_Open)
12371da177e4SLinus Torvalds 			tcp_vegas_enable(tp);
12381da177e4SLinus Torvalds 		else
12391da177e4SLinus Torvalds 			tcp_vegas_disable(tp);
12401da177e4SLinus Torvalds 	}
12411da177e4SLinus Torvalds 	tp->ca_state = ca_state;
12421da177e4SLinus Torvalds }
12431da177e4SLinus Torvalds 
12441da177e4SLinus Torvalds /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
12451da177e4SLinus Torvalds  * The exception is rate halving phase, when cwnd is decreasing towards
12461da177e4SLinus Torvalds  * ssthresh.
12471da177e4SLinus Torvalds  */
12481da177e4SLinus Torvalds static inline __u32 tcp_current_ssthresh(struct tcp_sock *tp)
12491da177e4SLinus Torvalds {
12501da177e4SLinus Torvalds 	if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery))
12511da177e4SLinus Torvalds 		return tp->snd_ssthresh;
12521da177e4SLinus Torvalds 	else
12531da177e4SLinus Torvalds 		return max(tp->snd_ssthresh,
12541da177e4SLinus Torvalds 			   ((tp->snd_cwnd >> 1) +
12551da177e4SLinus Torvalds 			    (tp->snd_cwnd >> 2)));
12561da177e4SLinus Torvalds }
12571da177e4SLinus Torvalds 
12581da177e4SLinus Torvalds static inline void tcp_sync_left_out(struct tcp_sock *tp)
12591da177e4SLinus Torvalds {
12601da177e4SLinus Torvalds 	if (tp->rx_opt.sack_ok &&
12611da177e4SLinus Torvalds 	    (tp->sacked_out >= tp->packets_out - tp->lost_out))
12621da177e4SLinus Torvalds 		tp->sacked_out = tp->packets_out - tp->lost_out;
12631da177e4SLinus Torvalds 	tp->left_out = tp->sacked_out + tp->lost_out;
12641da177e4SLinus Torvalds }
12651da177e4SLinus Torvalds 
12661da177e4SLinus Torvalds extern void tcp_cwnd_application_limited(struct sock *sk);
12671da177e4SLinus Torvalds 
12681da177e4SLinus Torvalds /* Congestion window validation. (RFC2861) */
12691da177e4SLinus Torvalds 
12701da177e4SLinus Torvalds static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
12711da177e4SLinus Torvalds {
12721da177e4SLinus Torvalds 	__u32 packets_out = tp->packets_out;
12731da177e4SLinus Torvalds 
12741da177e4SLinus Torvalds 	if (packets_out >= tp->snd_cwnd) {
12751da177e4SLinus Torvalds 		/* Network is feed fully. */
12761da177e4SLinus Torvalds 		tp->snd_cwnd_used = 0;
12771da177e4SLinus Torvalds 		tp->snd_cwnd_stamp = tcp_time_stamp;
12781da177e4SLinus Torvalds 	} else {
12791da177e4SLinus Torvalds 		/* Network starves. */
12801da177e4SLinus Torvalds 		if (tp->packets_out > tp->snd_cwnd_used)
12811da177e4SLinus Torvalds 			tp->snd_cwnd_used = tp->packets_out;
12821da177e4SLinus Torvalds 
12831da177e4SLinus Torvalds 		if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto)
12841da177e4SLinus Torvalds 			tcp_cwnd_application_limited(sk);
12851da177e4SLinus Torvalds 	}
12861da177e4SLinus Torvalds }
12871da177e4SLinus Torvalds 
12881da177e4SLinus Torvalds /* Set slow start threshould and cwnd not falling to slow start */
12891da177e4SLinus Torvalds static inline void __tcp_enter_cwr(struct tcp_sock *tp)
12901da177e4SLinus Torvalds {
12911da177e4SLinus Torvalds 	tp->undo_marker = 0;
12921da177e4SLinus Torvalds 	tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
12931da177e4SLinus Torvalds 	tp->snd_cwnd = min(tp->snd_cwnd,
12941da177e4SLinus Torvalds 			   tcp_packets_in_flight(tp) + 1U);
12951da177e4SLinus Torvalds 	tp->snd_cwnd_cnt = 0;
12961da177e4SLinus Torvalds 	tp->high_seq = tp->snd_nxt;
12971da177e4SLinus Torvalds 	tp->snd_cwnd_stamp = tcp_time_stamp;
12981da177e4SLinus Torvalds 	TCP_ECN_queue_cwr(tp);
12991da177e4SLinus Torvalds }
13001da177e4SLinus Torvalds 
13011da177e4SLinus Torvalds static inline void tcp_enter_cwr(struct tcp_sock *tp)
13021da177e4SLinus Torvalds {
13031da177e4SLinus Torvalds 	tp->prior_ssthresh = 0;
13041da177e4SLinus Torvalds 	if (tp->ca_state < TCP_CA_CWR) {
13051da177e4SLinus Torvalds 		__tcp_enter_cwr(tp);
13061da177e4SLinus Torvalds 		tcp_set_ca_state(tp, TCP_CA_CWR);
13071da177e4SLinus Torvalds 	}
13081da177e4SLinus Torvalds }
13091da177e4SLinus Torvalds 
13101da177e4SLinus Torvalds extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
13111da177e4SLinus Torvalds 
13121da177e4SLinus Torvalds /* Slow start with delack produces 3 packets of burst, so that
13131da177e4SLinus Torvalds  * it is safe "de facto".
13141da177e4SLinus Torvalds  */
13151da177e4SLinus Torvalds static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
13161da177e4SLinus Torvalds {
13171da177e4SLinus Torvalds 	return 3;
13181da177e4SLinus Torvalds }
13191da177e4SLinus Torvalds 
13201da177e4SLinus Torvalds static __inline__ int tcp_minshall_check(const struct tcp_sock *tp)
13211da177e4SLinus Torvalds {
13221da177e4SLinus Torvalds 	return after(tp->snd_sml,tp->snd_una) &&
13231da177e4SLinus Torvalds 		!after(tp->snd_sml, tp->snd_nxt);
13241da177e4SLinus Torvalds }
13251da177e4SLinus Torvalds 
13261da177e4SLinus Torvalds static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss,
13271da177e4SLinus Torvalds 					   const struct sk_buff *skb)
13281da177e4SLinus Torvalds {
13291da177e4SLinus Torvalds 	if (skb->len < mss)
13301da177e4SLinus Torvalds 		tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
13311da177e4SLinus Torvalds }
13321da177e4SLinus Torvalds 
13331da177e4SLinus Torvalds /* Return 0, if packet can be sent now without violation Nagle's rules:
13341da177e4SLinus Torvalds    1. It is full sized.
13351da177e4SLinus Torvalds    2. Or it contains FIN.
13361da177e4SLinus Torvalds    3. Or TCP_NODELAY was set.
13371da177e4SLinus Torvalds    4. Or TCP_CORK is not set, and all sent packets are ACKed.
13381da177e4SLinus Torvalds       With Minshall's modification: all sent small packets are ACKed.
13391da177e4SLinus Torvalds  */
13401da177e4SLinus Torvalds 
13411da177e4SLinus Torvalds static __inline__ int
13421da177e4SLinus Torvalds tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb,
13431da177e4SLinus Torvalds 		unsigned mss_now, int nonagle)
13441da177e4SLinus Torvalds {
13451da177e4SLinus Torvalds 	return (skb->len < mss_now &&
13461da177e4SLinus Torvalds 		!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
13471da177e4SLinus Torvalds 		((nonagle&TCP_NAGLE_CORK) ||
13481da177e4SLinus Torvalds 		 (!nonagle &&
13491da177e4SLinus Torvalds 		  tp->packets_out &&
13501da177e4SLinus Torvalds 		  tcp_minshall_check(tp))));
13511da177e4SLinus Torvalds }
13521da177e4SLinus Torvalds 
1353d5ac99a6SDavid S. Miller extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *);
13541da177e4SLinus Torvalds 
13551da177e4SLinus Torvalds /* This checks if the data bearing packet SKB (usually sk->sk_send_head)
13561da177e4SLinus Torvalds  * should be put on the wire right now.
13571da177e4SLinus Torvalds  */
1358d5ac99a6SDavid S. Miller static __inline__ int tcp_snd_test(struct sock *sk,
13591da177e4SLinus Torvalds 				   struct sk_buff *skb,
13601da177e4SLinus Torvalds 				   unsigned cur_mss, int nonagle)
13611da177e4SLinus Torvalds {
1362d5ac99a6SDavid S. Miller 	struct tcp_sock *tp = tcp_sk(sk);
13631da177e4SLinus Torvalds 	int pkts = tcp_skb_pcount(skb);
13641da177e4SLinus Torvalds 
13651da177e4SLinus Torvalds 	if (!pkts) {
1366d5ac99a6SDavid S. Miller 		tcp_set_skb_tso_segs(sk, skb);
13671da177e4SLinus Torvalds 		pkts = tcp_skb_pcount(skb);
13681da177e4SLinus Torvalds 	}
13691da177e4SLinus Torvalds 
13701da177e4SLinus Torvalds 	/*	RFC 1122 - section 4.2.3.4
13711da177e4SLinus Torvalds 	 *
13721da177e4SLinus Torvalds 	 *	We must queue if
13731da177e4SLinus Torvalds 	 *
13741da177e4SLinus Torvalds 	 *	a) The right edge of this frame exceeds the window
13751da177e4SLinus Torvalds 	 *	b) There are packets in flight and we have a small segment
13761da177e4SLinus Torvalds 	 *	   [SWS avoidance and Nagle algorithm]
13771da177e4SLinus Torvalds 	 *	   (part of SWS is done on packetization)
13781da177e4SLinus Torvalds 	 *	   Minshall version sounds: there are no _small_
13791da177e4SLinus Torvalds 	 *	   segments in flight. (tcp_nagle_check)
13801da177e4SLinus Torvalds 	 *	c) We have too many packets 'in flight'
13811da177e4SLinus Torvalds 	 *
13821da177e4SLinus Torvalds 	 * 	Don't use the nagle rule for urgent data (or
13831da177e4SLinus Torvalds 	 *	for the final FIN -DaveM).
13841da177e4SLinus Torvalds 	 *
13851da177e4SLinus Torvalds 	 *	Also, Nagle rule does not apply to frames, which
13861da177e4SLinus Torvalds 	 *	sit in the middle of queue (they have no chances
13871da177e4SLinus Torvalds 	 *	to get new data) and if room at tail of skb is
13881da177e4SLinus Torvalds 	 *	not enough to save something seriously (<32 for now).
13891da177e4SLinus Torvalds 	 */
13901da177e4SLinus Torvalds 
13911da177e4SLinus Torvalds 	/* Don't be strict about the congestion window for the
13921da177e4SLinus Torvalds 	 * final FIN frame.  -DaveM
13931da177e4SLinus Torvalds 	 */
13941da177e4SLinus Torvalds 	return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode
13951da177e4SLinus Torvalds 		 || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) &&
13961da177e4SLinus Torvalds 		(((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) ||
13971da177e4SLinus Torvalds 		 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
13981da177e4SLinus Torvalds 		!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd));
13991da177e4SLinus Torvalds }
14001da177e4SLinus Torvalds 
14011da177e4SLinus Torvalds static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
14021da177e4SLinus Torvalds {
14031da177e4SLinus Torvalds 	if (!tp->packets_out && !tp->pending)
14041da177e4SLinus Torvalds 		tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
14051da177e4SLinus Torvalds }
14061da177e4SLinus Torvalds 
14071da177e4SLinus Torvalds static __inline__ int tcp_skb_is_last(const struct sock *sk,
14081da177e4SLinus Torvalds 				      const struct sk_buff *skb)
14091da177e4SLinus Torvalds {
14101da177e4SLinus Torvalds 	return skb->next == (struct sk_buff *)&sk->sk_write_queue;
14111da177e4SLinus Torvalds }
14121da177e4SLinus Torvalds 
14131da177e4SLinus Torvalds /* Push out any pending frames which were held back due to
14141da177e4SLinus Torvalds  * TCP_CORK or attempt at coalescing tiny packets.
14151da177e4SLinus Torvalds  * The socket must be locked by the caller.
14161da177e4SLinus Torvalds  */
14171da177e4SLinus Torvalds static __inline__ void __tcp_push_pending_frames(struct sock *sk,
14181da177e4SLinus Torvalds 						 struct tcp_sock *tp,
14191da177e4SLinus Torvalds 						 unsigned cur_mss,
14201da177e4SLinus Torvalds 						 int nonagle)
14211da177e4SLinus Torvalds {
14221da177e4SLinus Torvalds 	struct sk_buff *skb = sk->sk_send_head;
14231da177e4SLinus Torvalds 
14241da177e4SLinus Torvalds 	if (skb) {
14251da177e4SLinus Torvalds 		if (!tcp_skb_is_last(sk, skb))
14261da177e4SLinus Torvalds 			nonagle = TCP_NAGLE_PUSH;
1427d5ac99a6SDavid S. Miller 		if (!tcp_snd_test(sk, skb, cur_mss, nonagle) ||
14281da177e4SLinus Torvalds 		    tcp_write_xmit(sk, nonagle))
14291da177e4SLinus Torvalds 			tcp_check_probe_timer(sk, tp);
14301da177e4SLinus Torvalds 	}
14311da177e4SLinus Torvalds 	tcp_cwnd_validate(sk, tp);
14321da177e4SLinus Torvalds }
14331da177e4SLinus Torvalds 
14341da177e4SLinus Torvalds static __inline__ void tcp_push_pending_frames(struct sock *sk,
14351da177e4SLinus Torvalds 					       struct tcp_sock *tp)
14361da177e4SLinus Torvalds {
14371da177e4SLinus Torvalds 	__tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
14381da177e4SLinus Torvalds }
14391da177e4SLinus Torvalds 
14401da177e4SLinus Torvalds static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
14411da177e4SLinus Torvalds {
14421da177e4SLinus Torvalds 	struct sk_buff *skb = sk->sk_send_head;
14431da177e4SLinus Torvalds 
14441da177e4SLinus Torvalds 	return (skb &&
1445d5ac99a6SDavid S. Miller 		tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
14461da177e4SLinus Torvalds 			     tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle));
14471da177e4SLinus Torvalds }
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
14501da177e4SLinus Torvalds {
14511da177e4SLinus Torvalds 	tp->snd_wl1 = seq;
14521da177e4SLinus Torvalds }
14531da177e4SLinus Torvalds 
14541da177e4SLinus Torvalds static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
14551da177e4SLinus Torvalds {
14561da177e4SLinus Torvalds 	tp->snd_wl1 = seq;
14571da177e4SLinus Torvalds }
14581da177e4SLinus Torvalds 
14591da177e4SLinus Torvalds extern void tcp_destroy_sock(struct sock *sk);
14601da177e4SLinus Torvalds 
14611da177e4SLinus Torvalds 
14621da177e4SLinus Torvalds /*
14631da177e4SLinus Torvalds  * Calculate(/check) TCP checksum
14641da177e4SLinus Torvalds  */
14651da177e4SLinus Torvalds static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
14661da177e4SLinus Torvalds 				   unsigned long saddr, unsigned long daddr,
14671da177e4SLinus Torvalds 				   unsigned long base)
14681da177e4SLinus Torvalds {
14691da177e4SLinus Torvalds 	return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
14701da177e4SLinus Torvalds }
14711da177e4SLinus Torvalds 
14721da177e4SLinus Torvalds static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
14731da177e4SLinus Torvalds {
14741da177e4SLinus Torvalds 	return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
14751da177e4SLinus Torvalds }
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
14781da177e4SLinus Torvalds {
14791da177e4SLinus Torvalds 	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
14801da177e4SLinus Torvalds 		__tcp_checksum_complete(skb);
14811da177e4SLinus Torvalds }
14821da177e4SLinus Torvalds 
14831da177e4SLinus Torvalds /* Prequeue for VJ style copy to user, combined with checksumming. */
14841da177e4SLinus Torvalds 
14851da177e4SLinus Torvalds static __inline__ void tcp_prequeue_init(struct tcp_sock *tp)
14861da177e4SLinus Torvalds {
14871da177e4SLinus Torvalds 	tp->ucopy.task = NULL;
14881da177e4SLinus Torvalds 	tp->ucopy.len = 0;
14891da177e4SLinus Torvalds 	tp->ucopy.memory = 0;
14901da177e4SLinus Torvalds 	skb_queue_head_init(&tp->ucopy.prequeue);
14911da177e4SLinus Torvalds }
14921da177e4SLinus Torvalds 
14931da177e4SLinus Torvalds /* Packet is added to VJ-style prequeue for processing in process
14941da177e4SLinus Torvalds  * context, if a reader task is waiting. Apparently, this exciting
14951da177e4SLinus Torvalds  * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93)
14961da177e4SLinus Torvalds  * failed somewhere. Latency? Burstiness? Well, at least now we will
14971da177e4SLinus Torvalds  * see, why it failed. 8)8)				  --ANK
14981da177e4SLinus Torvalds  *
14991da177e4SLinus Torvalds  * NOTE: is this not too big to inline?
15001da177e4SLinus Torvalds  */
15011da177e4SLinus Torvalds static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
15021da177e4SLinus Torvalds {
15031da177e4SLinus Torvalds 	struct tcp_sock *tp = tcp_sk(sk);
15041da177e4SLinus Torvalds 
15051da177e4SLinus Torvalds 	if (!sysctl_tcp_low_latency && tp->ucopy.task) {
15061da177e4SLinus Torvalds 		__skb_queue_tail(&tp->ucopy.prequeue, skb);
15071da177e4SLinus Torvalds 		tp->ucopy.memory += skb->truesize;
15081da177e4SLinus Torvalds 		if (tp->ucopy.memory > sk->sk_rcvbuf) {
15091da177e4SLinus Torvalds 			struct sk_buff *skb1;
15101da177e4SLinus Torvalds 
15111da177e4SLinus Torvalds 			BUG_ON(sock_owned_by_user(sk));
15121da177e4SLinus Torvalds 
15131da177e4SLinus Torvalds 			while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
15141da177e4SLinus Torvalds 				sk->sk_backlog_rcv(sk, skb1);
15151da177e4SLinus Torvalds 				NET_INC_STATS_BH(LINUX_MIB_TCPPREQUEUEDROPPED);
15161da177e4SLinus Torvalds 			}
15171da177e4SLinus Torvalds 
15181da177e4SLinus Torvalds 			tp->ucopy.memory = 0;
15191da177e4SLinus Torvalds 		} else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
15201da177e4SLinus Torvalds 			wake_up_interruptible(sk->sk_sleep);
15211da177e4SLinus Torvalds 			if (!tcp_ack_scheduled(tp))
15221da177e4SLinus Torvalds 				tcp_reset_xmit_timer(sk, TCP_TIME_DACK, (3*TCP_RTO_MIN)/4);
15231da177e4SLinus Torvalds 		}
15241da177e4SLinus Torvalds 		return 1;
15251da177e4SLinus Torvalds 	}
15261da177e4SLinus Torvalds 	return 0;
15271da177e4SLinus Torvalds }
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 
15301da177e4SLinus Torvalds #undef STATE_TRACE
15311da177e4SLinus Torvalds 
15321da177e4SLinus Torvalds #ifdef STATE_TRACE
15331da177e4SLinus Torvalds static const char *statename[]={
15341da177e4SLinus Torvalds 	"Unused","Established","Syn Sent","Syn Recv",
15351da177e4SLinus Torvalds 	"Fin Wait 1","Fin Wait 2","Time Wait", "Close",
15361da177e4SLinus Torvalds 	"Close Wait","Last ACK","Listen","Closing"
15371da177e4SLinus Torvalds };
15381da177e4SLinus Torvalds #endif
15391da177e4SLinus Torvalds 
15401da177e4SLinus Torvalds static __inline__ void tcp_set_state(struct sock *sk, int state)
15411da177e4SLinus Torvalds {
15421da177e4SLinus Torvalds 	int oldstate = sk->sk_state;
15431da177e4SLinus Torvalds 
15441da177e4SLinus Torvalds 	switch (state) {
15451da177e4SLinus Torvalds 	case TCP_ESTABLISHED:
15461da177e4SLinus Torvalds 		if (oldstate != TCP_ESTABLISHED)
15471da177e4SLinus Torvalds 			TCP_INC_STATS(TCP_MIB_CURRESTAB);
15481da177e4SLinus Torvalds 		break;
15491da177e4SLinus Torvalds 
15501da177e4SLinus Torvalds 	case TCP_CLOSE:
15511da177e4SLinus Torvalds 		if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
15521da177e4SLinus Torvalds 			TCP_INC_STATS(TCP_MIB_ESTABRESETS);
15531da177e4SLinus Torvalds 
15541da177e4SLinus Torvalds 		sk->sk_prot->unhash(sk);
15551da177e4SLinus Torvalds 		if (tcp_sk(sk)->bind_hash &&
15561da177e4SLinus Torvalds 		    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
15571da177e4SLinus Torvalds 			tcp_put_port(sk);
15581da177e4SLinus Torvalds 		/* fall through */
15591da177e4SLinus Torvalds 	default:
15601da177e4SLinus Torvalds 		if (oldstate==TCP_ESTABLISHED)
15611da177e4SLinus Torvalds 			TCP_DEC_STATS(TCP_MIB_CURRESTAB);
15621da177e4SLinus Torvalds 	}
15631da177e4SLinus Torvalds 
15641da177e4SLinus Torvalds 	/* Change state AFTER socket is unhashed to avoid closed
15651da177e4SLinus Torvalds 	 * socket sitting in hash tables.
15661da177e4SLinus Torvalds 	 */
15671da177e4SLinus Torvalds 	sk->sk_state = state;
15681da177e4SLinus Torvalds 
15691da177e4SLinus Torvalds #ifdef STATE_TRACE
15701da177e4SLinus Torvalds 	SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
15711da177e4SLinus Torvalds #endif
15721da177e4SLinus Torvalds }
15731da177e4SLinus Torvalds 
15741da177e4SLinus Torvalds static __inline__ void tcp_done(struct sock *sk)
15751da177e4SLinus Torvalds {
15761da177e4SLinus Torvalds 	tcp_set_state(sk, TCP_CLOSE);
15771da177e4SLinus Torvalds 	tcp_clear_xmit_timers(sk);
15781da177e4SLinus Torvalds 
15791da177e4SLinus Torvalds 	sk->sk_shutdown = SHUTDOWN_MASK;
15801da177e4SLinus Torvalds 
15811da177e4SLinus Torvalds 	if (!sock_flag(sk, SOCK_DEAD))
15821da177e4SLinus Torvalds 		sk->sk_state_change(sk);
15831da177e4SLinus Torvalds 	else
15841da177e4SLinus Torvalds 		tcp_destroy_sock(sk);
15851da177e4SLinus Torvalds }
15861da177e4SLinus Torvalds 
15871da177e4SLinus Torvalds static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt)
15881da177e4SLinus Torvalds {
15891da177e4SLinus Torvalds 	rx_opt->dsack = 0;
15901da177e4SLinus Torvalds 	rx_opt->eff_sacks = 0;
15911da177e4SLinus Torvalds 	rx_opt->num_sacks = 0;
15921da177e4SLinus Torvalds }
15931da177e4SLinus Torvalds 
15941da177e4SLinus Torvalds static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, __u32 tstamp)
15951da177e4SLinus Torvalds {
15961da177e4SLinus Torvalds 	if (tp->rx_opt.tstamp_ok) {
15971da177e4SLinus Torvalds 		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
15981da177e4SLinus Torvalds 					  (TCPOPT_NOP << 16) |
15991da177e4SLinus Torvalds 					  (TCPOPT_TIMESTAMP << 8) |
16001da177e4SLinus Torvalds 					  TCPOLEN_TIMESTAMP);
16011da177e4SLinus Torvalds 		*ptr++ = htonl(tstamp);
16021da177e4SLinus Torvalds 		*ptr++ = htonl(tp->rx_opt.ts_recent);
16031da177e4SLinus Torvalds 	}
16041da177e4SLinus Torvalds 	if (tp->rx_opt.eff_sacks) {
16051da177e4SLinus Torvalds 		struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks;
16061da177e4SLinus Torvalds 		int this_sack;
16071da177e4SLinus Torvalds 
16081da177e4SLinus Torvalds 		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
16091da177e4SLinus Torvalds 					  (TCPOPT_NOP << 16) |
16101da177e4SLinus Torvalds 					  (TCPOPT_SACK << 8) |
16111da177e4SLinus Torvalds 					  (TCPOLEN_SACK_BASE +
16121da177e4SLinus Torvalds 					   (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)));
16131da177e4SLinus Torvalds 		for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) {
16141da177e4SLinus Torvalds 			*ptr++ = htonl(sp[this_sack].start_seq);
16151da177e4SLinus Torvalds 			*ptr++ = htonl(sp[this_sack].end_seq);
16161da177e4SLinus Torvalds 		}
16171da177e4SLinus Torvalds 		if (tp->rx_opt.dsack) {
16181da177e4SLinus Torvalds 			tp->rx_opt.dsack = 0;
16191da177e4SLinus Torvalds 			tp->rx_opt.eff_sacks--;
16201da177e4SLinus Torvalds 		}
16211da177e4SLinus Torvalds 	}
16221da177e4SLinus Torvalds }
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds /* Construct a tcp options header for a SYN or SYN_ACK packet.
16251da177e4SLinus Torvalds  * If this is every changed make sure to change the definition of
16261da177e4SLinus Torvalds  * MAX_SYN_SIZE to match the new maximum number of options that you
16271da177e4SLinus Torvalds  * can generate.
16281da177e4SLinus Torvalds  */
16291da177e4SLinus Torvalds static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
16301da177e4SLinus Torvalds 					     int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent)
16311da177e4SLinus Torvalds {
16321da177e4SLinus Torvalds 	/* We always get an MSS option.
16331da177e4SLinus Torvalds 	 * The option bytes which will be seen in normal data
16341da177e4SLinus Torvalds 	 * packets should timestamps be used, must be in the MSS
16351da177e4SLinus Torvalds 	 * advertised.  But we subtract them from tp->mss_cache so
16361da177e4SLinus Torvalds 	 * that calculations in tcp_sendmsg are simpler etc.
16371da177e4SLinus Torvalds 	 * So account for this fact here if necessary.  If we
16381da177e4SLinus Torvalds 	 * don't do this correctly, as a receiver we won't
16391da177e4SLinus Torvalds 	 * recognize data packets as being full sized when we
16401da177e4SLinus Torvalds 	 * should, and thus we won't abide by the delayed ACK
16411da177e4SLinus Torvalds 	 * rules correctly.
16421da177e4SLinus Torvalds 	 * SACKs don't matter, we never delay an ACK when we
16431da177e4SLinus Torvalds 	 * have any of those going out.
16441da177e4SLinus Torvalds 	 */
16451da177e4SLinus Torvalds 	*ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
16461da177e4SLinus Torvalds 	if (ts) {
16471da177e4SLinus Torvalds 		if(sack)
16481da177e4SLinus Torvalds 			*ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
16491da177e4SLinus Torvalds 						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
16501da177e4SLinus Torvalds 		else
16511da177e4SLinus Torvalds 			*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
16521da177e4SLinus Torvalds 						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
16531da177e4SLinus Torvalds 		*ptr++ = htonl(tstamp);		/* TSVAL */
16541da177e4SLinus Torvalds 		*ptr++ = htonl(ts_recent);	/* TSECR */
16551da177e4SLinus Torvalds 	} else if(sack)
16561da177e4SLinus Torvalds 		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
16571da177e4SLinus Torvalds 					  (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
16581da177e4SLinus Torvalds 	if (offer_wscale)
16591da177e4SLinus Torvalds 		*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
16601da177e4SLinus Torvalds }
16611da177e4SLinus Torvalds 
16621da177e4SLinus Torvalds /* Determine a window scaling and initial window to offer. */
16631da177e4SLinus Torvalds extern void tcp_select_initial_window(int __space, __u32 mss,
16641da177e4SLinus Torvalds 				      __u32 *rcv_wnd, __u32 *window_clamp,
16651da177e4SLinus Torvalds 				      int wscale_ok, __u8 *rcv_wscale);
16661da177e4SLinus Torvalds 
16671da177e4SLinus Torvalds static inline int tcp_win_from_space(int space)
16681da177e4SLinus Torvalds {
16691da177e4SLinus Torvalds 	return sysctl_tcp_adv_win_scale<=0 ?
16701da177e4SLinus Torvalds 		(space>>(-sysctl_tcp_adv_win_scale)) :
16711da177e4SLinus Torvalds 		space - (space>>sysctl_tcp_adv_win_scale);
16721da177e4SLinus Torvalds }
16731da177e4SLinus Torvalds 
16741da177e4SLinus Torvalds /* Note: caller must be prepared to deal with negative returns */
16751da177e4SLinus Torvalds static inline int tcp_space(const struct sock *sk)
16761da177e4SLinus Torvalds {
16771da177e4SLinus Torvalds 	return tcp_win_from_space(sk->sk_rcvbuf -
16781da177e4SLinus Torvalds 				  atomic_read(&sk->sk_rmem_alloc));
16791da177e4SLinus Torvalds }
16801da177e4SLinus Torvalds 
16811da177e4SLinus Torvalds static inline int tcp_full_space(const struct sock *sk)
16821da177e4SLinus Torvalds {
16831da177e4SLinus Torvalds 	return tcp_win_from_space(sk->sk_rcvbuf);
16841da177e4SLinus Torvalds }
16851da177e4SLinus Torvalds 
16861da177e4SLinus Torvalds static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
16871da177e4SLinus Torvalds 					 struct sock *child)
16881da177e4SLinus Torvalds {
16891da177e4SLinus Torvalds 	struct tcp_sock *tp = tcp_sk(sk);
16901da177e4SLinus Torvalds 
16911da177e4SLinus Torvalds 	req->sk = child;
16921da177e4SLinus Torvalds 	sk_acceptq_added(sk);
16931da177e4SLinus Torvalds 
16941da177e4SLinus Torvalds 	if (!tp->accept_queue_tail) {
16951da177e4SLinus Torvalds 		tp->accept_queue = req;
16961da177e4SLinus Torvalds 	} else {
16971da177e4SLinus Torvalds 		tp->accept_queue_tail->dl_next = req;
16981da177e4SLinus Torvalds 	}
16991da177e4SLinus Torvalds 	tp->accept_queue_tail = req;
17001da177e4SLinus Torvalds 	req->dl_next = NULL;
17011da177e4SLinus Torvalds }
17021da177e4SLinus Torvalds 
17031da177e4SLinus Torvalds struct tcp_listen_opt
17041da177e4SLinus Torvalds {
17051da177e4SLinus Torvalds 	u8			max_qlen_log;	/* log_2 of maximal queued SYNs */
17061da177e4SLinus Torvalds 	int			qlen;
17071da177e4SLinus Torvalds 	int			qlen_young;
17081da177e4SLinus Torvalds 	int			clock_hand;
17091da177e4SLinus Torvalds 	u32			hash_rnd;
17101da177e4SLinus Torvalds 	struct open_request	*syn_table[TCP_SYNQ_HSIZE];
17111da177e4SLinus Torvalds };
17121da177e4SLinus Torvalds 
17131da177e4SLinus Torvalds static inline void
17141da177e4SLinus Torvalds tcp_synq_removed(struct sock *sk, struct open_request *req)
17151da177e4SLinus Torvalds {
17161da177e4SLinus Torvalds 	struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
17171da177e4SLinus Torvalds 
17181da177e4SLinus Torvalds 	if (--lopt->qlen == 0)
17191da177e4SLinus Torvalds 		tcp_delete_keepalive_timer(sk);
17201da177e4SLinus Torvalds 	if (req->retrans == 0)
17211da177e4SLinus Torvalds 		lopt->qlen_young--;
17221da177e4SLinus Torvalds }
17231da177e4SLinus Torvalds 
17241da177e4SLinus Torvalds static inline void tcp_synq_added(struct sock *sk)
17251da177e4SLinus Torvalds {
17261da177e4SLinus Torvalds 	struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
17271da177e4SLinus Torvalds 
17281da177e4SLinus Torvalds 	if (lopt->qlen++ == 0)
17291da177e4SLinus Torvalds 		tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT);
17301da177e4SLinus Torvalds 	lopt->qlen_young++;
17311da177e4SLinus Torvalds }
17321da177e4SLinus Torvalds 
17331da177e4SLinus Torvalds static inline int tcp_synq_len(struct sock *sk)
17341da177e4SLinus Torvalds {
17351da177e4SLinus Torvalds 	return tcp_sk(sk)->listen_opt->qlen;
17361da177e4SLinus Torvalds }
17371da177e4SLinus Torvalds 
17381da177e4SLinus Torvalds static inline int tcp_synq_young(struct sock *sk)
17391da177e4SLinus Torvalds {
17401da177e4SLinus Torvalds 	return tcp_sk(sk)->listen_opt->qlen_young;
17411da177e4SLinus Torvalds }
17421da177e4SLinus Torvalds 
17431da177e4SLinus Torvalds static inline int tcp_synq_is_full(struct sock *sk)
17441da177e4SLinus Torvalds {
17451da177e4SLinus Torvalds 	return tcp_synq_len(sk) >> tcp_sk(sk)->listen_opt->max_qlen_log;
17461da177e4SLinus Torvalds }
17471da177e4SLinus Torvalds 
17481da177e4SLinus Torvalds static inline void tcp_synq_unlink(struct tcp_sock *tp, struct open_request *req,
17491da177e4SLinus Torvalds 				       struct open_request **prev)
17501da177e4SLinus Torvalds {
17511da177e4SLinus Torvalds 	write_lock(&tp->syn_wait_lock);
17521da177e4SLinus Torvalds 	*prev = req->dl_next;
17531da177e4SLinus Torvalds 	write_unlock(&tp->syn_wait_lock);
17541da177e4SLinus Torvalds }
17551da177e4SLinus Torvalds 
17561da177e4SLinus Torvalds static inline void tcp_synq_drop(struct sock *sk, struct open_request *req,
17571da177e4SLinus Torvalds 				     struct open_request **prev)
17581da177e4SLinus Torvalds {
17591da177e4SLinus Torvalds 	tcp_synq_unlink(tcp_sk(sk), req, prev);
17601da177e4SLinus Torvalds 	tcp_synq_removed(sk, req);
17611da177e4SLinus Torvalds 	tcp_openreq_free(req);
17621da177e4SLinus Torvalds }
17631da177e4SLinus Torvalds 
17641da177e4SLinus Torvalds static __inline__ void tcp_openreq_init(struct open_request *req,
17651da177e4SLinus Torvalds 					struct tcp_options_received *rx_opt,
17661da177e4SLinus Torvalds 					struct sk_buff *skb)
17671da177e4SLinus Torvalds {
1768*2e6599cbSArnaldo Carvalho de Melo 	struct inet_request_sock *ireq = inet_rsk(req);
1769*2e6599cbSArnaldo Carvalho de Melo 
17701da177e4SLinus Torvalds 	req->rcv_wnd = 0;		/* So that tcp_send_synack() knows! */
1771*2e6599cbSArnaldo Carvalho de Melo 	tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq;
17721da177e4SLinus Torvalds 	req->mss = rx_opt->mss_clamp;
17731da177e4SLinus Torvalds 	req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0;
1774*2e6599cbSArnaldo Carvalho de Melo 	ireq->tstamp_ok = rx_opt->tstamp_ok;
1775*2e6599cbSArnaldo Carvalho de Melo 	ireq->sack_ok = rx_opt->sack_ok;
1776*2e6599cbSArnaldo Carvalho de Melo 	ireq->snd_wscale = rx_opt->snd_wscale;
1777*2e6599cbSArnaldo Carvalho de Melo 	ireq->wscale_ok = rx_opt->wscale_ok;
1778*2e6599cbSArnaldo Carvalho de Melo 	ireq->acked = 0;
1779*2e6599cbSArnaldo Carvalho de Melo 	ireq->ecn_ok = 0;
1780*2e6599cbSArnaldo Carvalho de Melo 	ireq->rmt_port = skb->h.th->source;
17811da177e4SLinus Torvalds }
17821da177e4SLinus Torvalds 
17831da177e4SLinus Torvalds extern void tcp_enter_memory_pressure(void);
17841da177e4SLinus Torvalds 
17851da177e4SLinus Torvalds extern void tcp_listen_wlock(void);
17861da177e4SLinus Torvalds 
17871da177e4SLinus Torvalds /* - We may sleep inside this lock.
17881da177e4SLinus Torvalds  * - If sleeping is not required (or called from BH),
17891da177e4SLinus Torvalds  *   use plain read_(un)lock(&tcp_lhash_lock).
17901da177e4SLinus Torvalds  */
17911da177e4SLinus Torvalds 
17921da177e4SLinus Torvalds static inline void tcp_listen_lock(void)
17931da177e4SLinus Torvalds {
17941da177e4SLinus Torvalds 	/* read_lock synchronizes to candidates to writers */
17951da177e4SLinus Torvalds 	read_lock(&tcp_lhash_lock);
17961da177e4SLinus Torvalds 	atomic_inc(&tcp_lhash_users);
17971da177e4SLinus Torvalds 	read_unlock(&tcp_lhash_lock);
17981da177e4SLinus Torvalds }
17991da177e4SLinus Torvalds 
18001da177e4SLinus Torvalds static inline void tcp_listen_unlock(void)
18011da177e4SLinus Torvalds {
18021da177e4SLinus Torvalds 	if (atomic_dec_and_test(&tcp_lhash_users))
18031da177e4SLinus Torvalds 		wake_up(&tcp_lhash_wait);
18041da177e4SLinus Torvalds }
18051da177e4SLinus Torvalds 
18061da177e4SLinus Torvalds static inline int keepalive_intvl_when(const struct tcp_sock *tp)
18071da177e4SLinus Torvalds {
18081da177e4SLinus Torvalds 	return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl;
18091da177e4SLinus Torvalds }
18101da177e4SLinus Torvalds 
18111da177e4SLinus Torvalds static inline int keepalive_time_when(const struct tcp_sock *tp)
18121da177e4SLinus Torvalds {
18131da177e4SLinus Torvalds 	return tp->keepalive_time ? : sysctl_tcp_keepalive_time;
18141da177e4SLinus Torvalds }
18151da177e4SLinus Torvalds 
18161da177e4SLinus Torvalds static inline int tcp_fin_time(const struct tcp_sock *tp)
18171da177e4SLinus Torvalds {
18181da177e4SLinus Torvalds 	int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout;
18191da177e4SLinus Torvalds 
18201da177e4SLinus Torvalds 	if (fin_timeout < (tp->rto<<2) - (tp->rto>>1))
18211da177e4SLinus Torvalds 		fin_timeout = (tp->rto<<2) - (tp->rto>>1);
18221da177e4SLinus Torvalds 
18231da177e4SLinus Torvalds 	return fin_timeout;
18241da177e4SLinus Torvalds }
18251da177e4SLinus Torvalds 
18261da177e4SLinus Torvalds static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, int rst)
18271da177e4SLinus Torvalds {
18281da177e4SLinus Torvalds 	if ((s32)(rx_opt->rcv_tsval - rx_opt->ts_recent) >= 0)
18291da177e4SLinus Torvalds 		return 0;
18301da177e4SLinus Torvalds 	if (xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)
18311da177e4SLinus Torvalds 		return 0;
18321da177e4SLinus Torvalds 
18331da177e4SLinus Torvalds 	/* RST segments are not recommended to carry timestamp,
18341da177e4SLinus Torvalds 	   and, if they do, it is recommended to ignore PAWS because
18351da177e4SLinus Torvalds 	   "their cleanup function should take precedence over timestamps."
18361da177e4SLinus Torvalds 	   Certainly, it is mistake. It is necessary to understand the reasons
18371da177e4SLinus Torvalds 	   of this constraint to relax it: if peer reboots, clock may go
18381da177e4SLinus Torvalds 	   out-of-sync and half-open connections will not be reset.
18391da177e4SLinus Torvalds 	   Actually, the problem would be not existing if all
18401da177e4SLinus Torvalds 	   the implementations followed draft about maintaining clock
18411da177e4SLinus Torvalds 	   via reboots. Linux-2.2 DOES NOT!
18421da177e4SLinus Torvalds 
18431da177e4SLinus Torvalds 	   However, we can relax time bounds for RST segments to MSL.
18441da177e4SLinus Torvalds 	 */
18451da177e4SLinus Torvalds 	if (rst && xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL)
18461da177e4SLinus Torvalds 		return 0;
18471da177e4SLinus Torvalds 	return 1;
18481da177e4SLinus Torvalds }
18491da177e4SLinus Torvalds 
18501da177e4SLinus Torvalds static inline void tcp_v4_setup_caps(struct sock *sk, struct dst_entry *dst)
18511da177e4SLinus Torvalds {
18521da177e4SLinus Torvalds 	sk->sk_route_caps = dst->dev->features;
18531da177e4SLinus Torvalds 	if (sk->sk_route_caps & NETIF_F_TSO) {
18541da177e4SLinus Torvalds 		if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
18551da177e4SLinus Torvalds 			sk->sk_route_caps &= ~NETIF_F_TSO;
18561da177e4SLinus Torvalds 	}
18571da177e4SLinus Torvalds }
18581da177e4SLinus Torvalds 
18591da177e4SLinus Torvalds #define TCP_CHECK_TIMER(sk) do { } while (0)
18601da177e4SLinus Torvalds 
18611da177e4SLinus Torvalds static inline int tcp_use_frto(const struct sock *sk)
18621da177e4SLinus Torvalds {
18631da177e4SLinus Torvalds 	const struct tcp_sock *tp = tcp_sk(sk);
18641da177e4SLinus Torvalds 
18651da177e4SLinus Torvalds 	/* F-RTO must be activated in sysctl and there must be some
18661da177e4SLinus Torvalds 	 * unsent new data, and the advertised window should allow
18671da177e4SLinus Torvalds 	 * sending it.
18681da177e4SLinus Torvalds 	 */
18691da177e4SLinus Torvalds 	return (sysctl_tcp_frto && sk->sk_send_head &&
18701da177e4SLinus Torvalds 		!after(TCP_SKB_CB(sk->sk_send_head)->end_seq,
18711da177e4SLinus Torvalds 		       tp->snd_una + tp->snd_wnd));
18721da177e4SLinus Torvalds }
18731da177e4SLinus Torvalds 
18741da177e4SLinus Torvalds static inline void tcp_mib_init(void)
18751da177e4SLinus Torvalds {
18761da177e4SLinus Torvalds 	/* See RFC 2012 */
18771da177e4SLinus Torvalds 	TCP_ADD_STATS_USER(TCP_MIB_RTOALGORITHM, 1);
18781da177e4SLinus Torvalds 	TCP_ADD_STATS_USER(TCP_MIB_RTOMIN, TCP_RTO_MIN*1000/HZ);
18791da177e4SLinus Torvalds 	TCP_ADD_STATS_USER(TCP_MIB_RTOMAX, TCP_RTO_MAX*1000/HZ);
18801da177e4SLinus Torvalds 	TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
18811da177e4SLinus Torvalds }
18821da177e4SLinus Torvalds 
18831da177e4SLinus Torvalds /* /proc */
18841da177e4SLinus Torvalds enum tcp_seq_states {
18851da177e4SLinus Torvalds 	TCP_SEQ_STATE_LISTENING,
18861da177e4SLinus Torvalds 	TCP_SEQ_STATE_OPENREQ,
18871da177e4SLinus Torvalds 	TCP_SEQ_STATE_ESTABLISHED,
18881da177e4SLinus Torvalds 	TCP_SEQ_STATE_TIME_WAIT,
18891da177e4SLinus Torvalds };
18901da177e4SLinus Torvalds 
18911da177e4SLinus Torvalds struct tcp_seq_afinfo {
18921da177e4SLinus Torvalds 	struct module		*owner;
18931da177e4SLinus Torvalds 	char			*name;
18941da177e4SLinus Torvalds 	sa_family_t		family;
18951da177e4SLinus Torvalds 	int			(*seq_show) (struct seq_file *m, void *v);
18961da177e4SLinus Torvalds 	struct file_operations	*seq_fops;
18971da177e4SLinus Torvalds };
18981da177e4SLinus Torvalds 
18991da177e4SLinus Torvalds struct tcp_iter_state {
19001da177e4SLinus Torvalds 	sa_family_t		family;
19011da177e4SLinus Torvalds 	enum tcp_seq_states	state;
19021da177e4SLinus Torvalds 	struct sock		*syn_wait_sk;
19031da177e4SLinus Torvalds 	int			bucket, sbucket, num, uid;
19041da177e4SLinus Torvalds 	struct seq_operations	seq_ops;
19051da177e4SLinus Torvalds };
19061da177e4SLinus Torvalds 
19071da177e4SLinus Torvalds extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);
19081da177e4SLinus Torvalds extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
19091da177e4SLinus Torvalds 
19101da177e4SLinus Torvalds /* TCP Westwood functions and constants */
19111da177e4SLinus Torvalds 
19121da177e4SLinus Torvalds #define TCP_WESTWOOD_INIT_RTT  (20*HZ)           /* maybe too conservative?! */
19131da177e4SLinus Torvalds #define TCP_WESTWOOD_RTT_MIN   (HZ/20)           /* 50ms */
19141da177e4SLinus Torvalds 
19151da177e4SLinus Torvalds static inline void tcp_westwood_update_rtt(struct tcp_sock *tp, __u32 rtt_seq)
19161da177e4SLinus Torvalds {
19171da177e4SLinus Torvalds         if (tcp_is_westwood(tp))
19181da177e4SLinus Torvalds                 tp->westwood.rtt = rtt_seq;
19191da177e4SLinus Torvalds }
19201da177e4SLinus Torvalds 
19211da177e4SLinus Torvalds static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_sock *tp)
19221da177e4SLinus Torvalds {
19231da177e4SLinus Torvalds         return max((tp->westwood.bw_est) * (tp->westwood.rtt_min) /
19241da177e4SLinus Torvalds 		   (__u32) (tp->mss_cache_std),
19251da177e4SLinus Torvalds 		   2U);
19261da177e4SLinus Torvalds }
19271da177e4SLinus Torvalds 
19281da177e4SLinus Torvalds static inline __u32 tcp_westwood_bw_rttmin(const struct tcp_sock *tp)
19291da177e4SLinus Torvalds {
19301da177e4SLinus Torvalds 	return tcp_is_westwood(tp) ? __tcp_westwood_bw_rttmin(tp) : 0;
19311da177e4SLinus Torvalds }
19321da177e4SLinus Torvalds 
19331da177e4SLinus Torvalds static inline int tcp_westwood_ssthresh(struct tcp_sock *tp)
19341da177e4SLinus Torvalds {
19351da177e4SLinus Torvalds 	__u32 ssthresh = 0;
19361da177e4SLinus Torvalds 
19371da177e4SLinus Torvalds 	if (tcp_is_westwood(tp)) {
19381da177e4SLinus Torvalds 		ssthresh = __tcp_westwood_bw_rttmin(tp);
19391da177e4SLinus Torvalds 		if (ssthresh)
19401da177e4SLinus Torvalds 			tp->snd_ssthresh = ssthresh;
19411da177e4SLinus Torvalds 	}
19421da177e4SLinus Torvalds 
19431da177e4SLinus Torvalds 	return (ssthresh != 0);
19441da177e4SLinus Torvalds }
19451da177e4SLinus Torvalds 
19461da177e4SLinus Torvalds static inline int tcp_westwood_cwnd(struct tcp_sock *tp)
19471da177e4SLinus Torvalds {
19481da177e4SLinus Torvalds 	__u32 cwnd = 0;
19491da177e4SLinus Torvalds 
19501da177e4SLinus Torvalds 	if (tcp_is_westwood(tp)) {
19511da177e4SLinus Torvalds 		cwnd = __tcp_westwood_bw_rttmin(tp);
19521da177e4SLinus Torvalds 		if (cwnd)
19531da177e4SLinus Torvalds 			tp->snd_cwnd = cwnd;
19541da177e4SLinus Torvalds 	}
19551da177e4SLinus Torvalds 
19561da177e4SLinus Torvalds 	return (cwnd != 0);
19571da177e4SLinus Torvalds }
19581da177e4SLinus Torvalds #endif	/* _TCP_H */
1959