Skip to content

Commit 95ac7b8

Browse files
Lee A. Robertsdavem330
authored andcommitted
sctp: fix association hangs due to errors when reneging events from the ordering queue
In sctp_ulpq_renege_list(), events being reneged from the ordering queue may correspond to multiple TSNs. Identify all affected packets; sum freed space and renege from the tsnmap. Signed-off-by: Lee A. Roberts <lee.roberts@hp.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Acked-by: Neil Horman <nhorman@tuxdriver.com>
1 parent e67f85e commit 95ac7b8

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

net/sctp/ulpqueue.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -962,8 +962,8 @@ static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq,
962962
struct sk_buff_head *list, __u16 needed)
963963
{
964964
__u16 freed = 0;
965-
__u32 tsn;
966-
struct sk_buff *skb;
965+
__u32 tsn, last_tsn;
966+
struct sk_buff *skb, *flist, *last;
967967
struct sctp_ulpevent *event;
968968
struct sctp_tsnmap *tsnmap;
969969

@@ -977,10 +977,28 @@ static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq,
977977
if (TSN_lte(tsn, sctp_tsnmap_get_ctsn(tsnmap)))
978978
break;
979979

980-
__skb_unlink(skb, list);
980+
/* Events in ordering queue may have multiple fragments
981+
* corresponding to additional TSNs. Sum the total
982+
* freed space; find the last TSN.
983+
*/
981984
freed += skb_headlen(skb);
985+
flist = skb_shinfo(skb)->frag_list;
986+
for (last = flist; flist; flist = flist->next) {
987+
last = flist;
988+
freed += skb_headlen(last);
989+
}
990+
if (last)
991+
last_tsn = sctp_skb2event(last)->tsn;
992+
else
993+
last_tsn = tsn;
994+
995+
/* Unlink the event, then renege all applicable TSNs. */
996+
__skb_unlink(skb, list);
982997
sctp_ulpevent_free(event);
983-
sctp_tsnmap_renege(tsnmap, tsn);
998+
while (TSN_lte(tsn, last_tsn)) {
999+
sctp_tsnmap_renege(tsnmap, tsn);
1000+
tsn++;
1001+
}
9841002
if (freed >= needed)
9851003
return freed;
9861004
}

0 commit comments

Comments
 (0)