diff options
author | Dave Barach <dave@barachs.net> | 2019-09-13 17:47:50 -0400 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-09-25 22:19:59 +0000 |
commit | 1b696ac9b334aa9305925e4759c6c6f6b47c3328 (patch) | |
tree | 6cbc009453d33c1a7d54b5aca1a4d347bbcf0a8a /src/vnet/classify/trace_classify.h | |
parent | 2abe699d10450553148307bb614979902f2bf4b3 (diff) |
misc: classifier-based packet trace filter
See .../src/vnet/classify/trace_classify.h for the business end
of the scheme.
It would be best to hash pkts, prefetch buckets, and do the primary
table lookups two at a time. The inline as given works, but perf
tuning will be required. "At least it works..."
Add "classify filter" debug cli, for example:
classify filter mask l3 ip4 src dst \
match l3 ip4 dst 192.168.2.10 src 192.168.1.10
Add "pcap rx | tx trace ... filter" to use the current classify filter chain
Patch includes sphinx documentation and doxygen tags.
Next step: device-driver integration
Type: feature
Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I05b1358a769f61e6d32470e0c87058f640486b26
(cherry picked from commit 9137e5400699bed9f7c0095187839a8b38273100)
Diffstat (limited to 'src/vnet/classify/trace_classify.h')
-rw-r--r-- | src/vnet/classify/trace_classify.h | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/vnet/classify/trace_classify.h b/src/vnet/classify/trace_classify.h new file mode 100644 index 00000000000..bc25ecd0ff7 --- /dev/null +++ b/src/vnet/classify/trace_classify.h @@ -0,0 +1,100 @@ +/* + * trace_classify.h - Use the classifier to decide if a packet is traced + * + * Copyright (c) 2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <vlib/vlib.h> +#include <vnet/vnet.h> +#include <vppinfra/error.h> +#include <vnet/classify/vnet_classify.h> + +/** @file trace_classify.h + * Use the vpp classifier to decide whether to trace packets + */ + +/** @brief vnet_is_packet_traced + * @param vlib_buffer_t *b - packet to classify + * @param int func - 0 => use classifier w/ supplied table index + * @param u32 classify_table_index - classifier table index + * @return 0 => no trace, 1 => trace, -1 => error + */ + +static inline int +vnet_is_packet_traced_inline (vlib_buffer_t * b, + u32 classify_table_index, int func) +{ + vnet_classify_main_t *vcm = &vnet_classify_main; + vnet_classify_table_t *t; + vnet_classify_entry_t *e; + u64 hash; + + /*$$$ add custom classifiers here, if any */ + if (func != 0) + return -1; + + /* This will happen... */ + if (pool_is_free_index (vcm->tables, classify_table_index)) + return -1; + + /* Get the table */ + t = pool_elt_at_index (vcm->tables, classify_table_index); + + /* Hash the packet */ + hash = vnet_classify_hash_packet (t, vlib_buffer_get_current (b)); + + /* See if there's a matching entry */ + e = vnet_classify_find_entry (t, vlib_buffer_get_current (b), hash, + 0 /* time = 0, disables hit-counter */ ); + /* Hit means trace the packet... */ + if (e) + { + /* Manual hit accounting */ + e->hits++; + return 1; + } + + /* + * Look for a hit in a less-specific table. + * Performance hint: for this use-case, don't go there. + */ + while (1) + { + /* Most likely, we're done right now */ + if (PREDICT_TRUE (t->next_table_index == ~0)) + return 0; + t = pool_elt_at_index (vcm->tables, t->next_table_index); + + /* Compute hash for this table */ + hash = vnet_classify_hash_packet (t, vlib_buffer_get_current (b)); + + /* See if there's a matching entry */ + e = vnet_classify_find_entry (t, vlib_buffer_get_current (b), hash, + 0 /* time = 0, disables hit-counter */ ); + if (e) + { + /* Manual hit accounting */ + e->hits++; + return 1; + } + } + /* NOTREACHED */ +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |