}
}
+#define NSIM_PKT_TAG 0xfefabeba
+
always_inline void
nsim_dispatch_buffer (vlib_main_t * vm, vlib_node_runtime_t * node,
nsim_main_t * nsm, nsim_wheel_t * wp, vlib_buffer_t * b,
u32 bi, nsim_node_ctx_t * ctx, u8 is_cross_connect,
u8 is_trace)
{
+ if (vnet_buffer (b)->ip.flow_hash == NSIM_PKT_TAG)
+ {
+ u32 next;
+ vnet_get_config_data (&ctx->fcm->config_main, &b->current_config_index,
+ &next, 0);
+
+ ctx->fwd[0] = bi;
+ ctx->fwd_nexts[0] = next;
+ ctx->fwd += 1;
+ ctx->fwd_nexts += 1;
+
+ goto trace;
+ }
+
if (PREDICT_TRUE (!(ctx->action[0] & NSIM_ACTION_DROP)))
{
if (PREDICT_FALSE (ctx->action[0] & NSIM_ACTION_REORDER))
{
u32 next;
- ctx->reord[0] = bi;
vnet_get_config_data (&ctx->fcm->config_main,
&b->current_config_index, &next, 0);
+ ctx->reord[0] = bi;
ctx->reord_nexts[0] = next;
ctx->reord += 1;
ctx->reord_nexts += 1;
ep->tx_time = ctx->expires;
ep->rx_sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
+ ep->tx_sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
nsim_buffer_fwd_lookup (nsm, b, &ep->output_next_index,
is_cross_connect);
- ep->tx_sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
ep->buffer_index = bi;
ctx->n_buffered += 1;
+ vnet_buffer (b)->ip.flow_hash = NSIM_PKT_TAG;
}
else
{
u32 n_left_from, *from, drops[VLIB_FRAME_SIZE], reorders[VLIB_FRAME_SIZE];
nsim_wheel_t *wp = nsm->wheel_by_thread[vm->thread_index];
vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
- u16 reorders_nexts[VLIB_FRAME_SIZE];
+ u16 reorders_nexts[VLIB_FRAME_SIZE], fwds_nexts[VLIB_FRAME_SIZE];
+ u32 fwds[VLIB_FRAME_SIZE];
u8 actions[VLIB_FRAME_SIZE];
nsim_node_ctx_t ctx;
ctx.drop = drops;
ctx.reord = reorders;
ctx.reord_nexts = reorders_nexts;
+ ctx.fwd = fwds;
+ ctx.fwd_nexts = fwds_nexts;
ctx.action = actions;
ctx.expires = vlib_time_now (vm) + nsm->delay;
vlib_node_increment_counter (vm, node->node_index, NSIM_ERROR_REORDERED,
n_reordered);
}
+ if (ctx.fwd > fwds)
+ {
+ vlib_buffer_enqueue_to_next (vm, node, fwds, fwds_nexts, ctx.fwd - fwds);
+ }
vlib_node_increment_counter (vm, node->node_index,
NSIM_ERROR_BUFFERED, ctx.n_buffered);
return frame->n_vectors;
hw = vnet_get_hw_interface (nsm->vnet_main, sw_if_index);
vec_validate_init_empty (nsm->output_next_index_by_sw_if_index, sw_if_index,
~0);
- /* Note: use the tx node, this pkt has already visited the output node... */
- nsm->output_next_index_by_sw_if_index[sw_if_index] =
- vlib_node_add_next (nsm->vlib_main, nsim_input_node.index,
- hw->tx_node_index);
+ nsm->output_next_index_by_sw_if_index[sw_if_index] = vlib_node_add_next (
+ nsm->vlib_main, nsim_input_node.index, hw->output_node_index);
vnet_feature_enable_disable ("interface-output", "nsim-output-feature",
sw_if_index, enable_disable, 0, 0);