#include <net/checksum.h>
#include <net/sock.h>
#include <net/snmp.h>
+#include <net/ip.h>
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#include <linux/ipv6.h>
#endif
#define tcptw_sk(__sk) ((struct tcp_tw_bucket *)(__sk))
-static inline const u32 tcp_v4_rcv_saddr(const struct sock *sk)
+static inline u32 tcp_v4_rcv_saddr(const struct sock *sk)
{
return likely(sk->sk_state != TCP_TIME_WAIT) ?
inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr;
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static inline const struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
{
return likely(sk->sk_state != TCP_TIME_WAIT) ?
&inet6_sk(sk)->rcv_saddr : &tcptw_sk(sk)->tw_v6_rcv_saddr;
}
-static inline const struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
{
return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
}
extern int sysctl_tcp_bic;
extern int sysctl_tcp_bic_fast_convergence;
extern int sysctl_tcp_bic_low_window;
+extern int sysctl_tcp_default_win_scale;
+extern int sysctl_tcp_moderate_rcvbuf;
extern atomic_t tcp_memory_allocated;
extern atomic_t tcp_sockets_allocated;
int (*setsockopt) (struct sock *sk,
int level,
int optname,
- char *optval,
+ char __user *optval,
int optlen);
int (*getsockopt) (struct sock *sk,
int level,
int optname,
- char *optval,
- int *optlen);
+ char __user *optval,
+ int __user *optlen);
void (*addr2sockaddr) (struct sock *sk,
struct tcphdr *th,
unsigned len);
+extern void tcp_rcv_space_adjust(struct sock *sk);
+
enum tcp_ack_state_t
{
TCP_ACK_SCHED = 1,
long timeout);
extern struct sock * tcp_accept(struct sock *sk, int flags, int *err);
extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
-extern void tcp_write_space(struct sock *sk);
extern int tcp_getsockopt(struct sock *sk, int level,
- int optname, char *optval,
- int *optlen);
+ int optname,
+ char __user *optval,
+ int __user *optlen);
extern int tcp_setsockopt(struct sock *sk, int level,
- int optname, char *optval,
+ int optname, char __user *optval,
int optlen);
extern void tcp_set_keepalive(struct sock *sk, int val);
extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
extern const char timer_bug_msg[];
+/* tcp_diag.c */
+extern void tcp_get_info(struct sock *, struct tcp_info *);
+
/* Read 'sendfile()'-style from a TCP socket */
typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
unsigned int, size_t);
tp->pending = 0;
#ifdef TCP_CLEAR_TIMERS
- if (timer_pending(&tp->retransmit_timer) &&
- del_timer(&tp->retransmit_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &tp->retransmit_timer);
#endif
break;
case TCP_TIME_DACK:
tp->ack.pending = 0;
#ifdef TCP_CLEAR_TIMERS
- if (timer_pending(&tp->delack_timer) &&
- del_timer(&tp->delack_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &tp->delack_timer);
#endif
break;
default:
case TCP_TIME_PROBE0:
tp->pending = what;
tp->timeout = jiffies+when;
- if (!mod_timer(&tp->retransmit_timer, tp->timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
break;
case TCP_TIME_DACK:
tp->ack.pending |= TCP_ACK_TIMER;
tp->ack.timeout = jiffies+when;
- if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
break;
default:
- printk(KERN_DEBUG "bug: unknown timer value\n");
+ printk(timer_bug_msg);
};
}
#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0]))
-#define for_retrans_queue(skb, sk, tp) \
- for (skb = (sk)->sk_write_queue.next; \
- (skb != (tp)->send_head) && \
- (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
- skb=skb->next)
-
-
#include <net/tcp_ecn.h>
-
-/*
- * Compute minimal free write space needed to queue new packets.
- */
-static inline int tcp_min_write_space(struct sock *sk)
-{
- return sk->sk_wmem_queued / 2;
-}
-
-static inline int tcp_wspace(struct sock *sk)
-{
- return sk->sk_sndbuf - sk->sk_wmem_queued;
-}
-
-
/* This determines how many packets are "in the network" to the best
* of our knowledge. In many cases it is conservative, but where
* detailed information is available from the receiver (via SACK
tcp_minshall_check(tp))));
}
-/* This checks if the data bearing packet SKB (usually tp->send_head)
+/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
* should be put on the wire right now.
*/
static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
unsigned cur_mss,
int nonagle)
{
- struct sk_buff *skb = tp->send_head;
+ struct sk_buff *skb = sk->sk_send_head;
if (skb) {
if (!tcp_skb_is_last(sk, skb))
static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp)
{
- struct sk_buff *skb = tp->send_head;
+ struct sk_buff *skb = sk->sk_send_head;
return (skb &&
tcp_snd_test(tp, skb, tcp_current_mss(sk, 1),
while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
sk->sk_backlog_rcv(sk, skb1);
- NET_INC_STATS_BH(TCPPrequeueDropped);
+ NET_INC_STATS_BH(LINUX_MIB_TCPPREQUEUEDROPPED);
}
tp->ucopy.memory = 0;
switch (state) {
case TCP_ESTABLISHED:
if (oldstate != TCP_ESTABLISHED)
- TCP_INC_STATS(TcpCurrEstab);
+ TCP_INC_STATS(TCP_MIB_CURRESTAB);
break;
case TCP_CLOSE:
if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
- TCP_INC_STATS(TcpEstabResets);
+ TCP_INC_STATS(TCP_MIB_ESTABRESETS);
sk->sk_prot->unhash(sk);
if (tcp_sk(sk)->bind_hash &&
/* fall through */
default:
if (oldstate==TCP_ESTABLISHED)
- TCP_DEC_STATS(TcpCurrEstab);
+ TCP_DEC_STATS(TCP_MIB_CURRESTAB);
}
/* Change state AFTER socket is unhashed to avoid closed
if (*rcv_wscale && sysctl_tcp_app_win && space>=mss &&
space - max((space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2)
(*rcv_wscale)--;
+
+ *rcv_wscale = max((__u8)sysctl_tcp_default_win_scale,
+ *rcv_wscale);
}
/* Set initial window to value enough for senders,
return tcp_win_from_space(sk->sk_rcvbuf);
}
-static inline void tcp_acceptq_removed(struct sock *sk)
-{
- sk->sk_ack_backlog--;
-}
-
-static inline void tcp_acceptq_added(struct sock *sk)
-{
- sk->sk_ack_backlog++;
-}
-
-static inline int tcp_acceptq_is_full(struct sock *sk)
-{
- return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
-}
-
static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
struct sock *child)
{
struct tcp_opt *tp = tcp_sk(sk);
req->sk = child;
- tcp_acceptq_added(sk);
+ sk_acceptq_added(sk);
if (!tp->accept_queue_tail) {
tp->accept_queue = req;
req->rmt_port = skb->h.th->source;
}
-#define TCP_MEM_QUANTUM ((int)PAGE_SIZE)
-
-static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb)
-{
- tcp_sk(sk)->queue_shrunk = 1;
- sk->sk_wmem_queued -= skb->truesize;
- sk->sk_forward_alloc += skb->truesize;
- __kfree_skb(skb);
-}
-
-static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb)
-{
- sk->sk_wmem_queued += skb->truesize;
- sk->sk_forward_alloc -= skb->truesize;
-}
-
-extern void __tcp_mem_reclaim(struct sock *sk);
-extern int tcp_mem_schedule(struct sock *sk, int size, int kind);
-
-static inline void tcp_mem_reclaim(struct sock *sk)
-{
- if (sk->sk_forward_alloc >= TCP_MEM_QUANTUM)
- __tcp_mem_reclaim(sk);
-}
-
-static inline void tcp_enter_memory_pressure(void)
-{
- if (!tcp_memory_pressure) {
- NET_INC_STATS(TCPMemoryPressures);
- tcp_memory_pressure = 1;
- }
-}
-
-static inline void tcp_moderate_sndbuf(struct sock *sk)
-{
- if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) {
- sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2);
- sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF);
- }
-}
-
-static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp)
-{
- struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp);
-
- if (skb) {
- skb->truesize += mem;
- if (sk->sk_forward_alloc >= (int)skb->truesize ||
- tcp_mem_schedule(sk, skb->truesize, 0)) {
- skb_reserve(skb, MAX_TCP_HEADER);
- return skb;
- }
- __kfree_skb(skb);
- } else {
- tcp_enter_memory_pressure();
- tcp_moderate_sndbuf(sk);
- }
- return NULL;
-}
-
-static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp)
-{
- return tcp_alloc_pskb(sk, size, 0, gfp);
-}
-
-static inline struct page * tcp_alloc_page(struct sock *sk)
-{
- if (sk->sk_forward_alloc >= (int)PAGE_SIZE ||
- tcp_mem_schedule(sk, PAGE_SIZE, 0)) {
- struct page *page = alloc_pages(sk->sk_allocation, 0);
- if (page)
- return page;
- }
- tcp_enter_memory_pressure();
- tcp_moderate_sndbuf(sk);
- return NULL;
-}
-
-static inline void tcp_writequeue_purge(struct sock *sk)
-{
- struct sk_buff *skb;
-
- while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
- tcp_free_skb(sk, skb);
- tcp_mem_reclaim(sk);
-}
-
-extern void tcp_rfree(struct sk_buff *skb);
-
-static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk)
-{
- skb->sk = sk;
- skb->destructor = tcp_rfree;
- atomic_add(skb->truesize, &sk->sk_rmem_alloc);
- sk->sk_forward_alloc -= skb->truesize;
-}
+extern void tcp_enter_memory_pressure(void);
extern void tcp_listen_wlock(void);
* unsent new data, and the advertised window should allow
* sending it.
*/
- return (sysctl_tcp_frto && tp->send_head &&
- !after(TCP_SKB_CB(tp->send_head)->end_seq,
+ return (sysctl_tcp_frto && sk->sk_send_head &&
+ !after(TCP_SKB_CB(sk->sk_send_head)->end_seq,
tp->snd_una + tp->snd_wnd));
}
static inline void tcp_mib_init(void)
{
/* See RFC 2012 */
- TCP_ADD_STATS_USER(TcpRtoAlgorithm, 1);
- TCP_ADD_STATS_USER(TcpRtoMin, TCP_RTO_MIN*1000/HZ);
- TCP_ADD_STATS_USER(TcpRtoMax, TCP_RTO_MAX*1000/HZ);
- TCP_ADD_STATS_USER(TcpMaxConn, -1);
+ TCP_ADD_STATS_USER(TCP_MIB_RTOALGORITHM, 1);
+ TCP_ADD_STATS_USER(TCP_MIB_RTOMIN, TCP_RTO_MIN*1000/HZ);
+ TCP_ADD_STATS_USER(TCP_MIB_RTOMAX, TCP_RTO_MAX*1000/HZ);
+ TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
}
/* /proc */