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 <dave@barachs.net>
This commit is contained in:
@ -18,6 +18,8 @@
|
||||
#include <vnet/api_errno.h> /* for API error numbers */
|
||||
#include <vnet/l2/l2_classify.h> /* 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
|
||||
|
@ -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__ */
|
||||
|
@ -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 */
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,7 @@ int main (int argc, char * argv[])
|
||||
#if __SSE3__
|
||||
_("sse3", "SSE3")
|
||||
#endif
|
||||
#undef _
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user