/* * handoff_trace.c - used to generate handoff trace records * * Copyright (c) 2019 Cisco Systems and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include typedef struct { u32 prev_thread; u32 prev_trace_index; } handoff_trace_t; /* packet trace format function */ static u8 * format_handoff_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); handoff_trace_t *t = va_arg (*args, handoff_trace_t *); s = format (s, "HANDED-OFF: from thread %d trace index %d", t->prev_thread, t->prev_trace_index); return s; } static vlib_node_registration_t handoff_trace_node; #define foreach_handoff_trace_error \ _(BUGS, "Warning: packets sent to the handoff trace node!") typedef enum { #define _(sym,str) HANDOFF_TRACE_ERROR_##sym, foreach_handoff_trace_error #undef _ HANDOFF_TRACE_N_ERROR, } handoff_trace_error_t; static char *handoff_trace_error_strings[] = { #define _(sym,string) string, foreach_handoff_trace_error #undef _ }; static uword handoff_trace_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { vlib_buffer_free (vm, vlib_frame_vector_args (frame), frame->n_vectors); vlib_node_increment_counter (vm, node->node_index, HANDOFF_TRACE_ERROR_BUGS, frame->n_vectors); return frame->n_vectors; } typedef enum { HANDOFF_TRACE_NEXT_DROP, HANDOFF_TRACE_N_NEXT, } tplaceholder_next_t; /* *INDENT-OFF* */ VLIB_REGISTER_NODE (handoff_trace_node, static) = { .name = "handoff_trace", .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED, .function = handoff_trace_node_fn, .vector_size = sizeof (u32), .format_trace = format_handoff_trace, .type = VLIB_NODE_TYPE_INTERNAL, .n_next_nodes = HANDOFF_TRACE_N_NEXT, /* edit / add dispositions here */ .next_nodes = { [HANDOFF_TRACE_NEXT_DROP] = "error-drop", }, .n_errors = ARRAY_LEN(handoff_trace_error_strings), .error_strings = handoff_trace_error_strings, }; /* *INDENT-ON* */ int vlib_add_handoff_trace (vlib_main_t * vm, vlib_buffer_t * b) { u32 prev_thread = vlib_buffer_get_trace_thread (b); u32 prev_trace_index = vlib_buffer_get_trace_index (b); handoff_trace_t *t; vlib_node_runtime_t *node = vlib_node_get_runtime (vm, handoff_trace_node.index); if (PREDICT_FALSE (!vlib_trace_buffer (vm, node, 0 /* fake next frame index */ , b, 1 /* follow chain */ ))) return 0; t = vlib_add_trace (vm, node, b, sizeof (*t)); t->prev_thread = prev_thread; t->prev_trace_index = prev_trace_index; return 1; } /* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */