LRO: Don't merge ACK and non-ACK packets together
LRO was willing to merge ACK and non-ACK packets together. This can cause incorrect th_ack values to be reported up the stack. While non-ACKs are quite unlikely to appear in practice, LRO's behaviour is against the spec. Make LRO unwilling to merge packets with different TH_ACK flag values in order to fix the issue. Found by: Sysunit test Differential Revision: https://reviews.freebsd.org/D33775 Reviewed by: rrs
This commit is contained in:
parent
24fe6643da
commit
3284f4925f
@ -921,6 +921,7 @@ tcp_set_entry_to_mbuf(struct lro_ctrl *lc, struct lro_entry *le,
|
||||
le->next_seq = ntohl(th->th_seq) + tcp_data_len;
|
||||
le->ack_seq = th->th_ack;
|
||||
le->window = th->th_win;
|
||||
le->flags = th->th_flags;
|
||||
le->needs_merge = 0;
|
||||
|
||||
/* Setup new data pointers. */
|
||||
@ -1092,10 +1093,12 @@ again:
|
||||
}
|
||||
/* Try to append the new segment. */
|
||||
if (__predict_false(ntohl(th->th_seq) != le->next_seq ||
|
||||
((th->th_flags & TH_ACK) !=
|
||||
(le->flags & TH_ACK)) ||
|
||||
(tcp_data_len == 0 &&
|
||||
le->ack_seq == th->th_ack &&
|
||||
le->window == th->th_win))) {
|
||||
/* Out of order packet or duplicate ACK. */
|
||||
/* Out of order packet, non-ACK + ACK or dup ACK. */
|
||||
tcp_push_and_replace(lc, le, m);
|
||||
goto again;
|
||||
}
|
||||
|
@ -146,8 +146,9 @@ struct lro_entry {
|
||||
uint16_t compressed;
|
||||
uint16_t uncompressed;
|
||||
uint16_t window;
|
||||
uint16_t timestamp : 1;
|
||||
uint16_t needs_merge : 1;
|
||||
uint8_t flags;
|
||||
uint8_t timestamp : 1;
|
||||
uint8_t needs_merge : 1;
|
||||
struct bintime alloc_time; /* time when entry was allocated */
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user