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:
Steve Shin
2016-11-08 10:47:10 -08:00
committed by John Lo
parent 9c6ae5f43b
commit 25e26dc513
8 changed files with 238 additions and 46 deletions

View File

@ -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", &current_data_flag))
;
else if (unformat (input, "current-data-offset %d", &current_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);

View File

@ -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 nodes 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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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", &current_data_flag))
;
else if (unformat (i, "current-data-offset %d", &current_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, \

View File

@ -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);
}

View File

@ -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 ");

View File

@ -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 nodes 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 headers 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];
};