| 5432 | */ |
| 5433 | |
| 5434 | static uint32_t |
| 5435 | bbr_update_entry(struct tcpcb *tp, struct tcp_bbr *bbr, |
| 5436 | struct bbr_sendmap *rsm, uint32_t cts, int32_t *lenp, uint32_t pacing_time) |
| 5437 | { |
| 5438 | /* |
| 5439 | * We (re-)transmitted starting at rsm->r_start for some length |
| 5440 | * (possibly less than r_end. |
| 5441 | */ |
| 5442 | struct bbr_sendmap *nrsm; |
| 5443 | uint32_t c_end; |
| 5444 | int32_t len; |
| 5445 | |
| 5446 | len = *lenp; |
| 5447 | c_end = rsm->r_start + len; |
| 5448 | if (SEQ_GEQ(c_end, rsm->r_end)) { |
| 5449 | /* |
| 5450 | * We retransmitted the whole piece or more than the whole |
| 5451 | * slopping into the next rsm. |
| 5452 | */ |
| 5453 | bbr_update_rsm(tp, bbr, rsm, cts, pacing_time); |
| 5454 | if (c_end == rsm->r_end) { |
| 5455 | *lenp = 0; |
| 5456 | return (0); |
| 5457 | } else { |
| 5458 | int32_t act_len; |
| 5459 | |
| 5460 | /* Hangs over the end return whats left */ |
| 5461 | act_len = rsm->r_end - rsm->r_start; |
| 5462 | *lenp = (len - act_len); |
| 5463 | return (rsm->r_end); |
| 5464 | } |
| 5465 | /* We don't get out of this block. */ |
| 5466 | } |
| 5467 | /* |
| 5468 | * Here we retransmitted less than the whole thing which means we |
| 5469 | * have to split this into what was transmitted and what was not. |
| 5470 | */ |
| 5471 | nrsm = bbr_alloc_full_limit(bbr); |
| 5472 | if (nrsm == NULL) { |
| 5473 | *lenp = 0; |
| 5474 | return (0); |
| 5475 | } |
| 5476 | /* |
| 5477 | * So here we are going to take the original rsm and make it what we |
| 5478 | * retransmitted. nrsm will be the tail portion we did not |
| 5479 | * retransmit. For example say the chunk was 1, 11 (10 bytes). And |
| 5480 | * we retransmitted 5 bytes i.e. 1, 5. The original piece shrinks to |
| 5481 | * 1, 6 and the new piece will be 6, 11. |
| 5482 | */ |
| 5483 | bbr_clone_rsm(bbr, nrsm, rsm, c_end); |
| 5484 | TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); |
| 5485 | nrsm->r_dupack = 0; |
| 5486 | if (rsm->r_in_tmap) { |
| 5487 | TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); |
| 5488 | nrsm->r_in_tmap = 1; |
| 5489 | } |
| 5490 | rsm->r_flags &= (~BBR_HAS_FIN); |
| 5491 | bbr_update_rsm(tp, bbr, rsm, cts, pacing_time); |
no test coverage detected