aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/examples/vlib/elog_samples.c (renamed from src/vlib/elog_samples.c)0
-rw-r--r--src/examples/vlib/plex_test.c527
-rw-r--r--src/vlib/parse.c1007
-rw-r--r--src/vlib/parse_builtin.c150
-rw-r--r--src/vnet/ethernet/mac_swap.c397
-rw-r--r--src/vnet/ip/ip4_test.c347
-rw-r--r--src/vpp/app/sticky_hash.c581
-rw-r--r--src/vppinfra/mod_test_hash.c27
-rw-r--r--src/vppinfra/pfhash.c689
-rw-r--r--src/vppinfra/test_pfhash.c322
-rw-r--r--src/vppinfra/test_pool.c86
11 files changed, 0 insertions, 4133 deletions
diff --git a/src/vlib/elog_samples.c b/src/examples/vlib/elog_samples.c
index a8c800df959..a8c800df959 100644
--- a/src/vlib/elog_samples.c
+++ b/src/examples/vlib/elog_samples.c
diff --git a/src/examples/vlib/plex_test.c b/src/examples/vlib/plex_test.c
deleted file mode 100644
index ce0c8ef1141..00000000000
--- a/src/examples/vlib/plex_test.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vlib/parse.h>
-#include <vlib/unix/unix.h>
-
-static u8 *
-format_value_v4_address (u8 * s, va_list * args)
-{
- vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *);
- u32 a = v->value.as_uword;
-
- s = format (s, "%d.%d.%d.%d",
- (a >> 24) & 0xFF,
- (a >> 16) & 0xFF, (a >> 8) & 0xFF, (a >> 0) & 0xFF);
-
- return s;
-}
-
-static vlib_parse_match_t
-v4_address_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- u32 digit;
- u32 value = 0;
- int i;
-
- if (vec_len (pm->tokens) - (t - pm->tokens) < 7)
- return VLIB_PARSE_MATCH_FAIL;
-
- /* NUMBER DOT NUMBER DOT NUMBER DOT NUMBER */
-
- for (i = 0; i < 7; i++)
- {
- if ((i & 1) == 0)
- {
- if (t[i].token != VLIB_LEX_number)
- return VLIB_PARSE_MATCH_FAIL;
- if (t[i].value.as_uword > 0xff)
- return VLIB_PARSE_MATCH_FAIL;
- digit = t[i].value.as_uword;
- value = (value << 8) | digit;
- }
- else
- {
- if (t[i].token != VLIB_LEX_dot)
- return VLIB_PARSE_MATCH_FAIL;
- }
- }
- /* note: caller advances by 1 */
- pm->current_token_index += 6;
- valuep->value.as_uword = value;
- return VLIB_PARSE_MATCH_VALUE;
-}
-
-PARSE_TYPE_INIT (v4_address, v4_address_match, 0, format_value_v4_address)
- static u8 *format_value_v4_address_and_mask (u8 * s, va_list * args)
-{
- vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *);
- u32 *a = v->value.as_pointer;
-
- s = format (s, "%d.%d.%d.%d",
- (a[0] >> 24) & 0xFF,
- (a[0] >> 16) & 0xFF, (a[0] >> 8) & 0xFF, (a[0] >> 0) & 0xFF);
- s = format (s, "/%d", a[1]);
-
- return s;
-}
-
-static vlib_parse_match_t
-v4_address_and_mask_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- u32 digit;
- u32 address = 0;
- u32 *rv = 0;
- int i;
-
- if (vec_len (pm->tokens) - (t - pm->tokens) < 9)
- return VLIB_PARSE_MATCH_FAIL;
-
- /* NUMBER DOT NUMBER DOT NUMBER DOT NUMBER */
-
- for (i = 0; i < 7; i++)
- {
- if ((i & 1) == 0)
- {
- if (t[i].token != VLIB_LEX_number)
- return VLIB_PARSE_MATCH_FAIL;
- if (t[i].value.as_uword > 0xff)
- return VLIB_PARSE_MATCH_FAIL;
- digit = t[i].value.as_uword;
- address = (address << 8) | digit;
- }
- else
- {
- if (t[i].token != VLIB_LEX_dot)
- return VLIB_PARSE_MATCH_FAIL;
- }
- }
-
- if (t[7].token != VLIB_LEX_slash || t[8].token != VLIB_LEX_number)
- return VLIB_PARSE_MATCH_FAIL;
-
- vec_add1 (rv, address);
- vec_add1 (rv, t[8].value.as_uword);
-
- /* note: caller advances by 1 */
- pm->current_token_index += 8;
- valuep->value.as_pointer = rv;
- return VLIB_PARSE_MATCH_VALUE;
-}
-
-void
-v4_address_and_mask_cleanup (vlib_parse_value_t * valuep)
-{
- u32 *trash = valuep->value.as_pointer;
- vec_free (trash);
-}
-
-PARSE_TYPE_INIT (v4_address_and_mask, v4_address_and_mask_match,
- v4_address_and_mask_cleanup,
- format_value_v4_address_and_mask)
- vlib_lex_main_t vlib_lex_main;
-
-
-
- vlib_parse_match_t eval_factor0 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item,
- vlib_parse_value_t * value)
-{
- clib_warning ("%U", format_vlib_parse_value, pm);
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_factor1 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- clib_warning ("%U", format_vlib_parse_value, pm);
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_factor2 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- word a;
- int index = vec_len (pm->parse_value) - 1;
-
- a = pm->parse_value[index].value.as_word;
-
- pm->parse_value[index].value.as_word = -a;
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_term0 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- clib_warning ("%U", format_vlib_parse_value, pm);
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_term1 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- uword a, b;
- int index = vec_len (pm->parse_value) - 2;
-
- a = pm->parse_value[index].value.as_uword;
- b = pm->parse_value[index + 1].value.as_uword;
-
- pm->parse_value[index].value.as_uword = a * b;
- _vec_len (pm->parse_value) -= 1;
- clib_warning ("%U", format_vlib_parse_value, pm);
-
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_term2 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- uword a, b;
- int index = vec_len (pm->parse_value) - 2;
-
- a = pm->parse_value[index].value.as_uword;
- b = pm->parse_value[index + 1].value.as_uword;
-
- pm->parse_value[index].value.as_uword = a / b;
- _vec_len (pm->parse_value) -= 1;
- clib_warning ("%U", format_vlib_parse_value, pm);
-
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_exp0 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_exp1 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- uword a, b;
- int index = vec_len (pm->parse_value) - 2;
-
- a = pm->parse_value[index].value.as_uword;
- b = pm->parse_value[index + 1].value.as_uword;
-
- pm->parse_value[index].value.as_uword = a + b;
- _vec_len (pm->parse_value) -= 1;
- clib_warning ("%U", format_vlib_parse_value, pm);
-
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_exp2 (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- uword a, b;
- int index = vec_len (pm->parse_value) - 2;
-
- a = pm->parse_value[index].value.as_uword;
- b = pm->parse_value[index + 1].value.as_uword;
-
- pm->parse_value[index].value.as_uword = a - b;
- _vec_len (pm->parse_value) -= 1;
- clib_warning ("%U", format_vlib_parse_value, pm);
-
- return VLIB_PARSE_MATCH_RULE;
-}
-
-vlib_parse_match_t
-eval_result (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- clib_warning ("%U", format_vlib_parse_value, pm);
- return VLIB_PARSE_MATCH_DONE;
-}
-
-vlib_parse_match_t
-noop_match_rule (vlib_parse_main_t * pm,
- vlib_parse_item_t * item, vlib_parse_value_t * value)
-{
- clib_warning ("%U", format_vlib_parse_value, pm);
- return VLIB_PARSE_MATCH_RULE;
-}
-
-#if 0
-PARSE_INIT (t1, "moo", eval0);
-PARSE_INIT (t2, "moo cow mumble", eval1);
-PARSE_INIT (t3, "moo cow", eval2);
-PARSE_INIT (t4, "moo cow mumble grunch", eval3);
-#endif
-
-#if 0
-PARSE_INIT (r1, "eval <exp>", eval_result);
-
-PARSE_INIT (r2, "<exp> = <term><exp2>", eval_exp0);
-PARSE_INIT (r3, "<exp2> = <plus> <exp>", eval_exp1);
-PARSE_INIT (r4, "<exp2> = <minus> <exp>", eval_exp2);
-PARSE_INIT (r5, "<exp2> = ", noop_match_rule);
-PARSE_TYPE_INIT (exp, rule_match, 0, 0);
-PARSE_TYPE_INIT (exp2, rule_match, 0, 0);
-
-PARSE_INIT (r6, "<term> = <factor><term2>", eval_term0);
-PARSE_INIT (r7, "<term2> = <star> <term>", eval_term1);
-PARSE_INIT (r8, "<term2> = <slash> <term>", eval_term2);
-PARSE_INIT (r9, "<term2> = ", noop_match_rule);
-PARSE_TYPE_INIT (term, rule_match, 0, 0);
-PARSE_TYPE_INIT (term2, rule_match, 0, 0);
-
-PARSE_INIT (r11, "<factor> = <lpar> <exp> <rpar>", eval_factor1);
-PARSE_INIT (r10, "<factor> = <number>", eval_factor0);
-PARSE_INIT (r12, "<factor> = <minus> <factor>", eval_factor2);
-
-PARSE_TYPE_INIT (factor, rule_match, 0, 0);
-#endif
-
-PARSE_INIT (r1, "eval <exp>", eval_result);
-
-#if 1
-PARSE_INIT (r2, "<exp> = <term><exp2>", eval_exp0);
-PARSE_INIT (r3, "<exp2> = <plus> <exp>", eval_exp1);
-PARSE_INIT (r4, "<exp2> = <minus> <exp>", eval_exp2);
-PARSE_INIT (r5, "<exp2> = ", noop_match_rule);
-PARSE_TYPE_INIT (exp, rule_match, 0, 0);
-PARSE_TYPE_INIT (exp2, rule_match, 0, 0);
-
-PARSE_INIT (r6, "<term> = <factor><term2>", eval_term0);
-PARSE_INIT (r7, "<term2> = <star> <term>", eval_term1);
-PARSE_INIT (r8, "<term2> = <slash> <term>", eval_term2);
-PARSE_INIT (r9, "<term2> = ", noop_match_rule);
-PARSE_TYPE_INIT (term, rule_match, 0, 0);
-PARSE_TYPE_INIT (term2, rule_match, 0, 0);
-
-PARSE_INIT (r11, "<factor> = <lpar> <exp> <rpar>", eval_factor1);
-PARSE_INIT (r10, "<factor> = <number>", eval_factor0);
-PARSE_INIT (r12, "<factor> = <minus> <factor>", eval_factor2);
-
-PARSE_TYPE_INIT (factor, rule_match, 0, 0);
-#endif
-
-#if 0
-PARSE_TYPE_INIT (exp, rule_match, 0, 0);
-PARSE_INIT (r6, "<exp> = a b", eval_term0);
-PARSE_INIT (r7, "<exp> = c d", eval_term1);
-PARSE_INIT (r9, "<exp> = ", noop_match_rule);
-#endif
-
-#if 0
-#define foreach_rule_evaluator \
-_(0) \
-_(1) \
-_(2) \
-_(3)
-
-#define _(n) \
-vlib_parse_match_t eval##n (vlib_parse_main_t *pm, \
- vlib_parse_item_t *item, \
- vlib_parse_value_t *value) \
-{ \
- clib_warning ("%U", format_vlib_parse_value, pm); \
- return VLIB_PARSE_MATCH_DONE; \
-}
-foreach_rule_evaluator
-#undef _
-PARSE_INIT (r1, "eval <moo>", eval_result);
-
-PARSE_INIT (r2, "<moo> = cow", eval0);
-PARSE_INIT (r4, "<moo> = ", eval1);
-PARSE_TYPE_INIT (moo, rule_match, 0, 0);
-#endif
-
-
-clib_error_t *
-test_init (vlib_main_t * vm)
-{
- clib_error_t *error;
-
- if ((error = vlib_call_init_function (vm, parse_init)))
- return error;
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (test_init);
-
-clib_error_t *
-vlib_stdlex_init (vlib_main_t * vm)
-{
- vlib_lex_main_t *lm = &vlib_lex_main;
- u16 top_index;
- u16 slash_index, slash_star_index, slash_slash_index, slash_star_star_index;
- u16 slash_token;
- u16 word_index;
- u16 zero_index, octal_index, decimal_index, hex_index, binary_index;
-
- top_index = vlib_lex_add_table ("top");
-
-#define foreach_top_level_single_character_token \
- _('(', lpar) \
- _(')', rpar) \
- _(';', semi) \
- _('[', lbrack) \
- _(']', rbrack) \
- _('{', lcurly) \
- _('}', rcurly) \
- _('+', plus) \
- _('-', minus) \
- _('*', star) \
- _('%', percent) \
- _('@', atsign) \
- _(',', comma) \
- _('.', dot) \
- _('?', qmark)
-
-#define _(c,t) \
- vlib_lex_set_action_range(top_index,c,c,VLIB_LEX_RETURN,vlib_lex_add_token(lm, #t), top_index);
- foreach_top_level_single_character_token;
-#undef _
-
- /* Numbers */
- zero_index = vlib_lex_add_table ("zero");
- octal_index = vlib_lex_add_table ("octal");
- decimal_index = vlib_lex_add_table ("decimal");
- hex_index = vlib_lex_add_table ("hex");
- binary_index = vlib_lex_add_table ("binary");
-
- /* Support 0x 0b 0t and 0123 [octal] */
- vlib_lex_set_action_range (top_index, '0', '0', VLIB_LEX_START_NUMBER, 10,
- zero_index);
- vlib_lex_set_action_range (top_index, '1', '9', VLIB_LEX_START_NUMBER, 10,
- decimal_index);
-
- vlib_lex_set_action_range (zero_index, 0, 0x7F, VLIB_LEX_RETURN_AND_RESCAN,
- VLIB_LEX_number, top_index);
-
- vlib_lex_set_action_range (zero_index, 'x', 'x', VLIB_LEX_IGNORE, ~0,
- hex_index);
- vlib_lex_set_action_range (zero_index, 'b', 'b', VLIB_LEX_IGNORE, ~0,
- binary_index);
- vlib_lex_set_action_range (zero_index, 't', 't', VLIB_LEX_IGNORE, ~0,
- decimal_index);
- vlib_lex_set_action_range (zero_index, '0', '7', VLIB_LEX_START_NUMBER, 8,
- octal_index);
-
- /* Octal */
- vlib_lex_set_action_range (octal_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN,
- VLIB_LEX_number, top_index);
- vlib_lex_set_action_range (octal_index, '0', '7', VLIB_LEX_ADD_TO_NUMBER, 8,
- octal_index);
-
- /* Decimal */
- vlib_lex_set_action_range (decimal_index, 0, 0x7f,
- VLIB_LEX_RETURN_AND_RESCAN, VLIB_LEX_number,
- top_index);
- vlib_lex_set_action_range (decimal_index, '0', '9', VLIB_LEX_ADD_TO_NUMBER,
- 10, decimal_index);
-
- /* Hex */
- vlib_lex_set_action_range (hex_index, 0, 0x7f, VLIB_LEX_RETURN_AND_RESCAN,
- VLIB_LEX_number, top_index);
- vlib_lex_set_action_range (hex_index, '0', '9', VLIB_LEX_ADD_TO_NUMBER, 16,
- hex_index);
- vlib_lex_set_action_range (hex_index, 'a', 'f', VLIB_LEX_ADD_TO_NUMBER, 16,
- hex_index);
- vlib_lex_set_action_range (hex_index, 'A', 'F', VLIB_LEX_ADD_TO_NUMBER, 16,
- hex_index);
-
- /* Binary */
- vlib_lex_set_action_range (binary_index, 0, 0x7f,
- VLIB_LEX_RETURN_AND_RESCAN, VLIB_LEX_number,
- top_index);
- vlib_lex_set_action_range (binary_index, '0', '1', VLIB_LEX_ADD_TO_NUMBER,
- 2, binary_index);
-
- /* c/c++ comment syntax is the worst... */
-
- slash_index = vlib_lex_add_table ("slash");
- slash_star_index = vlib_lex_add_table ("slash_star");
- slash_star_star_index = vlib_lex_add_table ("slash_star_star");
- slash_slash_index = vlib_lex_add_table ("slash_slash");
- slash_token = vlib_lex_add_token (lm, "slash");
-
- /* Top level: see a slash, ignore, go to slash table */
- vlib_lex_set_action_range (top_index, '/', '/', VLIB_LEX_IGNORE, ~0,
- slash_index);
-
- /* default for slash table: return SLASH, go to top table */
- vlib_lex_set_action_range (slash_index, 1, 0x7F, VLIB_LEX_RETURN_AND_RESCAN,
- slash_token, top_index);
- /* see slash-slash, go to s-s table */
- vlib_lex_set_action_range (slash_index, '/', '/', VLIB_LEX_IGNORE, ~0,
- slash_slash_index);
- /* see slash-star, go to s-* table */
- vlib_lex_set_action_range (slash_index, '*', '*', VLIB_LEX_IGNORE, ~0,
- slash_star_index);
-
- /* EOL in s-s table, ignore, go to top table */
- vlib_lex_set_action_range (slash_slash_index, '\n', '\n', VLIB_LEX_IGNORE,
- ~0, top_index);
-
- /* slash-star blah blah star */
- vlib_lex_set_action_range (slash_star_index, '*', '*', VLIB_LEX_IGNORE, ~0,
- slash_star_star_index);
-
- /* slash star blah blah star slash */
- vlib_lex_set_action_range (slash_star_star_index, '/', '/', VLIB_LEX_IGNORE,
- ~0, top_index);
-
- /* LT, =, GT */
- vlib_lex_set_action_range (top_index, '<', '<', VLIB_LEX_RETURN,
- VLIB_LEX_lt, top_index);
- vlib_lex_set_action_range (top_index, '=', '=', VLIB_LEX_RETURN,
- VLIB_LEX_equals, top_index);
- vlib_lex_set_action_range (top_index, '>', '>', VLIB_LEX_RETURN,
- VLIB_LEX_gt, top_index);
-
- /* words, key and otherwise */
- word_index = vlib_lex_add_table ("word");
-
- vlib_lex_set_action_range (top_index, 'a', 'z', VLIB_LEX_ADD_TO_TOKEN, ~0,
- word_index);
- vlib_lex_set_action_range (top_index, 'A', 'Z', VLIB_LEX_ADD_TO_TOKEN, ~0,
- word_index);
-
- vlib_lex_set_action_range (word_index, 0, 0x7f, VLIB_LEX_KEYWORD_CHECK, ~0,
- top_index);
-
- vlib_lex_set_action_range (word_index, 'a', 'z', VLIB_LEX_ADD_TO_TOKEN, ~0,
- word_index);
- vlib_lex_set_action_range (word_index, 'A', 'Z', VLIB_LEX_ADD_TO_TOKEN, ~0,
- word_index);
- vlib_lex_set_action_range (word_index, '_', '_', VLIB_LEX_ADD_TO_TOKEN, ~0,
- word_index);
- vlib_lex_set_action_range (word_index, '0', '9', VLIB_LEX_ADD_TO_TOKEN, ~0,
- word_index);
-
- return 0;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vlib/parse.c b/src/vlib/parse.c
deleted file mode 100644
index 1c4500ce85a..00000000000
--- a/src/vlib/parse.c
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vlib/parse.h>
-
-#define PARSE_DEBUG 0
-
-u16 word_type_index, number_type_index, eof_type_index, rule_eof_type_index,
- plus_type_index, minus_type_index, star_type_index, slash_type_index,
- lpar_type_index, rpar_type_index;
-
-u8 *
-format_vlib_parse_value (u8 * s, va_list * args)
-{
- vlib_parse_main_t *pm = va_arg (*args, vlib_parse_main_t *);
- vlib_parse_type_t *type;
- vlib_parse_value_t *v;
- u16 type_index;
-
- s = format (s, "%d items:\n", vec_len (pm->parse_value));
- vec_foreach (v, pm->parse_value)
- {
- type_index = v->type;
- type = pool_elt_at_index (pm->parse_types, type_index);
- if (type->format_value)
- s = format (s, "[%d]: %U\n", v - pm->parse_value,
- type->format_value, v);
- else
- s = format (s, "[%d]: (nofun)\n", v - pm->parse_value);
- }
- return s;
-}
-
-static u8 *
-format_vlib_parse_match (u8 * s, va_list * args)
-{
- vlib_parse_match_t m = va_arg (*args, vlib_parse_match_t);
- char *t = 0;
- switch (m)
- {
-#define _(a) case VLIB_PARSE_##a: t = #a; break;
- foreach_parse_match_type
-#undef _
- default:
- t = 0;
- break;
- }
-
- if (t)
- return format (s, "%s", t);
- else
- return format (s, "unknown 0x%x", m);
-}
-
-static u8 *
-format_vlib_parse_item (u8 * s, va_list * args)
-{
- vlib_parse_main_t *pm = va_arg (*args, vlib_parse_main_t *);
- vlib_parse_item_t *item = va_arg (*args, vlib_parse_item_t *);
- vlib_parse_type_t *type = pool_elt_at_index (pm->parse_types, item->type);
-
- if (item->type == word_type_index)
- s = format (s, "%s", item->value.as_pointer);
- else
- s = format (s, "<%s>", type->name);
- return s;
-}
-
-static u8 *
-format_vlib_parse_graph (u8 * s, va_list * args)
-{
- vlib_parse_main_t *pm = va_arg (*args, vlib_parse_main_t *);
- vlib_parse_graph_t *node = va_arg (*args, vlib_parse_graph_t *);
- vlib_parse_item_t *item;
- vlib_parse_type_t *type;
-
- /* $$$ hash table */
- /* *INDENT-OFF* */
- pool_foreach (type, pm->parse_types,
- ({
- if (type->rule_index == node - pm->parse_graph)
- s = format (s, "\n<%s>\n", type->name);
- }));
-/* *INDENT-ON* */
-
- if (pm->root_index == (node - pm->parse_graph))
- s = format (s, "\n<root>\n");
-
- item = pool_elt_at_index (pm->parse_items, node->item);
-
- s = format (s, "[%d] %U ", node - pm->parse_graph,
- format_vlib_parse_item, pm, item);
-
- if (node->peer == (u32) ~ 0)
- s = format (s, "peer nil ");
- else
- s = format (s, "peer %4u ", node->peer);
-
- if (node->deeper == (u32) ~ 0)
- s = format (s, "deeper nil ");
- else
- s = format (s, "deeper %4u ", node->deeper);
-
- return s;
-}
-
-void
-dump_parse_graph (void)
-{
- vlib_parse_main_t *pm = &vlib_parse_main;
- vlib_parse_graph_t *node;
-
- /* *INDENT-OFF* */
- pool_foreach (node, pm->parse_graph, ({
- fformat(stdout, "%U\n", format_vlib_parse_graph, pm, node);
- }));
-/* *INDENT-ON* */
-}
-
-always_inline void
-parse_cleanup_value (vlib_parse_main_t * pm, vlib_parse_value_t * pv)
-{
- vlib_parse_type_t *type = pool_elt_at_index (pm->parse_types, pv->type);
- if (type->value_cleanup_function)
- type->value_cleanup_function (pv);
-}
-
-static void
-parse_reset (vlib_parse_main_t * pm, u8 * input)
-{
- vlib_lex_token_t *t;
- vlib_parse_value_t *pv;
-
- vlib_lex_reset (pm->lex_main, input);
-
- vec_foreach (t, pm->tokens) vlib_lex_cleanup_token (t);
-
- vec_foreach (pv, pm->parse_value) parse_cleanup_value (pm, pv);
-
- _vec_len (pm->parse_value) = 0;
- _vec_len (pm->tokens) = 0;
- pm->current_token_index = 0;
-}
-
-static void
-parse_help (vlib_parse_main_t * pm, u32 index)
-{
- vlib_parse_graph_t *node;
- vlib_parse_item_t *item;
- vlib_parse_type_t *type;
- vlib_main_t *vm = pm->vlib_main;
- u8 *help_input;
- int i;
-
- help_input = vec_dup (pm->lex_main->input_vector);
-
- for (i = vec_len (help_input) - 1; i >= 0; i--)
- if (help_input[i] == '?')
- {
- help_input[i] = 0;
- _vec_len (help_input) = i;
- break;
- }
-
- for (i = vec_len (help_input) - 1; i >= 0; i--)
- {
- if (help_input[i] != ' ' && help_input[i] != '\t')
- break;
- help_input[i] = 0;
- break;
- }
- _vec_len (help_input) = i + 1;
-
- while (index != (u32) ~ 0)
- {
- node = pool_elt_at_index (pm->parse_graph, index);
- item = pool_elt_at_index (pm->parse_items, node->item);
- type = pool_elt_at_index (pm->parse_types, item->type);
-
- if (item->type == eof_type_index && vec_len (pm->match_items) == 0)
- /* do nothing */ ;
- else if (item->type == word_type_index)
- vlib_cli_output (vm, "%s %s\n", help_input, item->value.as_pointer);
- else
- vlib_cli_output (vm, "%s <%s>\n", help_input, type->name);
- index = node->peer;
- }
- vec_free (help_input);
-}
-
-static vlib_parse_match_t
-parse_eval_internal (vlib_parse_main_t * pm, u32 index)
-{
- vlib_parse_graph_t *node;
- vlib_parse_item_t *item;
- vlib_parse_type_t *type;
- vlib_parse_value_t value, *pv;
- vlib_parse_match_t rv;
- u32 *partial_matches = 0;
- vlib_lex_token_t *t;
- u32 save_token_index = (u32) ~ 0, save_match_items = 0;
- int had_value = 0;
-
- if (pm->current_token_index >= vec_len (pm->tokens))
- return VLIB_PARSE_MATCH_FAIL;
-
- /* current token */
- t = vec_elt_at_index (pm->tokens, pm->current_token_index);
-
- /* Help ? */
- if (PREDICT_FALSE (t->token == VLIB_LEX_qmark))
- {
- parse_help (pm, index);
- _vec_len (pm->match_items) = 0;
- return VLIB_PARSE_MATCH_DONE;
- }
-
- /* Across all peers at this level of the parse graph */
- while (index != (u32) ~ 0)
- {
- node = pool_elt_at_index (pm->parse_graph, index);
- item = pool_elt_at_index (pm->parse_items, node->item);
- type = pool_elt_at_index (pm->parse_types, item->type);
-
- /*
- * Save the token index. We may have to back up several
- * trie plies. Type-specific match functions can consume
- * multiple tokens, and they may not be optimally careful
- */
- save_token_index = pm->current_token_index;
- save_match_items = vec_len (pm->match_items);
- vec_add1 (pm->match_items, node->item);
-
- if (PARSE_DEBUG > 1)
- clib_warning ("Try to match token %U against node %d",
- format_vlib_lex_token, pm->lex_main, t, index);
-
- /* Call the type-specific match function */
- rv = type->match_function (pm, type, t, &value);
-
- if (PARSE_DEBUG > 1)
- clib_warning ("returned %U", format_vlib_parse_match, rv);
-
- switch (rv)
- {
- case VLIB_PARSE_MATCH_VALUE:
- /*
- * Matched, and returned a value to append to the
- * set of args passed to the action function
- */
- value.type = item->type;
- vec_add1 (pm->parse_value, value);
- had_value = 1;
- /* fallthrough */
-
- case VLIB_PARSE_MATCH_FULL:
- unambiguous_partial_match:
- /* Consume the matched token */
- pm->current_token_index++;
-
- /* continue matching along this path */
- rv = parse_eval_internal (pm, node->deeper);
-
- /* this is not the right path */
- if (rv == VLIB_PARSE_MATCH_FAIL)
- {
- if (had_value)
- {
- /* Delete the value */
- value = pm->parse_value[vec_len (pm->parse_value) - 1];
- parse_cleanup_value (pm, &value);
- _vec_len (pm->parse_value) -= 1;
- }
- /* Continue with the next sibling */
- pm->current_token_index = save_token_index;
- _vec_len (pm->match_items) = save_match_items;
- index = node->peer;
- break;
- }
- return rv;
-
- case VLIB_PARSE_MATCH_PARTIAL:
- /* Partial (substring) match, remember it but keep going */
- vec_add1 (partial_matches, node - pm->parse_graph);
- index = node->peer;
- break;
-
- case VLIB_PARSE_MATCH_FAIL:
- /* Continue with the next sibling */
- index = node->peer;
- _vec_len (pm->match_items) = save_match_items;
- break;
-
- case VLIB_PARSE_MATCH_DONE:
- /* Parse complete, invoke the action function */
- if (PARSE_DEBUG > 0)
- clib_warning ("parse_value: %U", format_vlib_parse_value, pm);
-
- {
- vlib_parse_eval_function_t *f = item->value.as_pointer;
- if (f)
- rv = f (pm, item, pm->parse_value);
- }
-
- vec_foreach (pv, pm->parse_value) parse_cleanup_value (pm, pv);
- _vec_len (pm->parse_value) = 0;
- _vec_len (pm->match_items) = 0;
- return rv;
-
- case VLIB_PARSE_MATCH_AMBIGUOUS:
- case VLIB_PARSE_MATCH_EVAL_FAIL:
- case VLIB_PARSE_MATCH_RULE:
- _vec_len (pm->match_items) = save_match_items;
- return rv;
- }
- }
-
- /*
- * Out of siblings. If we have exactly one partial match
- * we win
- */
- if (vec_len (partial_matches) == 1)
- {
- index = partial_matches[0];
- node = pool_elt_at_index (pm->parse_graph, index);
- vec_free (partial_matches);
- goto unambiguous_partial_match;
- }
-
- /* Ordinary loser */
- rv = VLIB_PARSE_MATCH_FAIL;
-
- /* Ambiguous loser */
- if (vec_len (partial_matches) > 1)
- {
- vec_free (partial_matches);
- rv = VLIB_PARSE_MATCH_AMBIGUOUS;
- }
-
- _vec_len (pm->match_items) = save_match_items;
- return rv;
-}
-
-vlib_parse_match_t
-rule_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- vlib_parse_match_t rv;
- static int recursion_level;
-
- if (PARSE_DEBUG > 1)
- clib_warning ("[%d]: try to match type %s graph index %d",
- recursion_level, type->name, type->rule_index);
- recursion_level++;
- rv = parse_eval_internal (pm, type->rule_index);
- recursion_level--;
-
- /* Break the recusive unwind here... */
- if (rv == VLIB_PARSE_MATCH_RULE)
- {
- if (PARSE_DEBUG > 1)
- clib_warning ("[%d]: type %s matched", recursion_level, type->name);
-
- return VLIB_PARSE_MATCH_FULL;
- }
- else
- {
- if (PARSE_DEBUG > 1)
- clib_warning ("[%d]: type %s returns %U", recursion_level, type->name,
- format_vlib_parse_match, rv);
- }
- return rv;
-}
-
-static int
-parse_eval (vlib_parse_main_t * pm, u8 * input)
-{
- vlib_lex_token_t *t;
-
- parse_reset (pm, input);
-
- /* Tokenize the entire input vector */
- do
- {
- vec_add2 (pm->tokens, t, 1);
- vlib_lex_get_token (pm->lex_main, t);
- }
- while (t->token != VLIB_LEX_eof);
-
- /* Feed it to the parser */
- return parse_eval_internal (pm, pm->root_index);
-}
-
-/* Temporary vlib stub */
-vlib_parse_match_t
-vlib_parse_eval (u8 * input)
-{
- return parse_eval (&vlib_parse_main, input);
-}
-
-u16
-parse_type_find_or_create (vlib_parse_main_t * pm, vlib_parse_type_t * t)
-{
- uword *p;
- vlib_parse_type_t *n;
- u8 *name_copy;
-
- p = hash_get_mem (pm->parse_type_by_name_hash, t->name);
- if (p)
- return p[0];
-
- pool_get (pm->parse_types, n);
- *n = *t;
- n->rule_index = (u32) ~ 0;
-
- name_copy = format (0, "%s%c", n->name, 0);
-
- hash_set_mem (pm->parse_type_by_name_hash, name_copy, n - pm->parse_types);
- return n - pm->parse_types;
-}
-
-u16
-parse_type_find_by_name (vlib_parse_main_t * pm, char *name)
-{
- uword *p;
-
- p = hash_get_mem (pm->parse_type_by_name_hash, name);
- if (p)
- return p[0];
-
- return (u16) ~ 0;
-}
-
-u32
-parse_item_find_or_create (vlib_parse_main_t * pm, vlib_parse_item_t * item)
-{
- uword *p;
- vlib_parse_item_t *i;
-
- /* Exact match the entire item */
- p = mhash_get (&pm->parse_item_hash, item);
- if (p)
- return p[0];
-
- pool_get (pm->parse_items, i);
- *i = *item;
-
- mhash_set (&pm->parse_item_hash, i, i - pm->parse_items, 0);
- return i - pm->parse_items;
-}
-
-static void
-parse_type_and_graph_init (vlib_parse_main_t * pm)
-{
- u32 eof_index;
- vlib_parse_type_t type;
- vlib_parse_item_t item;
-
- memset (&type, 0, sizeof (type));
-
-#define foreach_token_type \
- _ (eof) \
- _ (rule_eof) \
- _ (word) \
- _ (number) \
- _ (plus) \
- _ (minus) \
- _ (star) \
- _ (slash) \
- _ (lpar) \
- _ (rpar)
-
-#define _(a) a##_type_index = parse_type_find_by_name (pm, #a);
- foreach_token_type
-#undef _
- memset (&item, 0, sizeof (item));
- item.type = eof_type_index;
-
- eof_index = parse_item_find_or_create (pm, &item);
- pm->root_index = (u32) ~ 0;
-
-#if 0
- pool_get (pm->parse_graph, g);
- memset (g, 0xff, sizeof (*g));
- g->item = eof_index;
- pm->root_index = 0;
-#endif
-}
-
-
-
-static void
-tokenize (vlib_parse_main_t * pm, parse_registration_t * pr)
-{
- vlib_lex_token_t *t;
- pm->register_input = format (pm->register_input,
- "%s%c", pr->initializer, 0);
-
- parse_reset (pm, pm->register_input);
-
- do
- {
- vec_add2 (pm->tokens, t, 1);
- vlib_lex_get_token (pm->lex_main, t);
- }
- while (t->token != VLIB_LEX_eof);
- _vec_len (pm->register_input) = 0;
-}
-
-static int
-is_typed_rule (vlib_parse_main_t * pm)
-{
- vlib_lex_token_t *t = vec_elt_at_index (pm->tokens, 0);
-
- /* <mytype> = blah blah blah */
- if (vec_len (pm->tokens) >= 4
- && t[0].token == VLIB_LEX_lt
- && t[1].token == VLIB_LEX_word
- && t[2].token == VLIB_LEX_gt && t[3].token == VLIB_LEX_equals)
- return 1;
- return 0;
-}
-
-static int
-token_matches_graph_node (vlib_parse_main_t * pm,
- vlib_lex_token_t * t,
- vlib_parse_graph_t * node,
- vlib_parse_item_t * item,
- vlib_parse_type_t * type, u32 * token_increment)
-{
- /* EOFs don't match */
- if (t->token == VLIB_LEX_eof)
- return 0;
-
- /* New chain element is a word */
- if (t->token == VLIB_LEX_word)
- {
- /* but the item in hand is not a word */
- if (item->type != word_type_index)
- return 0;
-
- /* Or it's not this particular word */
- if (strcmp (t->value.as_pointer, item->value.as_pointer))
- return 0;
- *token_increment = 1;
- return 1;
- }
- /* New chain element is a type-name: < TYPE-NAME > */
- if (t->token == VLIB_LEX_lt)
- {
- u16 token_type_index;
-
- /* < TYPE > */
- if (t[1].token != VLIB_LEX_word || t[2].token != VLIB_LEX_gt)
- {
- clib_warning (0, "broken type name in '%s'", pm->register_input);
- return 0;
- }
-
- token_type_index = parse_type_find_by_name (pm, t[1].value.as_pointer);
- if (token_type_index == (u16) ~ 0)
- {
- clib_warning (0, "unknown type '%s'", t[1].value.as_pointer);
- return 0;
- }
-
- /* Its a known type but does not match. */
- if (item->type != token_type_index)
- return 0;
-
- *token_increment = 3;
- return 1;
- }
- clib_warning ("BUG: t->token = %d", t->token);
- return 0;
-}
-
-u32
-generate_subgraph_from_tokens (vlib_parse_main_t * pm,
- vlib_lex_token_t * t,
- u32 * new_subgraph_depth,
- parse_registration_t * pr, int not_a_rule)
-{
- vlib_parse_graph_t *g, *last_g;
- vlib_parse_item_t new_item;
- u32 rv = (u32) ~ 0, new_item_index, last_index = (u32) ~ 0;
- u16 token_type_index;
- u32 depth = 0;
-
- while (t < pm->tokens + vec_len (pm->tokens))
- {
- memset (&new_item, 0, sizeof (new_item));
-
- if (t->token == VLIB_LEX_word)
- {
- new_item.type = word_type_index;
- new_item.value.as_pointer = vec_dup ((u8 *) t->value.as_pointer);
- new_item_index = parse_item_find_or_create (pm, &new_item);
- t++;
- }
- else if (t->token == VLIB_LEX_lt)
- {
- if (t[1].token != VLIB_LEX_word || t[2].token != VLIB_LEX_gt)
- {
- clib_warning ("broken type name in '%s'", pm->register_input);
- goto screwed;
- }
- token_type_index = parse_type_find_by_name (pm,
- t[1].value.as_pointer);
- if (token_type_index == (u16) ~ 0)
- {
- clib_warning ("unknown type 2 '%s'", t[1].value.as_pointer);
- goto screwed;
- }
-
- new_item.type = token_type_index;
- new_item.value.as_pointer = 0;
- new_item_index = parse_item_find_or_create (pm, &new_item);
- t += 3; /* skip < <type-name> and > */
- }
- else if (t->token == VLIB_LEX_eof)
- {
- screwed:
- new_item.type = not_a_rule ? eof_type_index : rule_eof_type_index;
- new_item.value.as_pointer = pr->eof_match;
- new_item_index = parse_item_find_or_create (pm, &new_item);
- t++;
- }
- else
- {
- clib_warning ("unexpected token %U index %d in '%s'",
- format_vlib_lex_token, pm->lex_main, t,
- t - pm->tokens, pm->register_input);
- goto screwed;
- }
-
- pool_get (pm->parse_graph, g);
- memset (g, 0xff, sizeof (*g));
- g->item = new_item_index;
- depth++;
-
- if (rv == (u32) ~ 0)
- {
- rv = g - pm->parse_graph;
- last_index = rv;
- }
- else
- {
- last_g = pool_elt_at_index (pm->parse_graph, last_index);
- last_index = last_g->deeper = g - pm->parse_graph;
- }
- }
- *new_subgraph_depth = depth;
- return rv;
-}
-
-static u32
-measure_depth (vlib_parse_main_t * pm, u32 index)
-{
- vlib_parse_graph_t *node;
- vlib_parse_item_t *item;
- u32 max = 0;
- u32 depth;
-
- if (index == (u32) ~ 0)
- return 0;
-
- node = pool_elt_at_index (pm->parse_graph, index);
- item = pool_elt_at_index (pm->parse_items, node->item);
-
- if (item->type == eof_type_index)
- return 1;
-
- while (index != (u32) ~ 0)
- {
- node = pool_elt_at_index (pm->parse_graph, index);
- depth = measure_depth (pm, node->deeper);
- if (max < depth)
- max = depth;
- index = node->peer;
- }
-
- return max + 1;
-}
-
-static void
-add_subgraph_to_graph (vlib_parse_main_t * pm,
- u32 last_matching_index,
- u32 graph_root_index,
- u32 new_subgraph_index, u32 new_subgraph_depth)
-{
- vlib_parse_graph_t *parent_node;
- int new_subgraph_longest = 1;
- u32 current_peer_index;
- u32 current_depth;
- vlib_parse_graph_t *current_peer = 0;
- vlib_parse_graph_t *new_subgraph_node =
- pool_elt_at_index (pm->parse_graph, new_subgraph_index);
-
- /*
- * Case 1: top-level peer. Splice into the top-level
- * peer chain according to rule depth
- */
- if (last_matching_index == (u32) ~ 0)
- {
- u32 index = graph_root_index;
- while (1)
- {
- current_peer = pool_elt_at_index (pm->parse_graph, index);
- current_depth = measure_depth (pm, index);
- if (current_depth < new_subgraph_depth
- || current_peer->peer == (u32) ~ 0)
- break;
- index = current_peer->peer;
- }
- new_subgraph_node->peer = current_peer->peer;
- current_peer->peer = new_subgraph_index;
- return;
- }
-
- parent_node = pool_elt_at_index (pm->parse_graph, last_matching_index);
- current_peer_index = parent_node->deeper;
-
- while (current_peer_index != (u32) ~ 0)
- {
- current_peer = pool_elt_at_index (pm->parse_graph, current_peer_index);
- current_depth = measure_depth (pm, current_peer_index);
- if (current_depth < new_subgraph_depth)
- break;
- new_subgraph_longest = 0;
- current_peer_index = current_peer->peer;
- }
-
- ASSERT (current_peer);
-
- if (new_subgraph_longest)
- {
- new_subgraph_node->peer = parent_node->deeper;
- parent_node->deeper = new_subgraph_index;
- }
- else
- {
- new_subgraph_node->peer = current_peer->peer;
- current_peer->peer = new_subgraph_index;
- }
-}
-
-static clib_error_t *
-parse_register_one (vlib_parse_main_t * pm, parse_registration_t * pr)
-{
- u32 graph_root_index;
- u16 subgraph_type_index = (u16) ~ 0;
- vlib_parse_type_t *subgraph_type = 0;
- vlib_lex_token_t *t;
- vlib_parse_graph_t *node;
- u32 node_index, last_index, token_increment, new_subgraph_index;
- u32 new_subgraph_depth, last_matching_index;
- vlib_parse_item_t *item;
- vlib_parse_type_t *type;
-
- int use_main_graph = 1;
-
- tokenize (pm, pr);
-
- /* A typed rule? */
- if (is_typed_rule (pm))
- {
- /* Get the type and its current subgraph root, if any */
- t = vec_elt_at_index (pm->tokens, 1);
- subgraph_type_index = parse_type_find_by_name (pm, t->value.as_pointer);
- if (subgraph_type_index == (u16) ~ 0)
- return clib_error_return (0, "undeclared type '%s'",
- t->value.as_pointer);
- subgraph_type =
- pool_elt_at_index (pm->parse_types, subgraph_type_index);
- graph_root_index = subgraph_type->rule_index;
- /* Skip "mytype> = */
- t += 3;
- use_main_graph = 0;
- }
- else
- {
- /* top-level graph */
- graph_root_index = pm->root_index;
- t = vec_elt_at_index (pm->tokens, 0);
- }
-
- last_matching_index = (u32) ~ 0;
- last_index = node_index = graph_root_index;
-
- /* Find the first token which isn't already being parsed */
- while (t < pm->tokens + vec_len (pm->tokens) && node_index != (u32) ~ 0)
- {
- node = pool_elt_at_index (pm->parse_graph, node_index);
- item = pool_elt_at_index (pm->parse_items, node->item);
- type = pool_elt_at_index (pm->parse_types, item->type);
- last_index = node_index;
-
- if (token_matches_graph_node
- (pm, t, node, item, type, &token_increment))
- {
- t += token_increment;
- last_matching_index = node_index;
- node_index = node->deeper;
- }
- else
- node_index = node->peer;
- }
-
- new_subgraph_index =
- generate_subgraph_from_tokens (pm, t, &new_subgraph_depth, pr,
- use_main_graph);
-
- /* trivial cases: first graph node or first type rule */
- if (graph_root_index == (u32) ~ 0)
- {
- if (use_main_graph)
- pm->root_index = new_subgraph_index;
- else
- subgraph_type->rule_index = new_subgraph_index;
- return 0;
- }
-
- add_subgraph_to_graph (pm, last_matching_index, graph_root_index,
- new_subgraph_index, new_subgraph_depth);
- return 0;
-}
-
-static clib_error_t *
-parse_register (vlib_main_t * vm,
- parse_registration_t * lo,
- parse_registration_t * hi, vlib_parse_main_t * pm)
-{
- parse_registration_t *pr;
-
- for (pr = lo; pr < hi; pr = vlib_elf_section_data_next (pr, 0))
- vec_add1 (pm->parse_registrations, pr);
-
- return 0;
-}
-
-static clib_error_t *
-parse_register_one_type (vlib_parse_main_t * pm, vlib_parse_type_t * rp)
-{
- (void) parse_type_find_or_create (pm, (vlib_parse_type_t *) rp);
- return 0;
-}
-
-static clib_error_t *
-parse_type_register (vlib_main_t * vm,
- vlib_parse_type_t * lo,
- vlib_parse_type_t * hi, vlib_parse_main_t * pm)
-{
- clib_error_t *error = 0;
- vlib_parse_type_t *ptr;
-
- for (ptr = lo; ptr < hi; ptr = vlib_elf_section_data_next (ptr, 0))
- {
- error = parse_register_one_type (pm, ptr);
- if (error)
- goto done;
- }
-
-done:
- return error;
-}
-
-clib_error_t *vlib_stdlex_init (vlib_main_t * vm) __attribute__ ((weak));
-clib_error_t *
-vlib_stdlex_init (vlib_main_t * vm)
-{
- (void) vlib_lex_add_table ("ignore_everything");
- return 0;
-}
-
-static int
-compute_rule_length (parse_registration_t * r)
-{
- int length, i;
- vlib_parse_main_t *pm = &vlib_parse_main;
-
- if (r->rule_length)
- return r->rule_length;
-
- length = 0;
-
- tokenize (pm, r);
- length = vec_len (pm->tokens);
-
- /* Account for "<foo> = " in "<foo> = bar" etc. */
- if (is_typed_rule (pm))
- length -= 2;
-
- for (i = 0; i < vec_len (pm->tokens); i++)
- {
- switch (pm->tokens[i].token)
- {
- case VLIB_LEX_lt:
- case VLIB_LEX_gt:
- length -= 1;
-
- default:
- break;
- }
- }
-
- ASSERT (length > 0);
- r->rule_length = length;
- return length;
-}
-
-static int
-rule_length_compare (parse_registration_t * r1, parse_registration_t * r2)
-{
- compute_rule_length (r1);
- compute_rule_length (r2);
- /* Descending sort */
- return r2->rule_length - r1->rule_length;
-}
-
-
-static clib_error_t *
-parse_init (vlib_main_t * vm)
-{
- vlib_parse_main_t *pm = &vlib_parse_main;
- vlib_lex_main_t *lm = &vlib_lex_main;
- vlib_elf_section_bounds_t *b, *bounds;
- clib_error_t *error = 0;
- parse_registration_t *rule;
- int i;
-
- if ((error = vlib_call_init_function (vm, lex_onetime_init)))
- return error;
-
- if ((error = vlib_stdlex_init (vm)))
- return error;
-
- if ((error = vlib_call_init_function (vm, parse_builtin_init)))
- return error;
-
- pm->vlib_main = vm;
- pm->lex_main = lm;
-
- mhash_init (&pm->parse_item_hash, sizeof (u32), sizeof (vlib_parse_item_t));
- pm->parse_type_by_name_hash = hash_create_string (0, sizeof (u32));
-
- vec_validate (pm->parse_value, 16);
- vec_validate (pm->tokens, 16);
- vec_validate (pm->register_input, 32);
- vec_validate (pm->match_items, 16);
-
- _vec_len (pm->parse_value) = 0;
- _vec_len (pm->tokens) = 0;
- _vec_len (pm->register_input) = 0;
- _vec_len (pm->match_items) = 0;
-
- bounds = vlib_get_elf_section_bounds (vm, "parse_type_registrations");
- vec_foreach (b, bounds)
- {
- error = parse_type_register (vm, b->lo, b->hi, pm);
- if (error)
- break;
- }
- vec_free (bounds);
-
- parse_type_and_graph_init (pm);
-
- bounds = vlib_get_elf_section_bounds (vm, "parse_registrations");
- vec_foreach (b, bounds)
- {
- error = parse_register (vm, b->lo, b->hi, pm);
- if (error)
- break;
- }
- vec_free (bounds);
-
- vec_sort_with_function (pm->parse_registrations, rule_length_compare);
-
- for (i = 0; i < vec_len (pm->parse_registrations); i++)
- {
- rule = pm->parse_registrations[i];
- parse_register_one (pm, rule);
- }
-
- return error;
-}
-
-VLIB_INIT_FUNCTION (parse_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vlib/parse_builtin.c b/src/vlib/parse_builtin.c
deleted file mode 100644
index 0ce716b539e..00000000000
--- a/src/vlib/parse_builtin.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vlib/parse.h>
-
-always_inline void *
-parse_last_match_value (vlib_parse_main_t * pm)
-{
- vlib_parse_item_t *i;
- i = pool_elt_at_index (pm->parse_items,
- vec_elt (pm->match_items,
- vec_len (pm->match_items) - 1));
- return i->value.as_pointer;
-}
-
-vlib_parse_match_t
-eof_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- return t->token ==
- VLIB_LEX_eof ? VLIB_PARSE_MATCH_DONE : VLIB_PARSE_MATCH_FAIL;
-}
-
-PARSE_TYPE_INIT (eof, eof_match, 0 /* cleanup value */ ,
- 0 /* format value */ );
-
-vlib_parse_match_t
-rule_eof_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- vlib_parse_match_function_t *fp = parse_last_match_value (pm);
- pm->current_token_index--;
- return fp ? fp (pm, type, t, valuep) : VLIB_PARSE_MATCH_RULE;
-}
-
-PARSE_TYPE_INIT (rule_eof, rule_eof_match, 0, 0);
-
-vlib_parse_match_t
-word_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- u8 *tv, *iv;
- int i;
-
- if (t->token != VLIB_LEX_word)
- return VLIB_PARSE_MATCH_FAIL;
-
- tv = t->value.as_pointer;
- iv = parse_last_match_value (pm);
-
- for (i = 0; tv[i]; i++)
- {
- if (tv[i] != iv[i])
- return VLIB_PARSE_MATCH_FAIL;
- }
-
- return iv[i] == 0 ? VLIB_PARSE_MATCH_FULL : VLIB_PARSE_MATCH_PARTIAL;
-}
-
-PARSE_TYPE_INIT (word, word_match, 0 /* clnup value */ ,
- 0 /* format value */ );
-
-vlib_parse_match_t
-number_match (vlib_parse_main_t * pm, vlib_parse_type_t * type,
- vlib_lex_token_t * t, vlib_parse_value_t * valuep)
-{
- if (t->token == VLIB_LEX_number)
- {
- valuep->value.as_uword = t->value.as_uword;
- return VLIB_PARSE_MATCH_VALUE;
- }
- return VLIB_PARSE_MATCH_FAIL;
-}
-
-static u8 *
-format_value_number (u8 * s, va_list * args)
-{
- vlib_parse_value_t *v = va_arg (*args, vlib_parse_value_t *);
- uword a = v->value.as_uword;
-
- if (BITS (uword) == 64)
- s = format (s, "%lld(0x%llx)", a, a);
- else
- s = format (s, "%ld(0x%lx)", a, a);
- return s;
-}
-
-PARSE_TYPE_INIT (number, number_match, 0 /* cln value */ ,
- format_value_number /* fmt value */ );
-
-
-#define foreach_vanilla_lex_match_function \
- _(plus) \
- _(minus) \
- _(star) \
- _(slash) \
- _(lpar) \
- _(rpar)
-
-#define LEX_MATCH_DEBUG 0
-
-#define _(name) \
-vlib_parse_match_t name##_match (vlib_parse_main_t *pm, \
- vlib_parse_type_t *type, \
- vlib_lex_token_t *t, \
- vlib_parse_value_t *valuep) \
-{ \
- if (LEX_MATCH_DEBUG > 0) \
- clib_warning ("against %U returns %s", \
- format_vlib_lex_token, pm->lex_main, t, \
- (t->token == VLIB_LEX_##name) \
- ? "VLIB_PARSE_MATCH_FULL" : \
- "VLIB_PARSE_MATCH_FAIL"); \
- if (t->token == VLIB_LEX_##name) \
- return VLIB_PARSE_MATCH_FULL; \
- return VLIB_PARSE_MATCH_FAIL; \
-} \
- \
-PARSE_TYPE_INIT (name, name##_match, 0 /* cln value */, \
- 0 /* fmt val */);
-
-foreach_vanilla_lex_match_function
-#undef _
-/* So we're linked in. */
-static clib_error_t *
-parse_builtin_init (vlib_main_t * vm)
-{
- return 0;
-}
-
-VLIB_INIT_FUNCTION (parse_builtin_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/ethernet/mac_swap.c b/src/vnet/ethernet/mac_swap.c
deleted file mode 100644
index c0fec12e61e..00000000000
--- a/src/vnet/ethernet/mac_swap.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vlib/vlib.h>
-#include <vnet/pg/pg.h>
-#include <vnet/ethernet/ethernet.h>
-#include <vppinfra/error.h>
-#include <vnet/devices/pci/ige.h>
-#include <vnet/devices/pci/ixge.h>
-#include <vnet/devices/pci/ixgev.h>
-
-typedef struct
-{
- u32 cached_next_index;
- u32 cached_sw_if_index;
-
- /* Hash table to map sw_if_index to next node index */
- uword *next_node_index_by_sw_if_index;
-
- /* convenience */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
-} mac_swap_main_t;
-
-typedef struct
-{
- u8 src[6];
- u8 dst[6];
- u32 sw_if_index;
- u32 next_index;
-} swap_trace_t;
-
-/* packet trace format function */
-static u8 *
-format_swap_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 *);
- swap_trace_t *t = va_arg (*args, swap_trace_t *);
-
- s = format (s, "SWAP: dst now %U src now %U sw_if_index %d next_index %d",
- format_ethernet_address, t->dst,
- format_ethernet_address, t->src, t->sw_if_index, t->next_index);
- return s;
-}
-
-#define foreach_hw_driver_next \
- _(IP4) \
- _(IP6) \
- _(ETHERNET)
-
-mac_swap_main_t mac_swap_main;
-
-static vlib_node_registration_t mac_swap_node;
-
-#define foreach_mac_swap_error \
-_(SWAPS, "mac addresses swapped")
-
-typedef enum
-{
-#define _(sym,str) MAC_SWAP_ERROR_##sym,
- foreach_mac_swap_error
-#undef _
- MAC_SWAP_N_ERROR,
-} mac_swap_error_t;
-
-static char *mac_swap_error_strings[] = {
-#define _(sym,string) string,
- foreach_mac_swap_error
-#undef _
-};
-
-/*
- * To drop a pkt and increment one of the previous counters:
- *
- * set b0->error = error_node->errors[RANDOM_ERROR_SAMPLE];
- * set next0 to a disposition index bound to "error-drop".
- *
- * To manually increment the specific counter MAC_SWAP_ERROR_SAMPLE:
- *
- * vlib_node_t *n = vlib_get_node (vm, mac_swap.index);
- * u32 node_counter_base_index = n->error_heap_index;
- * vlib_error_main_t * em = &vm->error_main;
- * em->counters[node_counter_base_index + MAC_SWAP_ERROR_SAMPLE] += 1;
- *
- */
-
-typedef enum
-{
- MAC_SWAP_NEXT_DROP,
- MAC_SWAP_N_NEXT,
-} mac_swap_next_t;
-
-static uword
-mac_swap_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next;
- mac_swap_next_t next_index;
- mac_swap_main_t *msm = &mac_swap_main;
- vlib_node_t *n = vlib_get_node (vm, mac_swap_node.index);
- u32 node_counter_base_index = n->error_heap_index;
- vlib_error_main_t *em = &vm->error_main;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- u32 bi0, bi1;
- vlib_buffer_t *b0, *b1;
- u32 next0, next1;
- u32 sw_if_index0, sw_if_index1;
- uword *p0, *p1;
- u64 tmp0a, tmp0b;
- u64 tmp1a, tmp1b;
- ethernet_header_t *h0, *h1;
-
-
- /* Prefetch next iteration. */
- {
- vlib_buffer_t *p2, *p3;
-
- p2 = vlib_get_buffer (vm, from[2]);
- p3 = vlib_get_buffer (vm, from[3]);
-
- vlib_prefetch_buffer_header (p2, LOAD);
- vlib_prefetch_buffer_header (p3, LOAD);
-
- CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE);
- }
-
- to_next[0] = bi0 = from[0];
- to_next[1] = bi1 = from[1];
- from += 2;
- to_next += 2;
- n_left_from -= 2;
- n_left_to_next -= 2;
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- next0 = msm->cached_next_index;
- sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
- next1 = msm->cached_next_index;
-
- if (PREDICT_FALSE (msm->cached_sw_if_index != sw_if_index0))
- {
- p0 =
- hash_get (msm->next_node_index_by_sw_if_index, sw_if_index0);
- if (p0 == 0)
- {
- vnet_hw_interface_t *hw0;
-
- hw0 = vnet_get_sup_hw_interface (msm->vnet_main,
- sw_if_index0);
-
- next0 = vlib_node_add_next (msm->vlib_main,
- mac_swap_node.index,
- hw0->output_node_index);
- hash_set (msm->next_node_index_by_sw_if_index,
- sw_if_index0, next0);
- }
- else
- next0 = p0[0];
- msm->cached_sw_if_index = sw_if_index0;
- msm->cached_next_index = next0;
- next1 = next0;
- }
- if (PREDICT_FALSE (msm->cached_sw_if_index != sw_if_index1))
- {
- p1 =
- hash_get (msm->next_node_index_by_sw_if_index, sw_if_index1);
- if (p1 == 0)
- {
- vnet_hw_interface_t *hw1;
-
- hw1 = vnet_get_sup_hw_interface (msm->vnet_main,
- sw_if_index1);
-
- next1 = vlib_node_add_next (msm->vlib_main,
- mac_swap_node.index,
- hw1->output_node_index);
- hash_set (msm->next_node_index_by_sw_if_index,
- sw_if_index1, next1);
- }
- else
- next1 = p1[0];
- msm->cached_sw_if_index = sw_if_index1;
- msm->cached_next_index = next1;
- }
-
- em->counters[node_counter_base_index + MAC_SWAP_ERROR_SWAPS] += 2;
-
- /* reset buffer so we always point at the MAC hdr */
- vlib_buffer_reset (b0);
- vlib_buffer_reset (b1);
- h0 = vlib_buffer_get_current (b0);
- h1 = vlib_buffer_get_current (b1);
-
- /* Swap 2 x src and dst mac addresses using 8-byte load/stores */
- tmp0a = clib_net_to_host_u64 (((u64 *) (h0->dst_address))[0]);
- tmp1a = clib_net_to_host_u64 (((u64 *) (h1->dst_address))[0]);
- tmp0b = clib_net_to_host_u64 (((u64 *) (h0->src_address))[0]);
- tmp1b = clib_net_to_host_u64 (((u64 *) (h1->src_address))[0]);
- ((u64 *) (h0->dst_address))[0] = clib_host_to_net_u64 (tmp0b);
- ((u64 *) (h1->dst_address))[0] = clib_host_to_net_u64 (tmp1b);
- /* Move the ethertype from "b" to "a" */
- tmp0a &= ~(0xFFFF);
- tmp1a &= ~(0xFFFF);
- tmp0a |= tmp0b & 0xFFFF;
- ((u64 *) (h0->src_address))[0] = clib_host_to_net_u64 (tmp0a);
- tmp1a |= tmp1b & 0xFFFF;
- ((u64 *) (h1->src_address))[0] = clib_host_to_net_u64 (tmp1a);
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
- {
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
- {
- swap_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- clib_memcpy (t->src, h0->src_address, 6);
- clib_memcpy (t->dst, h0->dst_address, 6);
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
- {
- swap_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- clib_memcpy (t->src, h1->src_address, 6);
- clib_memcpy (t->dst, h1->dst_address, 6);
- t->sw_if_index = sw_if_index1;
- t->next_index = next1;
- }
- }
-
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, bi1, next0, next1);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- u32 next0;
- u32 sw_if_index0;
- uword *p0;
- u64 tmp0a, tmp0b;
- ethernet_header_t *h0;
-
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- next0 = msm->cached_next_index;
-
- if (PREDICT_FALSE (msm->cached_sw_if_index != sw_if_index0))
- {
- p0 =
- hash_get (msm->next_node_index_by_sw_if_index, sw_if_index0);
- if (p0 == 0)
- {
- vnet_hw_interface_t *hw0;
-
- hw0 = vnet_get_sup_hw_interface (msm->vnet_main,
- sw_if_index0);
-
- next0 = vlib_node_add_next (msm->vlib_main,
- mac_swap_node.index,
- hw0->output_node_index);
- hash_set (msm->next_node_index_by_sw_if_index,
- sw_if_index0, next0);
- }
- else
- next0 = p0[0];
- msm->cached_sw_if_index = sw_if_index0;
- msm->cached_next_index = next0;
- }
-
- em->counters[node_counter_base_index + MAC_SWAP_ERROR_SWAPS] += 1;
-
- /* reset buffer so we always point at the MAC hdr */
- vlib_buffer_reset (b0);
- h0 = vlib_buffer_get_current (b0);
-
- /* Exchange src and dst, preserve the ethertype */
- tmp0a = clib_net_to_host_u64 (((u64 *) (h0->dst_address))[0]);
- tmp0b = clib_net_to_host_u64 (((u64 *) (h0->src_address))[0]);
- ((u64 *) (h0->dst_address))[0] = clib_host_to_net_u64 (tmp0b);
- tmp0a &= ~(0xFFFF);
- tmp0a |= tmp0b & 0xFFFF;
- ((u64 *) (h0->src_address))[0] = clib_host_to_net_u64 (tmp0a);
-
- /* ship it */
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
- && (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- swap_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
- clib_memcpy (t->src, h0->src_address, 6);
- clib_memcpy (t->dst, h0->dst_address, 6);
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- return frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (mac_swap_node,static) = {
- .function = mac_swap_node_fn,
- .name = "mac-swap",
- .vector_size = sizeof (u32),
- .format_trace = format_swap_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
-
- .n_errors = ARRAY_LEN(mac_swap_error_strings),
- .error_strings = mac_swap_error_strings,
-
- .n_next_nodes = MAC_SWAP_N_NEXT,
-
- /* edit / add dispositions here */
- .next_nodes = {
- [MAC_SWAP_NEXT_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-clib_error_t *
-mac_swap_init (vlib_main_t * vm)
-{
- mac_swap_main_t *msm = &mac_swap_main;
-
- msm->next_node_index_by_sw_if_index = hash_create (0, sizeof (uword));
- msm->cached_next_index = (u32) ~ 0;
- msm->cached_sw_if_index = (u32) ~ 0;
- msm->vlib_main = vm;
- msm->vnet_main = vnet_get_main ();
-
- /* Driver RX nodes send pkts here... */
-#define _(a) ixge_set_next_node (IXGE_RX_NEXT_##a##_INPUT, "mac-swap");
- foreach_hw_driver_next
-#undef _
-#define _(a) ixgev_set_next_node (IXGEV_RX_NEXT_##a##_INPUT, "mac-swap");
- foreach_hw_driver_next
-#undef _
-#define _(a) ige_set_next_node (IGE_RX_NEXT_##a##_INPUT, "mac-swap");
- foreach_hw_driver_next
-#undef _
- return 0;
-}
-
-VLIB_INIT_FUNCTION (mac_swap_init);
-
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/ip/ip4_test.c b/src/vnet/ip/ip4_test.c
deleted file mode 100644
index 73dabfdc23a..00000000000
--- a/src/vnet/ip/ip4_test.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vnet/ip/ip.h>
-#include <vnet/ethernet/ethernet.h>
-
-/**
- * @file
- * @brief IPv4 FIB Tester.
- *
- * Not compiled in by default. IPv4 FIB tester. Add, probe, delete a bunch of
- * random routes / masks and make sure that the mtrie agrees with
- * the hash-table FIB.
- *
- * Manipulate the FIB by means of the debug CLI commands, to minimize
- * the chances of doing something idiotic.
- */
-
-/*
- * These routines need to be redeclared non-static elsewhere.
- *
- * Also: rename ip_route() -> vnet_ip_route_cmd() and add the usual
- * test_route_init() call to main.c
- */
-clib_error_t *vnet_ip_route_cmd (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd_arg);
-
-int ip4_lookup_validate (ip4_address_t * a, u32 fib_index0);
-
-ip4_fib_t *find_fib_by_table_index_or_id (ip4_main_t * im,
- u32 table_index_or_id, u32 flags);
-
-/* Routes to insert/delete/probe in FIB */
-typedef struct
-{
- ip4_address_t address;
- u32 mask_width;
- u32 interface_id; /* not an xx_if_index */
-} test_route_t;
-
-typedef struct
-{
- /* Test routes in use */
- test_route_t *route_pool;
-
- /* Number of fake ethernets created */
- u32 test_interfaces_created;
-} test_main_t;
-
-test_main_t test_main;
-
-/* fake ethernet device class, distinct from "fake-ethX" */
-static u8 *
-format_test_interface_name (u8 * s, va_list * args)
-{
- u32 dev_instance = va_arg (*args, u32);
- return format (s, "test-eth%d", dev_instance);
-}
-
-static uword
-dummy_interface_tx (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
-{
- clib_warning ("you shouldn't be here, leaking buffers...");
- return frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VNET_DEVICE_CLASS (test_interface_device_class,static) = {
- .name = "Test interface",
- .format_device_name = format_test_interface_name,
- .tx_function = dummy_interface_tx,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-thrash (vlib_main_t * vm,
- unformat_input_t * main_input, vlib_cli_command_t * cmd_arg)
-{
- u32 seed = 0xdeaddabe;
- u32 niter = 10;
- u32 nroutes = 10;
- u32 ninterfaces = 4;
- f64 min_mask_bits = 7.0;
- f64 max_mask_bits = 32.0;
- u32 table_id = 11; /* my amp goes to 11 (use fib 11) */
- u32 table_index;
- int iter, i;
- u8 *cmd;
- test_route_t *tr;
- test_main_t *tm = &test_main;
- ip4_main_t *im = &ip4_main;
- vnet_main_t *vnm = vnet_get_main ();
- unformat_input_t cmd_input;
- f64 rf;
- u32 *masks = 0;
- u32 tmp;
- u32 hw_if_index;
- clib_error_t *error = 0;
- uword *p;
- unformat_input_t _line_input, *line_input = &_line_input;
- u8 hw_address[6];
- ip4_fib_t *fib;
- int verbose = 0;
-
- /* Precompute mask width -> mask vector */
- tmp = (u32) ~ 0;
- vec_validate (masks, 32);
- for (i = 32; i > 0; i--)
- {
- masks[i] = tmp;
- tmp <<= 1;
- }
-
- if (unformat_user (main_input, unformat_line_input, line_input))
- {
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "seed %d", &seed))
- ;
- else if (unformat (line_input, "niter %d", &niter))
- ;
- else if (unformat (line_input, "nroutes %d", &nroutes))
- ;
- else if (unformat (line_input, "ninterfaces %d", &ninterfaces))
- ;
- else if (unformat (line_input, "min-mask-bits %d", &tmp))
- min_mask_bits = (f64) tmp;
- else if (unformat (line_input, "max-mask-bits %d", &tmp))
- max_mask_bits = (f64) tmp;
- else if (unformat (line_input, "verbose"))
- verbose = 1;
- else
- {
- error = clib_error_return (0, "unknown input `%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
- }
-
- /* Find or create FIB table 11 */
- fib = ip4_fib_find_or_create_fib_by_table_id (table_id);
-
- for (i = tm->test_interfaces_created; i < ninterfaces; i++)
- {
- vnet_hw_interface_t *hw;
- memset (hw_address, 0, sizeof (hw_address));
- hw_address[0] = 0xd0;
- hw_address[1] = 0x0f;
- hw_address[5] = i;
-
- error = ethernet_register_interface
- (vnm, test_interface_device_class.index, i /* instance */ ,
- hw_address, &hw_if_index,
- /* flag change */ 0);
-
- /* Fake interfaces use FIB table 11 */
- hw = vnet_get_hw_interface (vnm, hw_if_index);
- vec_validate (im->fib_index_by_sw_if_index, hw->sw_if_index);
- im->fib_index_by_sw_if_index[hw->sw_if_index] = fib->index;
- ip4_sw_interface_enable_disable (sw_if_index, 1);
- }
-
- tm->test_interfaces_created = ninterfaces;
-
- /* Find fib index corresponding to FIB id 11 */
- p = hash_get (im->fib_index_by_table_id, table_id);
- if (p == 0)
- {
- vlib_cli_output (vm, "Couldn't map fib id %d to fib index\n", table_id);
- goto done;
- }
- table_index = p[0];
-
- for (iter = 0; iter < niter; iter++)
- {
- /* Pick random routes to install */
- for (i = 0; i < nroutes; i++)
- {
- int j;
-
- pool_get (tm->route_pool, tr);
- memset (tr, 0, sizeof (*tr));
-
- again:
- rf = random_f64 (&seed);
- tr->mask_width = (u32) (min_mask_bits
- + rf * (max_mask_bits - min_mask_bits));
- tmp = random_u32 (&seed);
- tmp &= masks[tr->mask_width];
- tr->address.as_u32 = clib_host_to_net_u32 (tmp);
-
- /* We can't add the same address/mask twice... */
- for (j = 0; j < i; j++)
- {
- test_route_t *prev;
- prev = pool_elt_at_index (tm->route_pool, j);
- if ((prev->address.as_u32 == tr->address.as_u32)
- && (prev->mask_width == tr->mask_width))
- goto again;
- }
-
- rf = random_f64 (&seed);
- tr->interface_id = (u32) (rf * ninterfaces);
- }
-
- /* Add them */
- for (i = 0; i < nroutes; i++)
- {
- tr = pool_elt_at_index (tm->route_pool, i);
- cmd = format (0, "add table %d %U/%d via test-eth%d",
- table_id,
- format_ip4_address, &tr->address,
- tr->mask_width, tr->interface_id);
- vec_add1 (cmd, 0);
- if (verbose)
- fformat (stderr, "ip route %s\n", cmd);
- unformat_init_string (&cmd_input, (char *) cmd, vec_len (cmd) - 1);
- error = vnet_ip_route_cmd (vm, &cmd_input, cmd_arg);
- if (error)
- clib_error_report (error);
- unformat_free (&cmd_input);
- vec_free (cmd);
- }
- /* Probe them */
- for (i = 0; i < nroutes; i++)
- {
- tr = pool_elt_at_index (tm->route_pool, i);
- if (!ip4_lookup_validate (&tr->address, table_index))
- {
- if (verbose)
- fformat (stderr, "test lookup table %d %U\n",
- table_index, format_ip4_address, &tr->address);
-
- fformat (stderr, "FAIL-after-insert: %U/%d\n",
- format_ip4_address, &tr->address, tr->mask_width);
- }
- }
-
- /* Delete them */
- for (i = 0; i < nroutes; i++)
- {
- int j;
- tr = pool_elt_at_index (tm->route_pool, i);
- if (0)
- cmd = format (0, "del table %d %U/%d via test-eth%d",
- table_id,
- format_ip4_address, &tr->address,
- tr->mask_width, tr->interface_id);
- else
- cmd = format (0, "del table %d %U/%d",
- table_id,
- format_ip4_address, &tr->address, tr->mask_width);
- vec_add1 (cmd, 0);
- if (verbose)
- fformat (stderr, "ip route %s\n", cmd);
- unformat_init_string (&cmd_input, (char *) cmd, vec_len (cmd) - 1);
- error = vnet_ip_route_cmd (vm, &cmd_input, cmd_arg);
- if (error)
- clib_error_report (error);
- unformat_free (&cmd_input);
- vec_free (cmd);
-
- /* Make sure all undeleted routes still work */
- for (j = i + 1; j < nroutes; j++)
- {
- test_route_t *rr; /* remaining route */
- rr = pool_elt_at_index (tm->route_pool, j);
- if (!ip4_lookup_validate (&rr->address, table_index))
- {
- if (verbose)
- fformat (stderr, "test lookup table %d %U\n",
- table_index, format_ip4_address, &rr->address);
-
- fformat (stderr, "FAIL: %U/%d AWOL\n",
- format_ip4_address, &rr->address, rr->mask_width);
- fformat (stderr, " iter %d after %d of %d deletes\n",
- iter, i, nroutes);
- fformat (stderr, " last route deleted %U/%d\n",
- format_ip4_address, &tr->address, tr->mask_width);
- }
- }
- }
-
- pool_free (tm->route_pool);
- }
-
-done:
- unformat_free (line_input);
-
- return error;
-}
-
-/*?
- * This command in not in the build by default. It is an internal
- * command used to test the route functonality.
- *
- * Create test routes on IPv4 FIB table 11. Table will be created if it
- * does not exist.
- *
- * There are several optional attributes:
- * - If not provided, <seed> defaults to 0xdeaddabe.
- * - If not provided, <num-iter> defaults to 10.
- * - If not provided, <num-iface> defaults to 4.
- * - If not provided, <min-mask> defaults to 7.0.
- * - If not provided, <max-mask> defaults to 32.0.
- *
- * @cliexpar
- * Example of how to run:
- * @cliexcmd{test route}
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (test_route_command, static) = {
- .path = "test route",
- .short_help = "test route [seed <seed-num>] [niter <num-iter>] [ninterfaces <num-iface>] [min-mask-bits <min-mask>] [max-mask-bits <max-mask>] [verbose]", .function = thrash,
- .function = thrash,
-};
-/* *INDENT-ON* */
-
-clib_error_t *
-test_route_init (vlib_main_t * vm)
-{
- return 0;
-}
-
-VLIB_INIT_FUNCTION (test_route_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vpp/app/sticky_hash.c b/src/vpp/app/sticky_hash.c
deleted file mode 100644
index 5569c6770e6..00000000000
--- a/src/vpp/app/sticky_hash.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vnet/l2/l2_classify.h>
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
-#include <vnet/ip/ip.h>
-#include <vnet/ip/ip_packet.h>
-#include <vnet/ip/ip4_packet.h>
-#include <vnet/ip/ip6_packet.h>
-#include <vppinfra/error.h>
-
-typedef struct
-{
- u32 fwd_entry_index;
- u32 rev_entry_index;
- /* Not strictly needed, for show command */
- u32 fib_index;
-} sticky_hash_session_t;
-
-typedef struct
-{
- u32 cached_next_index;
-
- /* next index added to l2_classify */
- u32 fwd_miss_next_index;
-
- /* session pool */
- sticky_hash_session_t *sessions;
-
- /* Forward and reverse data session setup buffers */
- u8 fdata[3 * sizeof (u32x4)];
- u8 rdata[3 * sizeof (u32x4)];
-
- /* convenience variables */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
- vnet_classify_main_t *vnet_classify_main;
- l2_input_classify_main_t *l2_input_classify_main;
-}
-sticky_hash_main_t;
-
-typedef struct
-{
- /* $$$$ fill in with per-pkt trace data */
- u32 next_index;
- u32 sw_if_index;
-} sticky_hash_miss_trace_t;
-
-/* packet trace format function */
-static u8 *
-format_sticky_hash_miss_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 *);
- sticky_hash_miss_trace_t *t = va_arg (*args, sticky_hash_miss_trace_t *);
-
- s = format (s, "STICKY_HASH_MISS: sw_if_index %d", t->sw_if_index);
- return s;
-}
-
-typedef CLIB_PACKED (struct
- {
- ethernet_header_t eh; ip4_header_t ip;
- }) classify_data_or_mask_t;
-
-sticky_hash_main_t sticky_hash_main;
-
-vlib_node_registration_t sticky_hash_miss_node;
-
-#define foreach_sticky_hash_miss_error \
-_(MISSES, "forward flow classify misses")
-
-typedef enum
-{
-#define _(sym,str) STICKY_HASH_MISS_ERROR_##sym,
- foreach_sticky_hash_miss_error
-#undef _
- STICKY_HASH_MISS_N_ERROR,
-} sticky_hash_miss_error_t;
-
-static char *sticky_hash_miss_error_strings[] = {
-#define _(sym,string) string,
- foreach_sticky_hash_miss_error
-#undef _
-};
-
-/*
- * To drop a pkt and increment one of the previous counters:
- *
- * set b0->error = error_node->errors[STICKY_HASH_MISS_ERROR_EXAMPLE];
- * set next0 to a disposition index bound to "error-drop".
- *
- * To manually increment the specific counter STICKY_HASH_MISS_ERROR_EXAMPLE:
- *
- * vlib_node_t *n = vlib_get_node (vm, sticky_hash_miss.index);
- * u32 node_counter_base_index = n->error_heap_index;
- * vlib_error_main_t * em = &vm->error_main;
- * em->counters[node_counter_base_index + STICKY_HASH_MISS_ERROR_EXAMPLE] += 1;
- *
- */
-
-typedef enum
-{
- STICKY_HASH_MISS_NEXT_IP4_INPUT,
- STICKY_HASH_MISS_N_NEXT,
-} sticky_hash_miss_next_t;
-
-static uword
-sticky_hash_miss_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next;
- sticky_hash_miss_next_t next_index;
- sticky_hash_main_t *mp = &sticky_hash_main;
- vlib_node_t *n = vlib_get_node (vm, sticky_hash_miss_node.index);
- u32 node_counter_base_index = n->error_heap_index;
- vlib_error_main_t *em = &vm->error_main;
- vnet_classify_main_t *cm = mp->vnet_classify_main;
- ip4_main_t *im = &ip4_main;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- u32 next0;
- u32 sw_if_index0;
- u32 fib_index0, ft_index0, rt_index0;
- vnet_classify_table_3_t *ft0, *rt0;
- vnet_classify_entry_3_t *fe0, *re0;
- classify_data_or_mask_t *h0;
- u8 was_found0;
- ip4_fib_t *fib0;
- sticky_hash_session_t *s;
- u32 tmp;
-
- /* speculatively enqueue b0 to the current next frame */
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- next0 = mp->cached_next_index;
-
- h0 = vlib_buffer_get_current (b0);
-
- /* Add forward and reverse entries for this flow */
- clib_memcpy (mp->fdata, h0, sizeof (mp->fdata));
- clib_memcpy (mp->rdata, h0, sizeof (mp->rdata));
-
- h0 = (classify_data_or_mask_t *) (mp->rdata);
-
- /* swap src + dst addresses to form reverse data */
- tmp = h0->ip.src_address.as_u32;
- h0->ip.src_address.as_u32 = h0->ip.dst_address.as_u32;
- h0->ip.dst_address.as_u32 = tmp;
-
- /* dig up fwd + rev tables */
- fib_index0 = vec_elt (im->fib_index_by_sw_if_index, sw_if_index0);
- fib0 = vec_elt_at_index (im->fibs, fib_index0);
-
- ft_index0 = fib0->fwd_classify_table_index;
- rt_index0 = fib0->rev_classify_table_index;
-
- ft0 = (vnet_classify_table_3_t *)
- pool_elt_at_index (cm->tables, ft_index0);
- rt0 = (vnet_classify_table_3_t *)
- pool_elt_at_index (cm->tables, rt_index0);
-
- fe0 =
- vnet_classify_find_or_add_entry_3 (ft0, mp->fdata, &was_found0);
- fe0->next_index = L2_INPUT_CLASSIFY_NEXT_IP4_INPUT;
- fe0->advance = sizeof (ethernet_header_t);
-
- re0 = vnet_classify_find_or_add_entry_3 (rt0, mp->rdata, 0);
- re0->next_index = L2_INPUT_CLASSIFY_NEXT_IP4_INPUT; /* $$$ FIXME */
- re0->advance = sizeof (ethernet_header_t);
-
- /* Note: we could get a whole vector of misses for the same sess */
- if (was_found0 == 0)
- {
- pool_get (mp->sessions, s);
-
- fe0->opaque_index = s - mp->sessions;
- re0->opaque_index = s - mp->sessions;
-
- s->fwd_entry_index = fe0 - ft0->entries;
- s->rev_entry_index = re0 - rt0->entries;
- s->fib_index = fib_index0;
- }
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
- && (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- sticky_hash_miss_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
-
- em->counters[node_counter_base_index +
- STICKY_HASH_MISS_ERROR_MISSES] += 1;
-
- vlib_buffer_advance (b0, sizeof (ethernet_header_t));
-
- /* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- return frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (sticky_hash_miss_node) = {
- .function = sticky_hash_miss_node_fn,
- .name = "sticky-hash-miss",
- .vector_size = sizeof (u32),
- .format_trace = format_sticky_hash_miss_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
-
- .n_errors = ARRAY_LEN(sticky_hash_miss_error_strings),
- .error_strings = sticky_hash_miss_error_strings,
-
- .n_next_nodes = STICKY_HASH_MISS_N_NEXT,
-
- /* edit / add dispositions here */
- .next_nodes = {
- [STICKY_HASH_MISS_NEXT_IP4_INPUT] = "ip4-input",
- },
-};
-/* *INDENT-ON* */
-
-clib_error_t *
-sticky_hash_miss_init (vlib_main_t * vm)
-{
- sticky_hash_main_t *mp = &sticky_hash_main;
-
- mp->vlib_main = vm;
- mp->vnet_main = vnet_get_main ();
- mp->vnet_classify_main = &vnet_classify_main;
- mp->l2_input_classify_main = &l2_input_classify_main;
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (sticky_hash_miss_init);
-
-static int ip4_sticky_hash_enable_disable
- (sticky_hash_main_t * mp,
- u32 fwd_sw_if_index, u8 * fwd_mask,
- u32 rev_sw_if_index, u8 * rev_mask, u32 nbuckets, int enable_disable)
-{
- ip4_main_t *im = &ip4_main;
- u32 fib_index;
- ip4_fib_t *fib;
- vnet_classify_main_t *cm = mp->vnet_classify_main;
- l2_input_classify_main_t *l2cm = mp->l2_input_classify_main;
- vnet_classify_table_3_t *ft, *rt;
-
- fib_index = vec_elt (im->fib_index_by_sw_if_index, fwd_sw_if_index);
- fib = vec_elt_at_index (im->fibs, fib_index);
-
- if (fib->fwd_classify_table_index == ~0)
- {
- /* Set up forward table */
- ft = (vnet_classify_table_3_t *)
- vnet_classify_new_table (cm, fwd_mask, nbuckets,
- 0 /* skip */ , 3 /* match */ );
- fib->fwd_classify_table_index
- = ft - (vnet_classify_table_3_t *) cm->tables;
- mp->fwd_miss_next_index =
- vlib_node_add_next (mp->vlib_main, l2_input_classify_node.index,
- sticky_hash_miss_node.index);
- ft->miss_next_index = mp->fwd_miss_next_index;
-
- /* Set up reverse table */
- rt = (vnet_classify_table_3_t *)
- vnet_classify_new_table (cm, rev_mask, nbuckets,
- 0 /* skip */ , 3 /* match */ );
- fib->rev_classify_table_index
- = rt - (vnet_classify_table_3_t *) cm->tables;
- }
-
- vec_validate
- (l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP4],
- fwd_sw_if_index);
-
- vec_validate
- (l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP6],
- fwd_sw_if_index);
-
- vec_validate
- (l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_OTHER],
- fwd_sw_if_index);
-
- l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP4]
- [fwd_sw_if_index] = fib->fwd_classify_table_index;
-
- l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP6]
- [fwd_sw_if_index] = ~0;
-
- l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_OTHER]
- [fwd_sw_if_index] = ~0;
-
-
- vec_validate
- (l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP4],
- rev_sw_if_index);
-
- vec_validate
- (l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP6],
- rev_sw_if_index);
-
- vec_validate
- (l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_OTHER],
- rev_sw_if_index);
-
-
- l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP4]
- [rev_sw_if_index] = fib->rev_classify_table_index;
-
- l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_IP6]
- [rev_sw_if_index] = ~0;
-
- l2cm->classify_table_index_by_sw_if_index[L2_INPUT_CLASSIFY_TABLE_OTHER]
- [rev_sw_if_index] = ~0;
-
- vnet_l2_input_classify_enable_disable (fwd_sw_if_index, enable_disable);
- vnet_l2_input_classify_enable_disable (rev_sw_if_index, enable_disable);
- return 0;
-}
-
-static clib_error_t *
-ip4_sticky_hash_init_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- u32 fwd_sw_if_index = ~0, rev_sw_if_index = ~0;
- int enable_disable = 1;
- u32 nbuckets = 2;
- int rv;
- sticky_hash_main_t *mp = &sticky_hash_main;
- classify_data_or_mask_t fwd_mask, rev_mask;
- u8 *fm = 0, *rm = 0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (input, "fwd %U", unformat_vnet_sw_interface, mp->vnet_main,
- &fwd_sw_if_index))
- ;
- if (unformat
- (input, "rev %U", unformat_vnet_sw_interface, mp->vnet_main,
- &rev_sw_if_index))
- ;
- else if (unformat (input, "nbuckets %d", &nbuckets))
- ;
- else if (unformat (input, "disable"))
- enable_disable = 0;
-
- else
- break;
- }
-
- nbuckets = 1 << max_log2 (nbuckets);
-
- if (fwd_sw_if_index == ~0)
- return clib_error_return (0, "fwd interface not set");
-
- if (rev_sw_if_index == ~0)
- return clib_error_return (0, "rev interface not set");
-
- if (!is_pow2 (nbuckets))
- return clib_error_return (0, "nbuckets %d not a power of 2", nbuckets);
-
- ASSERT (sizeof (fwd_mask) <= 3 * sizeof (u32x4));
-
- /* Mask on src/dst address, depending on direction */
- memset (&fwd_mask, 0, sizeof (fwd_mask));
- memset (&fwd_mask.ip.src_address, 0xff, 4);
-
- memset (&rev_mask, 0, sizeof (rev_mask));
- memset (&rev_mask.ip.dst_address, 0xff, 4);
-
- vec_validate (fm, 3 * sizeof (u32x4) - 1);
- vec_validate (rm, 3 * sizeof (u32x4) - 1);
-
- clib_memcpy (fm, &fwd_mask, sizeof (fwd_mask));
- clib_memcpy (rm, &rev_mask, sizeof (rev_mask));
-
- rv = ip4_sticky_hash_enable_disable (mp, fwd_sw_if_index, fm,
- rev_sw_if_index, rm,
- nbuckets, enable_disable);
-
- vec_free (fm);
- vec_free (rm);
- switch (rv)
- {
- case 0:
- return 0;
-
- default:
- return clib_error_return (0,
- "ip4_sticky_hash_enable_disable returned %d",
- rv);
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (sticky_hash_init_command, static) = {
- .path = "ip sticky classify",
- .short_help = "ip sticky classify fwd <intfc> rev <intfc> "
- "[nbuckets <nn>][disable]",
- .function = ip4_sticky_hash_init_command_fn,
-};
-/* *INDENT-ON* */
-
-
-u8 *
-format_sticky_hash_session (u8 * s, va_list * args)
-{
- sticky_hash_main_t *mp = va_arg (*args, sticky_hash_main_t *);
- sticky_hash_session_t *session = va_arg (*args, sticky_hash_session_t *);
- vnet_classify_table_3_t *t;
- vnet_classify_entry_3_t *e;
- ip4_main_t *im = &ip4_main;
- vnet_classify_main_t *cm = mp->vnet_classify_main;
- ip4_fib_t *fib;
- classify_data_or_mask_t *match;
-
- fib = vec_elt_at_index (im->fibs, session->fib_index);
-
- t = (vnet_classify_table_3_t *)
- pool_elt_at_index (cm->tables, fib->fwd_classify_table_index);
- e = pool_elt_at_index (t->entries, session->fwd_entry_index);
- match = (classify_data_or_mask_t *) (e->key);
-
- s = format
- (s,
- "[%6d] fwd src %U next index %d session %d fib %d\n"
- " hits %lld last-heard %.6f\n",
- e - t->entries,
- format_ip4_address, &match->ip.src_address,
- e->next_index, e->opaque_index, fib->table_id, e->hits, e->last_heard);
-
- if (e->opaque_index != session - mp->sessions)
- s = format (s, "WARNING: forward session index mismatch!\n");
-
- t = (vnet_classify_table_3_t *)
- pool_elt_at_index (cm->tables, fib->rev_classify_table_index);
- e = pool_elt_at_index (t->entries, session->rev_entry_index);
- match = (classify_data_or_mask_t *) (e->key);
-
- s = format
- (s,
- "[%6d] rev dst %U next index %d session %d\n"
- " hits %lld last-heard %.6f\n",
- e - t->entries,
- format_ip4_address, &match->ip.dst_address,
- e->next_index, e->opaque_index, e->hits, e->last_heard);
-
- if (e->opaque_index != session - mp->sessions)
- s = format (s, "WARNING: reverse session index mismatch!\n");
- s = format (s, "---------\n");
-
- return s;
-}
-
-static clib_error_t *
-show_ip4_sticky_hash_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- sticky_hash_main_t *mp = &sticky_hash_main;
- sticky_hash_session_t *s;
- int verbose = 0;
- int dump_classifier_tables = 0;
- ip4_fib_t *fib;
- ip4_main_t *im4 = &ip4_main;
- vnet_classify_main_t *cm = mp->vnet_classify_main;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "verbose"))
- verbose = 1;
- else if (unformat (input, "dump-tables")
- || unformat (input, "dump-classifier-tables"))
- dump_classifier_tables = 1;
- else
- break;
- }
-
- if (pool_elts (mp->sessions) == 0)
- vlib_cli_output (vm, "No ip sticky hash sessions");
-
-
- vlib_cli_output (vm, "%d active sessions\n", pool_elts (mp->sessions));
-
- vec_foreach (fib, im4->fibs)
- {
- if (fib->fwd_classify_table_index != ~0)
- vlib_cli_output (vm, "fib %d fwd table: \n%U",
- fib->table_id,
- format_classify_table,
- cm,
- pool_elt_at_index
- (cm->tables, fib->fwd_classify_table_index),
- dump_classifier_tables);
- if (fib->rev_classify_table_index != ~0)
- vlib_cli_output (vm, "fib %d rev table: \n%U",
- fib->table_id,
- format_classify_table,
- cm,
- pool_elt_at_index
- (cm->tables, fib->rev_classify_table_index),
- dump_classifier_tables);
- }
-
- if (verbose)
- {
- /* *INDENT-OFF* */
- pool_foreach (s, mp->sessions,
- ({
- vlib_cli_output (vm, "%U", format_sticky_hash_session, mp, s);
- }));
- /* *INDENT-ON* */
- }
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (show_sticky_hash_command, static) = {
- .path = "show sticky classify",
- .short_help = "Display sticky classifier tables",
- .function = show_ip4_sticky_hash_command_fn,
-};
-/* *INDENT-ON* */
-
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vppinfra/mod_test_hash.c b/src/vppinfra/mod_test_hash.c
deleted file mode 100644
index b3fa676d2e2..00000000000
--- a/src/vppinfra/mod_test_hash.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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 <vppinfra/linux_kernel_init.h>
-#include <vppinfra/hash.h>
-
-CLIB_LINUX_KERNEL_MODULE ("test_hash", test_hash_main,
- /* kernel-thread flags */ 0 & CLONE_KERNEL);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vppinfra/pfhash.c b/src/vppinfra/pfhash.c
deleted file mode 100644
index 3b9fa8f34aa..00000000000
--- a/src/vppinfra/pfhash.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- Copyright (c) 2013 Cisco 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 <vppinfra/pfhash.h>
-#include <vppinfra/format.h>
-
-/* This is incredibly handy when debugging */
-u32 vl (void *v) __attribute__ ((weak));
-u32
-vl (void *v)
-{
- return vec_len (v);
-}
-
-#if defined(CLIB_HAVE_VEC128) && ! defined (__ALTIVEC__)
-
-typedef struct
-{
- u8 *key[16];
- u64 value;
-} pfhash_show_t;
-
-static int
-sh_compare (pfhash_show_t * sh0, pfhash_show_t * sh1)
-{
- return ((i32) (sh0->value) - ((i32) sh1->value));
-}
-
-u8 *
-format_pfhash (u8 * s, va_list * args)
-{
- pfhash_t *p = va_arg (*args, pfhash_t *);
- int verbose = va_arg (*args, int);
-
- if (p == 0 || p->overflow_hash == 0 || p->buckets == 0)
- {
- s = format (s, "*** uninitialized ***");
- return s;
- }
-
- s = format (s, "Prefetch hash '%s'\n", p->name);
- s =
- format (s, " %d buckets, %u bucket overflows, %.1f%% bucket overflow \n",
- vec_len (p->buckets), p->overflow_count,
- 100.0 * ((f64) p->overflow_count) / ((f64) vec_len (p->buckets)));
- if (p->nitems)
- s =
- format (s,
- " %u items, %u items in overflow, %.1f%% items in overflow\n",
- p->nitems, p->nitems_in_overflow,
- 100.0 * ((f64) p->nitems_in_overflow) / ((f64) p->nitems));
-
- if (verbose)
- {
- pfhash_show_t *shs = 0, *sh;
- hash_pair_t *hp;
- int i, j;
-
- for (i = 0; i < vec_len (p->buckets); i++)
- {
- pfhash_kv_t *kv;
- pfhash_kv_16_t *kv16;
- pfhash_kv_8_t *kv8;
- pfhash_kv_8v8_t *kv8v8;
- pfhash_kv_4_t *kv4;
-
- if (p->buckets[i] == 0 || p->buckets[i] == PFHASH_BUCKET_OVERFLOW)
- continue;
-
- kv = pool_elt_at_index (p->kvp, p->buckets[i]);
-
- switch (p->key_size)
- {
- case 16:
- kv16 = &kv->kv16;
- for (j = 0; j < 3; j++)
- {
- if (kv16->values[j] != (u32) ~ 0)
- {
- vec_add2 (shs, sh, 1);
- clib_memcpy (sh->key, &kv16->kb.k_u32x4[j],
- p->key_size);
- sh->value = kv16->values[j];
- }
- }
- break;
- case 8:
- if (p->value_size == 4)
- {
- kv8 = &kv->kv8;
- for (j = 0; j < 5; j++)
- {
- if (kv8->values[j] != (u32) ~ 0)
- {
- vec_add2 (shs, sh, 1);
- clib_memcpy (sh->key, &kv8->kb.k_u64[j],
- p->key_size);
- sh->value = kv8->values[j];
- }
- }
- }
- else
- {
- kv8v8 = &kv->kv8v8;
- for (j = 0; j < 4; j++)
- {
- if (kv8v8->values[j] != (u64) ~ 0)
- {
- vec_add2 (shs, sh, 1);
- clib_memcpy (sh->key, &kv8v8->kb.k_u64[j],
- p->key_size);
- sh->value = kv8v8->values[j];
- }
- }
-
- }
- break;
- case 4:
- kv4 = &kv->kv4;
- for (j = 0; j < 8; j++)
- {
- if (kv4->values[j] != (u32) ~ 0)
- {
- vec_add2 (shs, sh, 1);
- clib_memcpy (sh->key, &kv4->kb.kb[j], p->key_size);
- sh->value = kv4->values[j];
- }
- }
- break;
- }
- }
-
- /* *INDENT-OFF* */
- hash_foreach_pair (hp, p->overflow_hash,
- ({
- vec_add2 (shs, sh, 1);
- clib_memcpy (sh->key, (u8 *)hp->key, p->key_size);
- sh->value = hp->value[0];
- }));
- /* *INDENT-ON* */
-
- vec_sort_with_function (shs, sh_compare);
-
- for (i = 0; i < vec_len (shs); i++)
- {
- sh = vec_elt_at_index (shs, i);
- s = format (s, " %U value %u\n", format_hex_bytes, sh->key,
- p->key_size, sh->value);
- }
- vec_free (shs);
- }
- return s;
-}
-
-
-void abort (void);
-
-void
-pfhash_init (pfhash_t * p, char *name, u32 key_size, u32 value_size,
- u32 nbuckets)
-{
- pfhash_kv_t *kv;
- memset (p, 0, sizeof (*p));
- u32 key_bytes;
-
- switch (key_size)
- {
- case 4:
- key_bytes = 4;
- break;
- case 8:
- key_bytes = 8;
- break;
- case 16:
- key_bytes = 16;
- break;
- default:
- ASSERT (0);
- abort ();
- }
-
- switch (value_size)
- {
- case 4:
- case 8:
- break;
- default:
- ASSERT (0);
- abort ();
- }
-
-
- p->name = format (0, "%s", name);
- vec_add1 (p->name, 0);
- p->overflow_hash = hash_create_mem (0, key_bytes, sizeof (uword));
-
- nbuckets = 1 << (max_log2 (nbuckets));
-
- /* This sets the entire bucket array to zero */
- vec_validate (p->buckets, nbuckets - 1);
- p->key_size = key_size;
- p->value_size = value_size;
-
- /*
- * Unset buckets implicitly point at the 0th pool elt.
- * All search routines will return ~0 if they go there.
- */
- pool_get_aligned (p->kvp, kv, 16);
- memset (kv, 0xff, sizeof (*kv));
-}
-
-static pfhash_kv_16_t *
-pfhash_get_kv_16 (pfhash_t * p, u32 bucket_contents,
- u32x4 * key, u32 * match_index)
-{
- u32x4 diff[3];
- u32 is_equal[3];
- pfhash_kv_16_t *kv = 0;
-
- *match_index = (u32) ~ 0;
-
- kv = &p->kvp[bucket_contents].kv16;
-
- diff[0] = u32x4_sub (kv->kb.k_u32x4[0], key[0]);
- diff[1] = u32x4_sub (kv->kb.k_u32x4[1], key[0]);
- diff[2] = u32x4_sub (kv->kb.k_u32x4[2], key[0]);
-
- is_equal[0] = u32x4_zero_byte_mask (diff[0]) == 0xffff;
- is_equal[1] = u32x4_zero_byte_mask (diff[1]) == 0xffff;
- is_equal[2] = u32x4_zero_byte_mask (diff[2]) == 0xffff;
-
- if (is_equal[0])
- *match_index = 0;
- if (is_equal[1])
- *match_index = 1;
- if (is_equal[2])
- *match_index = 2;
-
- return kv;
-}
-
-static pfhash_kv_8_t *
-pfhash_get_kv_8 (pfhash_t * p, u32 bucket_contents,
- u64 * key, u32 * match_index)
-{
- pfhash_kv_8_t *kv;
-
- *match_index = (u32) ~ 0;
-
- kv = &p->kvp[bucket_contents].kv8;
-
- if (kv->kb.k_u64[0] == key[0])
- *match_index = 0;
- if (kv->kb.k_u64[1] == key[0])
- *match_index = 1;
- if (kv->kb.k_u64[2] == key[0])
- *match_index = 2;
- if (kv->kb.k_u64[3] == key[0])
- *match_index = 3;
- if (kv->kb.k_u64[4] == key[0])
- *match_index = 4;
-
- return kv;
-}
-
-static pfhash_kv_8v8_t *
-pfhash_get_kv_8v8 (pfhash_t * p,
- u32 bucket_contents, u64 * key, u32 * match_index)
-{
- pfhash_kv_8v8_t *kv;
-
- *match_index = (u32) ~ 0;
-
- kv = &p->kvp[bucket_contents].kv8v8;
-
- if (kv->kb.k_u64[0] == key[0])
- *match_index = 0;
- if (kv->kb.k_u64[1] == key[0])
- *match_index = 1;
- if (kv->kb.k_u64[2] == key[0])
- *match_index = 2;
- if (kv->kb.k_u64[3] == key[0])
- *match_index = 3;
-
- return kv;
-}
-
-static pfhash_kv_4_t *
-pfhash_get_kv_4 (pfhash_t * p, u32 bucket_contents,
- u32 * key, u32 * match_index)
-{
- u32x4 vector_key;
- u32x4 is_equal[2];
- u32 zbm[2], winner_index;
- pfhash_kv_4_t *kv;
-
- *match_index = (u32) ~ 0;
-
- kv = &p->kvp[bucket_contents].kv4;
-
- vector_key = u32x4_splat (key[0]);
-
- is_equal[0] = u32x4_is_equal (kv->kb.k_u32x4[0], vector_key);
- is_equal[1] = u32x4_is_equal (kv->kb.k_u32x4[1], vector_key);
- zbm[0] = ~u32x4_zero_byte_mask (is_equal[0]) & 0xFFFF;
- zbm[1] = ~u32x4_zero_byte_mask (is_equal[1]) & 0xFFFF;
-
- if (PREDICT_FALSE ((zbm[0] == 0) && (zbm[1] == 0)))
- return kv;
-
- winner_index = min_log2 (zbm[0]) >> 2;
- winner_index = zbm[1] ? (4 + (min_log2 (zbm[1]) >> 2)) : winner_index;
-
- *match_index = winner_index;
- return kv;
-}
-
-static pfhash_kv_t *
-pfhash_get_internal (pfhash_t * p, u32 bucket_contents,
- void *key, u32 * match_index)
-{
- pfhash_kv_t *kv = 0;
-
- switch (p->key_size)
- {
- case 16:
- kv =
- (pfhash_kv_t *) pfhash_get_kv_16 (p, bucket_contents, key,
- match_index);
- break;
- case 8:
- if (p->value_size == 4)
- kv = (pfhash_kv_t *) pfhash_get_kv_8 (p, bucket_contents,
- key, match_index);
- else
- kv = (pfhash_kv_t *) pfhash_get_kv_8v8 (p, bucket_contents,
- key, match_index);
- break;
- case 4:
- kv =
- (pfhash_kv_t *) pfhash_get_kv_4 (p, bucket_contents, key,
- match_index);
- break;
- default:
- ASSERT (0);
- }
- return kv;
-}
-
-u64
-pfhash_get (pfhash_t * p, u32 bucket, void *key)
-{
- pfhash_kv_t *kv;
- u32 match_index = ~0;
- pfhash_kv_16_t *kv16;
- pfhash_kv_8_t *kv8;
- pfhash_kv_8v8_t *kv8v8;
- pfhash_kv_4_t *kv4;
-
- u32 bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
-
- if (bucket_contents == PFHASH_BUCKET_OVERFLOW)
- {
- uword *hp;
-
- hp = hash_get_mem (p->overflow_hash, key);
- if (hp)
- return hp[0];
- return (u64) ~ 0;
- }
-
- kv = pfhash_get_internal (p, bucket_contents, key, &match_index);
- if (match_index == (u32) ~ 0)
- return (u64) ~ 0;
-
- kv16 = (void *) kv;
- kv8 = (void *) kv;
- kv4 = (void *) kv;
- kv8v8 = (void *) kv;
-
- switch (p->key_size)
- {
- case 16:
- return (kv16->values[match_index] == (u32) ~ 0)
- ? (u64) ~ 0 : (u64) kv16->values[match_index];
- case 8:
- if (p->value_size == 4)
- return (kv8->values[match_index] == (u32) ~ 0)
- ? (u64) ~ 0 : (u64) kv8->values[match_index];
- else
- return kv8v8->values[match_index];
- case 4:
- return (kv4->values[match_index] == (u32) ~ 0)
- ? (u64) ~ 0 : (u64) kv4->values[match_index];
- default:
- ASSERT (0);
- }
- return (u64) ~ 0;
-}
-
-void
-pfhash_set (pfhash_t * p, u32 bucket, void *key, void *value)
-{
- u32 bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
- u32 match_index = (u32) ~ 0;
- pfhash_kv_t *kv;
- pfhash_kv_16_t *kv16;
- pfhash_kv_8_t *kv8;
- pfhash_kv_8v8_t *kv8v8;
- pfhash_kv_4_t *kv4;
- int i;
- u8 *kcopy;
-
- if (bucket_contents == PFHASH_BUCKET_OVERFLOW)
- {
- hash_pair_t *hp;
- hp = hash_get_pair_mem (p->overflow_hash, key);
- if (hp)
- {
- clib_warning ("replace value 0x%08x with value 0x%08x",
- hp->value[0], (u64) value);
- hp->value[0] = (u64) value;
- return;
- }
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, key, p->key_size);
- hash_set_mem (p->overflow_hash, kcopy, value);
- p->nitems++;
- p->nitems_in_overflow++;
- return;
- }
-
- if (bucket_contents == 0)
- {
- pool_get_aligned (p->kvp, kv, 16);
- memset (kv, 0xff, sizeof (*kv));
- p->buckets[bucket] = kv - p->kvp;
- }
- else
- kv = pfhash_get_internal (p, bucket_contents, key, &match_index);
-
- kv16 = (void *) kv;
- kv8 = (void *) kv;
- kv8v8 = (void *) kv;
- kv4 = (void *) kv;
-
- p->nitems++;
-
- if (match_index != (u32) ~ 0)
- {
- switch (p->key_size)
- {
- case 16:
- kv16->values[match_index] = (u32) (u64) value;
- return;
-
- case 8:
- if (p->value_size == 4)
- kv8->values[match_index] = (u32) (u64) value;
- else
- kv8v8->values[match_index] = (u64) value;
- return;
-
- case 4:
- kv4->values[match_index] = (u64) value;
- return;
-
- default:
- ASSERT (0);
- }
- }
-
- switch (p->key_size)
- {
- case 16:
- for (i = 0; i < 3; i++)
- {
- if (kv16->values[i] == (u32) ~ 0)
- {
- clib_memcpy (&kv16->kb.k_u32x4[i], key, p->key_size);
- kv16->values[i] = (u32) (u64) value;
- return;
- }
- }
- /* copy bucket contents to overflow hash tbl */
- for (i = 0; i < 3; i++)
- {
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, &kv16->kb.k_u32x4[i], p->key_size);
- hash_set_mem (p->overflow_hash, kcopy, kv16->values[i]);
- p->nitems_in_overflow++;
- }
- /* Add new key to overflow */
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, key, p->key_size);
- hash_set_mem (p->overflow_hash, kcopy, value);
- p->buckets[bucket] = PFHASH_BUCKET_OVERFLOW;
- p->overflow_count++;
- p->nitems_in_overflow++;
- return;
-
- case 8:
- if (p->value_size == 4)
- {
- for (i = 0; i < 5; i++)
- {
- if (kv8->values[i] == (u32) ~ 0)
- {
- clib_memcpy (&kv8->kb.k_u64[i], key, 8);
- kv8->values[i] = (u32) (u64) value;
- return;
- }
- }
- /* copy bucket contents to overflow hash tbl */
- for (i = 0; i < 5; i++)
- {
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, &kv8->kb.k_u64[i], 8);
- hash_set_mem (p->overflow_hash, kcopy, kv8->values[i]);
- p->nitems_in_overflow++;
- }
- }
- else
- {
- for (i = 0; i < 4; i++)
- {
- if (kv8v8->values[i] == (u64) ~ 0)
- {
- clib_memcpy (&kv8v8->kb.k_u64[i], key, 8);
- kv8v8->values[i] = (u64) value;
- return;
- }
- }
- /* copy bucket contents to overflow hash tbl */
- for (i = 0; i < 4; i++)
- {
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, &kv8v8->kb.k_u64[i], 8);
- hash_set_mem (p->overflow_hash, kcopy, kv8v8->values[i]);
- p->nitems_in_overflow++;
- }
-
- }
- /* Add new key to overflow */
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, key, p->key_size);
- hash_set_mem (p->overflow_hash, kcopy, value);
- p->buckets[bucket] = PFHASH_BUCKET_OVERFLOW;
- p->overflow_count++;
- p->nitems_in_overflow++;
- return;
-
- case 4:
- for (i = 0; i < 8; i++)
- {
- if (kv4->values[i] == (u32) ~ 0)
- {
- clib_memcpy (&kv4->kb.kb[i], key, 4);
- kv4->values[i] = (u32) (u64) value;
- return;
- }
- }
- /* copy bucket contents to overflow hash tbl */
- for (i = 0; i < 8; i++)
- {
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, &kv4->kb.kb[i], 4);
- hash_set_mem (p->overflow_hash, kcopy, kv4->values[i]);
- p->nitems_in_overflow++;
- }
- /* Add new key to overflow */
- kcopy = clib_mem_alloc (p->key_size);
- clib_memcpy (kcopy, key, p->key_size);
- hash_set_mem (p->overflow_hash, kcopy, value);
- p->buckets[bucket] = PFHASH_BUCKET_OVERFLOW;
- p->overflow_count++;
- p->nitems_in_overflow++;
- return;
-
- default:
- ASSERT (0);
- }
-}
-
-void
-pfhash_unset (pfhash_t * p, u32 bucket, void *key)
-{
- u32 bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
- u32 match_index = (u32) ~ 0;
- pfhash_kv_t *kv;
- pfhash_kv_16_t *kv16;
- pfhash_kv_8_t *kv8;
- pfhash_kv_8v8_t *kv8v8;
- pfhash_kv_4_t *kv4;
- void *oldkey;
-
- if (bucket_contents == PFHASH_BUCKET_OVERFLOW)
- {
- hash_pair_t *hp;
- hp = hash_get_pair_mem (p->overflow_hash, key);
- if (hp)
- {
- oldkey = (void *) hp->key;
- hash_unset_mem (p->overflow_hash, key);
- clib_mem_free (oldkey);
- p->nitems--;
- p->nitems_in_overflow--;
- }
- return;
- }
-
- kv = pfhash_get_internal (p, bucket_contents, key, &match_index);
- if (match_index == (u32) ~ 0)
- return;
-
- p->nitems--;
-
- kv16 = (void *) kv;
- kv8 = (void *) kv;
- kv8v8 = (void *) kv;
- kv4 = (void *) kv;
-
- switch (p->key_size)
- {
- case 16:
- kv16->values[match_index] = (u32) ~ 0;
- return;
-
- case 8:
- if (p->value_size == 4)
- kv8->values[match_index] = (u32) ~ 0;
- else
- kv8v8->values[match_index] = (u64) ~ 0;
- return;
-
- case 4:
- kv4->values[match_index] = (u32) ~ 0;
- return;
-
- default:
- ASSERT (0);
- }
-}
-
-void
-pfhash_free (pfhash_t * p)
-{
- hash_pair_t *hp;
- int i;
- u8 **keys = 0;
-
- vec_free (p->name);
-
- pool_free (p->kvp);
-
- /* *INDENT-OFF* */
- hash_foreach_pair (hp, p->overflow_hash,
- ({
- vec_add1 (keys, (u8 *)hp->key);
- }));
- /* *INDENT-ON* */
- hash_free (p->overflow_hash);
- for (i = 0; i < vec_len (keys); i++)
- vec_free (keys[i]);
- vec_free (keys);
-}
-
-#endif
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vppinfra/test_pfhash.c b/src/vppinfra/test_pfhash.c
deleted file mode 100644
index ddbdbb34be5..00000000000
--- a/src/vppinfra/test_pfhash.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- Copyright (c) 2013 Cisco 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 <vppinfra/pfhash.h>
-#include <vppinfra/format.h>
-#include <vppinfra/random.h>
-
-#if defined(CLIB_HAVE_VEC128) && ! defined (__ALTIVEC__)
-
-int verbose = 0;
-
-always_inline u8 *
-random_aligned_string (u32 * seed, uword len)
-{
- u8 *alphabet = (u8 *) "abcdefghijklmnopqrstuvwxyz";
- u8 *s = 0;
- word i;
-
- vec_resize_aligned (s, len, 16);
- for (i = 0; i < len; i++)
- s[i] = alphabet[random_u32 (seed) % 26];
-
- return s;
-}
-
-void exit (int);
-
-int
-test_pfhash_main (unformat_input_t * input)
-{
- u32 seed = 0xdeaddabe;
- int i, iter;
- u32 nkeys = 4;
- u32 niter = 1;
- u32 nbuckets = 1;
- u32 bucket;
- u32 sizes[3] = { 16, 8, 4 }, this_size, size;
- u8 **keys = 0;
- pfhash_t _rec, *p = &_rec;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "seed %d", &seed))
- ;
- else if (unformat (input, "niter %d", &niter))
- ;
- else if (unformat (input, "nkeys %d", &nkeys))
- ;
- else if (unformat (input, "nbuckets %d", &nbuckets))
- ;
- else if (unformat (input, "verbose %d", &verbose))
- ;
- else if (unformat (input, "verbose"))
- verbose = 1;
- else
- clib_error ("unknown input `%U'", format_unformat_error, input);
- }
-
- vec_validate (keys, nkeys - 1);
-
- for (i = 0; i < nkeys; i++)
- {
- int j, k;
-
- again:
- keys[i] = random_aligned_string (&seed, 16);
- for (j = 0; j < (i - 1); j++)
- {
- /* Make sure we don't have a dup key in the min key size */
- for (k = 0; k < 4; k++)
- {
- if (keys[i][k] != keys[j][k])
- goto check_next_key;
- }
- vec_free (keys[i]);
- goto again;
- check_next_key:
- ;
- }
- }
-
- /* test 8 byte key, 8 byte value case separately */
-
- for (size = 8; size < 9; size++)
- {
- this_size = 8;
-
- fformat (stdout, "%d-byte key 8 byte value test\n", this_size);
-
- pfhash_init (p, "test", 8 /* key size */ , 8 /* value size */ ,
- nbuckets + 1);
-
- for (iter = 0; iter < niter; iter++)
- {
- bucket = 0;
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- pfhash_set (p, bucket, keys[i],
- (void *) (u64) 0x100000000ULL + i + 1);
- }
-
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- if (pfhash_get (p, bucket, keys[i])
- != (u64) 0x100000000ULL + i + 1)
- {
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- (void) pfhash_get (p, bucket, keys[i]);
- }
- }
-
- /* test inline functions */
- for (i = 0; i < nkeys; i++)
- {
- u32 bucket_contents;
- u64 value = 0xdeadbeef;
- bucket = (i % nbuckets) + 1;
-
- pfhash_prefetch_bucket (p, bucket);
- bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
-
- value = pfhash_search_kv_8v8 (p, bucket_contents,
- (u64 *) keys[i]);
- if (value != (u64) 0x100000000ULL + i + 1)
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- }
-
- if (verbose)
- fformat (stdout, "%U\n", format_pfhash, p, verbose > 1);
-
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- pfhash_unset (p, bucket, keys[i]);
- }
-
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- if (pfhash_get (p, bucket, keys[i]) != (u64) ~ 0)
- {
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- (void) pfhash_get (p, bucket, keys[i]);
- }
- }
- /* test inline functions */
- for (i = 0; i < nkeys; i++)
- {
- u32 bucket_contents;
- u64 value = 0xdeadbeef;
- bucket = (i % nbuckets) + 1;
-
- pfhash_prefetch_bucket (p, bucket);
- bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
-
- value = pfhash_search_kv_8v8 (p, bucket_contents,
- (u64 *) keys[i]);
-
- if (value != (u64) ~ 0)
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- }
- }
- pfhash_free (p);
- }
-
- /* test other cases */
-
- for (size = 0; size < ARRAY_LEN (sizes); size++)
- {
- this_size = sizes[size];
-
- fformat (stdout, "%d-byte key test\n", this_size);
-
- pfhash_init (p, "test", this_size, 4 /* value size */ , nbuckets + 1);
-
- for (iter = 0; iter < niter; iter++)
- {
- bucket = 0;
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- pfhash_set (p, bucket, keys[i], (void *) (u64) i + 1);
- }
-
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- if (pfhash_get (p, bucket, keys[i]) != i + 1)
- {
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- (void) pfhash_get (p, bucket, keys[i]);
- }
- }
-
- /* test inline functions */
- for (i = 0; i < nkeys; i++)
- {
- u32 bucket_contents;
- u32 value = 0xdeadbeef;
- bucket = (i % nbuckets) + 1;
-
- pfhash_prefetch_bucket (p, bucket);
- bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
- switch (p->key_size)
- {
- case 16:
- value =
- pfhash_search_kv_16 (p, bucket_contents,
- (u32x4 *) keys[i]);
- break;
- case 8:
- value =
- pfhash_search_kv_8 (p, bucket_contents, (u64 *) keys[i]);
- break;
- case 4:
- value =
- pfhash_search_kv_4 (p, bucket_contents, (u32 *) keys[i]);
- break;
- }
-
- if (value != (i + 1))
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- }
-
- if (verbose)
- fformat (stdout, "%U\n", format_pfhash, p, verbose > 1);
-
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- pfhash_unset (p, bucket, keys[i]);
- }
-
- for (i = 0; i < nkeys; i++)
- {
- bucket = (i % nbuckets) + 1;
- if (pfhash_get (p, bucket, keys[i]) != (u64) ~ 0)
- {
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- (void) pfhash_get (p, bucket, keys[i]);
- }
- }
- /* test inline functions */
- for (i = 0; i < nkeys; i++)
- {
- u32 bucket_contents;
- u32 value = 0xdeadbeef;
- bucket = (i % nbuckets) + 1;
-
- pfhash_prefetch_bucket (p, bucket);
- bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
- switch (p->key_size)
- {
- case 16:
- value =
- pfhash_search_kv_16 (p, bucket_contents,
- (u32x4 *) keys[i]);
- break;
- case 8:
- value =
- pfhash_search_kv_8 (p, bucket_contents, (u64 *) keys[i]);
- break;
- case 4:
- value =
- pfhash_search_kv_4 (p, bucket_contents, (u32 *) keys[i]);
- break;
- }
- if (value != (u32) ~ 0)
- clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
- }
- }
- pfhash_free (p);
- }
-
- exit (0);
-}
-#else
-int
-test_pfhash_main (unformat_input_t * input)
-{
- clib_warning ("MMX unit not available");
- return 0;
-}
-#endif
-
-#ifdef CLIB_UNIX
-int
-main (int argc, char *argv[])
-{
- unformat_input_t i;
- int ret;
-
- unformat_init_command_line (&i, argv);
- ret = test_pfhash_main (&i);
- unformat_free (&i);
-
- return ret;
-}
-#endif /* CLIB_UNIX */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vppinfra/test_pool.c b/src/vppinfra/test_pool.c
deleted file mode 100644
index 67a5e50a38a..00000000000
--- a/src/vppinfra/test_pool.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco 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.
- */
-/*
- Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <vppinfra/mem.h>
-#include <vppinfra/pool.h>
-
-#ifdef __KERNEL__
-#include <linux/unistd.h>
-#else
-#include <unistd.h>
-#endif
-
-int
-main (int argc, char *argv[])
-{
- int i, n, seed;
-
- int *p = 0, *e, j, *o = 0;
-
- n = atoi (argv[1]);
- seed = getpid ();
- srandom (1);
-
- for (i = 0; i < n; i++)
- {
- if (vec_len (o) < 10 || (random () & 1))
- {
- pool_get (p, e);
- j = e - p;
- *e = j;
- vec_add1 (o, j);
- }
- else
- {
- j = random () % vec_len (o);
- e = p + j;
- pool_put (p, e);
- vec_delete (o, 1, j);
- }
- }
- p = pool_free (p);
- vec_free (o);
- return 0;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */