#include <vnet/classify/input_acl.h>
#include <vnet/ip/ip.h>
#include <vnet/api_errno.h> /* for API error numbers */
-#include <vnet/l2/l2_classify.h> /* for L2_CLASSIFY_NEXT_xxx */
+#include <vnet/l2/l2_classify.h> /* for L2_INPUT_CLASSIFY_NEXT_xxx */
vnet_classify_main_t vnet_classify_main;
vec_add1 (cm->unformat_acl_next_index_fns, fn);
}
+void
+vnet_classify_register_unformat_policer_next_index_fn (unformat_function_t * fn)
+{
+ vnet_classify_main_t * cm = &vnet_classify_main;
+
+ vec_add1 (cm->unformat_policer_next_index_fns, fn);
+}
+
void vnet_classify_register_unformat_opaque_index_fn (unformat_function_t * fn)
{
vnet_classify_main_t * cm = &vnet_classify_main;
memset(t, 0, sizeof (*t));
vec_validate_aligned (t->mask, match_n_vectors - 1, sizeof(u32x4));
- memcpy (t->mask, mask, match_n_vectors * sizeof (u32x4));
+ clib_memcpy (t->mask, mask, match_n_vectors * sizeof (u32x4));
t->next_table_index = ~0;
t->nbuckets = nbuckets;
{
#define _(size) \
case size: \
- memcpy (working_copy, v, \
+ clib_memcpy (working_copy, v, \
sizeof (vnet_classify_entry_##size##_t) \
* (1<<b->log2_pages) \
* (t->entries_per_page)); \
if (vnet_classify_entry_is_free (new_v))
{
- memcpy (new_v, v, sizeof (vnet_classify_entry_t)
+ clib_memcpy (new_v, v, sizeof (vnet_classify_entry_t)
+ (t->match_n_vectors * sizeof (u32x4)));
new_v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
goto doublebreak;
}
v = vnet_classify_entry_alloc (t, 0 /* new_log2_pages */);
- memcpy (v, add_v, sizeof (vnet_classify_entry_t) +
+ clib_memcpy (v, add_v, sizeof (vnet_classify_entry_t) +
t->match_n_vectors * sizeof (u32x4));
v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
if (!memcmp (v->key, add_v->key, t->match_n_vectors * sizeof (u32x4)))
{
- memcpy (v, add_v, sizeof (vnet_classify_entry_t) +
+ clib_memcpy (v, add_v, sizeof (vnet_classify_entry_t) +
t->match_n_vectors * sizeof(u32x4));
v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
if (vnet_classify_entry_is_free (v))
{
- memcpy (v, add_v, sizeof (vnet_classify_entry_t) +
+ clib_memcpy (v, add_v, sizeof (vnet_classify_entry_t) +
t->match_n_vectors * sizeof(u32x4));
v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
CLIB_MEMORY_BARRIER();
if (vnet_classify_entry_is_free (new_v))
{
- memcpy (new_v, add_v, sizeof (vnet_classify_entry_t) +
+ clib_memcpy (new_v, add_v, sizeof (vnet_classify_entry_t) +
t->match_n_vectors * sizeof(u32x4));
new_v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
goto expand_ok;
if (l2 == 0)
vec_validate (l2, 13);
mask = l2;
- vec_append (mask, l3);
- vec_free (l3);
+ if (l3)
+ {
+ vec_append (mask, l3);
+ vec_free (l3);
+ }
}
/* Scan forward looking for the first significant mask octet */
return 0;
}
-#define foreach_l2_next \
+#define foreach_l2_input_next \
_(drop, DROP) \
_(ethernet, ETHERNET_INPUT) \
_(ip4, IP4_INPUT) \
_(ip6, IP6_INPUT) \
_(li, LI)
-uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
+uword unformat_l2_input_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 *);
}
#define _(n,N) \
- if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
- foreach_l2_next;
+ if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
+ foreach_l2_input_next;
+#undef _
+
+ if (unformat (input, "%d", &tmp))
+ {
+ next_index = tmp;
+ goto out;
+ }
+
+ return 0;
+
+ out:
+ *miss_next_indexp = next_index;
+ return 1;
+}
+
+#define foreach_l2_output_next \
+_(drop, DROP)
+
+uword unformat_l2_output_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_OUTPUT_CLASSIFY_NEXT_##N; goto out;}
+ foreach_l2_output_next;
#undef _
if (unformat (input, "%d", &tmp))
}
#define foreach_ip_next \
-_(miss, MISS) \
_(drop, DROP) \
-_(local, LOCAL) \
_(rewrite, REWRITE)
uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
return 1;
}
+uword unformat_policer_next_index (unformat_input_t * input, va_list * args)
+{
+ 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_policer_next_index_fns); i++)
+ {
+ if (unformat (input, "%U", cm->unformat_policer_next_index_fns[i], &tmp))
+ {
+ next_index = tmp;
+ goto out;
+ }
+ }
+
+ if (unformat (input, "%d", &tmp))
+ {
+ next_index = tmp;
+ goto out;
+ }
+
+ return 0;
+
+ out:
+ *next_indexp = next_index;
+ return 1;
+}
+
static clib_error_t *
classify_table_command_fn (vlib_main_t * vm,
unformat_input_t * input,
else if (unformat (input, "miss-next %U", unformat_ip_next_index,
&miss_next_index))
;
- else if (unformat (input, "l2-miss-next %U", unformat_l2_next_index,
+ else if (unformat (input, "l2-input-miss-next %U", unformat_l2_input_next_index,
+ &miss_next_index))
+ ;
+ else if (unformat (input, "l2-output-miss-next %U", unformat_l2_output_next_index,
&miss_next_index))
;
else if (unformat (input, "acl-miss-next %U", unformat_acl_next_index,
ip = (ip6_header_t *) match;
if (src)
- memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
+ clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
if (dst)
- memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
+ clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
if (proto)
ip->protocol = proto_val;
vec_validate_aligned (match, len-1, sizeof(u32x4));
if (dst)
- memcpy (match, dst_val, 6);
+ clib_memcpy (match, dst_val, 6);
if (src)
- memcpy (match + 6, src_val, 6);
+ clib_memcpy (match + 6, src_val, 6);
if (tag2)
{
if (l2 == 0)
vec_validate_aligned (l2, 13, sizeof(u32x4));
match = l2;
- vec_append_aligned (match, l3, sizeof(u32x4));
- vec_free (l3);
+ if (l3)
+ {
+ vec_append_aligned (match, l3, sizeof(u32x4));
+ vec_free (l3);
+ }
}
/* Make sure the vector is big enough even if key is all 0's */
e->flags = 0;
/* Copy key data, honoring skip_n_vectors */
- memcpy (&e->key, match + t->skip_n_vectors * sizeof (u32x4),
+ clib_memcpy (&e->key, match + t->skip_n_vectors * sizeof (u32x4),
t->match_n_vectors * sizeof (u32x4));
/* Clear don't-care bits; likely when dynamically creating sessions */
else if (unformat (input, "hit-next %U", unformat_ip_next_index,
&hit_next_index))
;
- else if (unformat (input, "l2-hit-next %U", unformat_l2_next_index,
+ else if (unformat (input, "l2-input-hit-next %U", unformat_l2_input_next_index,
+ &hit_next_index))
+ ;
+ else if (unformat (input, "l2-output-hit-next %U", unformat_l2_output_next_index,
&hit_next_index))
;
else if (unformat (input, "acl-hit-next %U", unformat_acl_next_index,
&hit_next_index))
;
+ else if (unformat (input, "policer-hit-next %U",
+ unformat_policer_next_index, &hit_next_index))
+ ;
else if (unformat (input, "opaque-index %lld", &opaque_index))
;
else if (unformat (input, "match %U", unformat_classify_match,
VLIB_CLI_COMMAND (classify_session_command, static) = {
.path = "classify session",
.short_help =
- "classify session [hit-next|l2-hit-next|acl-hit-next <next_index>]"
+ "classify session [hit-next|l2-hit-next|acl-hit-next <next_index>|"
+ "policer-hit-next <policer_name>]"
"\n table-index <nn> match [hex] [l2] [l3 ip4] [opaque-index <index>]",
.function = classify_session_command_fn,
};
}
static uword
-unformat_l2_next_node (unformat_input_t * input, va_list * args)
+unformat_l2_input_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,
+ if (unformat (input, "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);
+ (cm->vlib_main, l2_input_classify_node.index, node_index);
*next_indexp = next_index;
return 1;
return 0;
}
+static uword
+unformat_l2_output_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, "output-node %U", unformat_vlib_node,
+ cm->vlib_main, &node_index))
+ {
+ next_index = vlib_node_add_next
+ (cm->vlib_main, l2_output_classify_node.index, node_index);
+
+ *next_indexp = next_index;
+ return 1;
+ }
+ return 0;
+}
static clib_error_t *
vnet_classify_init (vlib_main_t * vm)
(unformat_ip_next_node);
vnet_classify_register_unformat_l2_next_index_fn
- (unformat_l2_next_node);
+ (unformat_l2_input_next_node);
+
+ vnet_classify_register_unformat_l2_next_index_fn
+ (unformat_l2_input_next_node);
+
+ vnet_classify_register_unformat_l2_next_index_fn
+ (unformat_l2_output_next_node);
vnet_classify_register_unformat_acl_next_index_fn
(unformat_acl_next_node);
memory_size,
0 /* skip */,
3 /* vectors to match */);
- t->miss_next_index = IP_LOOKUP_NEXT_LOCAL;
+ t->miss_next_index = IP_LOOKUP_NEXT_DROP;
vlib_cli_output (vm, "Create table %d", t - cm->tables);
}