Line data Source code
1 : /* 2 : * trace_classify.h - Use the classifier to decide if a packet is traced 3 : * 4 : * Copyright (c) 2019 Cisco and/or its affiliates. 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at: 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : #include <vlib/vlib.h> 18 : #include <vnet/vnet.h> 19 : #include <vppinfra/error.h> 20 : #include <vnet/classify/vnet_classify.h> 21 : 22 : /** @file trace_classify.h 23 : * Use the vpp classifier to decide whether to trace packets 24 : */ 25 : 26 : /** @brief vnet_is_packet_traced 27 : * @param vlib_buffer_t *b - packet to classify 28 : * @param int func - 0 => use classifier w/ supplied table index 29 : * @param u32 classify_table_index - classifier table index 30 : * @return 0 => no trace, 1 => trace, -1 => error 31 : */ 32 : int vnet_is_packet_traced (vlib_buffer_t *b, u32 classify_table_index, 33 : int func); 34 : 35 : static inline int 36 525 : vnet_is_packet_traced_inline (vlib_buffer_t * b, 37 : u32 classify_table_index, int func) 38 : { 39 525 : vnet_classify_main_t *vcm = &vnet_classify_main; 40 : vnet_classify_table_t *t; 41 : vnet_classify_entry_t *e; 42 : u64 hash; 43 : 44 : /*$$$ add custom classifiers here, if any */ 45 525 : if (func != 0) 46 0 : return -1; 47 : 48 : /* This will happen... */ 49 525 : if (pool_is_free_index (vcm->tables, classify_table_index)) 50 0 : return -1; 51 : 52 : /* Get the table */ 53 525 : t = pool_elt_at_index (vcm->tables, classify_table_index); 54 : 55 : /* Hash the packet */ 56 525 : hash = vnet_classify_hash_packet (t, vlib_buffer_get_current (b)); 57 : 58 : /* See if there's a matching entry */ 59 525 : e = vnet_classify_find_entry (t, vlib_buffer_get_current (b), hash, 60 : 0 /* time = 0, disables hit-counter */ ); 61 : /* Hit means trace the packet... */ 62 525 : if (e) 63 : { 64 : /* Manual hit accounting */ 65 162 : e->hits++; 66 162 : return 1; 67 : } 68 : 69 : /* 70 : * Look for a hit in a less-specific table. 71 : * Performance hint: for this use-case, don't go there. 72 : */ 73 : while (1) 74 : { 75 : /* Most likely, we're done right now */ 76 545 : if (PREDICT_TRUE (t->next_table_index == ~0)) 77 329 : return 0; 78 216 : t = pool_elt_at_index (vcm->tables, t->next_table_index); 79 : 80 : /* Compute hash for this table */ 81 216 : hash = vnet_classify_hash_packet (t, vlib_buffer_get_current (b)); 82 : 83 : /* See if there's a matching entry */ 84 216 : e = vnet_classify_find_entry (t, vlib_buffer_get_current (b), hash, 85 : 0 /* time = 0, disables hit-counter */ ); 86 216 : if (e) 87 : { 88 : /* Manual hit accounting */ 89 34 : e->hits++; 90 34 : return 1; 91 : } 92 : } 93 : /* NOTREACHED */ 94 : } 95 : 96 : /* 97 : * fd.io coding-style-patch-verification: ON 98 : * 99 : * Local Variables: 100 : * eval: (c-set-style "gnu") 101 : * End: 102 : */