diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5b5ae79..9bb1dbd 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -5349,7 +5349,7 @@ static int sctp_eat_data(const struct sc if (SCTP_CMD_CHUNK_ULP == deliver) sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); - chunk->data_accepted = 1; + chunk->data_accepted++; /* Note: Some chunks may get overcounted (if we drop) or overcounted * if we renege and the chunk arrives again. diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index ee23678..0e1f11d 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -685,6 +685,17 @@ struct sctp_ulpevent *sctp_ulpevent_make /* Initialize event with flags 0. */ sctp_ulpevent_init(event, 0); + /* Check to see if we need to fixup the truesize of the clone. + * We are about to charge the receive buffer for this chunk, + * and we always use skb->truesize. However, this doesn't work + * for bundled data chunks since we'll drastically overcharge. + * To get around that, keep the oiginal truesize on the clone + * only for the first data chunk, and update truesize for the clone + * on subsequent ones. + */ + if (chunk->data_accepted > 1) + skb->truesize = sizeof(struct skb); + sctp_ulpevent_receive_data(event, asoc); event->stream = ntohs(chunk->subh.data_hdr->stream);