2 * node.c - skeleton vpp engine plug-in dual-loop node skeleton
4 * Copyright (c) <current-year> <your-organization>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 #include <vlib/vlib.h>
18 #include <vnet/vnet.h>
19 #include <vnet/pg/pg.h>
20 #include <vppinfra/error.h>
21 #include <handoffdemo/handoffdemo.h>
26 } handoffdemo_trace_t;
28 /* packet trace format function */
30 format_handoffdemo_trace (u8 * s, va_list * args)
32 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
33 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
34 handoffdemo_trace_t *t = va_arg (*args, handoffdemo_trace_t *);
36 s = format (s, "HANDOFFDEMO: current thread %d", t->current_thread);
41 vlib_node_registration_t handoffdemo_node;
43 #define foreach_handoffdemo_error \
44 _(HANDED_OFF, "packets handed off processed") \
45 _(CONGESTION_DROP, "handoff queue congestion drops") \
46 _(COMPLETE, "completed packets")
50 #define _(sym,str) HANDOFFDEMO_ERROR_##sym,
51 foreach_handoffdemo_error
54 } handoffdemo_error_t;
56 static char *handoffdemo_error_strings[] = {
57 #define _(sym,string) string,
58 foreach_handoffdemo_error
64 HANDOFFDEMO_NEXT_DROP,
69 handoffdemo_inline (vlib_main_t * vm,
70 vlib_node_runtime_t * node, vlib_frame_t * frame,
71 int which, int is_trace)
73 handoffdemo_main_t *hmp = &handoffdemo_main;
74 u32 n_left_from, *from;
75 u32 error0 = node->errors[HANDOFFDEMO_ERROR_COMPLETE];
76 vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
77 u16 thread_indices[VLIB_FRAME_SIZE];
78 u16 nexts[VLIB_FRAME_SIZE], *next;
82 from = vlib_frame_vector_args (frame);
83 n_left_from = frame->n_vectors;
85 vlib_get_buffers (vm, from, bufs, n_left_from);
92 for (i = 0; i < frame->n_vectors; i++)
94 /* Pick a thread to handle this packet */
95 thread_indices[i] = 2;
97 if (is_trace && (b[0]->flags & VLIB_BUFFER_IS_TRACED))
99 handoffdemo_trace_t *t = vlib_add_trace (vm, node, b[0],
101 t->current_thread = vm->thread_index;
109 /* Enqueue buffers to threads */
110 n_enq = vlib_buffer_enqueue_to_thread (
111 vm, node, hmp->frame_queue_index, from, thread_indices,
112 frame->n_vectors, 1 /* drop on congestion */);
113 if (n_enq < frame->n_vectors)
114 vlib_node_increment_counter (vm, node->node_index,
115 HANDOFFDEMO_ERROR_CONGESTION_DROP,
116 frame->n_vectors - n_enq);
117 vlib_node_increment_counter (vm, node->node_index,
118 HANDOFFDEMO_ERROR_HANDED_OFF, n_enq);
119 return frame->n_vectors;
121 else /* Second thread */
125 from = vlib_frame_vector_args (frame);
126 n_left_from = frame->n_vectors;
128 vlib_get_buffers (vm, from, bufs, n_left_from);
132 while (n_left_from > 0)
134 if (is_trace && (b[0]->flags & VLIB_BUFFER_IS_TRACED))
136 handoffdemo_trace_t *t = vlib_add_trace (vm, node, b[0],
138 t->current_thread = vm->thread_index;
141 next[0] = HANDOFFDEMO_NEXT_DROP;
142 b[0]->error = error0;
148 vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
152 return frame->n_vectors;
156 handoffdemo_node_1_fn (vlib_main_t * vm,
157 vlib_node_runtime_t * node, vlib_frame_t * frame)
159 if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
160 return handoffdemo_inline (vm, node, frame, 1 /* which */ ,
163 return handoffdemo_inline (vm, node, frame, 1 /* which */ ,
168 VLIB_REGISTER_NODE (handoffdemo_node_1) =
170 .name = "handoffdemo-1",
171 .function = handoffdemo_node_1_fn,
172 .vector_size = sizeof (u32),
173 .format_trace = format_handoffdemo_trace,
174 .type = VLIB_NODE_TYPE_INTERNAL,
176 .n_errors = ARRAY_LEN(handoffdemo_error_strings),
177 .error_strings = handoffdemo_error_strings,
179 .n_next_nodes = HANDOFFDEMO_N_NEXT,
181 /* edit / add dispositions here */
183 [HANDOFFDEMO_NEXT_DROP] = "error-drop",
189 handoffdemo_node_2_fn (vlib_main_t * vm,
190 vlib_node_runtime_t * node, vlib_frame_t * frame)
192 if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
193 return handoffdemo_inline (vm, node, frame, 2 /* which */ ,
196 return handoffdemo_inline (vm, node, frame, 2 /* which */ ,
201 VLIB_REGISTER_NODE (handoffdemo_node_2) =
203 .name = "handoffdemo-2",
204 .function = handoffdemo_node_2_fn,
205 .vector_size = sizeof (u32),
206 .format_trace = format_handoffdemo_trace,
207 .type = VLIB_NODE_TYPE_INTERNAL,
209 .n_errors = ARRAY_LEN(handoffdemo_error_strings),
210 .error_strings = handoffdemo_error_strings,
212 .n_next_nodes = HANDOFFDEMO_N_NEXT,
214 /* edit / add dispositions here */
216 [HANDOFFDEMO_NEXT_DROP] = "error-drop",
221 static clib_error_t *
222 handoffdemo_node_init (vlib_main_t * vm)
224 handoffdemo_main_t *hmp = &handoffdemo_main;
226 hmp->frame_queue_index = vlib_frame_queue_main_init
227 (handoffdemo_node_2.index, 16);
232 VLIB_INIT_FUNCTION (handoffdemo_node_init);
235 * fd.io coding-style-patch-verification: ON
238 * eval: (c-set-style "gnu")