+/** Enqueue data out-of-order for delivery to application */
+always_inline int
+sctp_session_enqueue_data_ooo (sctp_connection_t * sctp_conn,
+ vlib_buffer_t * b, u16 data_len, u8 conn_idx)
+{
+ int written, error = SCTP_ERROR_ENQUEUED;
+
+ written =
+ session_enqueue_stream_connection (&sctp_conn->
+ sub_conn[conn_idx].connection, b, 0,
+ 1 /* queue event */ ,
+ 0);
+
+ /* Update next_tsn_expected */
+ if (PREDICT_TRUE (written == data_len))
+ {
+ sctp_conn->next_tsn_expected += written;
+
+ SCTP_ADV_DBG ("CONN = %u, WRITTEN [%u] == DATA_LEN [%d]",
+ sctp_conn->sub_conn[conn_idx].connection.c_index,
+ written, data_len);
+ }
+ /* If more data written than expected, account for out-of-order bytes. */
+ else if (written > data_len)
+ {
+ sctp_conn->next_tsn_expected += written;
+
+ SCTP_ADV_DBG ("CONN = %u, WRITTEN [%u] > DATA_LEN [%d]",
+ sctp_conn->sub_conn[conn_idx].connection.c_index,
+ written, data_len);
+ }
+ else if (written > 0)
+ {
+ /* We've written something but FIFO is probably full now */
+ sctp_conn->next_tsn_expected += written;
+
+ error = SCTP_ERROR_PARTIALLY_ENQUEUED;
+
+ SCTP_ADV_DBG
+ ("CONN = %u, WRITTEN [%u] > 0 (SCTP_ERROR_PARTIALLY_ENQUEUED)",
+ sctp_conn->sub_conn[conn_idx].connection.c_index, written);
+ }
+ else
+ {
+ SCTP_ADV_DBG ("CONN = %u, WRITTEN == 0 (SCTP_ERROR_FIFO_FULL)",
+ sctp_conn->sub_conn[conn_idx].connection.c_index);
+
+ return SCTP_ERROR_FIFO_FULL;
+ }
+
+ /* TODO: Update out_of_order_map & SACK list */
+
+ return error;
+}
+