blob: 2177ccb9d14a27a981d3378c8e088ae905e817ca [file] [log] [blame]
Dave Baracha638c182019-06-21 18:24:07 -04001/*
2 * node.c - skeleton vpp engine plug-in dual-loop node skeleton
3 *
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:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
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>
22
23typedef struct
24{
25 int current_thread;
26} handoffdemo_trace_t;
27
28/* packet trace format function */
29static u8 *
30format_handoffdemo_trace (u8 * s, va_list * args)
31{
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 *);
35
36 s = format (s, "HANDOFFDEMO: current thread %d", t->current_thread);
37
38 return s;
39}
40
41vlib_node_registration_t handoffdemo_node;
42
43#define foreach_handoffdemo_error \
44_(HANDED_OFF, "packets handed off processed") \
45_(CONGESTION_DROP, "handoff queue congestion drops") \
46_(COMPLETE, "completed packets")
47
48typedef enum
49{
50#define _(sym,str) HANDOFFDEMO_ERROR_##sym,
51 foreach_handoffdemo_error
52#undef _
53 HANDOFFDEMO_N_ERROR,
54} handoffdemo_error_t;
55
56static char *handoffdemo_error_strings[] = {
57#define _(sym,string) string,
58 foreach_handoffdemo_error
59#undef _
60};
61
62typedef enum
63{
64 HANDOFFDEMO_NEXT_DROP,
65 HANDOFFDEMO_N_NEXT,
66} handoffdemo_next_t;
67
68always_inline uword
69handoffdemo_inline (vlib_main_t * vm,
70 vlib_node_runtime_t * node, vlib_frame_t * frame,
71 int which, int is_trace)
72{
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;
79 u32 n_enq;
80 int i;
81
82 from = vlib_frame_vector_args (frame);
83 n_left_from = frame->n_vectors;
84
85 vlib_get_buffers (vm, from, bufs, n_left_from);
86 next = nexts;
87 b = bufs;
88
89 /* First thread */
90 if (which == 1)
91 {
92 for (i = 0; i < frame->n_vectors; i++)
93 {
94 /* Pick a thread to handle this packet */
95 thread_indices[i] = 2;
96
97 if (is_trace && (b[0]->flags & VLIB_BUFFER_IS_TRACED))
98 {
99 handoffdemo_trace_t *t = vlib_add_trace (vm, node, b[0],
100 sizeof (*t));
101 t->current_thread = vm->thread_index;
102 }
103
104 b += 1;
105 next += 1;
106 n_left_from -= 1;
107 }
108
109 /* Enqueue buffers to threads */
110 n_enq =
111 vlib_buffer_enqueue_to_thread (vm, hmp->frame_queue_index,
112 from, thread_indices, frame->n_vectors,
113 1 /* drop on congestion */ );
114 if (n_enq < frame->n_vectors)
115 vlib_node_increment_counter (vm, node->node_index,
116 HANDOFFDEMO_ERROR_CONGESTION_DROP,
117 frame->n_vectors - n_enq);
118 vlib_node_increment_counter (vm, node->node_index,
119 HANDOFFDEMO_ERROR_HANDED_OFF, n_enq);
120 return frame->n_vectors;
121 }
122 else /* Second thread */
123 {
124 u32 *from;
125
126 from = vlib_frame_vector_args (frame);
127 n_left_from = frame->n_vectors;
128
129 vlib_get_buffers (vm, from, bufs, n_left_from);
130 next = nexts;
131 b = bufs;
132
133 while (n_left_from > 0)
134 {
135 if (is_trace && (b[0]->flags & VLIB_BUFFER_IS_TRACED))
136 {
137 handoffdemo_trace_t *t = vlib_add_trace (vm, node, b[0],
138 sizeof (*t));
139 t->current_thread = vm->thread_index;
140 }
141
142 next[0] = HANDOFFDEMO_NEXT_DROP;
143 b[0]->error = error0;
144 next++;
145 b++;
146 n_left_from--;
147 }
148
149 vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
150 frame->n_vectors);
151 }
152
153 return frame->n_vectors;
154}
155
156static uword
157handoffdemo_node_1_fn (vlib_main_t * vm,
158 vlib_node_runtime_t * node, vlib_frame_t * frame)
159{
160 if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
161 return handoffdemo_inline (vm, node, frame, 1 /* which */ ,
162 1 /* is_trace */ );
163 else
164 return handoffdemo_inline (vm, node, frame, 1 /* which */ ,
165 0 /* is_trace */ );
166}
167
168/* *INDENT-OFF* */
169VLIB_REGISTER_NODE (handoffdemo_node_1) =
170{
171 .name = "handoffdemo-1",
172 .function = handoffdemo_node_1_fn,
173 .vector_size = sizeof (u32),
174 .format_trace = format_handoffdemo_trace,
175 .type = VLIB_NODE_TYPE_INTERNAL,
176
177 .n_errors = ARRAY_LEN(handoffdemo_error_strings),
178 .error_strings = handoffdemo_error_strings,
179
180 .n_next_nodes = HANDOFFDEMO_N_NEXT,
181
182 /* edit / add dispositions here */
183 .next_nodes = {
184 [HANDOFFDEMO_NEXT_DROP] = "error-drop",
185 },
186};
187/* *INDENT-ON* */
188
189uword
190handoffdemo_node_2_fn (vlib_main_t * vm,
191 vlib_node_runtime_t * node, vlib_frame_t * frame)
192{
193 if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
194 return handoffdemo_inline (vm, node, frame, 2 /* which */ ,
195 1 /* is_trace */ );
196 else
197 return handoffdemo_inline (vm, node, frame, 2 /* which */ ,
198 0 /* is_trace */ );
199}
200
201/* *INDENT-OFF* */
202VLIB_REGISTER_NODE (handoffdemo_node_2) =
203{
204 .name = "handoffdemo-2",
205 .function = handoffdemo_node_2_fn,
206 .vector_size = sizeof (u32),
207 .format_trace = format_handoffdemo_trace,
208 .type = VLIB_NODE_TYPE_INTERNAL,
209
210 .n_errors = ARRAY_LEN(handoffdemo_error_strings),
211 .error_strings = handoffdemo_error_strings,
212
213 .n_next_nodes = HANDOFFDEMO_N_NEXT,
214
215 /* edit / add dispositions here */
216 .next_nodes = {
217 [HANDOFFDEMO_NEXT_DROP] = "error-drop",
218 },
219};
220/* *INDENT-ON* */
221
222static clib_error_t *
223handoffdemo_node_init (vlib_main_t * vm)
224{
225 handoffdemo_main_t *hmp = &handoffdemo_main;
226
227 hmp->frame_queue_index = vlib_frame_queue_main_init
228 (handoffdemo_node_2.index, 16);
229
230 return 0;
231}
232
233VLIB_INIT_FUNCTION (handoffdemo_node_init);
234
235/*
236 * fd.io coding-style-patch-verification: ON
237 *
238 * Local Variables:
239 * eval: (c-set-style "gnu")
240 * End:
241 */