+session_parse_handle (u64 handle, u32 * index, u32 * thread_index)
+{
+ *index = session_index_from_handle (handle);
+ *thread_index = session_thread_from_handle (handle);
+}
+
+always_inline stream_session_t *
+session_get_from_handle (u64 handle)
+{
+ session_manager_main_t *smm = &session_manager_main;
+ return
+ pool_elt_at_index (smm->sessions[session_thread_from_handle (handle)],
+ session_index_from_handle (handle));
+}
+
+/**
+ * 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_main_t *smm = &session_manager_main;
+ if (thread_index == vlib_get_thread_index ())
+ return;
+ clib_spinlock_lock_if_init (&smm->peekers_readers_locks[thread_index]);
+ smm->session_peekers[thread_index] += 1;
+ if (smm->session_peekers[thread_index] == 1)
+ clib_spinlock_lock_if_init (&smm->peekers_write_locks[thread_index]);
+ clib_spinlock_unlock_if_init (&smm->peekers_readers_locks[thread_index]);
+}
+
+always_inline void
+session_pool_remove_peeker (u32 thread_index)