X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Finterface_output.c;h=b19ca7c50c3eb3e7babf89aa6117fc3f2ddb670c;hb=914f91b837564416b3a8b15566c627aae6d567d2;hp=f19b9152da7ab823ac1c1734783548925f197f0f;hpb=f1213b82771ce929c076339c24a777cfd59690e6;p=vpp.git diff --git a/vnet/vnet/interface_output.c b/vnet/vnet/interface_output.c index f19b9152da7..b19ca7c50c3 100644 --- a/vnet/vnet/interface_output.c +++ b/vnet/vnet/interface_output.c @@ -41,7 +41,7 @@ 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) @@ -393,11 +393,14 @@ vnet_interface_output_node (vlib_main_t * vm, 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; @@ -465,6 +468,7 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm, 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); @@ -493,19 +497,16 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm, 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)) @@ -520,18 +521,16 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm, } } - 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 */ @@ -546,7 +545,9 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm, 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) @@ -572,10 +573,10 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm, 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); @@ -613,6 +614,32 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm, 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 @@ -1137,6 +1164,8 @@ VLIB_REGISTER_NODE (drop_buffers,static) = { .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 @@ -1147,12 +1176,16 @@ VLIB_REGISTER_NODE (punt_buffers,static) = { .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,