net/bnxt: add TCAM table processing for search and alloc
[dpdk.git] / app / test-flow-perf / items_gen.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  *
4  * This file contain the implementations of the items
5  * related methods. Each Item have a method to prepare
6  * the item and add it into items array in given index.
7  */
8
9 #include <stdint.h>
10 #include <rte_flow.h>
11
12 #include "items_gen.h"
13 #include "config.h"
14
15 /* Storage for additional parameters for items */
16 struct additional_para {
17         rte_be32_t src_ip;
18 };
19
20 static void
21 add_ether(struct rte_flow_item *items,
22         uint8_t items_counter,
23         __rte_unused struct additional_para para)
24 {
25         static struct rte_flow_item_eth eth_spec;
26         static struct rte_flow_item_eth eth_mask;
27
28         memset(&eth_spec, 0, sizeof(struct rte_flow_item_eth));
29         memset(&eth_mask, 0, sizeof(struct rte_flow_item_eth));
30
31         items[items_counter].type = RTE_FLOW_ITEM_TYPE_ETH;
32         items[items_counter].spec = &eth_spec;
33         items[items_counter].mask = &eth_mask;
34 }
35
36 static void
37 add_vlan(struct rte_flow_item *items,
38         uint8_t items_counter,
39         __rte_unused struct additional_para para)
40 {
41         static struct rte_flow_item_vlan vlan_spec;
42         static struct rte_flow_item_vlan vlan_mask;
43
44         uint16_t vlan_value = VLAN_VALUE;
45
46         memset(&vlan_spec, 0, sizeof(struct rte_flow_item_vlan));
47         memset(&vlan_mask, 0, sizeof(struct rte_flow_item_vlan));
48
49         vlan_spec.tci = RTE_BE16(vlan_value);
50         vlan_mask.tci = RTE_BE16(0xffff);
51
52         items[items_counter].type = RTE_FLOW_ITEM_TYPE_VLAN;
53         items[items_counter].spec = &vlan_spec;
54         items[items_counter].mask = &vlan_mask;
55 }
56
57 static void
58 add_ipv4(struct rte_flow_item *items,
59         uint8_t items_counter, struct additional_para para)
60 {
61         static struct rte_flow_item_ipv4 ipv4_spec;
62         static struct rte_flow_item_ipv4 ipv4_mask;
63
64         memset(&ipv4_spec, 0, sizeof(struct rte_flow_item_ipv4));
65         memset(&ipv4_mask, 0, sizeof(struct rte_flow_item_ipv4));
66
67         ipv4_spec.hdr.src_addr = para.src_ip;
68         ipv4_mask.hdr.src_addr = RTE_BE32(0xffffffff);
69
70         items[items_counter].type = RTE_FLOW_ITEM_TYPE_IPV4;
71         items[items_counter].spec = &ipv4_spec;
72         items[items_counter].mask = &ipv4_mask;
73 }
74
75
76 static void
77 add_ipv6(struct rte_flow_item *items,
78         uint8_t items_counter, struct additional_para para)
79 {
80         static struct rte_flow_item_ipv6 ipv6_spec;
81         static struct rte_flow_item_ipv6 ipv6_mask;
82
83         memset(&ipv6_spec, 0, sizeof(struct rte_flow_item_ipv6));
84         memset(&ipv6_mask, 0, sizeof(struct rte_flow_item_ipv6));
85
86         /** Set ipv6 src **/
87         memset(&ipv6_spec.hdr.src_addr, para.src_ip,
88                 sizeof(ipv6_spec.hdr.src_addr) / 2);
89
90         /** Full mask **/
91         memset(&ipv6_mask.hdr.src_addr, 0xff,
92                 sizeof(ipv6_spec.hdr.src_addr));
93
94         items[items_counter].type = RTE_FLOW_ITEM_TYPE_IPV6;
95         items[items_counter].spec = &ipv6_spec;
96         items[items_counter].mask = &ipv6_mask;
97 }
98
99 static void
100 add_tcp(struct rte_flow_item *items,
101         uint8_t items_counter,
102         __rte_unused struct additional_para para)
103 {
104         static struct rte_flow_item_tcp tcp_spec;
105         static struct rte_flow_item_tcp tcp_mask;
106
107         memset(&tcp_spec, 0, sizeof(struct rte_flow_item_tcp));
108         memset(&tcp_mask, 0, sizeof(struct rte_flow_item_tcp));
109
110         items[items_counter].type = RTE_FLOW_ITEM_TYPE_TCP;
111         items[items_counter].spec = &tcp_spec;
112         items[items_counter].mask = &tcp_mask;
113 }
114
115 static void
116 add_udp(struct rte_flow_item *items,
117         uint8_t items_counter,
118         __rte_unused struct additional_para para)
119 {
120         static struct rte_flow_item_udp udp_spec;
121         static struct rte_flow_item_udp udp_mask;
122
123         memset(&udp_spec, 0, sizeof(struct rte_flow_item_udp));
124         memset(&udp_mask, 0, sizeof(struct rte_flow_item_udp));
125
126         items[items_counter].type = RTE_FLOW_ITEM_TYPE_UDP;
127         items[items_counter].spec = &udp_spec;
128         items[items_counter].mask = &udp_mask;
129 }
130
131 static void
132 add_vxlan(struct rte_flow_item *items,
133         uint8_t items_counter,
134         __rte_unused struct additional_para para)
135 {
136         static struct rte_flow_item_vxlan vxlan_spec;
137         static struct rte_flow_item_vxlan vxlan_mask;
138
139         uint32_t vni_value;
140         uint8_t i;
141
142         vni_value = VNI_VALUE;
143
144         memset(&vxlan_spec, 0, sizeof(struct rte_flow_item_vxlan));
145         memset(&vxlan_mask, 0, sizeof(struct rte_flow_item_vxlan));
146
147         /* Set standard vxlan vni */
148         for (i = 0; i < 3; i++) {
149                 vxlan_spec.vni[2 - i] = vni_value >> (i * 8);
150                 vxlan_mask.vni[2 - i] = 0xff;
151         }
152
153         /* Standard vxlan flags */
154         vxlan_spec.flags = 0x8;
155
156         items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN;
157         items[items_counter].spec = &vxlan_spec;
158         items[items_counter].mask = &vxlan_mask;
159 }
160
161 static void
162 add_vxlan_gpe(struct rte_flow_item *items,
163         uint8_t items_counter,
164         __rte_unused struct additional_para para)
165 {
166         static struct rte_flow_item_vxlan_gpe vxlan_gpe_spec;
167         static struct rte_flow_item_vxlan_gpe vxlan_gpe_mask;
168
169         uint32_t vni_value;
170         uint8_t i;
171
172         vni_value = VNI_VALUE;
173
174         memset(&vxlan_gpe_spec, 0, sizeof(struct rte_flow_item_vxlan_gpe));
175         memset(&vxlan_gpe_mask, 0, sizeof(struct rte_flow_item_vxlan_gpe));
176
177         /* Set vxlan-gpe vni */
178         for (i = 0; i < 3; i++) {
179                 vxlan_gpe_spec.vni[2 - i] = vni_value >> (i * 8);
180                 vxlan_gpe_mask.vni[2 - i] = 0xff;
181         }
182
183         /* vxlan-gpe flags */
184         vxlan_gpe_spec.flags = 0x0c;
185
186         items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE;
187         items[items_counter].spec = &vxlan_gpe_spec;
188         items[items_counter].mask = &vxlan_gpe_mask;
189 }
190
191 static void
192 add_gre(struct rte_flow_item *items,
193         uint8_t items_counter,
194         __rte_unused struct additional_para para)
195 {
196         static struct rte_flow_item_gre gre_spec;
197         static struct rte_flow_item_gre gre_mask;
198
199         uint16_t proto;
200
201         proto = RTE_ETHER_TYPE_TEB;
202
203         memset(&gre_spec, 0, sizeof(struct rte_flow_item_gre));
204         memset(&gre_mask, 0, sizeof(struct rte_flow_item_gre));
205
206         gre_spec.protocol = RTE_BE16(proto);
207         gre_mask.protocol = RTE_BE16(0xffff);
208
209         items[items_counter].type = RTE_FLOW_ITEM_TYPE_GRE;
210         items[items_counter].spec = &gre_spec;
211         items[items_counter].mask = &gre_mask;
212 }
213
214 static void
215 add_geneve(struct rte_flow_item *items,
216         uint8_t items_counter,
217         __rte_unused struct additional_para para)
218 {
219         static struct rte_flow_item_geneve geneve_spec;
220         static struct rte_flow_item_geneve geneve_mask;
221
222         uint32_t vni_value;
223         uint8_t i;
224
225         vni_value = VNI_VALUE;
226
227         memset(&geneve_spec, 0, sizeof(struct rte_flow_item_geneve));
228         memset(&geneve_mask, 0, sizeof(struct rte_flow_item_geneve));
229
230         for (i = 0; i < 3; i++) {
231                 geneve_spec.vni[2 - i] = vni_value >> (i * 8);
232                 geneve_mask.vni[2 - i] = 0xff;
233         }
234
235         items[items_counter].type = RTE_FLOW_ITEM_TYPE_GENEVE;
236         items[items_counter].spec = &geneve_spec;
237         items[items_counter].mask = &geneve_mask;
238 }
239
240 static void
241 add_gtp(struct rte_flow_item *items,
242         uint8_t items_counter,
243         __rte_unused struct additional_para para)
244 {
245         static struct rte_flow_item_gtp gtp_spec;
246         static struct rte_flow_item_gtp gtp_mask;
247
248         uint32_t teid_value;
249
250         teid_value = TEID_VALUE;
251
252         memset(&gtp_spec, 0, sizeof(struct rte_flow_item_gtp));
253         memset(&gtp_mask, 0, sizeof(struct rte_flow_item_gtp));
254
255         gtp_spec.teid = RTE_BE32(teid_value);
256         gtp_mask.teid = RTE_BE32(0xffffffff);
257
258         items[items_counter].type = RTE_FLOW_ITEM_TYPE_GTP;
259         items[items_counter].spec = &gtp_spec;
260         items[items_counter].mask = &gtp_mask;
261 }
262
263 static void
264 add_meta_data(struct rte_flow_item *items,
265         uint8_t items_counter,
266         __rte_unused struct additional_para para)
267 {
268         static struct rte_flow_item_meta meta_spec;
269         static struct rte_flow_item_meta meta_mask;
270
271         uint32_t data;
272
273         data = META_DATA;
274
275         memset(&meta_spec, 0, sizeof(struct rte_flow_item_meta));
276         memset(&meta_mask, 0, sizeof(struct rte_flow_item_meta));
277
278         meta_spec.data = RTE_BE32(data);
279         meta_mask.data = RTE_BE32(0xffffffff);
280
281         items[items_counter].type = RTE_FLOW_ITEM_TYPE_META;
282         items[items_counter].spec = &meta_spec;
283         items[items_counter].mask = &meta_mask;
284 }
285
286
287 static void
288 add_meta_tag(struct rte_flow_item *items,
289         uint8_t items_counter,
290         __rte_unused struct additional_para para)
291 {
292         static struct rte_flow_item_tag tag_spec;
293         static struct rte_flow_item_tag tag_mask;
294         uint32_t data;
295         uint8_t index;
296
297         data = META_DATA;
298         index = TAG_INDEX;
299
300         memset(&tag_spec, 0, sizeof(struct rte_flow_item_tag));
301         memset(&tag_mask, 0, sizeof(struct rte_flow_item_tag));
302
303         tag_spec.data = RTE_BE32(data);
304         tag_mask.data = RTE_BE32(0xffffffff);
305         tag_spec.index = index;
306         tag_mask.index = 0xff;
307
308         items[items_counter].type = RTE_FLOW_ITEM_TYPE_TAG;
309         items[items_counter].spec = &tag_spec;
310         items[items_counter].mask = &tag_mask;
311 }
312
313 void
314 fill_items(struct rte_flow_item *items,
315         uint64_t flow_items, uint32_t outer_ip_src)
316 {
317         uint8_t items_counter = 0;
318         uint8_t i;
319         struct additional_para additional_para_data = {
320                 .src_ip = outer_ip_src,
321         };
322
323         /* Support outer items up to tunnel layer only. */
324         static const struct items_dict {
325                 uint64_t mask;
326                 void (*funct)(
327                         struct rte_flow_item *items,
328                         uint8_t items_counter,
329                         struct additional_para para
330                         );
331         } flows_items[] = {
332                 {
333                         .mask = RTE_FLOW_ITEM_TYPE_META,
334                         .funct = add_meta_data,
335                 },
336                 {
337                         .mask = RTE_FLOW_ITEM_TYPE_TAG,
338                         .funct = add_meta_tag,
339                 },
340                 {
341                         .mask = RTE_FLOW_ITEM_TYPE_ETH,
342                         .funct = add_ether,
343                 },
344                 {
345                         .mask = RTE_FLOW_ITEM_TYPE_VLAN,
346                         .funct = add_vlan,
347                 },
348                 {
349                         .mask = RTE_FLOW_ITEM_TYPE_IPV4,
350                         .funct = add_ipv4,
351                 },
352                 {
353                         .mask = RTE_FLOW_ITEM_TYPE_IPV6,
354                         .funct = add_ipv6,
355                 },
356                 {
357                         .mask = RTE_FLOW_ITEM_TYPE_TCP,
358                         .funct = add_tcp,
359                 },
360                 {
361                         .mask = RTE_FLOW_ITEM_TYPE_UDP,
362                         .funct = add_udp,
363                 },
364                 {
365                         .mask = RTE_FLOW_ITEM_TYPE_VXLAN,
366                         .funct = add_vxlan,
367                 },
368                 {
369                         .mask = RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
370                         .funct = add_vxlan_gpe,
371                 },
372                 {
373                         .mask = RTE_FLOW_ITEM_TYPE_GRE,
374                         .funct = add_gre,
375                 },
376                 {
377                         .mask = RTE_FLOW_ITEM_TYPE_GENEVE,
378                         .funct = add_geneve,
379                 },
380                 {
381                         .mask = RTE_FLOW_ITEM_TYPE_GTP,
382                         .funct = add_gtp,
383                 },
384
385         };
386
387         for (i = 0; i < RTE_DIM(flows_items); i++) {
388                 if ((flow_items & FLOW_ITEM_MASK(flows_items[i].mask)) == 0)
389                         continue;
390                 flows_items[i].funct(
391                         items, items_counter++,
392                         additional_para_data
393                 );
394         }
395
396         items[items_counter].type = RTE_FLOW_ITEM_TYPE_END;
397 }