xref: /dpdk/app/test-flow-perf/items_gen.c (revision 444e5567)
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 }
398