X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Finterface_output.c;h=475b0b935af02c78bbfddd8185256bc57ebce67a;hb=3a2a1c47bc1f319d1f46abd2a364b3cf82404405;hp=b19ca7c50c3eb3e7babf89aa6117fc3f2ddb670c;hpb=6c56a3c6f0382f3751272d0784e9e0d16a646f3f;p=vpp.git diff --git a/vnet/vnet/interface_output.c b/vnet/vnet/interface_output.c index b19ca7c50c3..475b0b935af 100644 --- a/vnet/vnet/interface_output.c +++ b/vnet/vnet/interface_output.c @@ -38,31 +38,51 @@ */ #include +#include -typedef struct { +typedef struct +{ u32 sw_if_index; u8 data[128 - sizeof (u32)]; -} interface_output_trace_t; +} +interface_output_trace_t; -u8 * format_vnet_interface_output_trace (u8 * s, va_list * va) +u8 * +format_vnet_interface_output_trace (u8 * s, va_list * va) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *); - vlib_node_t * node = va_arg (*va, vlib_node_t *); - interface_output_trace_t * t = va_arg (*va, interface_output_trace_t *); - vnet_main_t * vnm = vnet_get_main(); - vnet_sw_interface_t * si; + vlib_node_t *node = va_arg (*va, vlib_node_t *); + interface_output_trace_t *t = va_arg (*va, interface_output_trace_t *); + vnet_main_t *vnm = vnet_get_main (); + vnet_sw_interface_t *si; uword indent; - if (t->sw_if_index != (u32)~0) + if (t->sw_if_index != (u32) ~ 0) { - si = vnet_get_sw_interface (vnm, t->sw_if_index); indent = format_get_indent (s); - - s = format (s, "%U\n%U%U", - format_vnet_sw_interface_name, vnm, si, - format_white_space, indent, - node->format_buffer ? node->format_buffer : format_hex_bytes, - t->data, sizeof (t->data)); + + if (pool_is_free_index + (vnm->interface_main.sw_interfaces, t->sw_if_index)) + { + /* the interface may have been deleted by the time the trace is printed */ + s = format (s, "sw_if_index: %d\n%U%U", + t->sw_if_index, + format_white_space, indent, + node->format_buffer ? node-> + format_buffer : format_hex_bytes, t->data, + sizeof (t->data)); + } + else + { + si = vnet_get_sw_interface (vnm, t->sw_if_index); + + s = format (s, "%U\n%U%U", + format_vnet_sw_interface_name, vnm, si, + format_white_space, indent, + node->format_buffer ? node-> + format_buffer : format_hex_bytes, t->data, + sizeof (t->data)); + } } return s; } @@ -70,19 +90,18 @@ u8 * format_vnet_interface_output_trace (u8 * s, va_list * va) static void vnet_interface_output_trace (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, - uword n_buffers) + vlib_frame_t * frame, uword n_buffers) { - u32 n_left, * from; + u32 n_left, *from; n_left = n_buffers; from = vlib_frame_args (frame); - + while (n_left >= 4) { u32 bi0, bi1; - vlib_buffer_t * b0, * b1; - interface_output_trace_t * t0, * t1; + vlib_buffer_t *b0, *b1; + interface_output_trace_t *t0, *t1; /* Prefetch next iteration. */ vlib_prefetch_buffer_with_index (vm, from[2], LOAD); @@ -99,14 +118,14 @@ vnet_interface_output_trace (vlib_main_t * vm, t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0])); t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; clib_memcpy (t0->data, vlib_buffer_get_current (b0), - sizeof (t0->data)); + sizeof (t0->data)); } if (b1->flags & VLIB_BUFFER_IS_TRACED) { t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0])); t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX]; clib_memcpy (t1->data, vlib_buffer_get_current (b1), - sizeof (t1->data)); + sizeof (t1->data)); } from += 2; n_left -= 2; @@ -115,8 +134,8 @@ vnet_interface_output_trace (vlib_main_t * vm, while (n_left >= 1) { u32 bi0; - vlib_buffer_t * b0; - interface_output_trace_t * t0; + vlib_buffer_t *b0; + interface_output_trace_t *t0; bi0 = from[0]; @@ -127,7 +146,7 @@ vnet_interface_output_trace (vlib_main_t * vm, t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0])); t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; clib_memcpy (t0->data, vlib_buffer_get_current (b0), - sizeof (t0->data)); + sizeof (t0->data)); } from += 1; n_left -= 1; @@ -138,9 +157,7 @@ static never_inline u32 slow_path (vlib_main_t * vm, u32 bi, vlib_buffer_t * b, - u32 n_left_to_tx, - u32 * to_tx, - u32 * n_slow_bytes_result) + u32 n_left_to_tx, u32 * to_tx, u32 * n_slow_bytes_result) { /* We've already enqueued a single buffer. */ u32 n_buffers = 0; @@ -155,10 +172,10 @@ slow_path (vlib_main_t * vm, n_slow_bytes += vlib_buffer_length_in_chain (vm, b); /* Be grumpy about zero length buffers for benefit of - driver tx function. */ + driver tx function. */ ASSERT (b->current_length > 0); - if (! (b->flags & VLIB_BUFFER_NEXT_PRESENT)) + if (!(b->flags & VLIB_BUFFER_NEXT_PRESENT)) break; bi = b->next_buffer; @@ -173,52 +190,54 @@ slow_path (vlib_main_t * vm, return n_buffers; } -/* - * Increment TX stats. Roll up consecutive increments to the same sw_if_index +/* + * Increment TX stats. Roll up consecutive increments to the same sw_if_index * into one increment. */ -static_always_inline -void incr_output_stats (vnet_main_t * vnm, - u32 cpu_index, - u32 length, - u32 sw_if_index, - u32 * last_sw_if_index, - u32 * n_packets, - u32 * n_bytes) { - vnet_interface_main_t * im; - - if (PREDICT_TRUE (sw_if_index == *last_sw_if_index)) { - *n_packets += 1; - *n_bytes += length; - } else { - if (PREDICT_TRUE (*last_sw_if_index != ~0)) { - im = &vnm->interface_main; - - vlib_increment_combined_counter (im->combined_sw_if_counters - + VNET_INTERFACE_COUNTER_TX, - cpu_index, - *last_sw_if_index, - *n_packets, - *n_bytes); +static_always_inline void +incr_output_stats (vnet_main_t * vnm, + u32 cpu_index, + u32 length, + u32 sw_if_index, + u32 * last_sw_if_index, u32 * n_packets, u32 * n_bytes) +{ + vnet_interface_main_t *im; + + if (PREDICT_TRUE (sw_if_index == *last_sw_if_index)) + { + *n_packets += 1; + *n_bytes += length; + } + else + { + if (PREDICT_TRUE (*last_sw_if_index != ~0)) + { + im = &vnm->interface_main; + + vlib_increment_combined_counter (im->combined_sw_if_counters + + VNET_INTERFACE_COUNTER_TX, + cpu_index, + *last_sw_if_index, + *n_packets, *n_bytes); + } + *last_sw_if_index = sw_if_index; + *n_packets = 1; + *n_bytes = length; } - *last_sw_if_index = sw_if_index; - *n_packets = 1; - *n_bytes = length; - } } /* Interface output functions. */ uword -vnet_interface_output_node (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +vnet_interface_output_node_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; - vnet_hw_interface_t * hi; - u32 n_left_to_tx, * from, * from_end, * to_tx; + vnet_main_t *vnm = vnet_get_main (); + vnet_interface_output_runtime_t *rt = (void *) node->runtime_data; + vnet_sw_interface_t *si; + vnet_hw_interface_t *hi; + u32 n_left_to_tx, *from, *from_end, *to_tx; u32 n_bytes, n_buffers, n_packets; u32 last_sw_if_index; u32 cpu_index = vm->cpu_index; @@ -231,8 +250,7 @@ vnet_interface_output_node (vlib_main_t * vm, from = vlib_frame_args (frame); if (rt->is_deleted) - return vlib_error_drop_buffers (vm, node, - from, + return vlib_error_drop_buffers (vm, node, from, /* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP, @@ -241,22 +259,21 @@ vnet_interface_output_node (vlib_main_t * vm, si = vnet_get_sw_interface (vnm, rt->sw_if_index); hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index); - if (! (si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) || - ! (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) + if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) || + !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) { - vlib_simple_counter_main_t * cm; - + vlib_simple_counter_main_t *cm; + cm = vec_elt_at_index (vnm->interface_main.sw_if_counters, - VNET_INTERFACE_COUNTER_TX_ERROR); + VNET_INTERFACE_COUNTER_TX_ERROR); vlib_increment_simple_counter (cm, cpu_index, - rt->sw_if_index, n_buffers); - return vlib_error_drop_buffers (vm, node, - from, - /* buffer stride */ 1, - n_buffers, - VNET_INTERFACE_OUTPUT_NEXT_DROP, - node->node_index, - VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN); + rt->sw_if_index, n_buffers); + return vlib_error_drop_buffers (vm, node, from, + /* buffer stride */ 1, + n_buffers, + VNET_INTERFACE_OUTPUT_NEXT_DROP, + node->node_index, + VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN); } from_end = from + n_buffers; @@ -269,14 +286,14 @@ vnet_interface_output_node (vlib_main_t * vm, while (from < from_end) { /* Get new next frame since previous incomplete frame may have less - than VNET_FRAME_SIZE vectors in it. */ + than VNET_FRAME_SIZE vectors in it. */ vlib_get_new_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX, to_tx, n_left_to_tx); while (from + 4 <= from_end && n_left_to_tx >= 2) { u32 bi0, bi1; - vlib_buffer_t * b0, * b1; + vlib_buffer_t *b0, *b1; /* Prefetch next iteration. */ vlib_prefetch_buffer_with_index (vm, from[2], LOAD); @@ -298,7 +315,8 @@ vnet_interface_output_node (vlib_main_t * vm, ASSERT (b0->current_length > 0); ASSERT (b1->current_length > 0); - if (PREDICT_FALSE ((b0->flags | b1->flags) & VLIB_BUFFER_NEXT_PRESENT)) + if (PREDICT_FALSE + ((b0->flags | b1->flags) & VLIB_BUFFER_NEXT_PRESENT)) { u32 n_buffers, n_slow_bytes, i; @@ -311,7 +329,7 @@ vnet_interface_output_node (vlib_main_t * vm, for (i = 0; i < 2; i++) { u32 bi = i ? bi1 : bi0; - vlib_buffer_t * b = i ? b1 : b0; + vlib_buffer_t *b = i ? b1 : b0; n_buffers = slow_path (vm, bi, b, n_left_to_tx, to_tx, &n_slow_bytes); @@ -324,25 +342,27 @@ vnet_interface_output_node (vlib_main_t * vm, to_tx += n_buffers; n_left_to_tx -= n_buffers; incr_output_stats (vnm, cpu_index, n_slow_bytes, - vnet_buffer(b)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); + vnet_buffer (b)->sw_if_index[VLIB_TX], + &last_sw_if_index, &n_packets, &n_bytes); } - } else { - incr_output_stats (vnm, cpu_index, - vlib_buffer_length_in_chain (vm, b0), - vnet_buffer(b0)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); - incr_output_stats (vnm, cpu_index, - vlib_buffer_length_in_chain (vm, b0), - vnet_buffer(b1)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); - } + } + else + { + incr_output_stats (vnm, cpu_index, + vlib_buffer_length_in_chain (vm, b0), + vnet_buffer (b0)->sw_if_index[VLIB_TX], + &last_sw_if_index, &n_packets, &n_bytes); + incr_output_stats (vnm, cpu_index, + vlib_buffer_length_in_chain (vm, b0), + vnet_buffer (b1)->sw_if_index[VLIB_TX], + &last_sw_if_index, &n_packets, &n_bytes); + } } while (from + 1 <= from_end && n_left_to_tx >= 1) { u32 bi0; - vlib_buffer_t * b0; + vlib_buffer_t *b0; bi0 = from[0]; to_tx[0] = bi0; @@ -376,42 +396,43 @@ vnet_interface_output_node (vlib_main_t * vm, to_tx += n_buffers; n_left_to_tx -= n_buffers; } - incr_output_stats (vnm, cpu_index, - vlib_buffer_length_in_chain (vm, b0), - vnet_buffer(b0)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); + incr_output_stats (vnm, cpu_index, + vlib_buffer_length_in_chain (vm, b0), + vnet_buffer (b0)->sw_if_index[VLIB_TX], + &last_sw_if_index, &n_packets, &n_bytes); } put: - vlib_put_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX, n_left_to_tx); + vlib_put_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX, + n_left_to_tx); } /* Final update of interface stats. */ - incr_output_stats (vnm, cpu_index, 0, ~0, /* ~0 will flush stats */ - &last_sw_if_index, &n_packets, &n_bytes); + incr_output_stats (vnm, cpu_index, 0, ~0, /* ~0 will flush stats */ + &last_sw_if_index, &n_packets, &n_bytes); return n_buffers; } -VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node) -CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node) +VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node_flatten); +CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node_flatten); -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) +uword +vnet_interface_output_node (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; - vnet_hw_interface_t * hi; - u32 n_left_to_tx, * from, * from_end, * to_tx; + vnet_main_t *vnm = vnet_get_main (); + vnet_interface_output_runtime_t *rt = (void *) node->runtime_data; + vnet_sw_interface_t *si; + vnet_hw_interface_t *hi; + u32 n_left_to_tx, *from, *from_end, *to_tx; u32 n_bytes, n_buffers, n_packets; u32 n_bytes_b0, n_bytes_b1; u32 cpu_index = vm->cpu_index; - vnet_interface_main_t * im = &vnm->interface_main; + vnet_interface_main_t *im = &vnm->interface_main; u32 next_index = VNET_INTERFACE_OUTPUT_NEXT_TX; + u32 current_config_index = ~0; + u8 arc = im->output_feature_arc_index; n_buffers = frame->n_vectors; @@ -421,8 +442,7 @@ vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm, from = vlib_frame_args (frame); if (rt->is_deleted) - return vlib_error_drop_buffers (vm, node, - from, + return vlib_error_drop_buffers (vm, node, from, /* buffer stride */ 1, n_buffers, VNET_INTERFACE_OUTPUT_NEXT_DROP, @@ -431,23 +451,22 @@ vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm, si = vnet_get_sw_interface (vnm, rt->sw_if_index); hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index); - if (! (si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) || - ! (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) + if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) || + !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) { - vlib_simple_counter_main_t * cm; - + vlib_simple_counter_main_t *cm; + cm = vec_elt_at_index (vnm->interface_main.sw_if_counters, - VNET_INTERFACE_COUNTER_TX_ERROR); + VNET_INTERFACE_COUNTER_TX_ERROR); vlib_increment_simple_counter (cm, cpu_index, - rt->sw_if_index, n_buffers); - - return vlib_error_drop_buffers (vm, node, - from, - /* buffer stride */ 1, - n_buffers, - VNET_INTERFACE_OUTPUT_NEXT_DROP, - node->node_index, - VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN); + rt->sw_if_index, n_buffers); + + return vlib_error_drop_buffers (vm, node, from, + /* buffer stride */ 1, + n_buffers, + VNET_INTERFACE_OUTPUT_NEXT_DROP, + node->node_index, + VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN); } from_end = from + n_buffers; @@ -456,19 +475,28 @@ vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm, n_bytes = 0; n_packets = 0; + /* interface-output feature arc handling */ + if (PREDICT_FALSE (vnet_have_features (arc, rt->sw_if_index))) + { + vnet_feature_config_main_t *fcm; + fcm = vnet_feature_get_config_main (arc); + current_config_index = vnet_get_feature_config_index (arc, + rt->sw_if_index); + vnet_get_config_data (&fcm->config_main, ¤t_config_index, + &next_index, 0); + } + while (from < from_end) { /* Get new next frame since previous incomplete frame may have less - than VNET_FRAME_SIZE vectors in it. */ - vlib_get_new_next_frame (vm, node, next_index, - to_tx, n_left_to_tx); + than VNET_FRAME_SIZE vectors in it. */ + vlib_get_new_next_frame (vm, node, next_index, to_tx, n_left_to_tx); while (from + 4 <= from_end && n_left_to_tx >= 2) { u32 bi0, bi1; - vlib_buffer_t * b0, * b1; - u32 tx_swif0, tx_swif1; - u32 next0, next1; + vlib_buffer_t *b0, *b1; + u32 tx_swif0, tx_swif1; /* Prefetch next iteration. */ vlib_prefetch_buffer_with_index (vm, from[2], LOAD); @@ -490,71 +518,47 @@ vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm, ASSERT (b0->current_length > 0); ASSERT (b1->current_length > 0); - n_bytes_b0 = vlib_buffer_length_in_chain (vm, b0); - n_bytes_b1 = vlib_buffer_length_in_chain (vm, b1); - tx_swif0 = vnet_buffer(b0)->sw_if_index[VLIB_TX]; - tx_swif1 = vnet_buffer(b1)->sw_if_index[VLIB_TX]; + n_bytes_b0 = vlib_buffer_length_in_chain (vm, b0); + n_bytes_b1 = vlib_buffer_length_in_chain (vm, b1); + tx_swif0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + tx_swif1 = vnet_buffer (b1)->sw_if_index[VLIB_TX]; n_bytes += n_bytes_b0 + n_bytes_b1; n_packets += 2; - if (with_features) - { - 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); - } - else - { - next0 = VNET_INTERFACE_OUTPUT_NEXT_TX; - vnet_buffer(b0)->output_features.bitmap = 0; - - if (PREDICT_FALSE(tx_swif0 != rt->sw_if_index)) - { - /* update vlan subif tx counts, if required */ - vlib_increment_combined_counter (im->combined_sw_if_counters - + VNET_INTERFACE_COUNTER_TX, - cpu_index, - tx_swif0, - 1, - n_bytes_b0); - } - } - - if (with_features) - { - 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); - } - else - { - next1 = VNET_INTERFACE_OUTPUT_NEXT_TX; - vnet_buffer(b1)->output_features.bitmap = 0; - - /* update vlan subif tx counts, if required */ - if (PREDICT_FALSE(tx_swif1 != rt->sw_if_index)) - { - - vlib_increment_combined_counter (im->combined_sw_if_counters - + VNET_INTERFACE_COUNTER_TX, - cpu_index, - tx_swif1, - 1, - 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); + + if (PREDICT_FALSE (current_config_index != ~0)) + { + b0->feature_arc_index = arc; + b1->feature_arc_index = arc; + b0->current_config_index = current_config_index; + b1->current_config_index = current_config_index; + } + + if (PREDICT_FALSE (tx_swif0 != rt->sw_if_index)) + { + /* update vlan subif tx counts, if required */ + vlib_increment_combined_counter (im->combined_sw_if_counters + + VNET_INTERFACE_COUNTER_TX, + cpu_index, tx_swif0, 1, + n_bytes_b0); + } + + /* update vlan subif tx counts, if required */ + if (PREDICT_FALSE (tx_swif1 != rt->sw_if_index)) + { + + vlib_increment_combined_counter (im->combined_sw_if_counters + + VNET_INTERFACE_COUNTER_TX, + cpu_index, tx_swif1, 1, + n_bytes_b1); + } } while (from + 1 <= from_end && n_left_to_tx >= 1) { u32 bi0; - vlib_buffer_t * b0; - u32 tx_swif0; + vlib_buffer_t *b0; + u32 tx_swif0; bi0 = from[0]; to_tx[0] = bi0; @@ -568,78 +572,40 @@ vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm, driver tx function. */ ASSERT (b0->current_length > 0); - n_bytes_b0 = vlib_buffer_length_in_chain (vm, b0); - tx_swif0 = vnet_buffer(b0)->sw_if_index[VLIB_TX]; + n_bytes_b0 = vlib_buffer_length_in_chain (vm, b0); + tx_swif0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; n_bytes += n_bytes_b0; n_packets += 1; - 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 - { - vnet_buffer(b0)->output_features.bitmap = 0; - - if (PREDICT_FALSE(tx_swif0 != rt->sw_if_index)) - { - - vlib_increment_combined_counter (im->combined_sw_if_counters - + VNET_INTERFACE_COUNTER_TX, - cpu_index, - tx_swif0, - 1, - n_bytes_b0); - } - } + if (PREDICT_FALSE (current_config_index != ~0)) + { + b0->feature_arc_index = arc; + b0->current_config_index = current_config_index; + } + + if (PREDICT_FALSE (tx_swif0 != rt->sw_if_index)) + { + + vlib_increment_combined_counter (im->combined_sw_if_counters + + VNET_INTERFACE_COUNTER_TX, + cpu_index, tx_swif0, 1, + n_bytes_b0); + } } - vlib_put_next_frame (vm, node, next_index, - n_left_to_tx); + vlib_put_next_frame (vm, node, next_index, n_left_to_tx); } /* Update main interface stats. */ vlib_increment_combined_counter (im->combined_sw_if_counters - + VNET_INTERFACE_COUNTER_TX, - cpu_index, - rt->sw_if_index, - n_packets, - n_bytes); + + VNET_INTERFACE_COUNTER_TX, + cpu_index, + rt->sw_if_index, n_packets, n_bytes); 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) +VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node); +CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node); /* Use buffer's sw_if_index[VNET_TX] to choose output interface. */ static uword @@ -647,8 +613,8 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - vnet_main_t * vnm = vnet_get_main(); - u32 n_left_to_next, * from, * to_next; + vnet_main_t *vnm = vnet_get_main (); + u32 n_left_to_next, *from, *to_next; u32 n_left_from, next_index; n_left_from = frame->n_vectors; @@ -663,8 +629,8 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, while (n_left_from >= 4 && n_left_to_next >= 2) { u32 bi0, bi1, next0, next1; - vlib_buffer_t * b0, * b1; - vnet_hw_interface_t * hi0, * hi1; + vlib_buffer_t *b0, *b1; + vnet_hw_interface_t *hi0, *hi1; /* Prefetch next iteration. */ vlib_prefetch_buffer_with_index (vm, from[2], LOAD); @@ -682,21 +648,28 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); b1 = vlib_get_buffer (vm, bi1); - hi0 = vnet_get_sup_hw_interface (vnm, vnet_buffer (b0)->sw_if_index[VLIB_TX]); - hi1 = vnet_get_sup_hw_interface (vnm, vnet_buffer (b1)->sw_if_index[VLIB_TX]); + hi0 = + vnet_get_sup_hw_interface (vnm, + vnet_buffer (b0)->sw_if_index + [VLIB_TX]); + hi1 = + vnet_get_sup_hw_interface (vnm, + vnet_buffer (b1)->sw_if_index + [VLIB_TX]); next0 = hi0->hw_if_index; next1 = hi1->hw_if_index; - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, n_left_to_next, - bi0, bi1, next0, next1); + vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, + n_left_to_next, bi0, bi1, next0, + next1); } while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0, next0; - vlib_buffer_t * b0; - vnet_hw_interface_t * hi0; + vlib_buffer_t *b0; + vnet_hw_interface_t *hi0; bi0 = from[0]; to_next[0] = bi0; @@ -707,12 +680,15 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); - hi0 = vnet_get_sup_hw_interface (vnm, vnet_buffer (b0)->sw_if_index[VLIB_TX]); + hi0 = + vnet_get_sup_hw_interface (vnm, + vnet_buffer (b0)->sw_if_index + [VLIB_TX]); next0 = hi0->hw_if_index; - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, - bi0, next0); + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); @@ -724,7 +700,7 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, always_inline u32 counter_index (vlib_main_t * vm, vlib_error_t e) { - vlib_node_t * n; + vlib_node_t *n; u32 ci, ni; ni = vlib_error_get_node (e); @@ -738,13 +714,14 @@ counter_index (vlib_main_t * vm, vlib_error_t e) return ci; } -static u8 * format_vnet_error_trace (u8 * s, va_list * va) +static u8 * +format_vnet_error_trace (u8 * s, va_list * va) { - vlib_main_t * vm = va_arg (*va, vlib_main_t *); + vlib_main_t *vm = va_arg (*va, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *); - vlib_error_t * e = va_arg (*va, vlib_error_t *); - vlib_node_t * error_node; - vlib_error_main_t * em = &vm->error_main; + vlib_error_t *e = va_arg (*va, vlib_error_t *); + vlib_node_t *error_node; + vlib_error_main_t *em = &vm->error_main; u32 i; error_node = vlib_get_node (vm, vlib_error_get_node (e[0])); @@ -756,19 +733,18 @@ static u8 * format_vnet_error_trace (u8 * s, va_list * va) static void trace_errors_with_buffers (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) + vlib_node_runtime_t * node, vlib_frame_t * frame) { - u32 n_left, * buffers; + u32 n_left, *buffers; buffers = vlib_frame_vector_args (frame); n_left = frame->n_vectors; - + while (n_left >= 4) { u32 bi0, bi1; - vlib_buffer_t * b0, * b1; - vlib_error_t * t0, * t1; + vlib_buffer_t *b0, *b1; + vlib_error_t *t0, *t1; /* Prefetch next iteration. */ vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD); @@ -797,8 +773,8 @@ trace_errors_with_buffers (vlib_main_t * vm, while (n_left >= 1) { u32 bi0; - vlib_buffer_t * b0; - vlib_error_t * t0; + vlib_buffer_t *b0; + vlib_error_t *t0; bi0 = buffers[0]; @@ -819,7 +795,7 @@ validate_error (vlib_main_t * vm, vlib_error_t * e, u32 index) { uword node_index = vlib_error_get_node (e[0]); uword code = vlib_error_get_code (e[0]); - vlib_node_t * n; + vlib_node_t *n; if (node_index >= vec_len (vm->node_main.nodes)) return format (0, "[%d], node index out of range 0x%x, error 0x%x", @@ -835,12 +811,11 @@ validate_error (vlib_main_t * vm, vlib_error_t * e, u32 index) static u8 * validate_error_frame (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * f) + vlib_node_runtime_t * node, vlib_frame_t * f) { - u32 * buffers = vlib_frame_args (f); - vlib_buffer_t * b; - u8 * msg = 0; + u32 *buffers = vlib_frame_args (f); + vlib_buffer_t *b; + u8 *msg = 0; uword i; for (i = 0; i < f->n_vectors; i++) @@ -854,7 +829,8 @@ validate_error_frame (vlib_main_t * vm, return msg; } -typedef enum { +typedef enum +{ VNET_ERROR_DISPOSITION_DROP, VNET_ERROR_DISPOSITION_PUNT, VNET_ERROR_N_DISPOSITION, @@ -863,26 +839,25 @@ typedef enum { always_inline void do_packet (vlib_main_t * vm, vlib_error_t a) { - vlib_error_main_t * em = &vm->error_main; + vlib_error_main_t *em = &vm->error_main; u32 i = counter_index (vm, a); em->counters[i] += 1; vlib_error_elog_count (vm, i, 1); } - + static_always_inline uword process_drop_punt (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, - vnet_error_disposition_t disposition) + vlib_frame_t * frame, vnet_error_disposition_t disposition) { - vnet_main_t * vnm = vnet_get_main(); - vlib_error_main_t * em = &vm->error_main; - u32 * buffers, * first_buffer; + vnet_main_t *vnm = vnet_get_main (); + vlib_error_main_t *em = &vm->error_main; + u32 *buffers, *first_buffer; vlib_error_t current_error; u32 current_counter_index, n_errors_left; u32 current_sw_if_index, n_errors_current_sw_if_index; u64 current_counter; - vlib_simple_counter_main_t * cm; + vlib_simple_counter_main_t *cm; u32 cpu_index = vm->cpu_index; static vlib_error_t memory[VNET_ERROR_N_DISPOSITION]; @@ -892,9 +867,9 @@ process_drop_punt (vlib_main_t * vm, first_buffer = buffers; { - vlib_buffer_t * b = vlib_get_buffer (vm, first_buffer[0]); + vlib_buffer_t *b = vlib_get_buffer (vm, first_buffer[0]); - if (! memory_init[disposition]) + if (!memory_init[disposition]) { memory_init[disposition] = 1; memory[disposition] = b->error; @@ -910,7 +885,7 @@ process_drop_punt (vlib_main_t * vm, if (node->flags & VLIB_NODE_FLAG_TRACE) trace_errors_with_buffers (vm, node, frame); - + n_errors_left = frame->n_vectors; cm = vec_elt_at_index (vnm->interface_main.sw_if_counters, (disposition == VNET_ERROR_DISPOSITION_PUNT @@ -919,8 +894,8 @@ process_drop_punt (vlib_main_t * vm, while (n_errors_left >= 2) { - vlib_buffer_t * b0, * b1; - vnet_sw_interface_t * sw_if0, * sw_if1; + vlib_buffer_t *b0, *b1; + vnet_sw_interface_t *sw_if0, *sw_if1; vlib_error_t e0, e1; u32 bi0, bi1; u32 sw_if_index0, sw_if_index1; @@ -944,7 +919,7 @@ process_drop_punt (vlib_main_t * vm, n_errors_current_sw_if_index += 2; /* Speculatively assume all 2 (node, code) pairs are equal - to current (node, code). */ + to current (node, code). */ current_counter += 2; if (PREDICT_FALSE (e0 != current_error @@ -962,13 +937,13 @@ process_drop_punt (vlib_main_t * vm, sub-interfaces. */ sw_if0 = vnet_get_sw_interface (vnm, sw_if_index0); vlib_increment_simple_counter - (cm, cpu_index, sw_if0->sup_sw_if_index, - sw_if0->sup_sw_if_index != sw_if_index0); + (cm, cpu_index, sw_if0->sup_sw_if_index, + sw_if0->sup_sw_if_index != sw_if_index0); sw_if1 = vnet_get_sw_interface (vnm, sw_if_index1); vlib_increment_simple_counter - (cm, cpu_index, sw_if1->sup_sw_if_index, - sw_if1->sup_sw_if_index != sw_if_index1); + (cm, cpu_index, sw_if1->sup_sw_if_index, + sw_if1->sup_sw_if_index != sw_if_index1); em->counters[current_counter_index] = current_counter; do_packet (vm, e0); @@ -986,8 +961,8 @@ process_drop_punt (vlib_main_t * vm, while (n_errors_left >= 1) { - vlib_buffer_t * b0; - vnet_sw_interface_t * sw_if0; + vlib_buffer_t *b0; + vnet_sw_interface_t *sw_if0; vlib_error_t e0; u32 bi0, sw_if_index0; @@ -1007,7 +982,7 @@ process_drop_punt (vlib_main_t * vm, /* Increment super-interface drop/punt counters for sub-interfaces. */ sw_if0 = vnet_get_sw_interface (vnm, sw_if_index0); - vlib_increment_simple_counter (cm, cpu_index, sw_if0->sup_sw_if_index, + vlib_increment_simple_counter (cm, cpu_index, sw_if0->sup_sw_if_index, sw_if0->sup_sw_if_index != sw_if_index0); if (PREDICT_FALSE (e0 != current_error)) @@ -1017,7 +992,7 @@ process_drop_punt (vlib_main_t * vm, vlib_error_elog_count (vm, current_counter_index, (current_counter - em->counters[current_counter_index])); - + em->counters[current_counter_index] = current_counter; do_packet (vm, e0); @@ -1029,15 +1004,15 @@ process_drop_punt (vlib_main_t * vm, if (n_errors_current_sw_if_index > 0) { - vnet_sw_interface_t * si; + vnet_sw_interface_t *si; vlib_increment_simple_counter (cm, cpu_index, current_sw_if_index, n_errors_current_sw_if_index); si = vnet_get_sw_interface (vnm, current_sw_if_index); if (si->sup_sw_if_index != current_sw_if_index) - vlib_increment_simple_counter (cm, cpu_index, si->sup_sw_if_index, - n_errors_current_sw_if_index); + vlib_increment_simple_counter (cm, cpu_index, si->sup_sw_if_index, + n_errors_current_sw_if_index); } vlib_error_elog_count (vm, current_counter_index, @@ -1050,16 +1025,12 @@ process_drop_punt (vlib_main_t * vm, /* Save memory for next iteration. */ memory[disposition] = current_error; - if (disposition == VNET_ERROR_DISPOSITION_DROP - || ! vm->os_punt_frame) + if (disposition == VNET_ERROR_DISPOSITION_DROP || !vm->os_punt_frame) { - vlib_buffer_free - (vm, - first_buffer, - frame->n_vectors); + vlib_buffer_free (vm, first_buffer, frame->n_vectors); /* If there is no punt function, free the frame as well. */ - if (disposition == VNET_ERROR_DISPOSITION_PUNT && ! vm->os_punt_frame) + if (disposition == VNET_ERROR_DISPOSITION_PUNT && !vm->os_punt_frame) vlib_frame_free (vm, node, frame); } else @@ -1068,14 +1039,13 @@ process_drop_punt (vlib_main_t * vm, return frame->n_vectors; } -static inline void -pcap_drop_trace (vlib_main_t * vm, - vnet_interface_main_t * im, - vlib_frame_t * f) +static inline void +pcap_drop_trace (vlib_main_t * vm, + vnet_interface_main_t * im, vlib_frame_t * f) { - u32 * from; + u32 *from; u32 n_left = f->n_vectors; - vlib_buffer_t * b0, * p1; + vlib_buffer_t *b0, *p1; u32 bi0; i16 save_current_data; u16 save_current_length; @@ -1085,48 +1055,49 @@ pcap_drop_trace (vlib_main_t * vm, while (n_left > 0) { if (PREDICT_TRUE (n_left > 1)) - { - p1 = vlib_get_buffer (vm, from[1]); - vlib_prefetch_buffer_header (p1, LOAD); - } - + { + p1 = vlib_get_buffer (vm, from[1]); + vlib_prefetch_buffer_header (p1, LOAD); + } + bi0 = from[0]; b0 = vlib_get_buffer (vm, bi0); from++; n_left--; - + /* See if we're pointedly ignoring this specific error */ - if (im->pcap_drop_filter_hash - && hash_get (im->pcap_drop_filter_hash, b0->error)) - continue; + if (im->pcap_drop_filter_hash + && hash_get (im->pcap_drop_filter_hash, b0->error)) + continue; /* Trace all drops, or drops received on a specific interface */ if (im->pcap_sw_if_index == 0 || - im->pcap_sw_if_index == vnet_buffer(b0)->sw_if_index [VLIB_RX]) - { - save_current_data = b0->current_data; - save_current_length = b0->current_length; - - /* - * Typically, we'll need to rewind the buffer - */ - if (b0->current_data > 0) - vlib_buffer_advance (b0, (word) -b0->current_data); - - pcap_add_buffer (&im->pcap_main, vm, bi0, 512); - - b0->current_data = save_current_data; - b0->current_length = save_current_length; - } + im->pcap_sw_if_index == vnet_buffer (b0)->sw_if_index[VLIB_RX]) + { + save_current_data = b0->current_data; + save_current_length = b0->current_length; + + /* + * Typically, we'll need to rewind the buffer + */ + if (b0->current_data > 0) + vlib_buffer_advance (b0, (word) - b0->current_data); + + pcap_add_buffer (&im->pcap_main, vm, bi0, 512); + + b0->current_data = save_current_data; + b0->current_length = save_current_length; + } } } -void vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add) +void +vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add) { - vnet_interface_main_t * im = &vnet_get_main()->interface_main; + vnet_interface_main_t *im = &vnet_get_main ()->interface_main; if (im->pcap_drop_filter_hash == 0) - im->pcap_drop_filter_hash = hash_create (0, sizeof (uword)); + im->pcap_drop_filter_hash = hash_create (0, sizeof (uword)); if (is_add) hash_set (im->pcap_drop_filter_hash, error_index, 1); @@ -1136,10 +1107,9 @@ void vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add) static uword process_drop (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) + vlib_node_runtime_t * node, vlib_frame_t * frame) { - vnet_interface_main_t * im = &vnet_get_main()->interface_main; + vnet_interface_main_t *im = &vnet_get_main ()->interface_main; if (PREDICT_FALSE (im->drop_pcap_enable)) pcap_drop_trace (vm, im, frame); @@ -1149,12 +1119,12 @@ process_drop (vlib_main_t * vm, static uword process_punt (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) + vlib_node_runtime_t * node, vlib_frame_t * frame) { return process_drop_punt (vm, node, frame, VNET_ERROR_DISPOSITION_PUNT); } +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (drop_buffers,static) = { .function = process_drop, .name = "error-drop", @@ -1163,9 +1133,11 @@ VLIB_REGISTER_NODE (drop_buffers,static) = { .format_trace = format_vnet_error_trace, .validate_frame = validate_error_frame, }; +/* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (drop_buffers, process_drop) +VLIB_NODE_FUNCTION_MULTIARCH (drop_buffers, process_drop); +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (punt_buffers,static) = { .function = process_punt, .flags = (VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH @@ -1175,23 +1147,105 @@ VLIB_REGISTER_NODE (punt_buffers,static) = { .format_trace = format_vnet_error_trace, .validate_frame = validate_error_frame, }; +/* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (punt_buffers, process_punt) +VLIB_NODE_FUNCTION_MULTIARCH (punt_buffers, process_punt); +/* *INDENT-OFF* */ VLIB_REGISTER_NODE (vnet_per_buffer_interface_output_node,static) = { .function = vnet_per_buffer_interface_output, .name = "interface-output", .vector_size = sizeof (u32), }; +/* *INDENT-ON* */ + +VLIB_NODE_FUNCTION_MULTIARCH (vnet_per_buffer_interface_output_node, + vnet_per_buffer_interface_output); + +static uword +interface_tx_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * from_frame) +{ + vnet_main_t *vnm = vnet_get_main (); + u32 last_sw_if_index = ~0; + vlib_frame_t *to_frame = 0; + vnet_hw_interface_t *hw = 0; + u32 *from, *to_next = 0; + u32 n_left_from; + + from = vlib_frame_vector_args (from_frame); + n_left_from = from_frame->n_vectors; + while (n_left_from > 0) + { + u32 bi0; + vlib_buffer_t *b0; + u32 sw_if_index0; -VLIB_NODE_FUNCTION_MULTIARCH (vnet_per_buffer_interface_output_node, vnet_per_buffer_interface_output) + bi0 = from[0]; + from++; + n_left_from--; + b0 = vlib_get_buffer (vm, bi0); + sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; + + if (PREDICT_FALSE ((last_sw_if_index != sw_if_index0) || to_frame == 0)) + { + if (to_frame) + { + hw = vnet_get_sup_hw_interface (vnm, last_sw_if_index); + vlib_put_frame_to_node (vm, hw->tx_node_index, to_frame); + } + last_sw_if_index = sw_if_index0; + hw = vnet_get_sup_hw_interface (vnm, sw_if_index0); + to_frame = vlib_get_frame_to_node (vm, hw->tx_node_index); + to_next = vlib_frame_vector_args (to_frame); + } + + to_next[0] = bi0; + to_next++; + to_frame->n_vectors++; + } + vlib_put_frame_to_node (vm, hw->tx_node_index, to_frame); + return from_frame->n_vectors; +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (interface_tx, static) = { + .function = interface_tx_node_fn, + .name = "interface-tx", + .vector_size = sizeof (u32), + .n_next_nodes = 1, + .next_nodes = { + [0] = "error-drop", + }, +}; + +VNET_FEATURE_ARC_INIT (interface_output, static) = +{ + .arc_name = "interface-output", + .start_nodes = VNET_FEATURES (0), + .end_node = "interface-tx", + .arc_index_ptr = &vnet_main.interface_main.output_feature_arc_index, +}; + +VNET_FEATURE_INIT (span_tx, static) = { + .arc_name = "interface-output", + .node_name = "span-output", + .runs_before = VNET_FEATURES ("interface-tx"), +}; + +VNET_FEATURE_INIT (interface_tx, static) = { + .arc_name = "interface-output", + .node_name = "interface-tx", + .runs_before = 0, +}; +/* *INDENT-ON* */ clib_error_t * vnet_per_buffer_interface_output_hw_interface_add_del (vnet_main_t * vnm, u32 hw_if_index, u32 is_create) { - vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, hw_if_index); + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); u32 next_index; next_index = vlib_node_add_next_with_slot @@ -1204,136 +1258,147 @@ vnet_per_buffer_interface_output_hw_interface_add_del (vnet_main_t * vnm, return 0; } -VNET_HW_INTERFACE_ADD_DEL_FUNCTION -(vnet_per_buffer_interface_output_hw_interface_add_del); +VNET_HW_INTERFACE_ADD_DEL_FUNCTION + (vnet_per_buffer_interface_output_hw_interface_add_del); static clib_error_t * pcap_drop_trace_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, + vlib_cli_command_t * cmd) { - vnet_main_t * vnm = vnet_get_main(); - vnet_interface_main_t * im = &vnm->interface_main; - u8 * filename; + vnet_main_t *vnm = vnet_get_main (); + vnet_interface_main_t *im = &vnm->interface_main; + u8 *filename; u32 max; int matched = 0; - clib_error_t * error = 0; + clib_error_t *error = 0; - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "on")) - { - if (im->drop_pcap_enable == 0) - { - if (im->pcap_filename == 0) - im->pcap_filename = format (0, "/tmp/drop.pcap%c", 0); - - memset (&im->pcap_main, 0, sizeof (im->pcap_main)); - im->pcap_main.file_name = (char *) im->pcap_filename; - im->pcap_main.n_packets_to_capture = 100; - if (im->pcap_pkts_to_capture) - im->pcap_main.n_packets_to_capture = im->pcap_pkts_to_capture; - - im->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet; - im->drop_pcap_enable = 1; - matched = 1; - vlib_cli_output (vm, "pcap drop capture on..."); - } - else - { - vlib_cli_output (vm, "pcap drop capture already on..."); - } - matched = 1; - } + { + if (im->drop_pcap_enable == 0) + { + if (im->pcap_filename == 0) + im->pcap_filename = format (0, "/tmp/drop.pcap%c", 0); + + memset (&im->pcap_main, 0, sizeof (im->pcap_main)); + im->pcap_main.file_name = (char *) im->pcap_filename; + im->pcap_main.n_packets_to_capture = 100; + if (im->pcap_pkts_to_capture) + im->pcap_main.n_packets_to_capture = im->pcap_pkts_to_capture; + + im->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet; + im->drop_pcap_enable = 1; + matched = 1; + vlib_cli_output (vm, "pcap drop capture on..."); + } + else + { + vlib_cli_output (vm, "pcap drop capture already on..."); + } + matched = 1; + } else if (unformat (input, "off")) - { - matched = 1; - - if (im->drop_pcap_enable) - { - vlib_cli_output (vm, "captured %d pkts...", - im->pcap_main.n_packets_captured); - if (im->pcap_main.n_packets_captured) - { - im->pcap_main.n_packets_to_capture = - im->pcap_main.n_packets_captured; - error = pcap_write (&im->pcap_main); - if (error) - clib_error_report (error); - else - vlib_cli_output (vm, "saved to %s...", im->pcap_filename); - } - } - else - { - vlib_cli_output (vm, "pcap drop capture already off..."); - } - - im->drop_pcap_enable = 0; - } + { + matched = 1; + + if (im->drop_pcap_enable) + { + vlib_cli_output (vm, "captured %d pkts...", + im->pcap_main.n_packets_captured); + if (im->pcap_main.n_packets_captured) + { + im->pcap_main.n_packets_to_capture = + im->pcap_main.n_packets_captured; + error = pcap_write (&im->pcap_main); + if (error) + clib_error_report (error); + else + vlib_cli_output (vm, "saved to %s...", im->pcap_filename); + } + } + else + { + vlib_cli_output (vm, "pcap drop capture already off..."); + } + + im->drop_pcap_enable = 0; + } else if (unformat (input, "max %d", &max)) - { - im->pcap_pkts_to_capture = max; - matched = 1; - } - - else if (unformat (input, "intfc %U", - unformat_vnet_sw_interface, vnm, - &im->pcap_sw_if_index)) - matched = 1; + { + im->pcap_pkts_to_capture = max; + matched = 1; + } + + else if (unformat (input, "intfc %U", + unformat_vnet_sw_interface, vnm, + &im->pcap_sw_if_index)) + matched = 1; else if (unformat (input, "intfc any")) - { - im->pcap_sw_if_index = 0; - matched = 1; - } + { + im->pcap_sw_if_index = 0; + matched = 1; + } else if (unformat (input, "file %s", &filename)) - { - u8 * chroot_filename; - /* Brain-police user path input */ - if (strstr((char *)filename, "..") || index((char *)filename, '/')) - { - vlib_cli_output (vm, "illegal characters in filename '%s'", - filename); - continue; - } - - chroot_filename = format (0, "/tmp/%s%c", filename, 0); - vec_free (filename); - - if (im->pcap_filename) - vec_free (im->pcap_filename); - vec_add1 (filename, 0); - im->pcap_filename = chroot_filename; - matched = 1; - } + { + u8 *chroot_filename; + /* Brain-police user path input */ + if (strstr ((char *) filename, "..") + || index ((char *) filename, '/')) + { + vlib_cli_output (vm, "illegal characters in filename '%s'", + filename); + continue; + } + + chroot_filename = format (0, "/tmp/%s%c", filename, 0); + vec_free (filename); + + if (im->pcap_filename) + vec_free (im->pcap_filename); + vec_add1 (filename, 0); + im->pcap_filename = chroot_filename; + matched = 1; + } else if (unformat (input, "status")) - { - if (im->drop_pcap_enable == 0) - { - vlib_cli_output (vm, "pcap drop capture is off..."); - continue; - } - - vlib_cli_output (vm, "pcap drop capture: %d of %d pkts...", - im->pcap_main.n_packets_captured, - im->pcap_main.n_packets_to_capture); - matched = 1; - } + { + if (im->drop_pcap_enable == 0) + { + vlib_cli_output (vm, "pcap drop capture is off..."); + continue; + } + + vlib_cli_output (vm, "pcap drop capture: %d of %d pkts...", + im->pcap_main.n_packets_captured, + im->pcap_main.n_packets_to_capture); + matched = 1; + } else - break; + break; } if (matched == 0) - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (pcap_trace_command, static) = { - .path = "pcap drop trace", - .short_help = - "pcap drop trace on off max intfc file status", - .function = pcap_drop_trace_command_fn, + .path = "pcap drop trace", + .short_help = + "pcap drop trace on off max intfc file status", + .function = pcap_drop_trace_command_fn, }; +/* *INDENT-ON* */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */