X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fclassify%2Fvnet_classify.c;h=bf030241f68bc3951cc887ebcc7febf33c8faf2d;hb=104112f2d412a4576b5e0d3bbb20665d2b5bd615;hp=fb61401b49ce07e661a9adc85bbda28252d0f8e4;hpb=f5667c3055dbd6755277f085c6778c2b1104aa6e;p=vpp.git diff --git a/src/vnet/classify/vnet_classify.c b/src/vnet/classify/vnet_classify.c index fb61401b49c..bf030241f68 100755 --- a/src/vnet/classify/vnet_classify.c +++ b/src/vnet/classify/vnet_classify.c @@ -19,6 +19,7 @@ #include /* for L2_INPUT_CLASSIFY_NEXT_xxx */ #include #include +#include /** * @file @@ -146,13 +147,9 @@ vnet_classify_new_table (vnet_classify_main_t * cm, t->skip_n_vectors = skip_n_vectors; t->entries_per_page = 2; -#if USE_DLMALLOC == 0 - t->mheap = mheap_alloc (0 /* use VM */ , memory_size); -#else t->mheap = create_mspace (memory_size, 1 /* locked */ ); /* classifier requires the memory to be contiguous, so can not expand. */ mspace_disable_expand (t->mheap); -#endif vec_validate_aligned (t->buckets, nbuckets - 1, CLIB_CACHE_LINE_BYTES); oldheap = clib_mem_set_heap (t->mheap); @@ -179,12 +176,7 @@ vnet_classify_delete_table_index (vnet_classify_main_t * cm, vec_free (t->mask); vec_free (t->buckets); -#if USE_DLMALLOC == 0 - mheap_free (t->mheap); -#else destroy_mspace (t->mheap); -#endif - pool_put (cm->tables, t); } @@ -774,6 +766,9 @@ vnet_classify_add_del_table (vnet_classify_main_t * cm, if (nbuckets == 0) return VNET_API_ERROR_INVALID_VALUE; + if (match < 1 || match > 5) + 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; @@ -1692,22 +1687,30 @@ classify_filter_command_fn (vlib_main_t * vm, u32 current_data_flag = 0; int current_data_offset = 0; u32 sw_if_index = ~0; + int pkt_trace = 0; + int pcap = 0; int i; vnet_classify_table_t *t; u8 *mask = 0; vnet_classify_main_t *cm = &vnet_classify_main; int rv = 0; vnet_classify_filter_set_t *set = 0; + u32 set_index = ~0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "del")) is_add = 0; - else if (unformat (input, "pcap %=", &sw_if_index, 0)) - ; + else if (unformat (input, "pcap %=", &pcap, 1)) + sw_if_index = 0; + else if (unformat (input, "trace")) + pkt_trace = 1; else if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) - ; + { + if (sw_if_index == 0) + return clib_error_return (0, "Local interface not supported..."); + } else if (unformat (input, "buckets %d", &nbuckets)) ; else if (unformat (input, "mask %U", unformat_classify_mask, @@ -1729,18 +1732,29 @@ classify_filter_command_fn (vlib_main_t * vm, if (is_add && match == ~0 && table_index == ~0) return clib_error_return (0, "match count required"); - if (sw_if_index == ~0) - return clib_error_return (0, "Must specify pcap or interface..."); + if (sw_if_index == ~0 && pkt_trace == 0 && pcap == 0) + return clib_error_return (0, "Must specify trace, pcap or interface..."); + + if (pkt_trace && pcap) + return clib_error_return + (0, "Packet trace and pcap are mutually exclusive..."); + + if (pkt_trace && sw_if_index != ~0) + return clib_error_return (0, "Packet trace filter is per-system"); if (!is_add) { - u32 set_index = 0; - if (sw_if_index < vec_len (cm->filter_set_by_sw_if_index)) + if (pkt_trace) + set_index = vlib_global_main.trace_filter.trace_filter_set_index; + else if (sw_if_index < vec_len (cm->filter_set_by_sw_if_index)) set_index = cm->filter_set_by_sw_if_index[sw_if_index]; - if (set_index == 0) + if (set_index == ~0) { + if (pkt_trace) + return clib_error_return (0, + "No pkt trace classify filter set..."); if (sw_if_index == 0) return clib_error_return (0, "No pcap classify filter set..."); else @@ -1759,27 +1773,36 @@ classify_filter_command_fn (vlib_main_t * vm, table_index = set->table_indices[0]; vec_reset_length (set->table_indices); pool_put (cm->filter_sets, set); - cm->filter_set_by_sw_if_index[sw_if_index] = 0; - if (sw_if_index > 0) + if (pkt_trace) { - vnet_hw_interface_t *hi = - vnet_get_sup_hw_interface (vnm, sw_if_index); - hi->trace_classify_table_index = ~0; + vlib_global_main.trace_filter.trace_filter_set_index = ~0; + vlib_global_main.trace_filter.trace_classify_table_index = ~0; + } + else + { + cm->filter_set_by_sw_if_index[sw_if_index] = ~0; + if (sw_if_index > 0) + { + vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, sw_if_index); + hi->trace_classify_table_index = ~0; + } } } } if (is_add) { - u32 set_index = 0; - - if (sw_if_index < vec_len (cm->filter_set_by_sw_if_index)) + if (pkt_trace) + set_index = vlib_global_main.trace_filter.trace_filter_set_index; + else if (sw_if_index < vec_len (cm->filter_set_by_sw_if_index)) set_index = cm->filter_set_by_sw_if_index[sw_if_index]; /* Do we have a filter set for this intfc / pcap yet? */ - if (set_index == 0) + if (set_index == ~0) { pool_get (cm->filter_sets, set); + set_index = set - cm->filter_sets; set->refcnt = 1; } else @@ -1826,11 +1849,18 @@ classify_filter_command_fn (vlib_main_t * vm, /* Remember the table */ vec_add1 (set->table_indices, table_index); - vec_validate_init_empty (cm->filter_set_by_sw_if_index, sw_if_index, 0); - cm->filter_set_by_sw_if_index[sw_if_index] = set - cm->filter_sets; + + if (pkt_trace) + vlib_global_main.trace_filter.trace_filter_set_index = set_index; + else + { + vec_validate_init_empty (cm->filter_set_by_sw_if_index, sw_if_index, + ~0); + cm->filter_set_by_sw_if_index[sw_if_index] = set - cm->filter_sets; + } /* Put top table index where device drivers can find them */ - if (sw_if_index > 0) + if (sw_if_index > 0 && pkt_trace == 0) { vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); ASSERT (vec_len (set->table_indices) > 0); @@ -1877,10 +1907,34 @@ found_table: return 0; } +/** Enable / disable packet trace filter */ +int +vlib_enable_disable_pkt_trace_filter (int enable) +{ + if (enable) + { + vnet_classify_main_t *cm = &vnet_classify_main; + vnet_classify_filter_set_t *set; + u32 set_index = vlib_global_main.trace_filter.trace_filter_set_index; + + if (set_index == ~0) + return -1; + + set = pool_elt_at_index (cm->filter_sets, set_index); + vlib_global_main.trace_filter.trace_classify_table_index = + set->table_indices[0]; + vlib_global_main.trace_filter.trace_filter_enable = 1; + } + else + { + vlib_global_main.trace_filter.trace_filter_enable = 0; + } + return 0; +} + /*? * Construct an arbitrary set of packet classifier tables for use with - * "pcap rx | tx trace," and (eventually) with the vpp packet - * tracer + * "pcap rx | tx trace," and with the vpp packet tracer * * Packets which match a rule in the classifier table chain * will be traced. The tables are automatically ordered so that @@ -1925,16 +1979,24 @@ found_table: * * Configure a simple classify filter, and configure pcap rx trace to use it: * - * classify filter mask l3 ip4 src match l3 ip4 src 192.168.1.11"
+ * classify filter rx mask l3 ip4 src match l3 ip4 src 192.168.1.11"
* pcap rx trace on max 100 filter * * Configure another fairly simple filter * * classify filter mask l3 ip4 src dst match l3 ip4 src 192.168.1.10 dst 192.168.2.10" * - * Clear all current classifier filters * - * classify filter del + * Configure a filter for use with the vpp packet tracer: + * classify filter trace mask l3 ip4 src dst match l3 ip4 src 192.168.1.10 dst 192.168.2.10" + * trace add dpdk-input 100 filter + * + * Clear classifier filters + * + * classify filter [trace | rx | tx | ] del + * + * To display the top-level classifier tables for each use case: + * show classify filter * * To inspect the classifier tables, use * @@ -1947,8 +2009,9 @@ VLIB_CLI_COMMAND (classify_filter, static) = { .path = "classify filter", .short_help = - "classify filter | pcap mask match [del]" - "[buckets ] [memory-size ]", + "classify filter | pcap mask match \n" + " | trace mask match [del]\n" + " [buckets ] [memory-size ]", .function = classify_filter_command_fn, }; /* *INDENT-ON* */ @@ -1966,30 +2029,42 @@ show_classify_filter_command_fn (vlib_main_t * vm, u32 set_index; u32 table_index; int verbose = 0; - int i, j; + int i, j, limit; (void) unformat (input, "verbose %=", &verbose, 1); vlib_cli_output (vm, "%-30s%s", "Filter Used By", " Table(s)"); vlib_cli_output (vm, "%-30s%s", "--------------", " --------"); - for (i = 0; i < vec_len (cm->filter_set_by_sw_if_index); i++) + limit = vec_len (cm->filter_set_by_sw_if_index); + + for (i = -1; i < limit; i++) { - set_index = cm->filter_set_by_sw_if_index[i]; + if (i < 0) + set_index = vlib_global_main.trace_filter.trace_filter_set_index; + else + set_index = cm->filter_set_by_sw_if_index[i]; - if (set_index == 0 && verbose == 0) + if (set_index == ~0) continue; set = pool_elt_at_index (cm->filter_sets, set_index); - if (i == 0) - name = format (0, "pcap rx/tx/drop:"); - else - name = format (0, "%U:", format_vnet_sw_if_index_name, vnm, i); + switch (i) + { + case -1: + name = format (0, "packet tracer:"); + break; + case 0: + name = format (0, "pcap rx/tx/drop:"); + break; + default: + name = format (0, "%U:", format_vnet_sw_if_index_name, vnm, i); + break; + } if (verbose) { - u8 *s = 0; u32 table_index; for (j = 0; j < vec_len (set->table_indices); j++) @@ -2001,20 +2076,19 @@ show_classify_filter_command_fn (vlib_main_t * vm, s = format (s, " none"); } - vlib_cli_output (vm, "%-30s table(s)%s", name, s); + vlib_cli_output (vm, "%-30v table(s)%v", name, s); vec_reset_length (s); } else { - u8 *s = 0; - table_index = set->table_indices[0]; + table_index = set->table_indices ? set->table_indices[0] : ~0; if (table_index != ~0) s = format (s, " %u", table_index); else s = format (s, " none"); - vlib_cli_output (vm, "%-30s first table%s", name, s); + vlib_cli_output (vm, "%-30v first table%v", name, s); vec_reset_length (s); } vec_reset_length (name); @@ -2869,18 +2943,26 @@ vnet_classify_init (vlib_main_t * vm) vnet_classify_register_unformat_acl_next_index_fn (unformat_acl_next_node); /* Filter set 0 is grounded... */ - pool_get (cm->filter_sets, set); + pool_get_zero (cm->filter_sets, set); set->refcnt = 0x7FFFFFFF; - vec_validate (set->table_indices, 0); - set->table_indices[0] = ~0; /* Initialize the pcap filter set */ vec_validate (cm->filter_set_by_sw_if_index, 0); + cm->filter_set_by_sw_if_index[0] = 0; + /* Initialize the packet tracer filter set */ + vlib_global_main.trace_filter.trace_filter_set_index = ~0; return 0; } VLIB_INIT_FUNCTION (vnet_classify_init); +int +vnet_is_packet_traced (vlib_buffer_t * b, u32 classify_table_index, int func) +{ + return vnet_is_packet_traced_inline (b, classify_table_index, func); +} + + #define TEST_CODE 0 #if TEST_CODE > 0