diff options
author | Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> | 2008-11-25 00:14:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 00:14:43 -0500 |
commit | f58b22fd3c16444edc393a217a74208f1894b601 (patch) | |
tree | df0c59de99d337c001703295d6d02919940dafc3 /net | |
parent | adb92db857ee2a0a2b925ccfbd560203c3f88aae (diff) |
tcp: make tcp_sacktag_one able to handle partial skb too
This is preparatory work for SACK combiner patch which may
have to count TCP state changes for only a part of the skb
because it will intentionally avoids splitting skb to SACKed
and not sacked parts.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_input.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ca46eb9151f8..3c8e297e2c39 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1289,7 +1289,8 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, | |||
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, | 1291 | static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, |
1292 | int *reord, int dup_sack, int fack_count) | 1292 | int *reord, int dup_sack, int fack_count, |
1293 | u8 *sackedto, int pcount) | ||
1293 | { | 1294 | { |
1294 | struct tcp_sock *tp = tcp_sk(sk); | 1295 | struct tcp_sock *tp = tcp_sk(sk); |
1295 | u8 sacked = TCP_SKB_CB(skb)->sacked; | 1296 | u8 sacked = TCP_SKB_CB(skb)->sacked; |
@@ -1314,10 +1315,9 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, | |||
1314 | * that retransmission is still in flight. | 1315 | * that retransmission is still in flight. |
1315 | */ | 1316 | */ |
1316 | if (sacked & TCPCB_LOST) { | 1317 | if (sacked & TCPCB_LOST) { |
1317 | TCP_SKB_CB(skb)->sacked &= | 1318 | *sackedto &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); |
1318 | ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); | 1319 | tp->lost_out -= pcount; |
1319 | tp->lost_out -= tcp_skb_pcount(skb); | 1320 | tp->retrans_out -= pcount; |
1320 | tp->retrans_out -= tcp_skb_pcount(skb); | ||
1321 | } | 1321 | } |
1322 | } else { | 1322 | } else { |
1323 | if (!(sacked & TCPCB_RETRANS)) { | 1323 | if (!(sacked & TCPCB_RETRANS)) { |
@@ -1334,22 +1334,22 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, | |||
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | if (sacked & TCPCB_LOST) { | 1336 | if (sacked & TCPCB_LOST) { |
1337 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; | 1337 | *sackedto &= ~TCPCB_LOST; |
1338 | tp->lost_out -= tcp_skb_pcount(skb); | 1338 | tp->lost_out -= pcount; |
1339 | } | 1339 | } |
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED; | 1342 | *sackedto |= TCPCB_SACKED_ACKED; |
1343 | flag |= FLAG_DATA_SACKED; | 1343 | flag |= FLAG_DATA_SACKED; |
1344 | tp->sacked_out += tcp_skb_pcount(skb); | 1344 | tp->sacked_out += pcount; |
1345 | 1345 | ||
1346 | fack_count += tcp_skb_pcount(skb); | 1346 | fack_count += pcount; |
1347 | 1347 | ||
1348 | /* Lost marker hint past SACKed? Tweak RFC3517 cnt */ | 1348 | /* Lost marker hint past SACKed? Tweak RFC3517 cnt */ |
1349 | if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) && | 1349 | if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) && |
1350 | before(TCP_SKB_CB(skb)->seq, | 1350 | before(TCP_SKB_CB(skb)->seq, |
1351 | TCP_SKB_CB(tp->lost_skb_hint)->seq)) | 1351 | TCP_SKB_CB(tp->lost_skb_hint)->seq)) |
1352 | tp->lost_cnt_hint += tcp_skb_pcount(skb); | 1352 | tp->lost_cnt_hint += pcount; |
1353 | 1353 | ||
1354 | if (fack_count > tp->fackets_out) | 1354 | if (fack_count > tp->fackets_out) |
1355 | tp->fackets_out = fack_count; | 1355 | tp->fackets_out = fack_count; |
@@ -1362,9 +1362,9 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, | |||
1362 | * frames and clear it. undo_retrans is decreased above, L|R frames | 1362 | * frames and clear it. undo_retrans is decreased above, L|R frames |
1363 | * are accounted above as well. | 1363 | * are accounted above as well. |
1364 | */ | 1364 | */ |
1365 | if (dup_sack && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)) { | 1365 | if (dup_sack && (*sackedto & TCPCB_SACKED_RETRANS)) { |
1366 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; | 1366 | *sackedto &= ~TCPCB_SACKED_RETRANS; |
1367 | tp->retrans_out -= tcp_skb_pcount(skb); | 1367 | tp->retrans_out -= pcount; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | return flag; | 1370 | return flag; |
@@ -1404,7 +1404,9 @@ static struct sk_buff *tcp_sacktag_walk(struct sk_buff *skb, struct sock *sk, | |||
1404 | 1404 | ||
1405 | if (in_sack) | 1405 | if (in_sack) |
1406 | *flag |= tcp_sacktag_one(skb, sk, reord, dup_sack, | 1406 | *flag |= tcp_sacktag_one(skb, sk, reord, dup_sack, |
1407 | *fack_count); | 1407 | *fack_count, |
1408 | &(TCP_SKB_CB(skb)->sacked), | ||
1409 | tcp_skb_pcount(skb)); | ||
1408 | 1410 | ||
1409 | *fack_count += tcp_skb_pcount(skb); | 1411 | *fack_count += tcp_skb_pcount(skb); |
1410 | } | 1412 | } |