]> err.no Git - linux-2.6/blobdiff - include/net/tcp.h
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[linux-2.6] / include / net / tcp.h
index dde04afbe0a468315e63edbf1ed08757762c7507..cb5b033e0e59c205980243d2b7e494db0925f218 100644 (file)
@@ -599,32 +599,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,
-                                      const struct sk_buff *skb)
-{
-       struct tcp_sock *tp = tcp_sk(sk);
-       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 */
@@ -714,6 +701,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
@@ -730,7 +750,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.
@@ -748,12 +768,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)
-{
-       BUG_ON(tp->rx_opt.sack_ok &&
-              (tp->sacked_out + tp->lost_out > tp->packets_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);
@@ -787,7 +803,7 @@ 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)
@@ -1050,12 +1066,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;
+}
+
+static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
+{
+       tcp_clear_retrans_hints_partial(tp);
        tp->fastpath_skb_hint = NULL;
 }
 
@@ -1266,6 +1288,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)