dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / vlib / example / plex_test.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/parse.h>
16 #include <vlib/unix/unix.h>
17
18 static u8 *
19 format_value_v4_address (u8 * s, va_list * args)
20 {
21   vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *);
22   u32 a = v->value.as_uword;
23
24   s = format (s, "%d.%d.%d.%d",
25               (a >> 24) & 0xFF,
26               (a >> 16) & 0xFF, (a >> 8) & 0xFF, (a >> 0) & 0xFF);
27
28   return s;
29 }
30
31 static vlib_parse_match_t
32 v4_address_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
33                   vlib_lex_token_t * t, vlib_parse_value_t * valuep)
34 {
35   u32 digit;
36   u32 value = 0;
37   int i;
38
39   if (vec_len (pm->tokens) - (t - pm->tokens) < 7)
40     return VLIB_PARSE_MATCH_FAIL;
41
42   /* NUMBER DOT NUMBER DOT NUMBER DOT NUMBER */
43
44   for (i = 0; i < 7; i++)
45     {
46       if ((i & 1) == 0)
47         {
48           if (t[i].token != VLIB_LEX_number)
49             return VLIB_PARSE_MATCH_FAIL;
50           if (t[i].value.as_uword > 0xff)
51             return VLIB_PARSE_MATCH_FAIL;
52           digit = t[i].value.as_uword;
53           value = (value << 8) | digit;
54         }
55       else
56         {
57           if (t[i].token != VLIB_LEX_dot)
58             return VLIB_PARSE_MATCH_FAIL;
59         }
60     }
61   /* note: caller advances by 1 */
62   pm->current_token_index += 6;
63   valuep->value.as_uword = value;
64   return VLIB_PARSE_MATCH_VALUE;
65 }
66
67 PARSE_TYPE_INIT (v4_address, v4_address_match, 0, format_value_v4_address)
68      static u8 *format_value_v4_address_and_mask (u8 * s, va_list * args)
69 {
70   vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *);
71   u32 *a = v->value.as_pointer;
72
73   s = format (s, "%d.%d.%d.%d",
74               (a[0] >> 24) & 0xFF,
75               (a[0] >> 16) & 0xFF, (a[0] >> 8) & 0xFF, (a[0] >> 0) & 0xFF);
76   s = format (s, "/%d", a[1]);
77
78   return s;
79 }
80
81 static vlib_parse_match_t
82 v4_address_and_mask_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
83                            vlib_lex_token_t * t, vlib_parse_value_t * valuep)
84 {
85   u32 digit;
86   u32 address = 0;
87   u32 *rv = 0;
88   int i;
89
90   if (vec_len (pm->tokens) - (t - pm->tokens) < 9)
91     return VLIB_PARSE_MATCH_FAIL;
92
93   /* NUMBER DOT NUMBER DOT NUMBER DOT NUMBER */
94
95   for (i = 0; i < 7; i++)
96     {
97       if ((i & 1) == 0)
98         {
99           if (t[i].token != VLIB_LEX_number)
100             return VLIB_PARSE_MATCH_FAIL;
101           if (t[i].value.as_uword > 0xff)
102             return VLIB_PARSE_MATCH_FAIL;
103           digit = t[i].value.as_uword;
104           address = (address << 8) | digit;
105         }
106       else
107         {
108           if (t[i].token != VLIB_LEX_dot)
109             return VLIB_PARSE_MATCH_FAIL;
110         }
111     }
112
113   if (t[7].token != VLIB_LEX_slash || t[8].token != VLIB_LEX_number)
114     return VLIB_PARSE_MATCH_FAIL;
115
116   vec_add1 (rv, address);
117   vec_add1 (rv, t[8].value.as_uword);
118
119   /* note: caller advances by 1 */
120   pm->current_token_index += 8;
121   valuep->value.as_pointer = rv;
122   return VLIB_PARSE_MATCH_VALUE;
123 }
124
125 void
126 v4_address_and_mask_cleanup (vlib_parse_value_t * valuep)
127 {
128   u32 *trash = valuep->value.as_pointer;
129   vec_free (trash);
130 }
131
132 PARSE_TYPE_INIT (v4_address_and_mask, v4_address_and_mask_match,
133                  v4_address_and_mask_cleanup,
134                  format_value_v4_address_and_mask)
135      vlib_lex_main_t vlib_lex_main;
136
137
138
139      vlib_parse_match_t eval_factor0 (vlib_parse_main_t * pm,
140                                       vlib_parse_item_t * item,
141                                       vlib_parse_value_t * value)
142 {
143   clib_warning ("%U", format_vlib_parse_value, pm);
144   return VLIB_PARSE_MATCH_RULE;
145 }
146
147 vlib_parse_match_t
148 eval_factor1 (vlib_parse_main_t * pm,
149               vlib_parse_item_t * item, vlib_parse_value_t * value)
150 {
151   clib_warning ("%U", format_vlib_parse_value, pm);
152   return VLIB_PARSE_MATCH_RULE;
153 }
154
155 vlib_parse_match_t
156 eval_factor2 (vlib_parse_main_t * pm,
157               vlib_parse_item_t * item, vlib_parse_value_t * value)
158 {
159   word a;
160   int index = vec_len (pm->parse_value) - 1;
161
162   a = pm->parse_value[index].value.as_word;
163
164   pm->parse_value[index].value.as_word = -a;
165   return VLIB_PARSE_MATCH_RULE;
166 }
167
168 vlib_parse_match_t
169 eval_term0 (vlib_parse_main_t * pm,
170             vlib_parse_item_t * item, vlib_parse_value_t * value)
171 {
172   clib_warning ("%U", format_vlib_parse_value, pm);
173   return VLIB_PARSE_MATCH_RULE;
174 }
175
176 vlib_parse_match_t
177 eval_term1 (vlib_parse_main_t * pm,
178             vlib_parse_item_t * item, vlib_parse_value_t * value)
179 {
180   uword a, b;
181   int index = vec_len (pm->parse_value) - 2;
182
183   a = pm->parse_value[index].value.as_uword;
184   b = pm->parse_value[index + 1].value.as_uword;
185
186   pm->parse_value[index].value.as_uword = a * b;
187   _vec_len (pm->parse_value) -= 1;
188   clib_warning ("%U", format_vlib_parse_value, pm);
189
190   return VLIB_PARSE_MATCH_RULE;
191 }
192
193 vlib_parse_match_t
194 eval_term2 (vlib_parse_main_t * pm,
195             vlib_parse_item_t * item, vlib_parse_value_t * value)
196 {
197   uword a, b;
198   int index = vec_len (pm->parse_value) - 2;
199
200   a = pm->parse_value[index].value.as_uword;
201   b = pm->parse_value[index + 1].value.as_uword;
202
203   pm->parse_value[index].value.as_uword = a / b;
204   _vec_len (pm->parse_value) -= 1;
205   clib_warning ("%U", format_vlib_parse_value, pm);
206
207   return VLIB_PARSE_MATCH_RULE;
208 }
209
210 vlib_parse_match_t
211 eval_exp0 (vlib_parse_main_t * pm,
212            vlib_parse_item_t * item, vlib_parse_value_t * value)
213 {
214   return VLIB_PARSE_MATCH_RULE;
215 }
216
217 vlib_parse_match_t
218 eval_exp1 (vlib_parse_main_t * pm,
219            vlib_parse_item_t * item, vlib_parse_value_t * value)
220 {
221   uword a, b;
222   int index = vec_len (pm->parse_value) - 2;
223
224   a = pm->parse_value[index].value.as_uword;
225   b = pm->parse_value[index + 1].value.as_uword;
226
227   pm->parse_value[index].value.as_uword = a + b;
228   _vec_len (pm->parse_value) -= 1;
229   clib_warning ("%U", format_vlib_parse_value, pm);
230
231   return VLIB_PARSE_MATCH_RULE;
232 }
233
234 vlib_parse_match_t
235 eval_exp2 (vlib_parse_main_t * pm,
236            vlib_parse_item_t * item, vlib_parse_value_t * value)
237 {
238   uword a, b;
239   int index = vec_len (pm->parse_value) - 2;
240
241   a = pm->parse_value[index].value.as_uword;
242   b = pm->parse_value[index + 1].value.as_uword;
243
244   pm->parse_value[index].value.as_uword = a - b;
245   _vec_len (pm->parse_value) -= 1;
246   clib_warning ("%U", format_vlib_parse_value, pm);
247
248   return VLIB_PARSE_MATCH_RULE;
249 }
250
251 vlib_parse_match_t
252 eval_result (vlib_parse_main_t * pm,
253              vlib_parse_item_t * item, vlib_parse_value_t * value)
254 {
255   clib_warning ("%U", format_vlib_parse_value, pm);
256   return VLIB_PARSE_MATCH_DONE;
257 }
258
259 vlib_parse_match_t
260 noop_match_rule (vlib_parse_main_t * pm,
261                  vlib_parse_item_t * item, vlib_parse_value_t * value)
262 {
263   clib_warning ("%U", format_vlib_parse_value, pm);
264   return VLIB_PARSE_MATCH_RULE;
265 }
266
267 #if 0
268 PARSE_INIT (t1, "moo", eval0);
269 PARSE_INIT (t2, "moo cow mumble", eval1);
270 PARSE_INIT (t3, "moo cow", eval2);
271 PARSE_INIT (t4, "moo cow mumble grunch", eval3);
272 #endif
273
274 #if 0
275 PARSE_INIT (r1, "eval <exp>", eval_result);
276
277 PARSE_INIT (r2, "<exp> = <term><exp2>", eval_exp0);
278 PARSE_INIT (r3, "<exp2> = <plus> <exp>", eval_exp1);
279 PARSE_INIT (r4, "<exp2> = <minus> <exp>", eval_exp2);
280 PARSE_INIT (r5, "<exp2> = ", noop_match_rule);
281 PARSE_TYPE_INIT (exp, rule_match, 0, 0);
282 PARSE_TYPE_INIT (exp2, rule_match, 0, 0);
283
284 PARSE_INIT (r6, "<term> = <factor><term2>", eval_term0);
285 PARSE_INIT (r7, "<term2> = <star> <term>", eval_term1);
286 PARSE_INIT (r8, "<term2> = <slash> <term>", eval_term2);
287 PARSE_INIT (r9, "<term2> = ", noop_match_rule);
288 PARSE_TYPE_INIT (term, rule_match, 0, 0);
289 PARSE_TYPE_INIT (term2, rule_match, 0, 0);
290
291 PARSE_INIT (r11, "<factor> = <lpar> <exp> <rpar>", eval_factor1);
292 PARSE_INIT (r10, "<factor> = <number>", eval_factor0);
293 PARSE_INIT (r12, "<factor> = <minus> <factor>", eval_factor2);
294
295 PARSE_TYPE_INIT (factor, rule_match, 0, 0);
296 #endif
297
298 PARSE_INIT (r1, "eval <exp>", eval_result);
299
300 #if 1
301 PARSE_INIT (r2, "<exp> = <term><exp2>", eval_exp0);
302 PARSE_INIT (r3, "<exp2> = <plus> <exp>", eval_exp1);
303 PARSE_INIT (r4, "<exp2> = <minus> <exp>", eval_exp2);
304 PARSE_INIT (r5, "<exp2> = ", noop_match_rule);
305 PARSE_TYPE_INIT (exp, rule_match, 0, 0);
306 PARSE_TYPE_INIT (exp2, rule_match, 0, 0);
307
308 PARSE_INIT (r6, "<term> = <factor><term2>", eval_term0);
309 PARSE_INIT (r7, "<term2> = <star> <term>", eval_term1);
310 PARSE_INIT (r8, "<term2> = <slash> <term>", eval_term2);
311 PARSE_INIT (r9, "<term2> = ", noop_match_rule);
312 PARSE_TYPE_INIT (term, rule_match, 0, 0);
313 PARSE_TYPE_INIT (term2, rule_match, 0, 0);
314
315 PARSE_INIT (r11, "<factor> = <lpar> <exp> <rpar>", eval_factor1);
316 PARSE_INIT (r10, "<factor> = <number>", eval_factor0);
317 PARSE_INIT (r12, "<factor> = <minus> <factor>", eval_factor2);
318
319 PARSE_TYPE_INIT (factor, rule_match, 0, 0);
320 #endif
321
322 #if 0
323 PARSE_TYPE_INIT (exp, rule_match, 0, 0);
324 PARSE_INIT (r6, "<exp> = a b", eval_term0);
325 PARSE_INIT (r7, "<exp> = c d", eval_term1);
326 PARSE_INIT (r9, "<exp> = ", noop_match_rule);
327 #endif
328
329 #if 0
330 #define foreach_rule_evaluator                  \
331 _(0)                                            \
332 _(1)                                            \
333 _(2)                                            \
334 _(3)
335
336 #define _(n)                                            \
337 vlib_parse_match_t eval##n (vlib_parse_main_t *pm,      \
338                             vlib_parse_item_t *item,    \
339                             vlib_parse_value_t *value)  \
340 {                                                       \
341   clib_warning ("%U", format_vlib_parse_value, pm);     \
342   return VLIB_PARSE_MATCH_DONE;                         \
343 }
344 foreach_rule_evaluator
345 #undef _
346 PARSE_INIT (r1, "eval <moo>", eval_result);
347
348 PARSE_INIT (r2, "<moo> = cow", eval0);
349 PARSE_INIT (r4, "<moo> = ", eval1);
350 PARSE_TYPE_INIT (moo, rule_match, 0, 0);
351 #endif
352
353
354 clib_error_t *
355 test_init (vlib_main_t * vm)
356 {
357   clib_error_t *error;
358
359   if ((error = vlib_call_init_function (vm, parse_init)))
360     return error;
361
362   return 0;
363 }
364
365 VLIB_INIT_FUNCTION (test_init);
366
367 clib_error_t *
368 vlib_stdlex_init (vlib_main_t * vm)
369 {
370   vlib_lex_main_t *lm = &vlib_lex_main;
371   u16 top_index;
372   u16 slash_index, slash_star_index, slash_slash_index, slash_star_star_index;
373   u16 slash_token;
374   u16 word_index;
375   u16 zero_index, octal_index, decimal_index, hex_index, binary_index;
376
377   top_index = vlib_lex_add_table ("top");
378
379 #define foreach_top_level_single_character_token        \
380   _('(', lpar)                                          \
381   _(')', rpar)                                          \
382   _(';', semi)                                          \
383   _('[', lbrack)                                        \
384   _(']', rbrack)                                        \
385   _('{', lcurly)                                        \
386   _('}', rcurly)                                        \
387   _('+', plus)                                          \
388   _('-', minus)                                         \
389   _('*', star)                                          \
390   _('%', percent)                                       \
391   _('@', atsign)                                        \
392   _(',', comma)                                         \
393   _('.', dot)                                           \
394   _('?', qmark)
395
396 #define _(c,t) \
397   vlib_lex_set_action_range(top_index,c,c,VLIB_LEX_RETURN,vlib_lex_add_token(lm, #t), top_index);
398   foreach_top_level_single_character_token;
399 #undef _
400
401   /* Numbers */
402   zero_index = vlib_lex_add_table ("zero");
403   octal_index = vlib_lex_add_table ("octal");
404   decimal_index = vlib_lex_add_table ("decimal");
405   hex_index = vlib_lex_add_table ("hex");
406   binary_index = vlib_lex_add_table ("binary");
407
408   /* Support 0x 0b 0t and 0123 [octal] */
409   vlib_lex_set_action_range (top_index, '0', '0', VLIB_LEX_START_NUMBER, 10,
410                              zero_index);
411   vlib_lex_set_action_range (top_index, '1', '9', VLIB_LEX_START_NUMBER, 10,
412                              decimal_index);
413
414   vlib_lex_set_action_range (zero_index, 0, 0x7F, VLIB_LEX_RETURN_AND_RESCAN,
415                              VLIB_LEX_number, top_index);
416
417   vlib_lex_set_action_range (zero_index, 'x', 'x', VLIB_LEX_IGNORE, ~0,
418                              hex_index);
419   vlib_lex_set_action_range (zero_index, 'b', 'b', VLIB_LEX_IGNORE, ~0,
420                              binary_index);
421   vlib_lex_set_action_range (zero_index, 't', 't', VLIB_LEX_IGNORE, ~0,
422                              decimal_index);
423   vlib_lex_set_action_range (zero_index, '0', '7', VLIB_LEX_START_NUMBER, 8,
424                              octal_index);
425
426   /* Octal */
427   vlib_lex_set_action_range (octal_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN,
428                              VLIB_LEX_number, top_index);
429   vlib_lex_set_action_range (octal_index, '0', '7', VLIB_LEX_ADD_TO_NUMBER, 8,
430                              octal_index);
431
432   /* Decimal */
433   vlib_lex_set_action_range (decimal_index, 0, 0x7f,
434                              VLIB_LEX_RETURN_AND_RESCAN, VLIB_LEX_number,
435                              top_index);
436   vlib_lex_set_action_range (decimal_index, '0', '9', VLIB_LEX_ADD_TO_NUMBER,
437                              10, decimal_index);
438
439   /* Hex */
440   vlib_lex_set_action_range (hex_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN,
441                              VLIB_LEX_number, top_index);
442   vlib_lex_set_action_range (hex_index, '0', '9', VLIB_LEX_ADD_TO_NUMBER, 16,
443                              hex_index);
444   vlib_lex_set_action_range (hex_index, 'a', 'f', VLIB_LEX_ADD_TO_NUMBER, 16,
445                              hex_index);
446   vlib_lex_set_action_range (hex_index, 'A', 'F', VLIB_LEX_ADD_TO_NUMBER, 16,
447                              hex_index);
448
449   /* Binary */
450   vlib_lex_set_action_range (binary_index, 0, 0x7f,
451                              VLIB_LEX_RETURN_AND_RESCAN, VLIB_LEX_number,
452                              top_index);
453   vlib_lex_set_action_range (binary_index, '0', '1', VLIB_LEX_ADD_TO_NUMBER,
454                              2, binary_index);
455
456   /* c/c++ comment syntax is the worst... */
457
458   slash_index = vlib_lex_add_table ("slash");
459   slash_star_index = vlib_lex_add_table ("slash_star");
460   slash_star_star_index = vlib_lex_add_table ("slash_star_star");
461   slash_slash_index = vlib_lex_add_table ("slash_slash");
462   slash_token = vlib_lex_add_token (lm, "slash");
463
464   /* Top level: see a slash, ignore, go to slash table */
465   vlib_lex_set_action_range (top_index, '/', '/', VLIB_LEX_IGNORE, ~0,
466                              slash_index);
467
468   /* default for slash table: return SLASH, go to top table */
469   vlib_lex_set_action_range (slash_index, 1, 0x7F, VLIB_LEX_RETURN_AND_RESCAN,
470                              slash_token, top_index);
471   /* see slash-slash, go to s-s table */
472   vlib_lex_set_action_range (slash_index, '/', '/', VLIB_LEX_IGNORE, ~0,
473                              slash_slash_index);
474   /* see slash-star, go to s-* table */
475   vlib_lex_set_action_range (slash_index, '*', '*', VLIB_LEX_IGNORE, ~0,
476                              slash_star_index);
477
478   /* EOL in s-s table, ignore, go to top table */
479   vlib_lex_set_action_range (slash_slash_index, '\n', '\n', VLIB_LEX_IGNORE,
480                              ~0, top_index);
481
482   /* slash-star blah blah star */
483   vlib_lex_set_action_range (slash_star_index, '*', '*', VLIB_LEX_IGNORE, ~0,
484                              slash_star_star_index);
485
486   /* slash star blah blah star slash */
487   vlib_lex_set_action_range (slash_star_star_index, '/', '/', VLIB_LEX_IGNORE,
488                              ~0, top_index);
489
490   /* LT, =, GT */
491   vlib_lex_set_action_range (top_index, '<', '<', VLIB_LEX_RETURN,
492                              VLIB_LEX_lt, top_index);
493   vlib_lex_set_action_range (top_index, '=', '=', VLIB_LEX_RETURN,
494                              VLIB_LEX_equals, top_index);
495   vlib_lex_set_action_range (top_index, '>', '>', VLIB_LEX_RETURN,
496                              VLIB_LEX_gt, top_index);
497
498   /* words, key and otherwise */
499   word_index = vlib_lex_add_table ("word");
500
501   vlib_lex_set_action_range (top_index, 'a', 'z', VLIB_LEX_ADD_TO_TOKEN, ~0,
502                              word_index);
503   vlib_lex_set_action_range (top_index, 'A', 'Z', VLIB_LEX_ADD_TO_TOKEN, ~0,
504                              word_index);
505
506   vlib_lex_set_action_range (word_index, 0, 0x7f, VLIB_LEX_KEYWORD_CHECK, ~0,
507                              top_index);
508
509   vlib_lex_set_action_range (word_index, 'a', 'z', VLIB_LEX_ADD_TO_TOKEN, ~0,
510                              word_index);
511   vlib_lex_set_action_range (word_index, 'A', 'Z', VLIB_LEX_ADD_TO_TOKEN, ~0,
512                              word_index);
513   vlib_lex_set_action_range (word_index, '_', '_', VLIB_LEX_ADD_TO_TOKEN, ~0,
514                              word_index);
515   vlib_lex_set_action_range (word_index, '0', '9', VLIB_LEX_ADD_TO_TOKEN, ~0,
516                              word_index);
517
518   return 0;
519 }
520
521 /*
522  * fd.io coding-style-patch-verification: ON
523  *
524  * Local Variables:
525  * eval: (c-set-style "gnu")
526  * End:
527  */