Added at counter and memcpy(&in[at], &in[i], ...). When a block is skipped via continue, at lags behind i, so subsequent accepted blocks are shifted forward into the gap. cnt_added equals at, so the caller iterates in[0..cnt_added-1] and sees exactly the accepted blocks.
Replaced unconditional sf->sf_used++ with if (sack_blk_used(sf, sf->sf_cur) == 0) sf->sf_used++. The bit is checked before it's set by sack_blk_set on the same line. If the slot was already in use (wraparound with numblks ≥ SACK_FILTER_BLOCKS), sf_used is not inflated. This matches the pattern in sack_filter_run.
Replaced if (sf->sf_cur) sf->sf_cur--; with sf->sf_cur = (sf->sf_cur + SACK_FILTER_BLOCKS - 1) % SACK_FILTER_BLOCKS;. The modular form handles the case where sf_cur wrapped to 0, correctly yielding SACK_FILTER_BLOCKS - 1. The condition changed from if (sf->sf_cur) to if (cnt_added) so we don't touch sf_cur when nothing was added.