From 9137e5400699bed9f7c0095187839a8b38273100 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Fri, 13 Sep 2019 17:47:50 -0400 Subject: 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 Change-Id: I05b1358a769f61e6d32470e0c87058f640486b26 --- src/vnet/classify/trace_classify.h | 100 +++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/vnet/classify/trace_classify.h (limited to 'src/vnet/classify/trace_classify.h') 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 +#include +#include +#include + +/** @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: + */ -- cgit 1.2.3-korg