+typedef struct session_listen_msg_
+{
+ u32 client_index;
+ u32 context; /* Not needed but keeping it for compatibility with bapi */
+ u32 wrk_index;
+ u32 vrf;
+ u16 port;
+ u8 proto;
+ u8 is_ip4;
+ ip46_address_t ip;
+ u32 ckpair_index;
+ u8 crypto_engine;
+} __clib_packed session_listen_msg_t;
+
+STATIC_ASSERT (sizeof (session_listen_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
+ "msg too large");
+
+typedef struct session_listen_uri_msg_
+{
+ u32 client_index;
+ u32 context;
+ u8 uri[56];
+} __clib_packed session_listen_uri_msg_t;
+
+STATIC_ASSERT (sizeof (session_listen_uri_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
+ "msg too large");
+
+typedef struct session_bound_msg_
+{
+ u32 context;
+ u64 handle;
+ i32 retval;
+ u8 lcl_is_ip4;
+ u8 lcl_ip[16];
+ u16 lcl_port;
+ uword rx_fifo;
+ uword tx_fifo;
+ uword vpp_evt_q;
+ u32 segment_size;
+ u8 segment_name_length;
+ u8 segment_name[128];
+} __clib_packed session_bound_msg_t;
+
+typedef struct session_unlisten_msg_
+{
+ u32 client_index;
+ u32 context;
+ u32 wrk_index;
+ session_handle_t handle;
+} __clib_packed session_unlisten_msg_t;
+
+typedef struct session_unlisten_reply_msg_
+{
+ u32 context;
+ u64 handle;
+ i32 retval;
+} __clib_packed session_unlisten_reply_msg_t;
+
+typedef struct session_accepted_msg_
+{
+ u32 context;
+ u64 listener_handle;
+ u64 handle;
+ uword server_rx_fifo;
+ uword server_tx_fifo;
+ u64 segment_handle;
+ uword vpp_event_queue_address;
+ transport_endpoint_t rmt;
+ u8 flags;
+} __clib_packed session_accepted_msg_t;
+
+typedef struct session_accepted_reply_msg_
+{
+ u32 context;
+ i32 retval;
+ u64 handle;
+} __clib_packed session_accepted_reply_msg_t;
+
+typedef struct session_connect_msg_
+{
+ u32 client_index;
+ u32 context;
+ u32 wrk_index;
+ u32 vrf;
+ u16 port;
+ u8 proto;
+ u8 is_ip4;
+ ip46_address_t ip;
+ ip46_address_t lcl_ip;
+ u8 hostname_len;
+ u8 hostname[16];
+ u64 parent_handle;
+ u32 ckpair_index;
+ u8 crypto_engine;
+ u8 flags;
+} __clib_packed session_connect_msg_t;
+
+STATIC_ASSERT (sizeof (session_connect_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
+ "msg too large");
+
+typedef struct session_connect_uri_msg_
+{
+ u32 client_index;
+ u32 context;
+ u8 uri[56];
+} __clib_packed session_connect_uri_msg_t;
+
+STATIC_ASSERT (sizeof (session_connect_uri_msg_t) <=
+ SESSION_CTRL_MSG_MAX_SIZE, "msg too large");
+
+typedef struct session_connected_msg_
+{
+ u32 context;
+ i32 retval;
+ u64 handle;
+ uword server_rx_fifo;
+ uword server_tx_fifo;
+ u64 segment_handle;
+ uword ct_rx_fifo;
+ uword ct_tx_fifo;
+ u64 ct_segment_handle;
+ uword vpp_event_queue_address;
+ u32 segment_size;
+ u8 segment_name_length;
+ u8 segment_name[64];
+ transport_endpoint_t lcl;
+} __clib_packed session_connected_msg_t;
+
+typedef struct session_disconnect_msg_
+{
+ u32 client_index;
+ u32 context;
+ session_handle_t handle;
+} __clib_packed session_disconnect_msg_t;
+
+typedef struct session_disconnected_msg_
+{
+ u32 client_index;
+ u32 context;
+ u64 handle;
+} __clib_packed session_disconnected_msg_t;
+
+typedef struct session_disconnected_reply_msg_
+{
+ u32 context;
+ i32 retval;
+ u64 handle;
+} __clib_packed session_disconnected_reply_msg_t;
+
+typedef struct session_reset_msg_
+{
+ u32 client_index;
+ u32 context;
+ u64 handle;
+} __clib_packed session_reset_msg_t;
+
+typedef struct session_reset_reply_msg_
+{
+ u32 context;
+ i32 retval;
+ u64 handle;
+} __clib_packed session_reset_reply_msg_t;
+
+typedef struct session_req_worker_update_msg_
+{
+ u64 session_handle;
+} __clib_packed session_req_worker_update_msg_t;
+
+/* NOTE: using u16 for wrk indices because message needs to fit in 18B */
+typedef struct session_worker_update_msg_
+{
+ u32 client_index;
+ u16 wrk_index;
+ u16 req_wrk_index;
+ u64 handle;
+} __clib_packed session_worker_update_msg_t;
+
+typedef struct session_worker_update_reply_msg_
+{
+ u64 handle;
+ uword rx_fifo;
+ uword tx_fifo;
+ u64 segment_handle;
+} __clib_packed session_worker_update_reply_msg_t;
+
+typedef struct session_app_detach_msg_
+{
+ u32 client_index;
+ u32 context;
+} session_app_detach_msg_t;
+
+typedef struct app_map_another_segment_msg_
+{
+ u32 client_index;
+ u32 context;
+ u8 fd_flags;
+ u32 segment_size;
+ u8 segment_name[128];
+ u64 segment_handle;
+} session_app_add_segment_msg_t;
+
+typedef struct app_unmap_segment_msg_
+{
+ u32 client_index;
+ u32 context;
+ u64 segment_handle;
+} session_app_del_segment_msg_t;
+
+typedef struct session_migrate_msg_
+{
+ uword vpp_evt_q;
+ session_handle_t handle;
+ session_handle_t new_handle;
+ u32 vpp_thread_index;
+} __clib_packed session_migrated_msg_t;
+
+typedef struct session_cleanup_msg_
+{
+ session_handle_t handle;
+} __clib_packed session_cleanup_msg_t;
+
+typedef struct app_session_event_
+{
+ svm_msg_q_msg_t msg;
+ session_event_t *evt;
+} __clib_packed app_session_evt_t;
+
+static inline void
+app_alloc_ctrl_evt_to_vpp (svm_msg_q_t * mq, app_session_evt_t * app_evt,
+ u8 evt_type)
+{
+ svm_msg_q_lock_and_alloc_msg_w_ring (mq,
+ SESSION_MQ_CTRL_EVT_RING,
+ SVM_Q_WAIT, &app_evt->msg);
+ app_evt->evt = svm_msg_q_msg_data (mq, &app_evt->msg);
+ clib_memset (app_evt->evt, 0, sizeof (*app_evt->evt));
+ app_evt->evt->event_type = evt_type;
+}
+
+static inline void
+app_send_ctrl_evt_to_vpp (svm_msg_q_t * mq, app_session_evt_t * app_evt)
+{
+ svm_msg_q_add_and_unlock (mq, &app_evt->msg);
+}
+
+/**
+ * Send fifo io event to vpp worker thread
+ *
+ * Because there may be multiple writers to one of vpp's queues, this
+ * protects message allocation and enqueueing.
+ *
+ * @param mq vpp message queue
+ * @param f fifo for which the event is sent
+ * @param evt_type type of event
+ * @param noblock flag to indicate is request is blocking or not
+ * @return 0 if success, negative integer otherwise
+ */
+static inline int
+app_send_io_evt_to_vpp (svm_msg_q_t * mq, u32 session_index, u8 evt_type,
+ u8 noblock)
+{
+ session_event_t *evt;
+ svm_msg_q_msg_t msg;
+
+ if (noblock)
+ {
+ if (svm_msg_q_try_lock (mq))
+ return -1;
+ if (PREDICT_FALSE (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)))
+ {
+ svm_msg_q_unlock (mq);
+ return -2;
+ }
+ msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
+ evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
+ evt->session_index = session_index;
+ evt->event_type = evt_type;
+ svm_msg_q_add_and_unlock (mq, &msg);
+ return 0;
+ }
+ else
+ {
+ svm_msg_q_lock (mq);
+ while (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)
+ || svm_msg_q_is_full (mq))
+ svm_msg_q_wait (mq);
+ msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
+ evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
+ evt->session_index = session_index;
+ evt->event_type = evt_type;
+ svm_msg_q_add_and_unlock (mq, &msg);
+ return 0;
+ }
+}
+