+static void
+tcp_enqueue_to_ip_lookup_now (tcp_worker_ctx_t * wrk, vlib_buffer_t * b,
+ u32 bi, u8 is_ip4, u32 fib_index)
+{
+ tcp_enqueue_to_ip_lookup_i (wrk, b, bi, is_ip4, fib_index, 1);
+}
+
+static void
+tcp_enqueue_to_ip_lookup (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
+ u8 is_ip4, u32 fib_index)
+{
+ tcp_enqueue_to_ip_lookup_i (wrk, b, bi, is_ip4, fib_index, 0);
+ if (wrk->vm->thread_index == 0 && vlib_num_workers ())
+ session_flush_frames_main_thread (wrk->vm);
+}
+
+always_inline void
+tcp_enqueue_to_output_i (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
+ u8 is_ip4, u8 flush)
+{
+ u32 *to_next, next_index;
+ vlib_frame_t *f;
+
+ b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
+ b->error = 0;
+
+ /* Decide where to send the packet */
+ next_index = is_ip4 ? tcp4_output_node.index : tcp6_output_node.index;
+ tcp_trajectory_add_start (b, 2);
+
+ /* Get frame to v4/6 output node */
+ f = wrk->tx_frames[!is_ip4];
+ if (!f)
+ {
+ f = vlib_get_frame_to_node (wrk->vm, next_index);
+ ASSERT (f);
+ wrk->tx_frames[!is_ip4] = f;
+ }
+ to_next = vlib_frame_vector_args (f);
+ to_next[f->n_vectors] = bi;
+ f->n_vectors += 1;
+ if (flush || f->n_vectors == VLIB_FRAME_SIZE)
+ {
+ vlib_put_frame_to_node (wrk->vm, next_index, f);
+ wrk->tx_frames[!is_ip4] = 0;
+ }
+}
+
+static void
+tcp_enqueue_to_output (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
+ u8 is_ip4)
+{
+ tcp_enqueue_to_output_i (wrk, b, bi, is_ip4, 0);
+}
+
+static void
+tcp_enqueue_to_output_now (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
+ u8 is_ip4)
+{
+ tcp_enqueue_to_output_i (wrk, b, bi, is_ip4, 1);
+}
+
+static int