From f39ff74346e86fb175da7e2a3981f2e6f8d3cc0c Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Sun, 20 Mar 2016 10:14:45 -0400 Subject: [PATCH] vnet classifier debug CLI enhancements Extensible next-index and opaque unformat function scheme. Added next-index-by-node-name and sw_if_index->opaque functions. Allow dynamic graph arcs to be added to ip4/6-inacl. Change-Id: Ie434335399a0708772eb82563a154df19c63b622 Signed-off-by: Dave Barach --- vnet/vnet/classify/vnet_classify.c | 197 +++++++++++++++++++++++++++++++++++-- vnet/vnet/classify/vnet_classify.h | 19 +++- vnet/vnet/ip/ip.h | 3 + vnet/vnet/ip/ip_input_acl.c | 9 +- vnet/vnet/mpls-gre/policy_encap.c | 16 +++ vpp/vnet/main.c | 1 + 6 files changed, 235 insertions(+), 10 deletions(-) diff --git a/vnet/vnet/classify/vnet_classify.c b/vnet/vnet/classify/vnet_classify.c index 7f7138af2af..2a7770194e3 100644 --- a/vnet/vnet/classify/vnet_classify.c +++ b/vnet/vnet/classify/vnet_classify.c @@ -18,6 +18,8 @@ #include /* for API error numbers */ #include /* for L2_CLASSIFY_NEXT_xxx */ +vnet_classify_main_t vnet_classify_main; + #if VALIDATION_SCAFFOLDING /* Validation scaffolding */ void mv (vnet_classify_table_t * t) @@ -64,6 +66,35 @@ void mv (vnet_classify_table_t * t) { } void rogue (vnet_classify_table_t * t) { } #endif +void vnet_classify_register_unformat_l2_next_index_fn (unformat_function_t * fn) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + + vec_add1 (cm->unformat_l2_next_index_fns, fn); +} + +void vnet_classify_register_unformat_ip_next_index_fn (unformat_function_t * fn) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + + vec_add1 (cm->unformat_ip_next_index_fns, fn); +} + +void +vnet_classify_register_unformat_acl_next_index_fn (unformat_function_t * fn) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + + vec_add1 (cm->unformat_acl_next_index_fns, fn); +} + +void vnet_classify_register_unformat_opaque_index_fn (unformat_function_t * fn) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + + vec_add1 (cm->unformat_opaque_index_fns, fn); +} + vnet_classify_table_t * vnet_classify_new_table (vnet_classify_main_t *cm, u8 * mask, u32 nbuckets, u32 memory_size, @@ -990,10 +1021,22 @@ _(li, LI) uword unformat_l2_next_index (unformat_input_t * input, va_list * args) { + vnet_classify_main_t * cm = &vnet_classify_main; u32 * miss_next_indexp = va_arg (*args, u32 *); u32 next_index = 0; u32 tmp; + int i; + /* First try registered unformat fns, allowing override... */ + for (i = 0; i < vec_len (cm->unformat_l2_next_index_fns); i++) + { + if (unformat (input, "%U", cm->unformat_l2_next_index_fns[i], &tmp)) + { + next_index = tmp; + goto out; + } + } + #define _(n,N) \ if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;} foreach_l2_next; @@ -1021,9 +1064,21 @@ _(rewrite, REWRITE) uword unformat_ip_next_index (unformat_input_t * input, va_list * args) { u32 * miss_next_indexp = va_arg (*args, u32 *); + vnet_classify_main_t * cm = &vnet_classify_main; u32 next_index = 0; u32 tmp; + int i; + /* First try registered unformat fns, allowing override... */ + for (i = 0; i < vec_len (cm->unformat_ip_next_index_fns); i++) + { + if (unformat (input, "%U", cm->unformat_ip_next_index_fns[i], &tmp)) + { + next_index = tmp; + goto out; + } + } + #define _(n,N) \ if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;} foreach_ip_next; @@ -1047,9 +1102,21 @@ _(deny, DENY) uword unformat_acl_next_index (unformat_input_t * input, va_list * args) { - u32 * miss_next_indexp = va_arg (*args, u32 *); + u32 * next_indexp = va_arg (*args, u32 *); + vnet_classify_main_t * cm = &vnet_classify_main; u32 next_index = 0; u32 tmp; + int i; + + /* First try registered unformat fns, allowing override... */ + for (i = 0; i < vec_len (cm->unformat_acl_next_index_fns); i++) + { + if (unformat (input, "%U", cm->unformat_acl_next_index_fns[i], &tmp)) + { + next_index = tmp; + goto out; + } + } #define _(n,N) \ if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;} @@ -1070,7 +1137,7 @@ uword unformat_acl_next_index (unformat_input_t * input, va_list * args) return 0; out: - *miss_next_indexp = next_index; + *next_indexp = next_index; return 1; } @@ -1678,10 +1745,10 @@ classify_session_command_fn (vlib_main_t * vm, int is_add = 1; u32 table_index = ~0; u32 hit_next_index = ~0; - u32 opaque_index = ~0; + u64 opaque_index = ~0; u8 * match = 0; i32 advance = 0; - int rv; + int i, rv; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -1696,7 +1763,7 @@ classify_session_command_fn (vlib_main_t * vm, else if (unformat (input, "acl-hit-next %U", unformat_acl_next_index, &hit_next_index)) ; - else if (unformat (input, "opaque-index %d", &opaque_index)) + else if (unformat (input, "opaque-index %lld", &opaque_index)) ; else if (unformat (input, "match %U", unformat_classify_match, cm, &match, table_index)) @@ -1706,7 +1773,18 @@ classify_session_command_fn (vlib_main_t * vm, else if (unformat (input, "table-index %d", &table_index)) ; else - break; + { + /* Try registered opaque-index unformat fns */ + for (i = 0; i < vec_len (cm->unformat_opaque_index_fns); i++) + { + if (unformat (input, "%U", cm->unformat_opaque_index_fns[i], + &opaque_index)) + goto found_opaque; + } + break; + } + found_opaque: + ; } if (table_index == ~0) @@ -1740,6 +1818,113 @@ VLIB_CLI_COMMAND (classify_session_command, static) = { .function = classify_session_command_fn, }; +static uword +unformat_opaque_sw_if_index (unformat_input_t * input, va_list * args) +{ + u64 * opaquep = va_arg (*args, u64 *); + u32 sw_if_index; + + if (unformat (input, "opaque-sw_if_index %U", unformat_vnet_sw_interface, + vnet_get_main(), &sw_if_index)) + { + *opaquep = sw_if_index; + return 1; + } + return 0; +} + +static uword +unformat_ip_next_node (unformat_input_t * input, va_list * args) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + u32 * next_indexp = va_arg (*args, u32 *); + u32 node_index; + u32 next_index, rv; + + if (unformat (input, "node %U", unformat_vlib_node, + cm->vlib_main, &node_index)) + { + rv = next_index = vlib_node_add_next + (cm->vlib_main, ip4_classify_node.index, node_index); + next_index = vlib_node_add_next + (cm->vlib_main, ip6_classify_node.index, node_index); + ASSERT(rv == next_index); + + *next_indexp = next_index; + return 1; + } + return 0; +} + +static uword +unformat_acl_next_node (unformat_input_t * input, va_list * args) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + u32 * next_indexp = va_arg (*args, u32 *); + u32 node_index; + u32 next_index, rv; + + if (unformat (input, "node %U", unformat_vlib_node, + cm->vlib_main, &node_index)) + { + rv = next_index = vlib_node_add_next + (cm->vlib_main, ip4_inacl_node.index, node_index); + next_index = vlib_node_add_next + (cm->vlib_main, ip6_inacl_node.index, node_index); + ASSERT(rv == next_index); + + *next_indexp = next_index; + return 1; + } + return 0; +} + +static uword +unformat_l2_next_node (unformat_input_t * input, va_list * args) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + u32 * next_indexp = va_arg (*args, u32 *); + u32 node_index; + u32 next_index; + + if (unformat (input, "node %U", unformat_vlib_node, + cm->vlib_main, &node_index)) + { + next_index = vlib_node_add_next + (cm->vlib_main, l2_classify_node.index, node_index); + + *next_indexp = next_index; + return 1; + } + return 0; +} + + +static clib_error_t * +vnet_classify_init (vlib_main_t * vm) +{ + vnet_classify_main_t * cm = &vnet_classify_main; + + cm->vlib_main = vm; + cm->vnet_main = vnet_get_main(); + + vnet_classify_register_unformat_opaque_index_fn + (unformat_opaque_sw_if_index); + + vnet_classify_register_unformat_ip_next_index_fn + (unformat_ip_next_node); + + vnet_classify_register_unformat_l2_next_index_fn + (unformat_l2_next_node); + + vnet_classify_register_unformat_acl_next_index_fn + (unformat_acl_next_node); + + return 0; +} + +VLIB_INIT_FUNCTION (vnet_classify_init); + #define TEST_CODE 1 #if TEST_CODE > 0 diff --git a/vnet/vnet/classify/vnet_classify.h b/vnet/vnet/classify/vnet_classify.h index e33e6dac201..b7056c565d7 100644 --- a/vnet/vnet/classify/vnet_classify.h +++ b/vnet/vnet/classify/vnet_classify.h @@ -158,12 +158,18 @@ struct _vnet_classify_main { /* Table pool */ vnet_classify_table_t * tables; + /* Registered next-index, opaque unformat fcns */ + unformat_function_t ** unformat_l2_next_index_fns; + unformat_function_t ** unformat_ip_next_index_fns; + unformat_function_t ** unformat_acl_next_index_fns; + unformat_function_t ** unformat_opaque_index_fns; + /* convenience variables */ vlib_main_t * vlib_main; vnet_main_t * vnet_main; }; -vnet_classify_main_t vnet_classify_main; +extern vnet_classify_main_t vnet_classify_main; u8 * format_classify_table (u8 * s, va_list * args); @@ -469,4 +475,15 @@ unformat_function_t unformat_vlan_tag; unformat_function_t unformat_l2_match; unformat_function_t unformat_classify_match; +void vnet_classify_register_unformat_ip_next_index_fn +(unformat_function_t * fn); + +void vnet_classify_register_unformat_l2_next_index_fn +(unformat_function_t * fn); + +void vnet_classify_register_unformat_acl_next_index_fn +(unformat_function_t * fn); + +void vnet_classify_register_unformat_opaque_index_fn (unformat_function_t * fn); + #endif /* __included_vnet_classify_h__ */ diff --git a/vnet/vnet/ip/ip.h b/vnet/vnet/ip/ip.h index 35159bf24f5..76a2552ffa4 100644 --- a/vnet/vnet/ip/ip.h +++ b/vnet/vnet/ip/ip.h @@ -218,4 +218,7 @@ ip_incremental_checksum_buffer (vlib_main_t * vm, vlib_buffer_t * first_buffer, void ip_del_all_interface_addresses (vlib_main_t *vm, u32 sw_if_index); +extern vlib_node_registration_t ip4_inacl_node; +extern vlib_node_registration_t ip6_inacl_node; + #endif /* included_ip_main_h */ diff --git a/vnet/vnet/ip/ip_input_acl.c b/vnet/vnet/ip/ip_input_acl.c index 75aa9ef818f..fb7255ecd0c 100644 --- a/vnet/vnet/ip/ip_input_acl.c +++ b/vnet/vnet/ip/ip_input_acl.c @@ -71,6 +71,9 @@ ip_inacl_inline (vlib_main_t * vm, u32 chain_hits = 0; input_acl_table_id_t tid; vlib_node_runtime_t * error_node; + u32 n_next_nodes; + + n_next_nodes = node->n_next_nodes; if (is_ip4) { @@ -245,7 +248,7 @@ ip_inacl_inline (vlib_main_t * vm, { vlib_buffer_advance (b0, e0->advance); - next0 = (e0->next_index < ACL_NEXT_INDEX_N_NEXT)? + next0 = (e0->next_index < n_next_nodes)? e0->next_index:next0; hits++; @@ -267,7 +270,7 @@ ip_inacl_inline (vlib_main_t * vm, t0->next_table_index); else { - next0 = (t0->miss_next_index < ACL_NEXT_INDEX_N_NEXT)? + next0 = (t0->miss_next_index < n_next_nodes)? t0->miss_next_index:next0; misses++; @@ -288,7 +291,7 @@ ip_inacl_inline (vlib_main_t * vm, if (e0) { vlib_buffer_advance (b0, e0->advance); - next0 = (e0->next_index < ACL_NEXT_INDEX_N_NEXT)? + next0 = (e0->next_index < n_next_nodes)? e0->next_index:next0; hits++; chain_hits++; diff --git a/vnet/vnet/mpls-gre/policy_encap.c b/vnet/vnet/mpls-gre/policy_encap.c index 53411515e69..850cdc196be 100644 --- a/vnet/vnet/mpls-gre/policy_encap.c +++ b/vnet/vnet/mpls-gre/policy_encap.c @@ -158,6 +158,7 @@ mpls_policy_encap_init (vlib_main_t * vm) { mpls_main_t * mm = &mpls_main; clib_error_t * error; + u32 ip6_next_index; if ((error = vlib_call_init_function (vm, mpls_init))) return error; @@ -166,6 +167,21 @@ mpls_policy_encap_init (vlib_main_t * vm) vlib_node_add_next (mm->vlib_main, ip4_classify_node.index, mpls_policy_encap_node.index); + + /* + * Must add the same arc to ip6_classify so the + * next-index vectors are congruent + */ + ip6_next_index = + vlib_node_add_next (mm->vlib_main, + ip6_classify_node.index, + mpls_policy_encap_node.index); + + if (ip6_next_index != mm->ip_classify_mpls_policy_encap_next_index) + return clib_error_return + (0, "ip4/ip6 classifier next vector botch: %d vs %d", + ip6_next_index, mm->ip_classify_mpls_policy_encap_next_index); + return 0; } diff --git a/vpp/vnet/main.c b/vpp/vnet/main.c index f6d21a675bc..03139c00556 100644 --- a/vpp/vnet/main.c +++ b/vpp/vnet/main.c @@ -91,6 +91,7 @@ int main (int argc, char * argv[]) #if __SSE3__ _("sse3", "SSE3") #endif +#undef _ #endif /* -- 2.16.6