FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
mma_template.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 #include <vppinfra/error.h>
17 
18 u8 RT (rule_is_exact_match) (RTT (mma_rule) * key, RTT (mma_rule) * r)
19 {
20  int i;
21 
22  for (i = 0; i < ARRAY_LEN (key->match.as_u64); i++)
23  {
24  if (key->match.as_u64[i] != r->match.as_u64[i])
25  return 0;
26  }
27  for (i = 0; i < ARRAY_LEN (key->mask.as_u64); i++)
28  {
29  if (key->mask.as_u64[i] != r->mask.as_u64[i])
30  return 0;
31  }
32  return 1;
33 }
34 
35 u8
36 RT (rule_is_match_for_key) (RTT (mma_mask_or_match) * key, RTT (mma_rule) * r)
37 {
38  RTT (mma_mask_or_match) _tmp_key, *tkp = &_tmp_key;
39  int i;
40 
41  *tkp = *key;
42  for (i = 0; i < ARRAY_LEN (tkp->as_u64); i++)
43  tkp->as_u64[i] &= r->mask.as_u64[i];
44  for (i = 0; i < ARRAY_LEN (tkp->as_u64); i++)
45  {
46  if (tkp->as_u64[i] != r->match.as_u64[i])
47  return 0;
48  }
49  return 1;
50 }
51 
52 RTT (mma_rule) * RT (mma_rules_table_rule_alloc) (RTT (mma_rules_table) * srt)
53 {
54  RTT (mma_rule) * rule;
55  pool_get (srt->rules, rule);
56  clib_memset (rule, 0, sizeof (*rule));
57  return rule;
58 }
59 
60 RTT (mma_rule) *
61 RT (mma_rule_free) (RTT (mma_rules_table) * srt, RTT (mma_rule) * rule)
62 {
63  clib_memset (rule, 0xfa, sizeof (*rule));
64  pool_put (srt->rules, rule);
65  return rule;
66 }
67 
68 void RT (mma_rules_table_free) (RTT (mma_rules_table) * srt)
69 {
70  pool_free (srt->rules);
71 }
72 
73 RTT (mma_rule) *
74 RT (mma_rules_table_get_rule) (RTT (mma_rules_table) * srt, u32 srt_index)
75 {
76  if (!pool_is_free_index (srt->rules, srt_index))
77  return (srt->rules + srt_index);
78  return 0;
79 }
80 
81 u32
82 RT (mma_rules_table_rule_index) (RTT (mma_rules_table) * srt,
83  RTT (mma_rule) * sr)
84 {
85  ASSERT (sr);
86  return (sr - srt->rules);
87 }
88 
89 /**
90  * Lookup key in table
91  *
92  * This should be optimized .. eventually
93  */
94 u32
95 RT (mma_rules_table_lookup) (RTT (mma_rules_table) * srt,
96  RTT (mma_mask_or_match) * key, u32 rule_index)
97 {
98  RTT (mma_rule) * rp;
99  u32 rv;
100  int i;
101 
102  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
103  rp = RT (mma_rules_table_get_rule) (srt, rule_index);
104  ASSERT (rp);
105 
106  if (!RT (rule_is_match_for_key) (key, rp))
108  for (i = 0; i < vec_len (rp->next_indices); i++)
109  {
110  rv = RT (mma_rules_table_lookup) (srt, key, rp->next_indices[i]);
112  return (rv);
113  }
114  return (rp->action_index);
115 }
116 
117 u32
118 RT (mma_rules_table_lookup_rule) (RTT (mma_rules_table) * srt,
119  RTT (mma_mask_or_match) * key,
120  u32 rule_index)
121 {
122  RTT (mma_rule) * rp;
123  u32 rv;
124  int i;
125 
126  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
127  rp = RT (mma_rules_table_get_rule) (srt, rule_index);
128  ASSERT (rp);
129 
130  if (!RT (rule_is_match_for_key) (key, rp))
132  for (i = 0; i < vec_len (rp->next_indices); i++)
133  {
134  rv = RT (mma_rules_table_lookup_rule) (srt, key, rp->next_indices[i]);
136  return (rv);
137  }
138  return rule_index;
139 }
140 
141 static
142 RTT (mma_rules_table) *
143 RTT (sort_srt);
144 
145  int RT (mma_sort_indices) (void *e1, void *e2)
146 {
147  u32 *ri1 = e1, *ri2 = e2;
148  RTT (mma_rule) * rule1, *rule2;
149  rule1 = RT (mma_rules_table_get_rule) (RTT (sort_srt), *ri1);
150  rule2 = RT (mma_rules_table_get_rule) (RTT (sort_srt), *ri2);
151  return RTT (sort_srt)->rule_cmp_fn (rule1, rule2);
152 }
153 
154 void RT (mma_sort) (RTT (mma_rules_table) * srt, u32 * next_indices)
155 {
156  RTT (sort_srt) = srt;
157  vec_sort_with_function (next_indices, RT (mma_sort_indices));
158 }
159 
160 int
161 RT (mma_rules_table_add_rule) (RTT (mma_rules_table) * srt,
162  RTT (mma_rule) * rule)
163 {
164  u32 parent_index, i, *next_indices = 0, added = 0, rule_index;
165  RTT (mma_rule) * parent, *child;
166 
167  rule_index = RT (mma_rules_table_rule_index) (srt, rule);
168  parent_index = RT (mma_rules_table_lookup_rule) (srt, &rule->match,
169  srt->root_index);
170  parent = RT (mma_rules_table_get_rule) (srt, parent_index);
171  if (RT (rule_is_exact_match) (rule, parent))
172  {
173  parent->action_index = rule->action_index;
174  RT (mma_rule_free) (srt, rule);
175  return -1;
176  }
177 
178  if (vec_len (parent->next_indices) == 0)
179  {
180  vec_add1 (parent->next_indices, rule_index);
181  return 0;
182  }
183 
184  /* Check if new rule is parent of some of the existing children */
185  for (i = 0; i < vec_len (parent->next_indices); i++)
186  {
187  child = RT (mma_rules_table_get_rule) (srt, parent->next_indices[i]);
188  if (RT (rule_is_match_for_key) (&child->match, rule))
189  {
190  vec_add1 (rule->next_indices, parent->next_indices[i]);
191  if (!added)
192  {
193  vec_add1 (next_indices, rule_index);
194  added = 1;
195  }
196  }
197  else
198  {
199  if (!added && srt->rule_cmp_fn (rule, child) < 0)
200  {
201  vec_add1 (next_indices, rule_index);
202  added = 1;
203  }
204  vec_add1 (next_indices, parent->next_indices[i]);
205  }
206  }
207  if (!added)
208  vec_add1 (next_indices, rule_index);
209  vec_free (parent->next_indices);
210  parent->next_indices = next_indices;
211  return 0;
212 }
213 
214 int
215 RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
216  RTT (mma_rule) * rule, u32 rule_index)
217 {
218  RTT (mma_rule) * rp;
219  u32 rv;
220  int i;
221 
222  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
223  rp = RT (mma_rules_table_get_rule) (srt, rule_index);
224 
225  if (!RT (rule_is_match_for_key) (&rule->match, rp))
227  if (RT (rule_is_exact_match) (rule, rp))
228  {
229  if (rule_index == srt->root_index)
230  rp->action_index = MMA_TABLE_INVALID_INDEX;
231  return 1;
232  }
233  for (i = 0; i < vec_len (rp->next_indices); i++)
234  {
235  rv = RT (mma_rules_table_del_rule) (srt, rule, rp->next_indices[i]);
236  if (rv == 1)
237  {
238  RTT (mma_rule) * child;
239  u32 *next_indices = 0, *new_elts, left_to_add;
240  child = RT (mma_rules_table_get_rule) (srt, rp->next_indices[i]);
241  ASSERT (RT (rule_is_exact_match) (rule, child));
242 
243  if (i != 0)
244  {
245  vec_add2 (next_indices, new_elts, i);
246  clib_memcpy_fast (new_elts, rp->next_indices, i * sizeof (u32));
247  }
248  if (vec_len (child->next_indices))
249  vec_append (next_indices, child->next_indices);
250  left_to_add = vec_len (rp->next_indices) - i - 1;
251  if (left_to_add)
252  {
253  vec_add2 (next_indices, new_elts, left_to_add);
254  clib_memcpy_fast (new_elts, &rp->next_indices[i + 1],
255  left_to_add * sizeof (u32));
256  }
257  RT (mma_rule_free) (srt, child);
258  vec_free (rp->next_indices);
259  rp->next_indices = next_indices;
260  return 0;
261  }
262  else if (rv == 0)
263  return rv;
264  }
266 }
267 
268 /*
269  * fd.io coding-style-patch-verification: ON
270  *
271  * Local Variables:
272  * eval: (c-set-style "gnu")
273  * End:
274  */
mma_sort
void RT() mma_sort(RTT(mma_rules_table) *srt, u32 *next_indices)
Definition: mma_template.c:154
RTT
RTT(mma_rule)
Definition: mma_template.c:52
rule_is_exact_match
u8 RT() rule_is_exact_match(RTT(mma_rule) *key, RTT(mma_rule) *r)
Definition: mma_template.c:18
mma_rules_table_del_rule
int RT() mma_rules_table_del_rule(RTT(mma_rules_table) *srt, RTT(mma_rule) *rule, u32 rule_index)
Definition: mma_template.c:215
vec_append
#define vec_append(v1, v2)
Append v2 after v1.
Definition: vec.h:911
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
mma_rules_table_free
void RT() mma_rules_table_free(RTT(mma_rules_table) *srt)
Definition: mma_template.c:68
mma_rules_table_add_rule
int RT() mma_rules_table_add_rule(RTT(mma_rules_table) *srt, RTT(mma_rule) *rule)
Definition: mma_template.c:161
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1089
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
key
typedef key
Definition: ipsec_types.api:91
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
error.h
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
mma_rules_table_rule_index
u32 RT() mma_rules_table_rule_index(RTT(mma_rules_table) *srt, RTT(mma_rule) *sr)
Definition: mma_template.c:82
mma_rules_table_lookup_rule
u32 RT() mma_rules_table_lookup_rule(RTT(mma_rules_table) *srt, RTT(mma_mask_or_match) *key, u32 rule_index)
Definition: mma_template.c:118
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
RT
#define RT(a)
Definition: mma_template.h:27
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
mma_rules_table_lookup
u32 RT() mma_rules_table_lookup(RTT(mma_rules_table) *srt, RTT(mma_mask_or_match) *key, u32 rule_index)
Lookup key in table.
Definition: mma_template.c:95
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
u32
unsigned int u32
Definition: types.h:88
srt_index
u32 srt_index
Definition: mma_template.h:80
for
for(i=1;i<=collision_buckets;i++)
Definition: flowhash_template.h:378
MMA_TABLE_INVALID_INDEX
#define MMA_TABLE_INVALID_INDEX
Definition: mma_template.h:33
vec_sort_with_function
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1097
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u8
unsigned char u8
Definition: types.h:56
i
int i
Definition: flowhash_template.h:376
pool_free
#define pool_free(p)
Free a pool.
Definition: pool.h:447
rv
int __clib_unused rv
Definition: application.c:491
rule_is_match_for_key
u8 RT() rule_is_match_for_key(RTT(mma_mask_or_match) *key, RTT(mma_rule) *r)
Definition: mma_template.c:36