diff options
author | Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> | 2007-12-01 17:48:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:55:46 -0500 |
commit | 6859d49475d4f32abe640372117e4b687906e6b6 (patch) | |
tree | 2133f2e26af6540f2a212c36f219873d34db2c1e /include/net | |
parent | 7201883599ac8bff76300117155e299b1a54092f (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')
-rw-r--r-- | include/net/tcp.h | 35 |
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 | ||
1274 | static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb) | 1278 | static 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 | ||
1332 | static 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 | |||
1338 | static inline struct sk_buff *tcp_highest_sack(struct sock *sk) | ||
1339 | { | ||
1340 | return tcp_sk(sk)->highest_sack; | ||
1341 | } | ||
1342 | |||
1343 | static 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) */ | ||
1349 | static 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 */ |
1325 | enum tcp_seq_states { | 1358 | enum tcp_seq_states { |
1326 | TCP_SEQ_STATE_LISTENING, | 1359 | TCP_SEQ_STATE_LISTENING, |