VPP-521: Classify API enhancement to redirect traffic to pre-defined VRF
Ingress packets are punted to the “Input ACL node” where traffic is classified based on n-tuple keys. If no matched session is found from the classify tables, then it will be passed to “the lookup node” for normal packet forwarding. If a classify session is hit from one of classify tables, then packet vnet buffer field sw_if_index[VLIB_TX] will be updated to the new FIB index used for subsequent IP lookup for this packet. Change-Id: Ifdea63196ddb81c2d5c43b8c98e11ddbf5b11858 Signed-off-by: Steve Shin <jonshin@cisco.com>
This commit is contained in:
@ -17,6 +17,7 @@
|
||||
#include <vnet/ip/ip.h>
|
||||
#include <vnet/api_errno.h> /* for API error numbers */
|
||||
#include <vnet/l2/l2_classify.h> /* for L2_INPUT_CLASSIFY_NEXT_xxx */
|
||||
#include <vnet/fib/fib_table.h>
|
||||
|
||||
vnet_classify_main_t vnet_classify_main;
|
||||
|
||||
@ -571,9 +572,9 @@ static u8 * format_classify_entry (u8 * s, va_list * args)
|
||||
vnet_classify_entry_t * e = va_arg (*args, vnet_classify_entry_t *);
|
||||
|
||||
s = format
|
||||
(s, "[%u]: next_index %d advance %d opaque %d\n",
|
||||
(s, "[%u]: next_index %d advance %d opaque %d action %d metadata %d\n",
|
||||
vnet_classify_get_offset (t, e), e->next_index, e->advance,
|
||||
e->opaque_index);
|
||||
e->opaque_index, e->action, e->metadata);
|
||||
|
||||
|
||||
s = format (s, " k: %U\n", format_hex_bytes, e->key,
|
||||
@ -653,24 +654,37 @@ int vnet_classify_add_del_table (vnet_classify_main_t * cm,
|
||||
u32 next_table_index,
|
||||
u32 miss_next_index,
|
||||
u32 * table_index,
|
||||
u8 current_data_flag,
|
||||
i16 current_data_offset,
|
||||
int is_add)
|
||||
{
|
||||
vnet_classify_table_t * t;
|
||||
|
||||
if (is_add)
|
||||
{
|
||||
*table_index = ~0;
|
||||
if (memory_size == 0)
|
||||
return VNET_API_ERROR_INVALID_MEMORY_SIZE;
|
||||
if (*table_index == ~0) /* add */
|
||||
{
|
||||
if (memory_size == 0)
|
||||
return VNET_API_ERROR_INVALID_MEMORY_SIZE;
|
||||
|
||||
if (nbuckets == 0)
|
||||
return VNET_API_ERROR_INVALID_VALUE;
|
||||
if (nbuckets == 0)
|
||||
return VNET_API_ERROR_INVALID_VALUE;
|
||||
|
||||
t = vnet_classify_new_table (cm, mask, nbuckets, memory_size,
|
||||
skip, match);
|
||||
t->next_table_index = next_table_index;
|
||||
t->miss_next_index = miss_next_index;
|
||||
*table_index = t - cm->tables;
|
||||
t = vnet_classify_new_table (cm, mask, nbuckets, memory_size,
|
||||
skip, match);
|
||||
t->next_table_index = next_table_index;
|
||||
t->miss_next_index = miss_next_index;
|
||||
t->current_data_flag = current_data_flag;
|
||||
t->current_data_offset = current_data_offset;
|
||||
*table_index = t - cm->tables;
|
||||
}
|
||||
else /* update */
|
||||
{
|
||||
vnet_classify_main_t *cm = &vnet_classify_main;
|
||||
t = pool_elt_at_index (cm->tables, *table_index);
|
||||
|
||||
t->next_table_index = next_table_index;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1376,6 +1390,8 @@ classify_table_command_fn (vlib_main_t * vm,
|
||||
u32 miss_next_index = ~0;
|
||||
u32 memory_size = 2<<20;
|
||||
u32 tmp;
|
||||
u32 current_data_flag = 0;
|
||||
int current_data_offset = 0;
|
||||
|
||||
u8 * mask = 0;
|
||||
vnet_classify_main_t * cm = &vnet_classify_main;
|
||||
@ -1413,18 +1429,22 @@ classify_table_command_fn (vlib_main_t * vm,
|
||||
else if (unformat (input, "acl-miss-next %U", unformat_acl_next_index,
|
||||
&miss_next_index))
|
||||
;
|
||||
|
||||
else if (unformat (input, "current-data-flag %d", ¤t_data_flag))
|
||||
;
|
||||
else if (unformat (input, "current-data-offset %d", ¤t_data_offset))
|
||||
;
|
||||
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_add && mask == 0)
|
||||
if (is_add && mask == 0 && table_index == ~0)
|
||||
return clib_error_return (0, "Mask required");
|
||||
|
||||
if (is_add && skip == ~0)
|
||||
if (is_add && skip == ~0 && table_index == ~0)
|
||||
return clib_error_return (0, "skip count required");
|
||||
|
||||
if (is_add && match == ~0)
|
||||
if (is_add && match == ~0 && table_index == ~0)
|
||||
return clib_error_return (0, "match count required");
|
||||
|
||||
if (!is_add && table_index == ~0)
|
||||
@ -1432,7 +1452,7 @@ classify_table_command_fn (vlib_main_t * vm,
|
||||
|
||||
rv = vnet_classify_add_del_table (cm, mask, nbuckets, memory_size,
|
||||
skip, match, next_table_index, miss_next_index,
|
||||
&table_index, is_add);
|
||||
&table_index, current_data_flag, current_data_offset, is_add);
|
||||
switch (rv)
|
||||
{
|
||||
case 0:
|
||||
@ -1449,7 +1469,8 @@ VLIB_CLI_COMMAND (classify_table, static) = {
|
||||
.path = "classify table",
|
||||
.short_help =
|
||||
"classify table [miss-next|l2-miss_next|acl-miss-next <next_index>]"
|
||||
"\n mask <mask-value> buckets <nn> [skip <n>] [match <n>] [del]",
|
||||
"\n mask <mask-value> buckets <nn> [skip <n>] [match <n>]"
|
||||
"\n [current-data-flag <n>] [current-data-offset <n>] [table <n>] [del]",
|
||||
.function = classify_table_command_fn,
|
||||
};
|
||||
|
||||
@ -1473,8 +1494,9 @@ static u8 * format_vnet_classify_table (u8 * s, va_list * args)
|
||||
|
||||
s = format (s, "\n Heap: %U", format_mheap, t->mheap, 0 /*verbose*/);
|
||||
|
||||
s = format (s, "\n nbuckets %d, skip %d match %d",
|
||||
t->nbuckets, t->skip_n_vectors, t->match_n_vectors);
|
||||
s = format (s, "\n nbuckets %d, skip %d match %d flag %d offset %d",
|
||||
t->nbuckets, t->skip_n_vectors, t->match_n_vectors,
|
||||
t->current_data_flag, t->current_data_offset);
|
||||
s = format (s, "\n mask %U", format_hex_bytes, t->mask,
|
||||
t->match_n_vectors * sizeof (u32x4));
|
||||
|
||||
@ -1974,6 +1996,8 @@ int vnet_classify_add_del_session (vnet_classify_main_t * cm,
|
||||
u32 hit_next_index,
|
||||
u32 opaque_index,
|
||||
i32 advance,
|
||||
u8 action,
|
||||
u32 metadata,
|
||||
int is_add)
|
||||
{
|
||||
vnet_classify_table_t * t;
|
||||
@ -1993,6 +2017,11 @@ int vnet_classify_add_del_session (vnet_classify_main_t * cm,
|
||||
e->hits = 0;
|
||||
e->last_heard = 0;
|
||||
e->flags = 0;
|
||||
e->action = action;
|
||||
if (e->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX)
|
||||
e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, metadata);
|
||||
else if (e->action == CLASSIFY_ACTION_SET_IP6_FIB_INDEX)
|
||||
e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, metadata);
|
||||
|
||||
/* Copy key data, honoring skip_n_vectors */
|
||||
clib_memcpy (&e->key, match + t->skip_n_vectors * sizeof (u32x4),
|
||||
@ -2020,6 +2049,8 @@ classify_session_command_fn (vlib_main_t * vm,
|
||||
u64 opaque_index = ~0;
|
||||
u8 * match = 0;
|
||||
i32 advance = 0;
|
||||
u32 action = 0;
|
||||
u32 metadata = 0;
|
||||
int i, rv;
|
||||
|
||||
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
||||
@ -2050,6 +2081,10 @@ classify_session_command_fn (vlib_main_t * vm,
|
||||
;
|
||||
else if (unformat (input, "table-index %d", &table_index))
|
||||
;
|
||||
else if (unformat (input, "action set-ip4-fib-id %d", &metadata))
|
||||
action = 1;
|
||||
else if (unformat (input, "action set-ip6-fib-id %d", &metadata))
|
||||
action = 2;
|
||||
else
|
||||
{
|
||||
/* Try registered opaque-index unformat fns */
|
||||
@ -2073,7 +2108,8 @@ classify_session_command_fn (vlib_main_t * vm,
|
||||
|
||||
rv = vnet_classify_add_del_session (cm, table_index, match,
|
||||
hit_next_index,
|
||||
opaque_index, advance, is_add);
|
||||
opaque_index, advance,
|
||||
action, metadata, is_add);
|
||||
|
||||
switch(rv)
|
||||
{
|
||||
@ -2093,7 +2129,8 @@ VLIB_CLI_COMMAND (classify_session_command, static) = {
|
||||
.short_help =
|
||||
"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>]",
|
||||
"\n table-index <nn> match [hex] [l2] [l3 ip4] [opaque-index <index>]"
|
||||
"\n [action set-ip4-fib-id <n>] [action set-ip6-fib-id <n>] [del]",
|
||||
.function = classify_session_command_fn,
|
||||
};
|
||||
|
||||
@ -2323,7 +2360,7 @@ test_classify_command_fn (vlib_main_t * vm,
|
||||
rv = vnet_classify_add_del_session (cm, t - cm->tables, (u8 *) data,
|
||||
IP_LOOKUP_NEXT_DROP,
|
||||
i+100 /* opaque_index */,
|
||||
0 /* advance */,
|
||||
0 /* advance */, 0, 0,
|
||||
1 /* is_add */);
|
||||
|
||||
if (rv != 0)
|
||||
@ -2362,7 +2399,7 @@ test_classify_command_fn (vlib_main_t * vm,
|
||||
rv = vnet_classify_add_del_session (cm, t - cm->tables, key_minus_skip,
|
||||
IP_LOOKUP_NEXT_DROP,
|
||||
i+100 /* opaque_index */,
|
||||
0 /* advance */,
|
||||
0 /* advance */, 0, 0,
|
||||
0 /* is_add */);
|
||||
if (rv != 0)
|
||||
clib_warning ("del: returned %d", rv);
|
||||
|
@ -46,6 +46,25 @@ extern vlib_node_registration_t ip6_classify_node;
|
||||
|
||||
#define U32X4_ALIGNED(p) PREDICT_TRUE((((intptr_t)p) & 0xf) == 0)
|
||||
|
||||
/*
|
||||
* Classify table option to process packets
|
||||
* CLASSIFY_FLAG_USE_CURR_DATA:
|
||||
* - classify packets starting from VPP node’s current data pointer
|
||||
*/
|
||||
#define CLASSIFY_FLAG_USE_CURR_DATA 1
|
||||
|
||||
/*
|
||||
* Classify session action
|
||||
* CLASSIFY_ACTION_SET_IP4_FIB_INDEX:
|
||||
* - Classified IP packets will be looked up
|
||||
* from the specified ipv4 fib table
|
||||
* CLASSIFY_ACTION_SET_IP6_FIB_INDEX:
|
||||
* - Classified IP packets will be looked up
|
||||
* from the specified ipv6 fib table
|
||||
*/
|
||||
#define CLASSIFY_ACTION_SET_IP4_FIB_INDEX 1
|
||||
#define CLASSIFY_ACTION_SET_IP6_FIB_INDEX 2
|
||||
|
||||
struct _vnet_classify_main;
|
||||
typedef struct _vnet_classify_main vnet_classify_main_t;
|
||||
|
||||
@ -71,9 +90,12 @@ typedef CLIB_PACKED(struct _vnet_classify_entry {
|
||||
};
|
||||
|
||||
/* Really only need 1 bit */
|
||||
u32 flags;
|
||||
u8 flags;
|
||||
#define VNET_CLASSIFY_ENTRY_FREE (1<<0)
|
||||
|
||||
u8 action;
|
||||
u16 metadata;
|
||||
|
||||
/* Hit counter, last heard time */
|
||||
union {
|
||||
u64 hits;
|
||||
@ -131,6 +153,9 @@ typedef struct {
|
||||
u32 log2_nbuckets;
|
||||
int entries_per_page;
|
||||
u32 active_elements;
|
||||
u32 current_data_flag;
|
||||
int current_data_offset;
|
||||
u32 data_offset;
|
||||
/* Index of next table to try */
|
||||
u32 next_table_index;
|
||||
|
||||
@ -449,6 +474,8 @@ int vnet_classify_add_del_session (vnet_classify_main_t * cm,
|
||||
u32 hit_next_index,
|
||||
u32 opaque_index,
|
||||
i32 advance,
|
||||
u8 action,
|
||||
u32 metadata,
|
||||
int is_add);
|
||||
|
||||
int vnet_classify_add_del_table (vnet_classify_main_t * cm,
|
||||
@ -460,6 +487,8 @@ int vnet_classify_add_del_table (vnet_classify_main_t * cm,
|
||||
u32 next_table_index,
|
||||
u32 miss_next_index,
|
||||
u32 * table_index,
|
||||
u8 current_data_flag,
|
||||
i16 current_data_offset,
|
||||
int is_add);
|
||||
|
||||
unformat_function_t unformat_ip4_mask;
|
||||
|
@ -115,11 +115,9 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
|
||||
bi0 = from[0];
|
||||
b0 = vlib_get_buffer (vm, bi0);
|
||||
h0 = b0->data;
|
||||
|
||||
bi1 = from[1];
|
||||
b1 = vlib_get_buffer (vm, bi1);
|
||||
h1 = b1->data;
|
||||
|
||||
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
|
||||
table_index0 = am->classify_table_index_by_sw_if_index[tid][sw_if_index0];
|
||||
@ -131,11 +129,21 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
|
||||
t1 = pool_elt_at_index (vcm->tables, table_index1);
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 = (void *)vlib_buffer_get_current (b0) + t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
vnet_buffer(b0)->l2_classify.hash =
|
||||
vnet_classify_hash_packet (t0, (u8 *) h0);
|
||||
|
||||
vnet_classify_prefetch_bucket (t0, vnet_buffer(b0)->l2_classify.hash);
|
||||
|
||||
if (t1->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h1 = (void *)vlib_buffer_get_current (b1) + t1->current_data_offset;
|
||||
else
|
||||
h1 = b1->data;
|
||||
|
||||
vnet_buffer(b1)->l2_classify.hash =
|
||||
vnet_classify_hash_packet (t1, (u8 *) h1);
|
||||
|
||||
@ -160,12 +168,17 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
|
||||
bi0 = from[0];
|
||||
b0 = vlib_get_buffer (vm, bi0);
|
||||
h0 = b0->data;
|
||||
|
||||
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
|
||||
table_index0 = am->classify_table_index_by_sw_if_index[tid][sw_if_index0];
|
||||
|
||||
t0 = pool_elt_at_index (vcm->tables, table_index0);
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 = (void *)vlib_buffer_get_current (b0) + t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
vnet_buffer(b0)->l2_classify.hash =
|
||||
vnet_classify_hash_packet (t0, (u8 *) h0);
|
||||
|
||||
@ -227,7 +240,6 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
n_left_to_next -= 1;
|
||||
|
||||
b0 = vlib_get_buffer (vm, bi0);
|
||||
h0 = b0->data;
|
||||
table_index0 = vnet_buffer(b0)->l2_classify.table_index;
|
||||
e0 = 0;
|
||||
t0 = 0;
|
||||
@ -243,6 +255,11 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
hash0 = vnet_buffer(b0)->l2_classify.hash;
|
||||
t0 = pool_elt_at_index (vcm->tables, table_index0);
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 = (void *)vlib_buffer_get_current (b0) + t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
e0 = vnet_classify_find_entry (t0, (u8 *) h0, hash0,
|
||||
now);
|
||||
if (e0)
|
||||
@ -263,6 +280,10 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
error0 = (next0 == ACL_NEXT_INDEX_DENY)?
|
||||
IP6_ERROR_INACL_SESSION_DENY:IP6_ERROR_NONE;
|
||||
b0->error = error_node->errors[error0];
|
||||
|
||||
if (e0->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX ||
|
||||
e0->action == CLASSIFY_ACTION_SET_IP6_FIB_INDEX)
|
||||
vnet_buffer (b0)->sw_if_index[VLIB_TX] = e0->metadata;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -288,6 +309,11 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
break;
|
||||
}
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 = (void *)vlib_buffer_get_current (b0) + t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
hash0 = vnet_classify_hash_packet (t0, (u8 *) h0);
|
||||
e0 = vnet_classify_find_entry
|
||||
(t0, (u8 *) h0, hash0, now);
|
||||
@ -308,6 +334,10 @@ ip_inacl_inline (vlib_main_t * vm,
|
||||
error0 = (next0 == ACL_NEXT_INDEX_DENY)?
|
||||
IP6_ERROR_INACL_SESSION_DENY:IP6_ERROR_NONE;
|
||||
b0->error = error_node->errors[error0];
|
||||
|
||||
if (e0->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX ||
|
||||
e0->action == CLASSIFY_ACTION_SET_IP6_FIB_INDEX)
|
||||
vnet_buffer (b0)->sw_if_index[VLIB_TX] = e0->metadata;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -137,11 +137,9 @@ l2_inacl_node_fn (vlib_main_t * vm,
|
||||
|
||||
bi0 = from[0];
|
||||
b0 = vlib_get_buffer (vm, bi0);
|
||||
h0 = b0->data;
|
||||
|
||||
bi1 = from[1];
|
||||
b1 = vlib_get_buffer (vm, bi1);
|
||||
h1 = b1->data;
|
||||
|
||||
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
|
||||
table_index0 =
|
||||
@ -155,11 +153,21 @@ l2_inacl_node_fn (vlib_main_t * vm,
|
||||
|
||||
t1 = pool_elt_at_index (vcm->tables, table_index1);
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 = (void *) vlib_buffer_get_current (b0) + t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
vnet_buffer (b0)->l2_classify.hash =
|
||||
vnet_classify_hash_packet (t0, (u8 *) h0);
|
||||
|
||||
vnet_classify_prefetch_bucket (t0, vnet_buffer (b0)->l2_classify.hash);
|
||||
|
||||
if (t1->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h1 = (void *) vlib_buffer_get_current (b1) + t1->current_data_offset;
|
||||
else
|
||||
h1 = b1->data;
|
||||
|
||||
vnet_buffer (b1)->l2_classify.hash =
|
||||
vnet_classify_hash_packet (t1, (u8 *) h1);
|
||||
|
||||
@ -184,13 +192,18 @@ l2_inacl_node_fn (vlib_main_t * vm,
|
||||
|
||||
bi0 = from[0];
|
||||
b0 = vlib_get_buffer (vm, bi0);
|
||||
h0 = b0->data;
|
||||
|
||||
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
|
||||
table_index0 =
|
||||
am->classify_table_index_by_sw_if_index[tid][sw_if_index0];
|
||||
|
||||
t0 = pool_elt_at_index (vcm->tables, table_index0);
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 = (void *) vlib_buffer_get_current (b0) + t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
vnet_buffer (b0)->l2_classify.hash =
|
||||
vnet_classify_hash_packet (t0, (u8 *) h0);
|
||||
|
||||
@ -251,7 +264,7 @@ l2_inacl_node_fn (vlib_main_t * vm,
|
||||
n_left_to_next -= 1;
|
||||
|
||||
b0 = vlib_get_buffer (vm, bi0);
|
||||
h0 = b0->data;
|
||||
|
||||
table_index0 = vnet_buffer (b0)->l2_classify.table_index;
|
||||
e0 = 0;
|
||||
t0 = 0;
|
||||
@ -270,6 +283,13 @@ l2_inacl_node_fn (vlib_main_t * vm,
|
||||
hash0 = vnet_buffer (b0)->l2_classify.hash;
|
||||
t0 = pool_elt_at_index (vcm->tables, table_index0);
|
||||
|
||||
if (t0->current_data_flag == CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 =
|
||||
(void *) vlib_buffer_get_current (b0) +
|
||||
t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
e0 = vnet_classify_find_entry (t0, (u8 *) h0, hash0, now);
|
||||
if (e0)
|
||||
{
|
||||
@ -308,6 +328,14 @@ l2_inacl_node_fn (vlib_main_t * vm,
|
||||
break;
|
||||
}
|
||||
|
||||
if (t0->current_data_flag ==
|
||||
CLASSIFY_FLAG_USE_CURR_DATA)
|
||||
h0 =
|
||||
(void *) vlib_buffer_get_current (b0) +
|
||||
t0->current_data_offset;
|
||||
else
|
||||
h0 = b0->data;
|
||||
|
||||
hash0 = vnet_classify_hash_packet (t0, (u8 *) h0);
|
||||
e0 = vnet_classify_find_entry
|
||||
(t0, (u8 *) h0, hash0, now);
|
||||
|
@ -8756,6 +8756,8 @@ api_classify_add_del_table (vat_main_t * vam)
|
||||
u32 memory_size = 32 << 20;
|
||||
u8 *mask = 0;
|
||||
f64 timeout;
|
||||
u32 current_data_flag = 0;
|
||||
int current_data_offset = 0;
|
||||
|
||||
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
@ -8785,6 +8787,10 @@ api_classify_add_del_table (vat_main_t * vam)
|
||||
else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
|
||||
&miss_next_index))
|
||||
;
|
||||
else if (unformat (i, "current-data-flag %d", ¤t_data_flag))
|
||||
;
|
||||
else if (unformat (i, "current-data-offset %d", ¤t_data_offset))
|
||||
;
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -8823,6 +8829,8 @@ api_classify_add_del_table (vat_main_t * vam)
|
||||
mp->match_n_vectors = ntohl (match);
|
||||
mp->next_table_index = ntohl (next_table_index);
|
||||
mp->miss_next_index = ntohl (miss_next_index);
|
||||
mp->current_data_flag = ntohl (current_data_flag);
|
||||
mp->current_data_offset = ntohl (current_data_offset);
|
||||
clib_memcpy (mp->mask, mask, vec_len (mask));
|
||||
|
||||
vec_free (mask);
|
||||
@ -9282,6 +9290,8 @@ api_classify_add_del_session (vat_main_t * vam)
|
||||
f64 timeout;
|
||||
u32 skip_n_vectors = 0;
|
||||
u32 match_n_vectors = 0;
|
||||
u32 action = 0;
|
||||
u32 metadata = 0;
|
||||
|
||||
/*
|
||||
* Warning: you have to supply skip_n and match_n
|
||||
@ -9319,6 +9329,14 @@ api_classify_add_del_session (vat_main_t * vam)
|
||||
;
|
||||
else if (unformat (i, "table-index %d", &table_index))
|
||||
;
|
||||
else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
|
||||
action = 1;
|
||||
else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
|
||||
action = 2;
|
||||
else if (unformat (i, "action %d", &action))
|
||||
;
|
||||
else if (unformat (i, "metadata %d", &metadata))
|
||||
;
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -9342,6 +9360,8 @@ api_classify_add_del_session (vat_main_t * vam)
|
||||
mp->hit_next_index = ntohl (hit_next_index);
|
||||
mp->opaque_index = ntohl (opaque_index);
|
||||
mp->advance = ntohl (advance);
|
||||
mp->action = action;
|
||||
mp->metadata = ntohl (metadata);
|
||||
clib_memcpy (mp->match, match, vec_len (match));
|
||||
vec_free (match);
|
||||
|
||||
@ -16641,12 +16661,14 @@ _(sr_multicast_map_add_del, \
|
||||
"address [ip6 multicast address] sr-policy [policy name] [del]") \
|
||||
_(classify_add_del_table, \
|
||||
"buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
|
||||
"[del] mask <mask-value>\n" \
|
||||
" [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
|
||||
" [del] mask <mask-value>\n" \
|
||||
" [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n" \
|
||||
" [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]") \
|
||||
_(classify_add_del_session, \
|
||||
"[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
|
||||
" table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
|
||||
" [l3 [ip4|ip6]]") \
|
||||
" [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n" \
|
||||
" [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]") \
|
||||
_(classify_set_interface_ip_table, \
|
||||
"<intfc> | sw_if_index <nn> table <nn>") \
|
||||
_(classify_set_interface_l2_tables, \
|
||||
|
@ -3922,7 +3922,9 @@ _(memory_size) \
|
||||
_(skip_n_vectors) \
|
||||
_(match_n_vectors) \
|
||||
_(next_table_index) \
|
||||
_(miss_next_index)
|
||||
_(miss_next_index) \
|
||||
_(current_data_flag) \
|
||||
_(current_data_offset)
|
||||
|
||||
static void vl_api_classify_add_del_table_t_handler
|
||||
(vl_api_classify_add_del_table_t * mp)
|
||||
@ -3941,17 +3943,25 @@ static void vl_api_classify_add_del_table_t_handler
|
||||
#undef _
|
||||
|
||||
/* The underlying API fails silently, on purpose, so check here */
|
||||
if (mp->is_add == 0)
|
||||
if (pool_is_free_index (cm->tables, table_index))
|
||||
{
|
||||
rv = VNET_API_ERROR_NO_SUCH_TABLE;
|
||||
goto out;
|
||||
}
|
||||
if (mp->is_add == 0) /* delete */
|
||||
{
|
||||
if (pool_is_free_index (cm->tables, table_index))
|
||||
{
|
||||
rv = VNET_API_ERROR_NO_SUCH_TABLE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else /* add or update */
|
||||
{
|
||||
if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
|
||||
table_index = ~0;
|
||||
}
|
||||
|
||||
rv = vnet_classify_add_del_table
|
||||
(cm, mp->mask, nbuckets, memory_size,
|
||||
skip_n_vectors, match_n_vectors,
|
||||
next_table_index, miss_next_index, &table_index, mp->is_add);
|
||||
next_table_index, miss_next_index, &table_index,
|
||||
current_data_flag, current_data_offset, mp->is_add);
|
||||
|
||||
out:
|
||||
/* *INDENT-OFF* */
|
||||
@ -3980,17 +3990,20 @@ static void vl_api_classify_add_del_session_t_handler
|
||||
vnet_classify_main_t *cm = &vnet_classify_main;
|
||||
vl_api_classify_add_del_session_reply_t *rmp;
|
||||
int rv;
|
||||
u32 table_index, hit_next_index, opaque_index;
|
||||
u32 table_index, hit_next_index, opaque_index, metadata;
|
||||
i32 advance;
|
||||
u8 action;
|
||||
|
||||
table_index = ntohl (mp->table_index);
|
||||
hit_next_index = ntohl (mp->hit_next_index);
|
||||
opaque_index = ntohl (mp->opaque_index);
|
||||
advance = ntohl (mp->advance);
|
||||
action = mp->action;
|
||||
metadata = ntohl (mp->metadata);
|
||||
|
||||
rv = vnet_classify_add_del_session
|
||||
(cm, table_index, mp->match, hit_next_index, opaque_index,
|
||||
advance, mp->is_add);
|
||||
advance, action, metadata, mp->is_add);
|
||||
|
||||
REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
|
||||
}
|
||||
|
@ -1222,6 +1222,10 @@ static void *vl_api_classify_add_del_table_t_print
|
||||
s = format (s, "match %d ", ntohl (mp->match_n_vectors));
|
||||
s = format (s, "next-table %d ", ntohl (mp->next_table_index));
|
||||
s = format (s, "miss-next %d ", ntohl (mp->miss_next_index));
|
||||
s = format (s, "current-data-flag %d ", ntohl (mp->current_data_flag));
|
||||
if (mp->current_data_flag)
|
||||
s = format (s, "current-data-offset %d ",
|
||||
ntohl (mp->current_data_offset));
|
||||
s = format (s, "mask hex ");
|
||||
for (i = 0; i < ntohl (mp->match_n_vectors) * sizeof (u32x4); i++)
|
||||
s = format (s, "%02x", mp->mask[i]);
|
||||
@ -1243,6 +1247,9 @@ static void *vl_api_classify_add_del_session_t_print
|
||||
s = format (s, "hit_next_index %d ", ntohl (mp->hit_next_index));
|
||||
s = format (s, "opaque_index %d ", ntohl (mp->opaque_index));
|
||||
s = format (s, "advance %d ", ntohl (mp->advance));
|
||||
s = format (s, "action %d ", mp->action);
|
||||
if (mp->action)
|
||||
s = format (s, "metadata %d ", ntohl (mp->metadata));
|
||||
if (mp->is_add == 0)
|
||||
s = format (s, "del ");
|
||||
|
||||
|
@ -1766,6 +1766,17 @@ define bd_ip_mac_add_del_reply
|
||||
@param match_n_vectors - number of match vectors
|
||||
@param next_table_index - index of next table
|
||||
@param miss_next_index - index of miss table
|
||||
@param current_data_flag - option to use current node's packet payload
|
||||
as the starting point from where packets are classified,
|
||||
This option is only valid for L2/L3 input ACL for now.
|
||||
0: by default, classify data from the buffer's start location
|
||||
1: classify packets from VPP node’s current data pointer
|
||||
@param current_data_offset - a signed value to shift the start location of
|
||||
the packet to be classified
|
||||
For example, if input IP ACL node is used, L2 header’s first byte
|
||||
can be accessible by configuring current_data_offset to -14
|
||||
if there is no vlan tag.
|
||||
This is valid only if current_data_flag is set to 1.
|
||||
@param mask[] - match mask
|
||||
*/
|
||||
define classify_add_del_table
|
||||
@ -1780,6 +1791,8 @@ define classify_add_del_table
|
||||
u32 match_n_vectors;
|
||||
u32 next_table_index;
|
||||
u32 miss_next_index;
|
||||
u32 current_data_flag;
|
||||
i32 current_data_offset;
|
||||
u8 mask[0];
|
||||
};
|
||||
|
||||
@ -1807,6 +1820,17 @@ define classify_add_del_table_reply
|
||||
@param hit_next_index - for add, hit_next_index of new session, required
|
||||
@param opaque_index - for add, opaque_index of new session
|
||||
@param advance -for add, advance value for session
|
||||
@param action -
|
||||
0: no action (by default)
|
||||
metadata is not used.
|
||||
1: Classified IP packets will be looked up from the
|
||||
specified ipv4 fib table (configured by metadata as VRF id).
|
||||
Only valid for L3 input ACL node
|
||||
2: Classified IP packets will be looked up from the
|
||||
specified ipv6 fib table (configured by metadata as VRF id).
|
||||
Only valid for L3 input ACL node
|
||||
@param metadata - valid only if action != 0
|
||||
VRF id if action is 1 or 2.
|
||||
@param match[] - for add, match value for session, required
|
||||
*/
|
||||
define classify_add_del_session
|
||||
@ -1818,6 +1842,8 @@ define classify_add_del_session
|
||||
u32 hit_next_index;
|
||||
u32 opaque_index;
|
||||
i32 advance;
|
||||
u8 action;
|
||||
u32 metadata;
|
||||
u8 match[0];
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user