Initial commit of vpp code.
[vpp.git] / vlib / example / main_stub.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vlib/vlib.h>
16 #include <vlib/unix/unix.h>
17 #include <math.h>
18
19 int main (int argc, char * argv[])
20 {
21   return vlib_unix_main (argc, argv);
22 }
23
24 static clib_error_t *
25 main_stub_init (vlib_main_t * vm)
26 {
27   clib_error_t * error;
28
29   if ((error = unix_physmem_init (vm, /* fail_if_physical_memory_not_present */ 0)))
30     return error;
31
32  if ((error = vlib_call_init_function (vm, unix_cli_init)))
33    return error;
34
35  return error;
36 }
37
38 VLIB_INIT_FUNCTION (main_stub_init);
39
40 #if 0
41 /* Node test code. */
42 typedef struct {
43   int scalar;
44   int vector[0];
45 } my_frame_t;
46
47 static u8 * format_my_node_frame (u8 * s, va_list * va)
48 {
49   vlib_frame_t * f = va_arg (*va, vlib_frame_t *);
50   my_frame_t * g = vlib_frame_args (f);
51   int i;
52
53   s = format (s, "scalar %d, vector { ", g->scalar);
54   for (i = 0; i < f->n_vectors; i++)
55     s = format (s, "%d, ", g->vector[i]);
56   s = format (s, " }");
57
58   return s;
59 }
60
61 static uword
62 my_func (vlib_main_t * vm,
63          vlib_node_runtime_t * rt,
64          vlib_frame_t * f)
65 {
66   vlib_node_t * node;
67   my_frame_t * y;
68   u32 i, n_left = 0;
69   static int serial;
70   int verbose;
71
72   node = vlib_get_node (vm, rt->node_index);
73
74   verbose = 0;
75
76   if (verbose && f)
77     vlib_cli_output (vm, "%v: call frame %p %U", node->name,
78                      f, format_my_node_frame, f);
79
80   if (rt->n_next_nodes > 0)
81     {
82       vlib_frame_t * next = vlib_get_next_frame (vm, rt, /* next index */ 0);
83       n_left = VLIB_FRAME_SIZE - next->n_vectors;
84       y = vlib_frame_args (next);
85       y->scalar = serial++;
86     }
87   else
88     y = 0;
89
90   for (i = 0; i < 5; i++)
91     {
92       if (y)
93         {
94           ASSERT (n_left > 0);
95           n_left--;
96           y->vector[i] = y->scalar + i;
97         }
98     }
99   if (y)
100     vlib_put_next_frame (vm, rt, /* next index */ 0, n_left);
101
102   if (verbose)
103     vlib_cli_output (vm, "%v: return frame %p", node->name, f);
104
105   return i;
106 }
107
108 VLIB_REGISTER_NODE (my_node1,static) = {
109   .function = my_func,
110   .type = VLIB_NODE_TYPE_INPUT,
111   .name = "my-node1",
112   .scalar_size = sizeof (my_frame_t),
113   .vector_size = STRUCT_SIZE_OF (my_frame_t, vector[0]),
114   .n_next_nodes = 1,
115   .next_nodes = {
116     [0] = "my-node2",
117   },
118 };
119
120 VLIB_REGISTER_NODE (my_node2,static) = {
121   .function = my_func,
122   .name = "my-node2",
123   .scalar_size = sizeof (my_frame_t),
124   .vector_size = STRUCT_SIZE_OF (my_frame_t, vector[0]),
125 };
126
127 #endif
128
129 #if 0
130
131 typedef enum {
132   MY_EVENT_TYPE1,
133   MY_EVENT_TYPE2,
134 } my_process_completion_type_t;
135
136 typedef struct {
137   int a;
138   f64 b;
139 } my_process_event_data_t;
140
141 static u8 * format_my_process_event_data (u8 * s, va_list * va)
142 {
143   my_process_event_data_t * d = va_arg (*va, my_process_event_data_t *);
144   return format (s, "{ a %d b %.6f}", d->a, d->b);
145 }
146
147 static uword
148 my_proc (vlib_main_t * vm,
149          vlib_node_runtime_t * rt,
150          vlib_frame_t * f)
151 {
152   vlib_node_t * node;
153   u32 i;
154
155   node = vlib_get_node (vm, rt->node_index);
156
157   vlib_cli_output (vm, "%v: call frame %p", node->name, f);
158
159   for (i = 0; i < 5; i++)
160     {
161       vlib_cli_output (vm, "%v: %d", node->name, i);
162       vlib_process_suspend (vm, 1e0 /* secs */);
163     }
164
165   vlib_cli_output (vm, "%v: return frame %p", node->name, f);
166
167   if (0)
168     {
169       uword n_events_seen, type, * data = 0;
170
171       for (n_events_seen = 0; n_events_seen < 2;)
172         {
173           vlib_process_wait_for_event (vm);
174           type = vlib_process_get_events (vm, &data);
175           n_events_seen += vec_len (data);
176           vlib_cli_output (vm, "%U %v: completion #%d type %d data 0x%wx",
177                            format_time_interval, "h:m:s:u", vlib_time_now (vm),
178                            node->name, i, type, data[0]);
179           _vec_len (data) = 0;
180         }
181
182       vec_free (data);
183     }
184   else
185     {
186       uword n_events_seen, i, type;
187       my_process_event_data_t * data;
188       for (n_events_seen = 0; n_events_seen < 2;)
189         {
190           vlib_process_wait_for_event (vm);
191           data = vlib_process_get_event_data (vm, &type);
192           vec_foreach_index (i, data) {
193             vlib_cli_output (vm, "%U event type %d data %U",
194                              format_time_interval, "h:m:s:u", vlib_time_now (vm),
195                              type, format_my_process_event_data, data);
196           }
197           n_events_seen += vec_len (data);
198           vlib_process_put_event_data (vm, data);
199         }
200     }
201
202   return i;
203 }
204
205 VLIB_REGISTER_NODE (my_proc_node,static) = {
206   .function = my_proc,
207   .type = VLIB_NODE_TYPE_PROCESS,
208   .name = "my-proc",
209 };
210
211 static uword
212 my_proc_input (vlib_main_t * vm,
213                vlib_node_runtime_t * rt,
214                vlib_frame_t * f)
215 {
216   static int i;
217
218   if (i++ < 2)
219     {
220       if (0)
221         vlib_process_signal_event (vm, my_proc_node.index,
222                                    i == 1 ? MY_EVENT_TYPE1 : MY_EVENT_TYPE2,
223                                    0x12340000 + i);
224       else
225         {
226           my_process_event_data_t * d;
227           f64 dt = 5;
228           d = vlib_process_signal_event_at_time (vm,
229                                                  i * dt,
230                                                  my_proc_node.index,
231                                                  i == 1 ? MY_EVENT_TYPE1 : MY_EVENT_TYPE2,
232                                                  1 /* elts */,
233                                                  sizeof (d[0]));
234           d->a = i;
235           d->b = vlib_time_now (vm);
236         }
237     }
238   else
239     vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);
240
241   return 0; 
242 }
243
244 VLIB_REGISTER_NODE (my_proc_input_node,static) = {
245   .function = my_proc_input,
246   .type = VLIB_NODE_TYPE_INPUT,
247   .name = "my-proc-input",
248 };
249
250 static uword _unformat_farith (unformat_input_t * i, va_list * args)
251 {
252   u32 prec = va_arg (*args, u32);
253   f64 * result = va_arg (*args, f64 *);
254   f64 tmp[2];
255
256   /* Binary operations in from lowest to highest precedence. */
257   char * binops[] = {
258     "+%U", "-%U", "/%U", "*%U", "^%U",
259   };
260
261   if (prec <= ARRAY_LEN (binops) - 1
262       && unformat_user (i, _unformat_farith, prec + 1, &tmp[0]))
263     {
264       int p;
265       for (p = prec; p < ARRAY_LEN (binops); p++)
266         {
267           if (unformat (i, binops[p],
268                         _unformat_farith, prec + 0, &tmp[1]))
269             {
270               switch (binops[p][0])
271                 {
272                 case '+': result[0] = tmp[0] + tmp[1]; break;
273                 case '-': result[0] = tmp[0] - tmp[1]; break;
274                 case '/': result[0] = tmp[0] / tmp[1]; break;
275                 case '*': result[0] = tmp[0] * tmp[1]; break;
276                 case '^': result[0] = pow (tmp[0], tmp[1]); break;
277                 default: abort ();
278                 }
279               return 1;
280             }
281         }
282       result[0] = tmp[0];
283       return 1;
284     }
285
286   else if (unformat (i, "-%U",
287                      _unformat_farith, prec + 0, &tmp[0]))
288     {
289       result[0] = -tmp[0];
290       return 1;
291     }
292
293   else if (unformat (i, "(%U)",
294                      _unformat_farith, 0, &tmp[0]))
295     {
296       result[0] = tmp[0];
297       return 1;
298     }
299
300   else if (unformat (i, "%f", result))
301     return 1;
302
303   else
304     return 0;
305 }
306
307 static uword unformat_farith (unformat_input_t * i, va_list * args)
308 {
309   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
310   f64 * result = va_arg (*args, f64 *);
311   return unformat_user (i, _unformat_farith, 0, result);
312 }
313
314 static uword unformat_integer (unformat_input_t * i, va_list * args)
315 {
316   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
317   u32 * data = va_arg (*args, u32 *);
318   return unformat (i, "%d", data);
319 }
320
321 static VLIB_CLI_PARSE_RULE (my_parse_rule1) = {
322   .name = "decimal_integer",
323   .short_help = "a decimal integer",
324   .unformat_function = unformat_integer,
325   .data_size = sizeof (u32),
326 };
327
328 static VLIB_CLI_PARSE_RULE (my_parse_rule2) = {
329   .name = "float_expression",
330   .short_help = "floating point expression",
331   .unformat_function = unformat_farith,
332   .data_size = sizeof (f64),
333 };
334
335 static clib_error_t *
336 bar_command (vlib_main_t * vm,
337              unformat_input_t * input,
338              vlib_cli_command_t * cmd)
339 {
340   switch (cmd->function_arg)
341     {
342     case 2: {
343       u32 * d, * e;
344       d = vlib_cli_get_parse_rule_result (vm, 0);
345       e = vlib_cli_get_parse_rule_result (vm, 1);
346       vlib_cli_output (vm, "bar2 %d %d", d[0], e[0]);
347       break;
348     }
349
350     case 1: {
351       u32 * d = vlib_cli_get_parse_rule_result (vm, 0);
352       vlib_cli_output (vm, "bar1 %d", d[0]);
353       break;
354     }
355
356     case 3: {
357       f64 * d = vlib_cli_get_parse_rule_result (vm, 0);
358       vlib_cli_output (vm, "expr %.6f", d[0]);
359     }
360     }
361
362   return 0;
363 }
364
365 VLIB_CLI_COMMAND (bar_command2, static) = {
366   .path = "bar %decimal_integer",
367   .short_help = "bar1 command",
368   .function = bar_command,
369   .function_arg = 1,
370 };
371 VLIB_CLI_COMMAND (bar_command1, static) = {
372   .path = "bar %decimal_integer %decimal_integer",
373   .short_help = "bar2 command",
374   .function = bar_command,
375   .function_arg = 2,
376 };
377 VLIB_CLI_COMMAND (bar_command3, static) = {
378   .path = "zap %float_expression",
379   .short_help = "bar3 command",
380   .function = bar_command,
381   .function_arg = 3,
382 };
383
384 #endif
385