typedef struct {
u32 sw_if_index;
- u8 data[64 - sizeof (u32)];
+ u8 data[128 - sizeof (u32)];
} interface_output_trace_t;
u8 * format_vnet_interface_output_trace (u8 * s, va_list * va)
return n_buffers;
}
+VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node)
+CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node)
-uword
-vnet_interface_output_node_no_flatten (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+always_inline uword
+vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame,
+ int with_features)
{
vnet_main_t * vnm = vnet_get_main();
vnet_interface_output_runtime_t * rt = (void *) node->runtime_data;
u32 bi0, bi1;
vlib_buffer_t * b0, * b1;
u32 tx_swif0, tx_swif1;
+ u32 next0, next1;
/* Prefetch next iteration. */
vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
n_bytes += n_bytes_b0 + n_bytes_b1;
n_packets += 2;
-
- if (PREDICT_FALSE(si->output_feature_bitmap &&
- vnet_buffer(b0)->output_features.bitmap != (1 << INTF_OUTPUT_FEAT_DONE)))
+ if (with_features)
{
- u32 next0;
+ b0->flags |= BUFFER_OUTPUT_FEAT_DONE;
vnet_buffer(b0)->output_features.bitmap = si->output_feature_bitmap;
count_trailing_zeros(next0, vnet_buffer(b0)->output_features.bitmap);
vnet_buffer(b0)->output_features.bitmap &= ~(1 << next0);
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_tx,
- n_left_to_tx, bi0, next0);
}
else
{
+ next0 = VNET_INTERFACE_OUTPUT_NEXT_TX;
vnet_buffer(b0)->output_features.bitmap = 0;
if (PREDICT_FALSE(tx_swif0 != rt->sw_if_index))
}
}
- if (PREDICT_FALSE(si->output_feature_bitmap &&
- vnet_buffer(b1)->output_features.bitmap != (1 << INTF_OUTPUT_FEAT_DONE)))
+ if (with_features)
{
- u32 next1;
+ b1->flags |= BUFFER_OUTPUT_FEAT_DONE;
vnet_buffer(b1)->output_features.bitmap = si->output_feature_bitmap;
count_trailing_zeros(next1, vnet_buffer(b1)->output_features.bitmap);
vnet_buffer(b1)->output_features.bitmap &= ~(1 << next1);
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_tx,
- n_left_to_tx, bi1, next1);
}
else
{
+ next1 = VNET_INTERFACE_OUTPUT_NEXT_TX;
vnet_buffer(b1)->output_features.bitmap = 0;
/* update vlan subif tx counts, if required */
n_bytes_b1);
}
}
-
+ if (with_features)
+ vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_tx,
+ n_left_to_tx, bi0, bi1, next0, next1);
}
while (from + 1 <= from_end && n_left_to_tx >= 1)
n_bytes += n_bytes_b0;
n_packets += 1;
- if (PREDICT_FALSE(si->output_feature_bitmap &&
- vnet_buffer(b0)->output_features.bitmap != (1 << INTF_OUTPUT_FEAT_DONE)))
+ if (with_features)
{
u32 next0;
+ b0->flags |= BUFFER_OUTPUT_FEAT_DONE;
vnet_buffer(b0)->output_features.bitmap = si->output_feature_bitmap;
count_trailing_zeros(next0, vnet_buffer(b0)->output_features.bitmap);
vnet_buffer(b0)->output_features.bitmap &= ~(1 << next0);
return n_buffers;
}
+uword
+vnet_interface_output_node_no_flatten (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ vnet_main_t * vnm = vnet_get_main ();
+ vnet_interface_output_runtime_t * rt = (void *) node->runtime_data;
+ vnet_sw_interface_t * si;
+ si = vnet_get_sw_interface (vnm, rt->sw_if_index);
+
+ if (PREDICT_FALSE(si->output_feature_bitmap))
+ {
+ /* if first pakcet in the frame have BUFFER_OUTPUT_FEAT_DONE flag set
+ then whole frame is arriving from feature node */
+
+ u32 * from = vlib_frame_args (frame);
+ vlib_buffer_t * b = vlib_get_buffer (vm, from[0]);
+
+ if ((b->flags & BUFFER_OUTPUT_FEAT_DONE) == 0)
+ return vnet_interface_output_node_no_flatten_inline (vm, node, frame, 1);
+ }
+ return vnet_interface_output_node_no_flatten_inline (vm, node, frame, 0);
+}
+
+VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node_no_flatten)
+CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node_no_flatten)
/* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
static uword
.validate_frame = validate_error_frame,
};
+VLIB_NODE_FUNCTION_MULTIARCH (drop_buffers, process_drop)
+
VLIB_REGISTER_NODE (punt_buffers,static) = {
.function = process_punt,
.flags = (VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
.validate_frame = validate_error_frame,
};
+VLIB_NODE_FUNCTION_MULTIARCH (punt_buffers, process_punt)
+
VLIB_REGISTER_NODE (vnet_per_buffer_interface_output_node,static) = {
.function = vnet_per_buffer_interface_output,
.name = "interface-output",
.vector_size = sizeof (u32),
};
+VLIB_NODE_FUNCTION_MULTIARCH (vnet_per_buffer_interface_output_node, vnet_per_buffer_interface_output)
+
clib_error_t *
vnet_per_buffer_interface_output_hw_interface_add_del (vnet_main_t * vnm,
u32 hw_if_index,