diff options
Diffstat (limited to 'vnet/vnet/pg/input.c')
-rw-r--r-- | vnet/vnet/pg/input.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/vnet/vnet/pg/input.c b/vnet/vnet/pg/input.c index c3a54ad6e44..af81d5386cb 100644 --- a/vnet/vnet/pg/input.c +++ b/vnet/vnet/pg/input.c @@ -40,6 +40,8 @@ #include <vlib/vlib.h> #include <vnet/pg/pg.h> #include <vnet/vnet.h> +#include <vnet/feature/feature.h> +#include <vnet/devices/devices.h> #if DPDK==1 #include <vnet/devices/dpdk/dpdk.h> @@ -1550,6 +1552,13 @@ pg_generate_packets (vlib_node_runtime_t * node, u32 *to_next, n_this_frame, n_left, n_trace, n_packets_in_fifo; uword n_packets_generated; pg_buffer_index_t *bi, *bi0; + u32 next_index = s->next_index; + vnet_feature_main_t *fm = &feature_main; + vnet_feature_config_main_t *cm; + u8 feature_arc_index = fm->device_input_feature_arc_index; + cm = &fm->feature_config_mains[feature_arc_index]; + u32 current_config_index = ~(u32) 0; + int i; bi0 = s->buffer_indices; @@ -1557,11 +1566,20 @@ pg_generate_packets (vlib_node_runtime_t * node, n_packets_to_generate = clib_min (n_packets_in_fifo, n_packets_to_generate); n_packets_generated = 0; + if (PREDICT_FALSE + (vnet_have_features (feature_arc_index, s->sw_if_index[VLIB_RX]))) + { + current_config_index = + vec_elt (cm->config_index_by_sw_if_index, s->sw_if_index[VLIB_RX]); + vnet_get_config_data (&cm->config_main, ¤t_config_index, + &next_index, 0); + } + while (n_packets_to_generate > 0) { u32 *head, *start, *end; - vlib_get_next_frame (vm, node, s->next_index, to_next, n_left); + vlib_get_next_frame (vm, node, next_index, to_next, n_left); n_this_frame = n_packets_to_generate; if (n_this_frame > n_left) @@ -1583,6 +1601,18 @@ pg_generate_packets (vlib_node_runtime_t * node, vec_foreach (bi, s->buffer_indices) clib_fifo_advance_head (bi->buffer_fifo, n_this_frame); + if (current_config_index != ~(u32) 0) + for (i = 0; i < n_this_frame; i++) + { + vlib_buffer_t *b; + b = vlib_get_buffer (vm, to_next[i]); + vnet_buffer (b)->device_input_feat.saved_next_index = + s->next_index; + vnet_buffer (b)->device_input_feat.buffer_advance = 0; + b->current_config_index = current_config_index; + b->feature_arc_index = feature_arc_index; + } + n_trace = vlib_get_trace_count (vm, node); if (n_trace > 0) { @@ -1593,7 +1623,7 @@ pg_generate_packets (vlib_node_runtime_t * node, n_packets_to_generate -= n_this_frame; n_packets_generated += n_this_frame; n_left -= n_this_frame; - vlib_put_next_frame (vm, node, s->next_index, n_left); + vlib_put_next_frame (vm, node, next_index, n_left); } return n_packets_generated; @@ -1673,6 +1703,8 @@ VLIB_REGISTER_NODE (pg_input_node) = { /* Input node will be left disabled until a stream is active. */ .state = VLIB_NODE_STATE_DISABLED, + .n_next_nodes = VNET_DEVICE_INPUT_N_NEXT_NODES, + .next_nodes = VNET_DEVICE_INPUT_NEXT_NODES, }; /* *INDENT-ON* */ |