| 6952 | } |
| 6953 | |
| 6954 | static uint32_t |
| 6955 | rack_proc_sack_blk(struct tcpcb *tp, struct tcp_rack *rack, struct sackblk *sack, |
| 6956 | struct tcpopt *to, struct rack_sendmap **prsm, uint32_t cts, int *moved_two) |
| 6957 | { |
| 6958 | uint32_t start, end, changed = 0; |
| 6959 | struct rack_sendmap stack_map; |
| 6960 | struct rack_sendmap *rsm, *nrsm, fe, *insret, *prev, *next; |
| 6961 | int32_t used_ref = 1; |
| 6962 | int moved = 0; |
| 6963 | |
| 6964 | start = sack->start; |
| 6965 | end = sack->end; |
| 6966 | rsm = *prsm; |
| 6967 | memset(&fe, 0, sizeof(fe)); |
| 6968 | do_rest_ofb: |
| 6969 | if ((rsm == NULL) || |
| 6970 | (SEQ_LT(end, rsm->r_start)) || |
| 6971 | (SEQ_GEQ(start, rsm->r_end)) || |
| 6972 | (SEQ_LT(start, rsm->r_start))) { |
| 6973 | /* |
| 6974 | * We are not in the right spot, |
| 6975 | * find the correct spot in the tree. |
| 6976 | */ |
| 6977 | used_ref = 0; |
| 6978 | fe.r_start = start; |
| 6979 | rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); |
| 6980 | moved++; |
| 6981 | } |
| 6982 | if (rsm == NULL) { |
| 6983 | /* TSNH */ |
| 6984 | goto out; |
| 6985 | } |
| 6986 | /* Ok we have an ACK for some piece of this rsm */ |
| 6987 | if (rsm->r_start != start) { |
| 6988 | if ((rsm->r_flags & RACK_ACKED) == 0) { |
| 6989 | /** |
| 6990 | * Need to split this in two pieces the before and after, |
| 6991 | * the before remains in the map, the after must be |
| 6992 | * added. In other words we have: |
| 6993 | * rsm |--------------| |
| 6994 | * sackblk |-------> |
| 6995 | * rsm will become |
| 6996 | * rsm |---| |
| 6997 | * and nrsm will be the sacked piece |
| 6998 | * nrsm |----------| |
| 6999 | * |
| 7000 | * But before we start down that path lets |
| 7001 | * see if the sack spans over on top of |
| 7002 | * the next guy and it is already sacked. |
| 7003 | */ |
| 7004 | next = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); |
| 7005 | if (next && (next->r_flags & RACK_ACKED) && |
| 7006 | SEQ_GEQ(end, next->r_start)) { |
| 7007 | /** |
| 7008 | * So the next one is already acked, and |
| 7009 | * we can thus by hookery use our stack_map |
| 7010 | * to reflect the piece being sacked and |
| 7011 | * then adjust the two tree entries moving |
no test coverage detected