aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-12-01 17:48:06 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:55:46 -0500
commit6859d49475d4f32abe640372117e4b687906e6b6 (patch)
tree2133f2e26af6540f2a212c36f219873d34db2c1e /include/net/tcp.h
parent7201883599ac8bff76300117155e299b1a54092f (diff)
[TCP]: Abstract tp->highest_sack accessing & point to next skb
Pointing to the next skb is necessary to avoid referencing already SACKed skbs which will soon be on a separate list. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h35
1 files changed, 34 insertions, 1 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6e392babda4a..5ec1cacca8a1 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1267,8 +1267,12 @@ static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb
1267 __tcp_add_write_queue_tail(sk, skb); 1267 __tcp_add_write_queue_tail(sk, skb);
1268 1268
1269 /* Queue it, remembering where we must start sending. */ 1269 /* Queue it, remembering where we must start sending. */
1270 if (sk->sk_send_head == NULL) 1270 if (sk->sk_send_head == NULL) {
1271 sk->sk_send_head = skb; 1271 sk->sk_send_head = skb;
1272
1273 if (tcp_sk(sk)->highest_sack == NULL)
1274 tcp_sk(sk)->highest_sack = skb;
1275 }
1272} 1276}
1273 1277
1274static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb) 1278static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb)
@@ -1318,9 +1322,38 @@ static inline u32 tcp_highest_sack_seq(struct tcp_sock *tp)
1318{ 1322{
1319 if (!tp->sacked_out) 1323 if (!tp->sacked_out)
1320 return tp->snd_una; 1324 return tp->snd_una;
1325
1326 if (tp->highest_sack == NULL)
1327 return tp->snd_nxt;
1328
1321 return TCP_SKB_CB(tp->highest_sack)->seq; 1329 return TCP_SKB_CB(tp->highest_sack)->seq;
1322} 1330}
1323 1331
1332static inline void tcp_advance_highest_sack(struct sock *sk, struct sk_buff *skb)
1333{
1334 tcp_sk(sk)->highest_sack = tcp_skb_is_last(sk, skb) ? NULL :
1335 tcp_write_queue_next(sk, skb);
1336}
1337
1338static inline struct sk_buff *tcp_highest_sack(struct sock *sk)
1339{
1340 return tcp_sk(sk)->highest_sack;
1341}
1342
1343static inline void tcp_highest_sack_reset(struct sock *sk)
1344{
1345 tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
1346}
1347
1348/* Called when old skb is about to be deleted (to be combined with new skb) */
1349static inline void tcp_highest_sack_combine(struct sock *sk,
1350 struct sk_buff *old,
1351 struct sk_buff *new)
1352{
1353 if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
1354 tcp_sk(sk)->highest_sack = new;
1355}
1356
1324/* /proc */ 1357/* /proc */
1325enum tcp_seq_states { 1358enum tcp_seq_states {
1326 TCP_SEQ_STATE_LISTENING, 1359 TCP_SEQ_STATE_LISTENING,