@@ -3387,6 +3387,8 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
struct sk_buff *next_skb;
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ int tx_seq_offset, next_tx_seq_offset;
bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
@@ -3397,11 +3399,20 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s
return 0;
}
+ tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ if (tx_seq_offset < 0)
+ tx_seq_offset += 64;
+
do {
if (bt_cb(next_skb)->tx_seq == tx_seq)
return -EINVAL;
- if (bt_cb(next_skb)->tx_seq > tx_seq) {
+ next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
+ pi->buffer_seq) % 64;
+ if (next_tx_seq_offset < 0)
+ next_tx_seq_offset += 64;
+
+ if (next_tx_seq_offset > tx_seq_offset) {
__skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
return 0;
}