sctp: add SCTP_SEND_FAILED_EVENT event

This patch is to add a new event SCTP_SEND_FAILED_EVENT described in
rfc6458#section-6.1.11. It's a update of SCTP_SEND_FAILED event:

  struct sctp_sndrcvinfo ssf_info is replaced with
  struct sctp_sndinfo ssfe_info in struct sctp_send_failed_event.

SCTP_SEND_FAILED is being deprecated, but we don't remove it in this
patch. Both are being processed in sctp_datamsg_destroy() when the
corresp event flag is set.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
This commit is contained in:
Xin Long
2019-10-08 19:27:36 +08:00
committed by Jakub Kicinski
parent 5cd0b91733
commit b6e6b5f1da
4 changed files with 79 additions and 21 deletions

View File

@@ -75,41 +75,39 @@ static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
struct list_head *pos, *temp;
struct sctp_chunk *chunk;
struct sctp_ulpevent *ev;
int error = 0, notify;
/* If we failed, we may need to notify. */
notify = msg->send_failed ? -1 : 0;
int error, sent;
/* Release all references. */
list_for_each_safe(pos, temp, &msg->chunks) {
list_del_init(pos);
chunk = list_entry(pos, struct sctp_chunk, frag_list);
/* Check whether we _really_ need to notify. */
if (notify < 0) {
asoc = chunk->asoc;
if (msg->send_error)
error = msg->send_error;
else
error = asoc->outqueue.error;
notify = sctp_ulpevent_type_enabled(asoc->subscribe,
SCTP_SEND_FAILED);
if (!msg->send_failed) {
sctp_chunk_put(chunk);
continue;
}
/* Generate a SEND FAILED event only if enabled. */
if (notify > 0) {
int sent;
if (chunk->has_tsn)
sent = SCTP_DATA_SENT;
else
sent = SCTP_DATA_UNSENT;
asoc = chunk->asoc;
error = msg->send_error ?: asoc->outqueue.error;
sent = chunk->has_tsn ? SCTP_DATA_SENT : SCTP_DATA_UNSENT;
if (sctp_ulpevent_type_enabled(asoc->subscribe,
SCTP_SEND_FAILED)) {
ev = sctp_ulpevent_make_send_failed(asoc, chunk, sent,
error, GFP_ATOMIC);
if (ev)
asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
}
if (sctp_ulpevent_type_enabled(asoc->subscribe,
SCTP_SEND_FAILED_EVENT)) {
ev = sctp_ulpevent_make_send_failed_event(asoc, chunk,
sent, error,
GFP_ATOMIC);
if (ev)
asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
}
sctp_chunk_put(chunk);
}