[TCP]: Uninline tcp_set_state
[safe/jmp/linux-2.6] / include / net / tcp.h
index af92732..306580c 100644 (file)
@@ -39,6 +39,7 @@
 #include <net/snmp.h>
 #include <net/ip.h>
 #include <net/tcp_states.h>
+#include <net/inet_ecn.h>
 
 #include <linux/seq_file.h>
 
@@ -254,6 +255,12 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
        return seq3 - seq2 >= seq1 - seq2;
 }
 
+static inline int tcp_too_many_orphans(struct sock *sk, int num)
+{
+       return (num > sysctl_tcp_max_orphans) ||
+               (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
+                atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
+}
 
 extern struct proto tcp_prot;
 
@@ -275,7 +282,7 @@ extern int                  tcp_v4_remember_stamp(struct sock *sk);
 
 extern int                     tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
 
-extern int                     tcp_sendmsg(struct kiocb *iocb, struct sock *sk,
+extern int                     tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
                                            struct msghdr *msg, size_t size);
 extern ssize_t                 tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
 
@@ -302,6 +309,9 @@ extern int                  tcp_twsk_unique(struct sock *sk,
 
 extern void                    tcp_twsk_destructor(struct sock *sk);
 
+extern ssize_t                 tcp_splice_read(struct socket *sk, loff_t *ppos,
+                                               struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
                                         const unsigned int pkts)
 {
@@ -324,6 +334,17 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
        rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0;
 }
 
+#define        TCP_ECN_OK              1
+#define        TCP_ECN_QUEUE_CWR       2
+#define        TCP_ECN_DEMAND_CWR      4
+
+static __inline__ void
+TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th)
+{
+       if (sysctl_tcp_ecn && th->ece && th->cwr)
+               inet_rsk(req)->ecn_ok = 1;
+}
+
 enum tcp_tw_status
 {
        TCP_TW_SUCCESS = 0,
@@ -420,9 +441,9 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
 
 /* tcp_output.c */
 
-extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp,
-                                     unsigned int cur_mss, int nonagle);
-extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp);
+extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
+                                     int nonagle);
+extern int tcp_may_send_now(struct sock *sk);
 extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
 extern void tcp_xmit_retransmit_queue(struct sock *);
 extern void tcp_simple_retransmit(struct sock *);
@@ -479,8 +500,10 @@ static inline void tcp_fast_path_on(struct tcp_sock *tp)
        __tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
 }
 
-static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_fast_path_check(struct sock *sk)
 {
+       struct tcp_sock *tp = tcp_sk(sk);
+
        if (skb_queue_empty(&tp->out_of_order_queue) &&
            tp->rcv_wnd &&
            atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf &&
@@ -555,18 +578,12 @@ struct tcp_skb_cb {
 #define TCPCB_EVER_RETRANS     0x80    /* Ever retransmitted frame     */
 #define TCPCB_RETRANS          (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
 
-#define TCPCB_URG              0x20    /* Urgent pointer advanced here */
-
-#define TCPCB_AT_TAIL          (TCPCB_URG)
-
        __u16           urg_ptr;        /* Valid w/URG flags is set.    */
        __u32           ack_seq;        /* Sequence number ACK'd        */
 };
 
 #define TCP_SKB_CB(__skb)      ((struct tcp_skb_cb *)&((__skb)->cb[0]))
 
-#include <net/tcp_ecn.h>
-
 /* Due to TSO, an SKB can be composed of multiple actual
  * packets.  To keep these tracked properly, we use this.
  */
@@ -581,32 +598,19 @@ static inline int tcp_skb_mss(const struct sk_buff *skb)
        return skb_shinfo(skb)->gso_size;
 }
 
-static inline void tcp_dec_pcount_approx(__u32 *count,
-                                        const struct sk_buff *skb)
+static inline void tcp_dec_pcount_approx_int(__u32 *count, const int decr)
 {
        if (*count) {
-               *count -= tcp_skb_pcount(skb);
+               *count -= decr;
                if ((int)*count < 0)
                        *count = 0;
        }
 }
 
-static inline void tcp_packets_out_inc(struct sock *sk, 
-                                      struct tcp_sock *tp,
-                                      const struct sk_buff *skb)
-{
-       int orig = tp->packets_out;
-
-       tp->packets_out += tcp_skb_pcount(skb);
-       if (!orig)
-               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
-}
-
-static inline void tcp_packets_out_dec(struct tcp_sock *tp, 
-                                      const struct sk_buff *skb)
+static inline void tcp_dec_pcount_approx(__u32 *count,
+                                        const struct sk_buff *skb)
 {
-       tp->packets_out -= tcp_skb_pcount(skb);
+       tcp_dec_pcount_approx_int(count, tcp_skb_pcount(skb));
 }
 
 /* Events passed to congestion control interface */
@@ -627,9 +631,12 @@ enum tcp_ca_event {
 #define TCP_CA_MAX     128
 #define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX)
 
+#define TCP_CONG_NON_RESTRICTED 0x1
+#define TCP_CONG_RTT_STAMP     0x2
+
 struct tcp_congestion_ops {
        struct list_head        list;
-       int     non_restricted;
+       unsigned long flags;
 
        /* initialize private data (optional) */
        void (*init)(struct sock *sk);
@@ -641,10 +648,7 @@ struct tcp_congestion_ops {
        /* lower bound for congestion window (optional) */
        u32 (*min_cwnd)(const struct sock *sk);
        /* do new cwnd calculation (required) */
-       void (*cong_avoid)(struct sock *sk, u32 ack,
-                          u32 rtt, u32 in_flight, int good_ack);
-       /* round trip time sample per acked packet (optional) */
-       void (*rtt_sample)(struct sock *sk, u32 usrtt);
+       void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);
        /* call before changing ca_state (optional) */
        void (*set_state)(struct sock *sk, u8 new_state);
        /* call when cwnd event occurs (optional) */
@@ -652,7 +656,7 @@ struct tcp_congestion_ops {
        /* new value of cwnd after loss (optional) */
        u32  (*undo_cwnd)(struct sock *sk);
        /* hook for packet ack accounting (optional) */
-       void (*pkts_acked)(struct sock *sk, u32 num_acked);
+       void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);
        /* get info for inet_diag (optional) */
        void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);
 
@@ -675,8 +679,7 @@ extern void tcp_slow_start(struct tcp_sock *tp);
 
 extern struct tcp_congestion_ops tcp_init_congestion_ops;
 extern u32 tcp_reno_ssthresh(struct sock *sk);
-extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack,
-                               u32 rtt, u32 in_flight, int flag);
+extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight);
 extern u32 tcp_reno_min_cwnd(const struct sock *sk);
 extern struct tcp_congestion_ops tcp_reno;
 
@@ -697,6 +700,39 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event)
                icsk->icsk_ca_ops->cwnd_event(sk, event);
 }
 
+/* These functions determine how the current flow behaves in respect of SACK
+ * handling. SACK is negotiated with the peer, and therefore it can vary
+ * between different flows.
+ *
+ * tcp_is_sack - SACK enabled
+ * tcp_is_reno - No SACK
+ * tcp_is_fack - FACK enabled, implies SACK enabled
+ */
+static inline int tcp_is_sack(const struct tcp_sock *tp)
+{
+       return tp->rx_opt.sack_ok;
+}
+
+static inline int tcp_is_reno(const struct tcp_sock *tp)
+{
+       return !tcp_is_sack(tp);
+}
+
+static inline int tcp_is_fack(const struct tcp_sock *tp)
+{
+       return tp->rx_opt.sack_ok & 2;
+}
+
+static inline void tcp_enable_fack(struct tcp_sock *tp)
+{
+       tp->rx_opt.sack_ok |= 2;
+}
+
+static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
+{
+       return tp->sacked_out + tp->lost_out;
+}
+
 /* 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
@@ -713,7 +749,7 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event)
  */
 static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 {
-       return (tp->packets_out - tp->left_out + tp->retrans_out);
+       return tp->packets_out - tcp_left_out(tp) + tp->retrans_out;
 }
 
 /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
@@ -731,13 +767,8 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
                            (tp->snd_cwnd >> 2)));
 }
 
-static inline void tcp_sync_left_out(struct tcp_sock *tp)
-{
-       if (tp->rx_opt.sack_ok &&
-           (tp->sacked_out >= tp->packets_out - tp->lost_out))
-               tp->sacked_out = tp->packets_out - tp->lost_out;
-       tp->left_out = tp->sacked_out + tp->lost_out;
-}
+/* Use define here intentionally to get WARN_ON location shown at the caller */
+#define tcp_verify_left_out(tp)        WARN_ON(tcp_left_out(tp) > tp->packets_out)
 
 extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh);
 extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
@@ -750,6 +781,12 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
        return 3;
 }
 
+/* Returns end sequence number of the receiver's advertised window */
+static inline u32 tcp_wnd_end(const struct tcp_sock *tp)
+{
+       return tp->snd_una + tp->snd_wnd;
+}
+
 /* RFC2861 Check whether we are limited by application or congestion window
  * This is the inverse of cwnd check in tcp_tso_should_defer
  */
@@ -771,25 +808,28 @@ static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
                return left <= tcp_max_burst(tp);
 }
 
-static inline void tcp_minshall_update(struct tcp_sock *tp, int mss,
+static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss,
                                       const struct sk_buff *skb)
 {
        if (skb->len < mss)
                tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
 }
 
-static inline void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_check_probe_timer(struct sock *sk)
 {
+       struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
+
        if (!tp->packets_out && !icsk->icsk_pending)
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0,
                                          icsk->icsk_rto, TCP_RTO_MAX);
 }
 
-static inline void tcp_push_pending_frames(struct sock *sk,
-                                          struct tcp_sock *tp)
+static inline void tcp_push_pending_frames(struct sock *sk)
 {
-       __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
+       struct tcp_sock *tp = tcp_sk(sk);
+
+       __tcp_push_pending_frames(sk, tcp_current_mss(sk, 1), tp->nonagle);
 }
 
 static inline void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
@@ -818,7 +858,7 @@ static inline __sum16 __tcp_checksum_complete(struct sk_buff *skb)
 
 static inline int tcp_checksum_complete(struct sk_buff *skb)
 {
-       return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+       return !skb_csum_unnecessary(skb) &&
                __tcp_checksum_complete(skb);
 }
 
@@ -886,56 +926,9 @@ static const char *statename[]={
        "Close Wait","Last ACK","Listen","Closing"
 };
 #endif
+extern void tcp_set_state(struct sock *sk, int state);
 
-static inline void tcp_set_state(struct sock *sk, int state)
-{
-       int oldstate = sk->sk_state;
-
-       switch (state) {
-       case TCP_ESTABLISHED:
-               if (oldstate != TCP_ESTABLISHED)
-                       TCP_INC_STATS(TCP_MIB_CURRESTAB);
-               break;
-
-       case TCP_CLOSE:
-               if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
-                       TCP_INC_STATS(TCP_MIB_ESTABRESETS);
-
-               sk->sk_prot->unhash(sk);
-               if (inet_csk(sk)->icsk_bind_hash &&
-                   !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
-                       inet_put_port(&tcp_hashinfo, sk);
-               /* fall through */
-       default:
-               if (oldstate==TCP_ESTABLISHED)
-                       TCP_DEC_STATS(TCP_MIB_CURRESTAB);
-       }
-
-       /* Change state AFTER socket is unhashed to avoid closed
-        * socket sitting in hash tables.
-        */
-       sk->sk_state = state;
-
-#ifdef STATE_TRACE
-       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
-#endif 
-}
-
-static inline void tcp_done(struct sock *sk)
-{
-       if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
-               TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
-
-       tcp_set_state(sk, TCP_CLOSE);
-       tcp_clear_xmit_timers(sk);
-
-       sk->sk_shutdown = SHUTDOWN_MASK;
-
-       if (!sock_flag(sk, SOCK_DEAD))
-               sk->sk_state_change(sk);
-       else
-               inet_csk_destroy_sock(sk);
-}
+extern void tcp_done(struct sock *sk);
 
 static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
 {
@@ -1045,13 +1038,18 @@ static inline void tcp_mib_init(void)
        TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
 }
 
-/*from STCP */
-static inline void clear_all_retrans_hints(struct tcp_sock *tp){
+/* from STCP */
+static inline void tcp_clear_retrans_hints_partial(struct tcp_sock *tp)
+{
        tp->lost_skb_hint = NULL;
        tp->scoreboard_skb_hint = NULL;
        tp->retransmit_skb_hint = NULL;
        tp->forward_skb_hint = NULL;
-       tp->fastpath_skb_hint = NULL;
+}
+
+static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
+{
+       tcp_clear_retrans_hints_partial(tp);
 }
 
 /* MD5 Signature */
@@ -1064,14 +1062,12 @@ struct tcp_md5sig_key {
 };
 
 struct tcp4_md5sig_key {
-       u8                      *key;
-       u16                     keylen;
+       struct tcp_md5sig_key   base;
        __be32                  addr;
 };
 
 struct tcp6_md5sig_key {
-       u8                      *key;
-       u16                     keylen;
+       struct tcp_md5sig_key   base;
 #if 0
        u32                     scope_id;       /* XXX */
 #endif
@@ -1128,7 +1124,8 @@ extern int                        tcp_v4_calc_md5_hash(char *md5_hash,
                                                     struct dst_entry *dst,
                                                     struct request_sock *req,
                                                     struct tcphdr *th,
-                                                    int protocol, int tcplen);
+                                                    int protocol,
+                                                    unsigned int tcplen);
 extern struct tcp_md5sig_key   *tcp_v4_md5_lookup(struct sock *sk,
                                                   struct sock *addr_sk);
 
@@ -1168,8 +1165,8 @@ static inline void tcp_write_queue_purge(struct sock *sk)
        struct sk_buff *skb;
 
        while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
-               sk_stream_free_skb(sk, skb);
-       sk_stream_mem_reclaim(sk);
+               sk_wmem_free_skb(sk, skb);
+       sk_mem_reclaim(sk);
 }
 
 static inline struct sk_buff *tcp_write_queue_head(struct sock *sk)
@@ -1202,6 +1199,11 @@ static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_bu
                for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\
                     skb = skb->next)
 
+#define tcp_for_write_queue_from_safe(skb, tmp, sk)                    \
+               for (tmp = skb->next;                                   \
+                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
+                    skb = tmp, tmp = skb->next)
+
 static inline struct sk_buff *tcp_send_head(struct sock *sk)
 {
        return sk->sk_send_head;
@@ -1235,8 +1237,12 @@ static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb
        __tcp_add_write_queue_tail(sk, skb);
 
        /* Queue it, remembering where we must start sending. */
-       if (sk->sk_send_head == NULL)
+       if (sk->sk_send_head == NULL) {
                sk->sk_send_head = skb;
+
+               if (tcp_sk(sk)->highest_sack == NULL)
+                       tcp_sk(sk)->highest_sack = skb;
+       }
 }
 
 static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb)
@@ -1258,6 +1264,9 @@ static inline void tcp_insert_write_queue_before(struct sk_buff *new,
                                                  struct sock *sk)
 {
        __skb_insert(new, skb->prev, skb, &sk->sk_write_queue);
+
+       if (sk->sk_send_head == skb)
+               sk->sk_send_head = new;
 }
 
 static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk)
@@ -1276,6 +1285,45 @@ static inline int tcp_write_queue_empty(struct sock *sk)
        return skb_queue_empty(&sk->sk_write_queue);
 }
 
+/* Start sequence of the highest skb with SACKed bit, valid only if
+ * sacked > 0 or when the caller has ensured validity by itself.
+ */
+static inline u32 tcp_highest_sack_seq(struct tcp_sock *tp)
+{
+       if (!tp->sacked_out)
+               return tp->snd_una;
+
+       if (tp->highest_sack == NULL)
+               return tp->snd_nxt;
+
+       return TCP_SKB_CB(tp->highest_sack)->seq;
+}
+
+static inline void tcp_advance_highest_sack(struct sock *sk, struct sk_buff *skb)
+{
+       tcp_sk(sk)->highest_sack = tcp_skb_is_last(sk, skb) ? NULL :
+                                               tcp_write_queue_next(sk, skb);
+}
+
+static inline struct sk_buff *tcp_highest_sack(struct sock *sk)
+{
+       return tcp_sk(sk)->highest_sack;
+}
+
+static inline void tcp_highest_sack_reset(struct sock *sk)
+{
+       tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
+}
+
+/* Called when old skb is about to be deleted (to be combined with new skb) */
+static inline void tcp_highest_sack_combine(struct sock *sk,
+                                           struct sk_buff *old,
+                                           struct sk_buff *new)
+{
+       if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
+               tcp_sk(sk)->highest_sack = new;
+}
+
 /* /proc */
 enum tcp_seq_states {
        TCP_SEQ_STATE_LISTENING,
@@ -1326,7 +1374,8 @@ struct tcp_sock_af_ops {
                                                  struct dst_entry *dst,
                                                  struct request_sock *req,
                                                  struct tcphdr *th,
-                                                 int protocol, int len);
+                                                 int protocol,
+                                                 unsigned int len);
        int                     (*md5_add) (struct sock *sk,
                                            struct sock *addr_sk,
                                            u8 *newkey,