+ n_bytes_per_seg = MAX_HDRS_LEN + ctx->snd_mss;
+ ctx->n_bufs_per_seg = ceil ((f64) n_bytes_per_seg / n_bytes_per_buf);
+ ctx->deq_per_buf = clib_min (ctx->snd_mss, n_bytes_per_buf);
+ ctx->deq_per_first_buf = clib_min (ctx->snd_mss,
+ n_bytes_per_buf - MAX_HDRS_LEN);
+}
+
+always_inline int
+session_tx_fifo_read_and_snd_i (vlib_main_t * vm, vlib_node_runtime_t * node,
+ session_fifo_event_t * e,
+ stream_session_t * s, int *n_tx_packets,
+ u8 peek_data)
+{
+ u32 next_index, next0, next1, *to_next, n_left_to_next;
+ u32 n_trace = vlib_get_trace_count (vm, node), n_bufs_needed = 0;
+ u32 thread_index = s->thread_index, n_left, pbi;
+ session_manager_main_t *smm = &session_manager_main;
+ session_tx_context_t *ctx = &smm->ctx[thread_index];
+ transport_proto_t tp;
+ vlib_buffer_t *pb;
+ u16 n_bufs, rv;
+
+ if (PREDICT_FALSE ((rv = session_tx_not_ready (s, peek_data))))
+ {
+ if (rv < 2)
+ vec_add1 (smm->pending_event_vector[thread_index], *e);
+ return 0;
+ }
+
+ next_index = smm->session_type_to_next[s->session_type];
+ next0 = next1 = next_index;
+
+ tp = session_get_transport_proto (s);
+ ctx->s = s;
+ ctx->transport_vft = transport_protocol_get_vft (tp);
+ ctx->tc = session_tx_get_transport (ctx, peek_data);
+ ctx->snd_mss = ctx->transport_vft->send_mss (ctx->tc);
+ ctx->snd_space = ctx->transport_vft->send_space (ctx->tc);
+ if (ctx->snd_space == 0 || ctx->snd_mss == 0)
+ {
+ vec_add1 (smm->pending_event_vector[thread_index], *e);
+ return 0;
+ }
+
+ /* Allow enqueuing of a new event */
+ svm_fifo_unset_event (s->server_tx_fifo);
+
+ /* Check how much we can pull. */
+ session_tx_set_dequeue_params (vm, ctx, VLIB_FRAME_SIZE - *n_tx_packets,
+ peek_data);