diff options
author | Steve Shin <jonshin@cisco.com> | 2016-11-08 10:47:10 -0800 |
---|---|---|
committer | John Lo <loj@cisco.com> | 2016-11-16 02:29:44 +0000 |
commit | 25e26dc5136137c771715145dd5b2884060ff9eb (patch) | |
tree | 9279b106952a9a603060a185bda6b9f2e89ec8f4 | |
parent | 9c6ae5f43b1f3141d37d6d7b3963926302826f08 (diff) |
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>
-rw-r--r-- | vnet/vnet/classify/vnet_classify.c | 89 | ||||
-rw-r--r-- | vnet/vnet/classify/vnet_classify.h | 31 | ||||
-rw-r--r-- | vnet/vnet/ip/ip_input_acl.c | 38 | ||||
-rw-r--r-- | vnet/vnet/l2/l2_input_acl.c | 36 | ||||
-rw-r--r-- | vpp-api-test/vat/api_format.c | 28 | ||||
-rw-r--r-- | vpp/vpp-api/api.c | 33 | ||||
-rw-r--r-- | vpp/vpp-api/custom_dump.c | 7 | ||||
-rw-r--r-- | vpp/vpp-api/vpe.api | 26 |
8 files changed, 240 insertions, 48 deletions
diff --git a/vnet/vnet/classify/vnet_classify.c b/vnet/vnet/classify/vnet_classify.c index e179045814c..d7a0d815e5c 100644 --- a/vnet/vnet/classify/vnet_classify.c +++ b/vnet/vnet/classify/vnet_classify.c @@ -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 (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; + 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; + + 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); diff --git a/vnet/vnet/classify/vnet_classify.h b/vnet/vnet/classify/vnet_classify.h index f609aaa49d6..ed8442b3dce 100644 --- a/vnet/vnet/classify/vnet_classify.h +++ b/vnet/vnet/classify/vnet_classify.h @@ -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; diff --git a/vnet/vnet/ip/ip_input_acl.c b/vnet/vnet/ip/ip_input_acl.c index 6331cf4fa6b..93a580ce47c 100644 --- a/vnet/vnet/ip/ip_input_acl.c +++ b/vnet/vnet/ip/ip_input_acl.c @@ -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; } } diff --git a/vnet/vnet/l2/l2_input_acl.c b/vnet/vnet/l2/l2_input_acl.c index de9f6791225..104fcd15b85 100644 --- a/vnet/vnet/l2/l2_input_acl.c +++ b/vnet/vnet/l2/l2_input_acl.c @@ -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); diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index 65114ec2d70..b32c159da8f 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -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, \ diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index 1ecd148186b..b29757602c9 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -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); } diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c index b42130d6972..1dc96650aec 100644 --- a/vpp/vpp-api/custom_dump.c +++ b/vpp/vpp-api/custom_dump.c @@ -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 "); diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index e69979c64fa..8a7fac67604 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -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]; }; |