+always_inline session_type_t
+session_type_from_proto_and_ip (transport_proto_t proto, u8 is_ip4)
+{
+ return (proto << 1 | is_ip4);
+}
+
+always_inline u64
+session_segment_handle (stream_session_t * s)
+{
+ svm_fifo_t *f = s->server_rx_fifo;
+ return segment_manager_make_segment_handle (f->segment_manager,
+ f->segment_index);
+}
+
+always_inline u8
+session_has_transport (stream_session_t * s)
+{
+ return (session_get_transport_proto (s) != TRANSPORT_PROTO_NONE);
+}
+
+transport_service_type_t session_transport_service_type (stream_session_t *);
+transport_tx_fn_type_t session_transport_tx_fn_type (stream_session_t *);
+u8 session_tx_is_dgram (stream_session_t * s);
+
+/**
+ * Acquires a lock that blocks a session pool from expanding.
+ *
+ * This is typically used for safely peeking into other threads'
+ * pools in order to clone elements. Lock should be dropped as soon
+ * as possible by calling @ref session_pool_remove_peeker.
+ *
+ * NOTE: Avoid using pool_elt_at_index while the lock is held because
+ * it may lead to free elt bitmap expansion/contraction!
+ */
+always_inline void
+session_pool_add_peeker (u32 thread_index)
+{
+ session_manager_worker_t *wrk = &session_manager_main.wrk[thread_index];
+ if (thread_index == vlib_get_thread_index ())
+ return;
+ clib_rwlock_reader_lock (&wrk->peekers_rw_locks);
+}
+
+always_inline void
+session_pool_remove_peeker (u32 thread_index)
+{
+ session_manager_worker_t *wrk = &session_manager_main.wrk[thread_index];
+ if (thread_index == vlib_get_thread_index ())
+ return;
+ clib_rwlock_reader_unlock (&wrk->peekers_rw_locks);
+}
+
+/**
+ * Get session from handle and 'lock' pool resize if not in same thread
+ *
+ * Caller should drop the peek 'lock' as soon as possible.
+ */
+always_inline stream_session_t *
+session_get_from_handle_safe (u64 handle)
+{
+ u32 thread_index = session_thread_from_handle (handle);
+ session_manager_worker_t *wrk = &session_manager_main.wrk[thread_index];
+
+ if (thread_index == vlib_get_thread_index ())
+ {
+ return pool_elt_at_index (wrk->sessions,
+ session_index_from_handle (handle));
+ }
+ else
+ {
+ session_pool_add_peeker (thread_index);
+ /* Don't use pool_elt_at index. See @ref session_pool_add_peeker */
+ return wrk->sessions + session_index_from_handle (handle);
+ }