Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2016-2017 Intel Corporation
3 : : */
4 : :
5 : : #include <sys/queue.h>
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <unistd.h>
11 : : #include <stdarg.h>
12 : : #include <stdlib.h>
13 : :
14 : : #include <rte_debug.h>
15 : : #include <rte_ether.h>
16 : : #include <ethdev_driver.h>
17 : : #include <rte_log.h>
18 : : #include <rte_malloc.h>
19 : : #include <rte_tailq.h>
20 : : #include <rte_hexdump.h>
21 : : #include <rte_flow_driver.h>
22 : : #include <rte_bitmap.h>
23 : :
24 : : #include "i40e_logs.h"
25 : : #include "base/i40e_type.h"
26 : : #include "base/i40e_prototype.h"
27 : : #include "i40e_ethdev.h"
28 : : #include "i40e_hash.h"
29 : :
30 : : #define I40E_IPV6_TC_MASK (0xFF << I40E_FDIR_IPv6_TC_OFFSET)
31 : : #define I40E_IPV6_FRAG_HEADER 44
32 : : #define I40E_TENANT_ARRAY_NUM 3
33 : : #define I40E_VLAN_TCI_MASK 0xFFFF
34 : :
35 : : static int i40e_flow_validate(struct rte_eth_dev *dev,
36 : : const struct rte_flow_attr *attr,
37 : : const struct rte_flow_item pattern[],
38 : : const struct rte_flow_action actions[],
39 : : struct rte_flow_error *error);
40 : : static struct rte_flow *i40e_flow_create(struct rte_eth_dev *dev,
41 : : const struct rte_flow_attr *attr,
42 : : const struct rte_flow_item pattern[],
43 : : const struct rte_flow_action actions[],
44 : : struct rte_flow_error *error);
45 : : static int i40e_flow_destroy(struct rte_eth_dev *dev,
46 : : struct rte_flow *flow,
47 : : struct rte_flow_error *error);
48 : : static int i40e_flow_flush(struct rte_eth_dev *dev,
49 : : struct rte_flow_error *error);
50 : : static int i40e_flow_query(struct rte_eth_dev *dev,
51 : : struct rte_flow *flow,
52 : : const struct rte_flow_action *actions,
53 : : void *data, struct rte_flow_error *error);
54 : : static int i40e_flow_dev_dump(struct rte_eth_dev *dev,
55 : : struct rte_flow *flow,
56 : : FILE *file,
57 : : struct rte_flow_error *error);
58 : : static int
59 : : i40e_flow_parse_ethertype_pattern(struct rte_eth_dev *dev,
60 : : const struct rte_flow_item *pattern,
61 : : struct rte_flow_error *error,
62 : : struct rte_eth_ethertype_filter *filter);
63 : : static int i40e_flow_parse_ethertype_action(struct rte_eth_dev *dev,
64 : : const struct rte_flow_action *actions,
65 : : struct rte_flow_error *error,
66 : : struct rte_eth_ethertype_filter *filter);
67 : : static int i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
68 : : const struct rte_flow_item *pattern,
69 : : struct rte_flow_error *error,
70 : : struct i40e_fdir_filter_conf *filter);
71 : : static int i40e_flow_parse_fdir_action(struct rte_eth_dev *dev,
72 : : const struct rte_flow_action *actions,
73 : : struct rte_flow_error *error,
74 : : struct i40e_fdir_filter_conf *filter);
75 : : static int i40e_flow_parse_tunnel_action(struct rte_eth_dev *dev,
76 : : const struct rte_flow_action *actions,
77 : : struct rte_flow_error *error,
78 : : struct i40e_tunnel_filter_conf *filter);
79 : : static int i40e_flow_parse_attr(const struct rte_flow_attr *attr,
80 : : struct rte_flow_error *error);
81 : : static int i40e_flow_parse_ethertype_filter(struct rte_eth_dev *dev,
82 : : const struct rte_flow_attr *attr,
83 : : const struct rte_flow_item pattern[],
84 : : const struct rte_flow_action actions[],
85 : : struct rte_flow_error *error,
86 : : struct i40e_filter_ctx *filter);
87 : : static int i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
88 : : const struct rte_flow_attr *attr,
89 : : const struct rte_flow_item pattern[],
90 : : const struct rte_flow_action actions[],
91 : : struct rte_flow_error *error,
92 : : struct i40e_filter_ctx *filter);
93 : : static int i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
94 : : const struct rte_flow_attr *attr,
95 : : const struct rte_flow_item pattern[],
96 : : const struct rte_flow_action actions[],
97 : : struct rte_flow_error *error,
98 : : struct i40e_filter_ctx *filter);
99 : : static int i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
100 : : const struct rte_flow_attr *attr,
101 : : const struct rte_flow_item pattern[],
102 : : const struct rte_flow_action actions[],
103 : : struct rte_flow_error *error,
104 : : struct i40e_filter_ctx *filter);
105 : : static int i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
106 : : const struct rte_flow_attr *attr,
107 : : const struct rte_flow_item pattern[],
108 : : const struct rte_flow_action actions[],
109 : : struct rte_flow_error *error,
110 : : struct i40e_filter_ctx *filter);
111 : : static int i40e_flow_parse_gtp_filter(struct rte_eth_dev *dev,
112 : : const struct rte_flow_attr *attr,
113 : : const struct rte_flow_item pattern[],
114 : : const struct rte_flow_action actions[],
115 : : struct rte_flow_error *error,
116 : : struct i40e_filter_ctx *filter);
117 : : static int i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
118 : : struct i40e_ethertype_filter *filter);
119 : : static int i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
120 : : struct i40e_tunnel_filter *filter);
121 : : static int i40e_flow_flush_fdir_filter(struct i40e_pf *pf);
122 : : static int i40e_flow_flush_ethertype_filter(struct i40e_pf *pf);
123 : : static int i40e_flow_flush_tunnel_filter(struct i40e_pf *pf);
124 : : static int
125 : : i40e_flow_parse_qinq_filter(struct rte_eth_dev *dev,
126 : : const struct rte_flow_attr *attr,
127 : : const struct rte_flow_item pattern[],
128 : : const struct rte_flow_action actions[],
129 : : struct rte_flow_error *error,
130 : : struct i40e_filter_ctx *filter);
131 : : static int
132 : : i40e_flow_parse_qinq_pattern(struct rte_eth_dev *dev,
133 : : const struct rte_flow_item *pattern,
134 : : struct rte_flow_error *error,
135 : : struct i40e_tunnel_filter_conf *filter);
136 : :
137 : : static int i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,
138 : : const struct rte_flow_attr *attr,
139 : : const struct rte_flow_item pattern[],
140 : : const struct rte_flow_action actions[],
141 : : struct rte_flow_error *error,
142 : : struct i40e_filter_ctx *filter);
143 : : const struct rte_flow_ops i40e_flow_ops = {
144 : : .validate = i40e_flow_validate,
145 : : .create = i40e_flow_create,
146 : : .destroy = i40e_flow_destroy,
147 : : .flush = i40e_flow_flush,
148 : : .query = i40e_flow_query,
149 : : .dev_dump = i40e_flow_dev_dump,
150 : : };
151 : :
152 : : /* Pattern matched ethertype filter */
153 : : static enum rte_flow_item_type pattern_ethertype[] = {
154 : : RTE_FLOW_ITEM_TYPE_ETH,
155 : : RTE_FLOW_ITEM_TYPE_END,
156 : : };
157 : :
158 : : /* Pattern matched flow director filter */
159 : : static enum rte_flow_item_type pattern_fdir_ipv4[] = {
160 : : RTE_FLOW_ITEM_TYPE_ETH,
161 : : RTE_FLOW_ITEM_TYPE_IPV4,
162 : : RTE_FLOW_ITEM_TYPE_END,
163 : : };
164 : :
165 : : static enum rte_flow_item_type pattern_fdir_ipv4_udp[] = {
166 : : RTE_FLOW_ITEM_TYPE_ETH,
167 : : RTE_FLOW_ITEM_TYPE_IPV4,
168 : : RTE_FLOW_ITEM_TYPE_UDP,
169 : : RTE_FLOW_ITEM_TYPE_END,
170 : : };
171 : :
172 : : static enum rte_flow_item_type pattern_fdir_ipv4_tcp[] = {
173 : : RTE_FLOW_ITEM_TYPE_ETH,
174 : : RTE_FLOW_ITEM_TYPE_IPV4,
175 : : RTE_FLOW_ITEM_TYPE_TCP,
176 : : RTE_FLOW_ITEM_TYPE_END,
177 : : };
178 : :
179 : : static enum rte_flow_item_type pattern_fdir_ipv4_sctp[] = {
180 : : RTE_FLOW_ITEM_TYPE_ETH,
181 : : RTE_FLOW_ITEM_TYPE_IPV4,
182 : : RTE_FLOW_ITEM_TYPE_SCTP,
183 : : RTE_FLOW_ITEM_TYPE_END,
184 : : };
185 : :
186 : : static enum rte_flow_item_type pattern_fdir_ipv4_gtpc[] = {
187 : : RTE_FLOW_ITEM_TYPE_ETH,
188 : : RTE_FLOW_ITEM_TYPE_IPV4,
189 : : RTE_FLOW_ITEM_TYPE_UDP,
190 : : RTE_FLOW_ITEM_TYPE_GTPC,
191 : : RTE_FLOW_ITEM_TYPE_END,
192 : : };
193 : :
194 : : static enum rte_flow_item_type pattern_fdir_ipv4_gtpu[] = {
195 : : RTE_FLOW_ITEM_TYPE_ETH,
196 : : RTE_FLOW_ITEM_TYPE_IPV4,
197 : : RTE_FLOW_ITEM_TYPE_UDP,
198 : : RTE_FLOW_ITEM_TYPE_GTPU,
199 : : RTE_FLOW_ITEM_TYPE_END,
200 : : };
201 : :
202 : : static enum rte_flow_item_type pattern_fdir_ipv4_gtpu_ipv4[] = {
203 : : RTE_FLOW_ITEM_TYPE_ETH,
204 : : RTE_FLOW_ITEM_TYPE_IPV4,
205 : : RTE_FLOW_ITEM_TYPE_UDP,
206 : : RTE_FLOW_ITEM_TYPE_GTPU,
207 : : RTE_FLOW_ITEM_TYPE_IPV4,
208 : : RTE_FLOW_ITEM_TYPE_END,
209 : : };
210 : :
211 : : static enum rte_flow_item_type pattern_fdir_ipv4_gtpu_ipv6[] = {
212 : : RTE_FLOW_ITEM_TYPE_ETH,
213 : : RTE_FLOW_ITEM_TYPE_IPV4,
214 : : RTE_FLOW_ITEM_TYPE_UDP,
215 : : RTE_FLOW_ITEM_TYPE_GTPU,
216 : : RTE_FLOW_ITEM_TYPE_IPV6,
217 : : RTE_FLOW_ITEM_TYPE_END,
218 : : };
219 : :
220 : : static enum rte_flow_item_type pattern_fdir_ipv6[] = {
221 : : RTE_FLOW_ITEM_TYPE_ETH,
222 : : RTE_FLOW_ITEM_TYPE_IPV6,
223 : : RTE_FLOW_ITEM_TYPE_END,
224 : : };
225 : :
226 : : static enum rte_flow_item_type pattern_fdir_ipv6_udp[] = {
227 : : RTE_FLOW_ITEM_TYPE_ETH,
228 : : RTE_FLOW_ITEM_TYPE_IPV6,
229 : : RTE_FLOW_ITEM_TYPE_UDP,
230 : : RTE_FLOW_ITEM_TYPE_END,
231 : : };
232 : :
233 : : static enum rte_flow_item_type pattern_fdir_ipv6_tcp[] = {
234 : : RTE_FLOW_ITEM_TYPE_ETH,
235 : : RTE_FLOW_ITEM_TYPE_IPV6,
236 : : RTE_FLOW_ITEM_TYPE_TCP,
237 : : RTE_FLOW_ITEM_TYPE_END,
238 : : };
239 : :
240 : : static enum rte_flow_item_type pattern_fdir_ipv6_sctp[] = {
241 : : RTE_FLOW_ITEM_TYPE_ETH,
242 : : RTE_FLOW_ITEM_TYPE_IPV6,
243 : : RTE_FLOW_ITEM_TYPE_SCTP,
244 : : RTE_FLOW_ITEM_TYPE_END,
245 : : };
246 : :
247 : : static enum rte_flow_item_type pattern_fdir_ipv6_gtpc[] = {
248 : : RTE_FLOW_ITEM_TYPE_ETH,
249 : : RTE_FLOW_ITEM_TYPE_IPV6,
250 : : RTE_FLOW_ITEM_TYPE_UDP,
251 : : RTE_FLOW_ITEM_TYPE_GTPC,
252 : : RTE_FLOW_ITEM_TYPE_END,
253 : : };
254 : :
255 : : static enum rte_flow_item_type pattern_fdir_ipv6_gtpu[] = {
256 : : RTE_FLOW_ITEM_TYPE_ETH,
257 : : RTE_FLOW_ITEM_TYPE_IPV6,
258 : : RTE_FLOW_ITEM_TYPE_UDP,
259 : : RTE_FLOW_ITEM_TYPE_GTPU,
260 : : RTE_FLOW_ITEM_TYPE_END,
261 : : };
262 : :
263 : : static enum rte_flow_item_type pattern_fdir_ipv6_gtpu_ipv4[] = {
264 : : RTE_FLOW_ITEM_TYPE_ETH,
265 : : RTE_FLOW_ITEM_TYPE_IPV6,
266 : : RTE_FLOW_ITEM_TYPE_UDP,
267 : : RTE_FLOW_ITEM_TYPE_GTPU,
268 : : RTE_FLOW_ITEM_TYPE_IPV4,
269 : : RTE_FLOW_ITEM_TYPE_END,
270 : : };
271 : :
272 : : static enum rte_flow_item_type pattern_fdir_ipv6_gtpu_ipv6[] = {
273 : : RTE_FLOW_ITEM_TYPE_ETH,
274 : : RTE_FLOW_ITEM_TYPE_IPV6,
275 : : RTE_FLOW_ITEM_TYPE_UDP,
276 : : RTE_FLOW_ITEM_TYPE_GTPU,
277 : : RTE_FLOW_ITEM_TYPE_IPV6,
278 : : RTE_FLOW_ITEM_TYPE_END,
279 : : };
280 : :
281 : : static enum rte_flow_item_type pattern_fdir_ethertype_raw_1[] = {
282 : : RTE_FLOW_ITEM_TYPE_ETH,
283 : : RTE_FLOW_ITEM_TYPE_RAW,
284 : : RTE_FLOW_ITEM_TYPE_END,
285 : : };
286 : :
287 : : static enum rte_flow_item_type pattern_fdir_ethertype_raw_2[] = {
288 : : RTE_FLOW_ITEM_TYPE_ETH,
289 : : RTE_FLOW_ITEM_TYPE_RAW,
290 : : RTE_FLOW_ITEM_TYPE_RAW,
291 : : RTE_FLOW_ITEM_TYPE_END,
292 : : };
293 : :
294 : : static enum rte_flow_item_type pattern_fdir_ethertype_raw_3[] = {
295 : : RTE_FLOW_ITEM_TYPE_ETH,
296 : : RTE_FLOW_ITEM_TYPE_RAW,
297 : : RTE_FLOW_ITEM_TYPE_RAW,
298 : : RTE_FLOW_ITEM_TYPE_RAW,
299 : : RTE_FLOW_ITEM_TYPE_END,
300 : : };
301 : :
302 : : static enum rte_flow_item_type pattern_fdir_ipv4_raw_1[] = {
303 : : RTE_FLOW_ITEM_TYPE_ETH,
304 : : RTE_FLOW_ITEM_TYPE_IPV4,
305 : : RTE_FLOW_ITEM_TYPE_RAW,
306 : : RTE_FLOW_ITEM_TYPE_END,
307 : : };
308 : :
309 : : static enum rte_flow_item_type pattern_fdir_ipv4_raw_2[] = {
310 : : RTE_FLOW_ITEM_TYPE_ETH,
311 : : RTE_FLOW_ITEM_TYPE_IPV4,
312 : : RTE_FLOW_ITEM_TYPE_RAW,
313 : : RTE_FLOW_ITEM_TYPE_RAW,
314 : : RTE_FLOW_ITEM_TYPE_END,
315 : : };
316 : :
317 : : static enum rte_flow_item_type pattern_fdir_ipv4_raw_3[] = {
318 : : RTE_FLOW_ITEM_TYPE_ETH,
319 : : RTE_FLOW_ITEM_TYPE_IPV4,
320 : : RTE_FLOW_ITEM_TYPE_RAW,
321 : : RTE_FLOW_ITEM_TYPE_RAW,
322 : : RTE_FLOW_ITEM_TYPE_RAW,
323 : : RTE_FLOW_ITEM_TYPE_END,
324 : : };
325 : :
326 : : static enum rte_flow_item_type pattern_fdir_ipv4_udp_raw_1[] = {
327 : : RTE_FLOW_ITEM_TYPE_ETH,
328 : : RTE_FLOW_ITEM_TYPE_IPV4,
329 : : RTE_FLOW_ITEM_TYPE_UDP,
330 : : RTE_FLOW_ITEM_TYPE_RAW,
331 : : RTE_FLOW_ITEM_TYPE_END,
332 : : };
333 : :
334 : : static enum rte_flow_item_type pattern_fdir_ipv4_udp_raw_2[] = {
335 : : RTE_FLOW_ITEM_TYPE_ETH,
336 : : RTE_FLOW_ITEM_TYPE_IPV4,
337 : : RTE_FLOW_ITEM_TYPE_UDP,
338 : : RTE_FLOW_ITEM_TYPE_RAW,
339 : : RTE_FLOW_ITEM_TYPE_RAW,
340 : : RTE_FLOW_ITEM_TYPE_END,
341 : : };
342 : :
343 : : static enum rte_flow_item_type pattern_fdir_ipv4_udp_raw_3[] = {
344 : : RTE_FLOW_ITEM_TYPE_ETH,
345 : : RTE_FLOW_ITEM_TYPE_IPV4,
346 : : RTE_FLOW_ITEM_TYPE_UDP,
347 : : RTE_FLOW_ITEM_TYPE_RAW,
348 : : RTE_FLOW_ITEM_TYPE_RAW,
349 : : RTE_FLOW_ITEM_TYPE_RAW,
350 : : RTE_FLOW_ITEM_TYPE_END,
351 : : };
352 : :
353 : : static enum rte_flow_item_type pattern_fdir_ipv4_tcp_raw_1[] = {
354 : : RTE_FLOW_ITEM_TYPE_ETH,
355 : : RTE_FLOW_ITEM_TYPE_IPV4,
356 : : RTE_FLOW_ITEM_TYPE_TCP,
357 : : RTE_FLOW_ITEM_TYPE_RAW,
358 : : RTE_FLOW_ITEM_TYPE_END,
359 : : };
360 : :
361 : : static enum rte_flow_item_type pattern_fdir_ipv4_tcp_raw_2[] = {
362 : : RTE_FLOW_ITEM_TYPE_ETH,
363 : : RTE_FLOW_ITEM_TYPE_IPV4,
364 : : RTE_FLOW_ITEM_TYPE_TCP,
365 : : RTE_FLOW_ITEM_TYPE_RAW,
366 : : RTE_FLOW_ITEM_TYPE_RAW,
367 : : RTE_FLOW_ITEM_TYPE_END,
368 : : };
369 : :
370 : : static enum rte_flow_item_type pattern_fdir_ipv4_tcp_raw_3[] = {
371 : : RTE_FLOW_ITEM_TYPE_ETH,
372 : : RTE_FLOW_ITEM_TYPE_IPV4,
373 : : RTE_FLOW_ITEM_TYPE_TCP,
374 : : RTE_FLOW_ITEM_TYPE_RAW,
375 : : RTE_FLOW_ITEM_TYPE_RAW,
376 : : RTE_FLOW_ITEM_TYPE_RAW,
377 : : RTE_FLOW_ITEM_TYPE_END,
378 : : };
379 : :
380 : : static enum rte_flow_item_type pattern_fdir_ipv4_sctp_raw_1[] = {
381 : : RTE_FLOW_ITEM_TYPE_ETH,
382 : : RTE_FLOW_ITEM_TYPE_IPV4,
383 : : RTE_FLOW_ITEM_TYPE_SCTP,
384 : : RTE_FLOW_ITEM_TYPE_RAW,
385 : : RTE_FLOW_ITEM_TYPE_END,
386 : : };
387 : :
388 : : static enum rte_flow_item_type pattern_fdir_ipv4_sctp_raw_2[] = {
389 : : RTE_FLOW_ITEM_TYPE_ETH,
390 : : RTE_FLOW_ITEM_TYPE_IPV4,
391 : : RTE_FLOW_ITEM_TYPE_SCTP,
392 : : RTE_FLOW_ITEM_TYPE_RAW,
393 : : RTE_FLOW_ITEM_TYPE_RAW,
394 : : RTE_FLOW_ITEM_TYPE_END,
395 : : };
396 : :
397 : : static enum rte_flow_item_type pattern_fdir_ipv4_sctp_raw_3[] = {
398 : : RTE_FLOW_ITEM_TYPE_ETH,
399 : : RTE_FLOW_ITEM_TYPE_IPV4,
400 : : RTE_FLOW_ITEM_TYPE_SCTP,
401 : : RTE_FLOW_ITEM_TYPE_RAW,
402 : : RTE_FLOW_ITEM_TYPE_RAW,
403 : : RTE_FLOW_ITEM_TYPE_RAW,
404 : : RTE_FLOW_ITEM_TYPE_END,
405 : : };
406 : :
407 : : static enum rte_flow_item_type pattern_fdir_ipv6_raw_1[] = {
408 : : RTE_FLOW_ITEM_TYPE_ETH,
409 : : RTE_FLOW_ITEM_TYPE_IPV6,
410 : : RTE_FLOW_ITEM_TYPE_RAW,
411 : : RTE_FLOW_ITEM_TYPE_END,
412 : : };
413 : :
414 : : static enum rte_flow_item_type pattern_fdir_ipv6_raw_2[] = {
415 : : RTE_FLOW_ITEM_TYPE_ETH,
416 : : RTE_FLOW_ITEM_TYPE_IPV6,
417 : : RTE_FLOW_ITEM_TYPE_RAW,
418 : : RTE_FLOW_ITEM_TYPE_RAW,
419 : : RTE_FLOW_ITEM_TYPE_END,
420 : : };
421 : :
422 : : static enum rte_flow_item_type pattern_fdir_ipv6_raw_3[] = {
423 : : RTE_FLOW_ITEM_TYPE_ETH,
424 : : RTE_FLOW_ITEM_TYPE_IPV6,
425 : : RTE_FLOW_ITEM_TYPE_RAW,
426 : : RTE_FLOW_ITEM_TYPE_RAW,
427 : : RTE_FLOW_ITEM_TYPE_RAW,
428 : : RTE_FLOW_ITEM_TYPE_END,
429 : : };
430 : :
431 : : static enum rte_flow_item_type pattern_fdir_ipv6_udp_raw_1[] = {
432 : : RTE_FLOW_ITEM_TYPE_ETH,
433 : : RTE_FLOW_ITEM_TYPE_IPV6,
434 : : RTE_FLOW_ITEM_TYPE_UDP,
435 : : RTE_FLOW_ITEM_TYPE_RAW,
436 : : RTE_FLOW_ITEM_TYPE_END,
437 : : };
438 : :
439 : : static enum rte_flow_item_type pattern_fdir_ipv6_udp_raw_2[] = {
440 : : RTE_FLOW_ITEM_TYPE_ETH,
441 : : RTE_FLOW_ITEM_TYPE_IPV6,
442 : : RTE_FLOW_ITEM_TYPE_UDP,
443 : : RTE_FLOW_ITEM_TYPE_RAW,
444 : : RTE_FLOW_ITEM_TYPE_RAW,
445 : : RTE_FLOW_ITEM_TYPE_END,
446 : : };
447 : :
448 : : static enum rte_flow_item_type pattern_fdir_ipv6_udp_raw_3[] = {
449 : : RTE_FLOW_ITEM_TYPE_ETH,
450 : : RTE_FLOW_ITEM_TYPE_IPV6,
451 : : RTE_FLOW_ITEM_TYPE_UDP,
452 : : RTE_FLOW_ITEM_TYPE_RAW,
453 : : RTE_FLOW_ITEM_TYPE_RAW,
454 : : RTE_FLOW_ITEM_TYPE_RAW,
455 : : RTE_FLOW_ITEM_TYPE_END,
456 : : };
457 : :
458 : : static enum rte_flow_item_type pattern_fdir_ipv6_tcp_raw_1[] = {
459 : : RTE_FLOW_ITEM_TYPE_ETH,
460 : : RTE_FLOW_ITEM_TYPE_IPV6,
461 : : RTE_FLOW_ITEM_TYPE_TCP,
462 : : RTE_FLOW_ITEM_TYPE_RAW,
463 : : RTE_FLOW_ITEM_TYPE_END,
464 : : };
465 : :
466 : : static enum rte_flow_item_type pattern_fdir_ipv6_tcp_raw_2[] = {
467 : : RTE_FLOW_ITEM_TYPE_ETH,
468 : : RTE_FLOW_ITEM_TYPE_IPV6,
469 : : RTE_FLOW_ITEM_TYPE_TCP,
470 : : RTE_FLOW_ITEM_TYPE_RAW,
471 : : RTE_FLOW_ITEM_TYPE_RAW,
472 : : RTE_FLOW_ITEM_TYPE_END,
473 : : };
474 : :
475 : : static enum rte_flow_item_type pattern_fdir_ipv6_tcp_raw_3[] = {
476 : : RTE_FLOW_ITEM_TYPE_ETH,
477 : : RTE_FLOW_ITEM_TYPE_IPV6,
478 : : RTE_FLOW_ITEM_TYPE_TCP,
479 : : RTE_FLOW_ITEM_TYPE_RAW,
480 : : RTE_FLOW_ITEM_TYPE_RAW,
481 : : RTE_FLOW_ITEM_TYPE_RAW,
482 : : RTE_FLOW_ITEM_TYPE_END,
483 : : };
484 : :
485 : : static enum rte_flow_item_type pattern_fdir_ipv6_sctp_raw_1[] = {
486 : : RTE_FLOW_ITEM_TYPE_ETH,
487 : : RTE_FLOW_ITEM_TYPE_IPV6,
488 : : RTE_FLOW_ITEM_TYPE_SCTP,
489 : : RTE_FLOW_ITEM_TYPE_RAW,
490 : : RTE_FLOW_ITEM_TYPE_END,
491 : : };
492 : :
493 : : static enum rte_flow_item_type pattern_fdir_ipv6_sctp_raw_2[] = {
494 : : RTE_FLOW_ITEM_TYPE_ETH,
495 : : RTE_FLOW_ITEM_TYPE_IPV6,
496 : : RTE_FLOW_ITEM_TYPE_SCTP,
497 : : RTE_FLOW_ITEM_TYPE_RAW,
498 : : RTE_FLOW_ITEM_TYPE_RAW,
499 : : RTE_FLOW_ITEM_TYPE_END,
500 : : };
501 : :
502 : : static enum rte_flow_item_type pattern_fdir_ipv6_sctp_raw_3[] = {
503 : : RTE_FLOW_ITEM_TYPE_ETH,
504 : : RTE_FLOW_ITEM_TYPE_IPV6,
505 : : RTE_FLOW_ITEM_TYPE_SCTP,
506 : : RTE_FLOW_ITEM_TYPE_RAW,
507 : : RTE_FLOW_ITEM_TYPE_RAW,
508 : : RTE_FLOW_ITEM_TYPE_RAW,
509 : : RTE_FLOW_ITEM_TYPE_END,
510 : : };
511 : :
512 : : static enum rte_flow_item_type pattern_fdir_ethertype_vlan[] = {
513 : : RTE_FLOW_ITEM_TYPE_ETH,
514 : : RTE_FLOW_ITEM_TYPE_VLAN,
515 : : RTE_FLOW_ITEM_TYPE_END,
516 : : };
517 : :
518 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4[] = {
519 : : RTE_FLOW_ITEM_TYPE_ETH,
520 : : RTE_FLOW_ITEM_TYPE_VLAN,
521 : : RTE_FLOW_ITEM_TYPE_IPV4,
522 : : RTE_FLOW_ITEM_TYPE_END,
523 : : };
524 : :
525 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_udp[] = {
526 : : RTE_FLOW_ITEM_TYPE_ETH,
527 : : RTE_FLOW_ITEM_TYPE_VLAN,
528 : : RTE_FLOW_ITEM_TYPE_IPV4,
529 : : RTE_FLOW_ITEM_TYPE_UDP,
530 : : RTE_FLOW_ITEM_TYPE_END,
531 : : };
532 : :
533 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_tcp[] = {
534 : : RTE_FLOW_ITEM_TYPE_ETH,
535 : : RTE_FLOW_ITEM_TYPE_VLAN,
536 : : RTE_FLOW_ITEM_TYPE_IPV4,
537 : : RTE_FLOW_ITEM_TYPE_TCP,
538 : : RTE_FLOW_ITEM_TYPE_END,
539 : : };
540 : :
541 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_sctp[] = {
542 : : RTE_FLOW_ITEM_TYPE_ETH,
543 : : RTE_FLOW_ITEM_TYPE_VLAN,
544 : : RTE_FLOW_ITEM_TYPE_IPV4,
545 : : RTE_FLOW_ITEM_TYPE_SCTP,
546 : : RTE_FLOW_ITEM_TYPE_END,
547 : : };
548 : :
549 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6[] = {
550 : : RTE_FLOW_ITEM_TYPE_ETH,
551 : : RTE_FLOW_ITEM_TYPE_VLAN,
552 : : RTE_FLOW_ITEM_TYPE_IPV6,
553 : : RTE_FLOW_ITEM_TYPE_END,
554 : : };
555 : :
556 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_udp[] = {
557 : : RTE_FLOW_ITEM_TYPE_ETH,
558 : : RTE_FLOW_ITEM_TYPE_VLAN,
559 : : RTE_FLOW_ITEM_TYPE_IPV6,
560 : : RTE_FLOW_ITEM_TYPE_UDP,
561 : : RTE_FLOW_ITEM_TYPE_END,
562 : : };
563 : :
564 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_tcp[] = {
565 : : RTE_FLOW_ITEM_TYPE_ETH,
566 : : RTE_FLOW_ITEM_TYPE_VLAN,
567 : : RTE_FLOW_ITEM_TYPE_IPV6,
568 : : RTE_FLOW_ITEM_TYPE_TCP,
569 : : RTE_FLOW_ITEM_TYPE_END,
570 : : };
571 : :
572 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_sctp[] = {
573 : : RTE_FLOW_ITEM_TYPE_ETH,
574 : : RTE_FLOW_ITEM_TYPE_VLAN,
575 : : RTE_FLOW_ITEM_TYPE_IPV6,
576 : : RTE_FLOW_ITEM_TYPE_SCTP,
577 : : RTE_FLOW_ITEM_TYPE_END,
578 : : };
579 : :
580 : : static enum rte_flow_item_type pattern_fdir_ethertype_vlan_raw_1[] = {
581 : : RTE_FLOW_ITEM_TYPE_ETH,
582 : : RTE_FLOW_ITEM_TYPE_VLAN,
583 : : RTE_FLOW_ITEM_TYPE_RAW,
584 : : RTE_FLOW_ITEM_TYPE_END,
585 : : };
586 : :
587 : : static enum rte_flow_item_type pattern_fdir_ethertype_vlan_raw_2[] = {
588 : : RTE_FLOW_ITEM_TYPE_ETH,
589 : : RTE_FLOW_ITEM_TYPE_VLAN,
590 : : RTE_FLOW_ITEM_TYPE_RAW,
591 : : RTE_FLOW_ITEM_TYPE_RAW,
592 : : RTE_FLOW_ITEM_TYPE_END,
593 : : };
594 : :
595 : : static enum rte_flow_item_type pattern_fdir_ethertype_vlan_raw_3[] = {
596 : : RTE_FLOW_ITEM_TYPE_ETH,
597 : : RTE_FLOW_ITEM_TYPE_VLAN,
598 : : RTE_FLOW_ITEM_TYPE_RAW,
599 : : RTE_FLOW_ITEM_TYPE_RAW,
600 : : RTE_FLOW_ITEM_TYPE_RAW,
601 : : RTE_FLOW_ITEM_TYPE_END,
602 : : };
603 : :
604 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_raw_1[] = {
605 : : RTE_FLOW_ITEM_TYPE_ETH,
606 : : RTE_FLOW_ITEM_TYPE_VLAN,
607 : : RTE_FLOW_ITEM_TYPE_IPV4,
608 : : RTE_FLOW_ITEM_TYPE_RAW,
609 : : RTE_FLOW_ITEM_TYPE_END,
610 : : };
611 : :
612 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_raw_2[] = {
613 : : RTE_FLOW_ITEM_TYPE_ETH,
614 : : RTE_FLOW_ITEM_TYPE_VLAN,
615 : : RTE_FLOW_ITEM_TYPE_IPV4,
616 : : RTE_FLOW_ITEM_TYPE_RAW,
617 : : RTE_FLOW_ITEM_TYPE_RAW,
618 : : RTE_FLOW_ITEM_TYPE_END,
619 : : };
620 : :
621 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_raw_3[] = {
622 : : RTE_FLOW_ITEM_TYPE_ETH,
623 : : RTE_FLOW_ITEM_TYPE_VLAN,
624 : : RTE_FLOW_ITEM_TYPE_IPV4,
625 : : RTE_FLOW_ITEM_TYPE_RAW,
626 : : RTE_FLOW_ITEM_TYPE_RAW,
627 : : RTE_FLOW_ITEM_TYPE_RAW,
628 : : RTE_FLOW_ITEM_TYPE_END,
629 : : };
630 : :
631 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_udp_raw_1[] = {
632 : : RTE_FLOW_ITEM_TYPE_ETH,
633 : : RTE_FLOW_ITEM_TYPE_VLAN,
634 : : RTE_FLOW_ITEM_TYPE_IPV4,
635 : : RTE_FLOW_ITEM_TYPE_UDP,
636 : : RTE_FLOW_ITEM_TYPE_RAW,
637 : : RTE_FLOW_ITEM_TYPE_END,
638 : : };
639 : :
640 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_udp_raw_2[] = {
641 : : RTE_FLOW_ITEM_TYPE_ETH,
642 : : RTE_FLOW_ITEM_TYPE_VLAN,
643 : : RTE_FLOW_ITEM_TYPE_IPV4,
644 : : RTE_FLOW_ITEM_TYPE_UDP,
645 : : RTE_FLOW_ITEM_TYPE_RAW,
646 : : RTE_FLOW_ITEM_TYPE_RAW,
647 : : RTE_FLOW_ITEM_TYPE_END,
648 : : };
649 : :
650 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_udp_raw_3[] = {
651 : : RTE_FLOW_ITEM_TYPE_ETH,
652 : : RTE_FLOW_ITEM_TYPE_VLAN,
653 : : RTE_FLOW_ITEM_TYPE_IPV4,
654 : : RTE_FLOW_ITEM_TYPE_UDP,
655 : : RTE_FLOW_ITEM_TYPE_RAW,
656 : : RTE_FLOW_ITEM_TYPE_RAW,
657 : : RTE_FLOW_ITEM_TYPE_RAW,
658 : : RTE_FLOW_ITEM_TYPE_END,
659 : : };
660 : :
661 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_tcp_raw_1[] = {
662 : : RTE_FLOW_ITEM_TYPE_ETH,
663 : : RTE_FLOW_ITEM_TYPE_VLAN,
664 : : RTE_FLOW_ITEM_TYPE_IPV4,
665 : : RTE_FLOW_ITEM_TYPE_TCP,
666 : : RTE_FLOW_ITEM_TYPE_RAW,
667 : : RTE_FLOW_ITEM_TYPE_END,
668 : : };
669 : :
670 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_tcp_raw_2[] = {
671 : : RTE_FLOW_ITEM_TYPE_ETH,
672 : : RTE_FLOW_ITEM_TYPE_VLAN,
673 : : RTE_FLOW_ITEM_TYPE_IPV4,
674 : : RTE_FLOW_ITEM_TYPE_TCP,
675 : : RTE_FLOW_ITEM_TYPE_RAW,
676 : : RTE_FLOW_ITEM_TYPE_RAW,
677 : : RTE_FLOW_ITEM_TYPE_END,
678 : : };
679 : :
680 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_tcp_raw_3[] = {
681 : : RTE_FLOW_ITEM_TYPE_ETH,
682 : : RTE_FLOW_ITEM_TYPE_VLAN,
683 : : RTE_FLOW_ITEM_TYPE_IPV4,
684 : : RTE_FLOW_ITEM_TYPE_TCP,
685 : : RTE_FLOW_ITEM_TYPE_RAW,
686 : : RTE_FLOW_ITEM_TYPE_RAW,
687 : : RTE_FLOW_ITEM_TYPE_RAW,
688 : : RTE_FLOW_ITEM_TYPE_END,
689 : : };
690 : :
691 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_sctp_raw_1[] = {
692 : : RTE_FLOW_ITEM_TYPE_ETH,
693 : : RTE_FLOW_ITEM_TYPE_VLAN,
694 : : RTE_FLOW_ITEM_TYPE_IPV4,
695 : : RTE_FLOW_ITEM_TYPE_SCTP,
696 : : RTE_FLOW_ITEM_TYPE_RAW,
697 : : RTE_FLOW_ITEM_TYPE_END,
698 : : };
699 : :
700 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_sctp_raw_2[] = {
701 : : RTE_FLOW_ITEM_TYPE_ETH,
702 : : RTE_FLOW_ITEM_TYPE_VLAN,
703 : : RTE_FLOW_ITEM_TYPE_IPV4,
704 : : RTE_FLOW_ITEM_TYPE_SCTP,
705 : : RTE_FLOW_ITEM_TYPE_RAW,
706 : : RTE_FLOW_ITEM_TYPE_RAW,
707 : : RTE_FLOW_ITEM_TYPE_END,
708 : : };
709 : :
710 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv4_sctp_raw_3[] = {
711 : : RTE_FLOW_ITEM_TYPE_ETH,
712 : : RTE_FLOW_ITEM_TYPE_VLAN,
713 : : RTE_FLOW_ITEM_TYPE_IPV4,
714 : : RTE_FLOW_ITEM_TYPE_SCTP,
715 : : RTE_FLOW_ITEM_TYPE_RAW,
716 : : RTE_FLOW_ITEM_TYPE_RAW,
717 : : RTE_FLOW_ITEM_TYPE_RAW,
718 : : RTE_FLOW_ITEM_TYPE_END,
719 : : };
720 : :
721 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_raw_1[] = {
722 : : RTE_FLOW_ITEM_TYPE_ETH,
723 : : RTE_FLOW_ITEM_TYPE_VLAN,
724 : : RTE_FLOW_ITEM_TYPE_IPV6,
725 : : RTE_FLOW_ITEM_TYPE_RAW,
726 : : RTE_FLOW_ITEM_TYPE_END,
727 : : };
728 : :
729 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_raw_2[] = {
730 : : RTE_FLOW_ITEM_TYPE_ETH,
731 : : RTE_FLOW_ITEM_TYPE_VLAN,
732 : : RTE_FLOW_ITEM_TYPE_IPV6,
733 : : RTE_FLOW_ITEM_TYPE_RAW,
734 : : RTE_FLOW_ITEM_TYPE_RAW,
735 : : RTE_FLOW_ITEM_TYPE_END,
736 : : };
737 : :
738 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_raw_3[] = {
739 : : RTE_FLOW_ITEM_TYPE_ETH,
740 : : RTE_FLOW_ITEM_TYPE_VLAN,
741 : : RTE_FLOW_ITEM_TYPE_IPV6,
742 : : RTE_FLOW_ITEM_TYPE_RAW,
743 : : RTE_FLOW_ITEM_TYPE_RAW,
744 : : RTE_FLOW_ITEM_TYPE_RAW,
745 : : RTE_FLOW_ITEM_TYPE_END,
746 : : };
747 : :
748 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_udp_raw_1[] = {
749 : : RTE_FLOW_ITEM_TYPE_ETH,
750 : : RTE_FLOW_ITEM_TYPE_VLAN,
751 : : RTE_FLOW_ITEM_TYPE_IPV6,
752 : : RTE_FLOW_ITEM_TYPE_UDP,
753 : : RTE_FLOW_ITEM_TYPE_RAW,
754 : : RTE_FLOW_ITEM_TYPE_END,
755 : : };
756 : :
757 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_udp_raw_2[] = {
758 : : RTE_FLOW_ITEM_TYPE_ETH,
759 : : RTE_FLOW_ITEM_TYPE_VLAN,
760 : : RTE_FLOW_ITEM_TYPE_IPV6,
761 : : RTE_FLOW_ITEM_TYPE_UDP,
762 : : RTE_FLOW_ITEM_TYPE_RAW,
763 : : RTE_FLOW_ITEM_TYPE_RAW,
764 : : RTE_FLOW_ITEM_TYPE_END,
765 : : };
766 : :
767 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_udp_raw_3[] = {
768 : : RTE_FLOW_ITEM_TYPE_ETH,
769 : : RTE_FLOW_ITEM_TYPE_VLAN,
770 : : RTE_FLOW_ITEM_TYPE_IPV6,
771 : : RTE_FLOW_ITEM_TYPE_UDP,
772 : : RTE_FLOW_ITEM_TYPE_RAW,
773 : : RTE_FLOW_ITEM_TYPE_RAW,
774 : : RTE_FLOW_ITEM_TYPE_RAW,
775 : : RTE_FLOW_ITEM_TYPE_END,
776 : : };
777 : :
778 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_tcp_raw_1[] = {
779 : : RTE_FLOW_ITEM_TYPE_ETH,
780 : : RTE_FLOW_ITEM_TYPE_VLAN,
781 : : RTE_FLOW_ITEM_TYPE_IPV6,
782 : : RTE_FLOW_ITEM_TYPE_TCP,
783 : : RTE_FLOW_ITEM_TYPE_RAW,
784 : : RTE_FLOW_ITEM_TYPE_END,
785 : : };
786 : :
787 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_tcp_raw_2[] = {
788 : : RTE_FLOW_ITEM_TYPE_ETH,
789 : : RTE_FLOW_ITEM_TYPE_VLAN,
790 : : RTE_FLOW_ITEM_TYPE_IPV6,
791 : : RTE_FLOW_ITEM_TYPE_TCP,
792 : : RTE_FLOW_ITEM_TYPE_RAW,
793 : : RTE_FLOW_ITEM_TYPE_RAW,
794 : : RTE_FLOW_ITEM_TYPE_END,
795 : : };
796 : :
797 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_tcp_raw_3[] = {
798 : : RTE_FLOW_ITEM_TYPE_ETH,
799 : : RTE_FLOW_ITEM_TYPE_VLAN,
800 : : RTE_FLOW_ITEM_TYPE_IPV6,
801 : : RTE_FLOW_ITEM_TYPE_TCP,
802 : : RTE_FLOW_ITEM_TYPE_RAW,
803 : : RTE_FLOW_ITEM_TYPE_RAW,
804 : : RTE_FLOW_ITEM_TYPE_RAW,
805 : : RTE_FLOW_ITEM_TYPE_END,
806 : : };
807 : :
808 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_sctp_raw_1[] = {
809 : : RTE_FLOW_ITEM_TYPE_ETH,
810 : : RTE_FLOW_ITEM_TYPE_VLAN,
811 : : RTE_FLOW_ITEM_TYPE_IPV6,
812 : : RTE_FLOW_ITEM_TYPE_SCTP,
813 : : RTE_FLOW_ITEM_TYPE_RAW,
814 : : RTE_FLOW_ITEM_TYPE_END,
815 : : };
816 : :
817 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_sctp_raw_2[] = {
818 : : RTE_FLOW_ITEM_TYPE_ETH,
819 : : RTE_FLOW_ITEM_TYPE_VLAN,
820 : : RTE_FLOW_ITEM_TYPE_IPV6,
821 : : RTE_FLOW_ITEM_TYPE_SCTP,
822 : : RTE_FLOW_ITEM_TYPE_RAW,
823 : : RTE_FLOW_ITEM_TYPE_RAW,
824 : : RTE_FLOW_ITEM_TYPE_END,
825 : : };
826 : :
827 : : static enum rte_flow_item_type pattern_fdir_vlan_ipv6_sctp_raw_3[] = {
828 : : RTE_FLOW_ITEM_TYPE_ETH,
829 : : RTE_FLOW_ITEM_TYPE_VLAN,
830 : : RTE_FLOW_ITEM_TYPE_IPV6,
831 : : RTE_FLOW_ITEM_TYPE_SCTP,
832 : : RTE_FLOW_ITEM_TYPE_RAW,
833 : : RTE_FLOW_ITEM_TYPE_RAW,
834 : : RTE_FLOW_ITEM_TYPE_RAW,
835 : : RTE_FLOW_ITEM_TYPE_END,
836 : : };
837 : :
838 : : /* Pattern matched tunnel filter */
839 : : static enum rte_flow_item_type pattern_vxlan_1[] = {
840 : : RTE_FLOW_ITEM_TYPE_ETH,
841 : : RTE_FLOW_ITEM_TYPE_IPV4,
842 : : RTE_FLOW_ITEM_TYPE_UDP,
843 : : RTE_FLOW_ITEM_TYPE_VXLAN,
844 : : RTE_FLOW_ITEM_TYPE_ETH,
845 : : RTE_FLOW_ITEM_TYPE_END,
846 : : };
847 : :
848 : : static enum rte_flow_item_type pattern_vxlan_2[] = {
849 : : RTE_FLOW_ITEM_TYPE_ETH,
850 : : RTE_FLOW_ITEM_TYPE_IPV6,
851 : : RTE_FLOW_ITEM_TYPE_UDP,
852 : : RTE_FLOW_ITEM_TYPE_VXLAN,
853 : : RTE_FLOW_ITEM_TYPE_ETH,
854 : : RTE_FLOW_ITEM_TYPE_END,
855 : : };
856 : :
857 : : static enum rte_flow_item_type pattern_vxlan_3[] = {
858 : : RTE_FLOW_ITEM_TYPE_ETH,
859 : : RTE_FLOW_ITEM_TYPE_IPV4,
860 : : RTE_FLOW_ITEM_TYPE_UDP,
861 : : RTE_FLOW_ITEM_TYPE_VXLAN,
862 : : RTE_FLOW_ITEM_TYPE_ETH,
863 : : RTE_FLOW_ITEM_TYPE_VLAN,
864 : : RTE_FLOW_ITEM_TYPE_END,
865 : : };
866 : :
867 : : static enum rte_flow_item_type pattern_vxlan_4[] = {
868 : : RTE_FLOW_ITEM_TYPE_ETH,
869 : : RTE_FLOW_ITEM_TYPE_IPV6,
870 : : RTE_FLOW_ITEM_TYPE_UDP,
871 : : RTE_FLOW_ITEM_TYPE_VXLAN,
872 : : RTE_FLOW_ITEM_TYPE_ETH,
873 : : RTE_FLOW_ITEM_TYPE_VLAN,
874 : : RTE_FLOW_ITEM_TYPE_END,
875 : : };
876 : :
877 : : static enum rte_flow_item_type pattern_nvgre_1[] = {
878 : : RTE_FLOW_ITEM_TYPE_ETH,
879 : : RTE_FLOW_ITEM_TYPE_IPV4,
880 : : RTE_FLOW_ITEM_TYPE_NVGRE,
881 : : RTE_FLOW_ITEM_TYPE_ETH,
882 : : RTE_FLOW_ITEM_TYPE_END,
883 : : };
884 : :
885 : : static enum rte_flow_item_type pattern_nvgre_2[] = {
886 : : RTE_FLOW_ITEM_TYPE_ETH,
887 : : RTE_FLOW_ITEM_TYPE_IPV6,
888 : : RTE_FLOW_ITEM_TYPE_NVGRE,
889 : : RTE_FLOW_ITEM_TYPE_ETH,
890 : : RTE_FLOW_ITEM_TYPE_END,
891 : : };
892 : :
893 : : static enum rte_flow_item_type pattern_nvgre_3[] = {
894 : : RTE_FLOW_ITEM_TYPE_ETH,
895 : : RTE_FLOW_ITEM_TYPE_IPV4,
896 : : RTE_FLOW_ITEM_TYPE_NVGRE,
897 : : RTE_FLOW_ITEM_TYPE_ETH,
898 : : RTE_FLOW_ITEM_TYPE_VLAN,
899 : : RTE_FLOW_ITEM_TYPE_END,
900 : : };
901 : :
902 : : static enum rte_flow_item_type pattern_nvgre_4[] = {
903 : : RTE_FLOW_ITEM_TYPE_ETH,
904 : : RTE_FLOW_ITEM_TYPE_IPV6,
905 : : RTE_FLOW_ITEM_TYPE_NVGRE,
906 : : RTE_FLOW_ITEM_TYPE_ETH,
907 : : RTE_FLOW_ITEM_TYPE_VLAN,
908 : : RTE_FLOW_ITEM_TYPE_END,
909 : : };
910 : :
911 : : static enum rte_flow_item_type pattern_mpls_1[] = {
912 : : RTE_FLOW_ITEM_TYPE_ETH,
913 : : RTE_FLOW_ITEM_TYPE_IPV4,
914 : : RTE_FLOW_ITEM_TYPE_UDP,
915 : : RTE_FLOW_ITEM_TYPE_MPLS,
916 : : RTE_FLOW_ITEM_TYPE_END,
917 : : };
918 : :
919 : : static enum rte_flow_item_type pattern_mpls_2[] = {
920 : : RTE_FLOW_ITEM_TYPE_ETH,
921 : : RTE_FLOW_ITEM_TYPE_IPV6,
922 : : RTE_FLOW_ITEM_TYPE_UDP,
923 : : RTE_FLOW_ITEM_TYPE_MPLS,
924 : : RTE_FLOW_ITEM_TYPE_END,
925 : : };
926 : :
927 : : static enum rte_flow_item_type pattern_mpls_3[] = {
928 : : RTE_FLOW_ITEM_TYPE_ETH,
929 : : RTE_FLOW_ITEM_TYPE_IPV4,
930 : : RTE_FLOW_ITEM_TYPE_GRE,
931 : : RTE_FLOW_ITEM_TYPE_MPLS,
932 : : RTE_FLOW_ITEM_TYPE_END,
933 : : };
934 : :
935 : : static enum rte_flow_item_type pattern_mpls_4[] = {
936 : : RTE_FLOW_ITEM_TYPE_ETH,
937 : : RTE_FLOW_ITEM_TYPE_IPV6,
938 : : RTE_FLOW_ITEM_TYPE_GRE,
939 : : RTE_FLOW_ITEM_TYPE_MPLS,
940 : : RTE_FLOW_ITEM_TYPE_END,
941 : : };
942 : :
943 : : static enum rte_flow_item_type pattern_qinq_1[] = {
944 : : RTE_FLOW_ITEM_TYPE_ETH,
945 : : RTE_FLOW_ITEM_TYPE_VLAN,
946 : : RTE_FLOW_ITEM_TYPE_VLAN,
947 : : RTE_FLOW_ITEM_TYPE_END,
948 : : };
949 : :
950 : : static enum rte_flow_item_type pattern_fdir_ipv4_l2tpv3oip[] = {
951 : : RTE_FLOW_ITEM_TYPE_ETH,
952 : : RTE_FLOW_ITEM_TYPE_IPV4,
953 : : RTE_FLOW_ITEM_TYPE_L2TPV3OIP,
954 : : RTE_FLOW_ITEM_TYPE_END,
955 : : };
956 : :
957 : : static enum rte_flow_item_type pattern_fdir_ipv6_l2tpv3oip[] = {
958 : : RTE_FLOW_ITEM_TYPE_ETH,
959 : : RTE_FLOW_ITEM_TYPE_IPV6,
960 : : RTE_FLOW_ITEM_TYPE_L2TPV3OIP,
961 : : RTE_FLOW_ITEM_TYPE_END,
962 : : };
963 : :
964 : : static enum rte_flow_item_type pattern_fdir_ipv4_esp[] = {
965 : : RTE_FLOW_ITEM_TYPE_ETH,
966 : : RTE_FLOW_ITEM_TYPE_IPV4,
967 : : RTE_FLOW_ITEM_TYPE_ESP,
968 : : RTE_FLOW_ITEM_TYPE_END,
969 : : };
970 : :
971 : : static enum rte_flow_item_type pattern_fdir_ipv6_esp[] = {
972 : : RTE_FLOW_ITEM_TYPE_ETH,
973 : : RTE_FLOW_ITEM_TYPE_IPV6,
974 : : RTE_FLOW_ITEM_TYPE_ESP,
975 : : RTE_FLOW_ITEM_TYPE_END,
976 : : };
977 : :
978 : : static enum rte_flow_item_type pattern_fdir_ipv4_udp_esp[] = {
979 : : RTE_FLOW_ITEM_TYPE_ETH,
980 : : RTE_FLOW_ITEM_TYPE_IPV4,
981 : : RTE_FLOW_ITEM_TYPE_UDP,
982 : : RTE_FLOW_ITEM_TYPE_ESP,
983 : : RTE_FLOW_ITEM_TYPE_END,
984 : : };
985 : :
986 : : static enum rte_flow_item_type pattern_fdir_ipv6_udp_esp[] = {
987 : : RTE_FLOW_ITEM_TYPE_ETH,
988 : : RTE_FLOW_ITEM_TYPE_IPV6,
989 : : RTE_FLOW_ITEM_TYPE_UDP,
990 : : RTE_FLOW_ITEM_TYPE_ESP,
991 : : RTE_FLOW_ITEM_TYPE_END,
992 : : };
993 : :
994 : : static struct i40e_valid_pattern i40e_supported_patterns[] = {
995 : : /* Ethertype */
996 : : { pattern_ethertype, i40e_flow_parse_ethertype_filter },
997 : : /* FDIR - support default flow type without flexible payload*/
998 : : { pattern_ethertype, i40e_flow_parse_fdir_filter },
999 : : { pattern_fdir_ipv4, i40e_flow_parse_fdir_filter },
1000 : : { pattern_fdir_ipv4_udp, i40e_flow_parse_fdir_filter },
1001 : : { pattern_fdir_ipv4_tcp, i40e_flow_parse_fdir_filter },
1002 : : { pattern_fdir_ipv4_sctp, i40e_flow_parse_fdir_filter },
1003 : : { pattern_fdir_ipv4_gtpc, i40e_flow_parse_fdir_filter },
1004 : : { pattern_fdir_ipv4_gtpu, i40e_flow_parse_fdir_filter },
1005 : : { pattern_fdir_ipv4_gtpu_ipv4, i40e_flow_parse_fdir_filter },
1006 : : { pattern_fdir_ipv4_gtpu_ipv6, i40e_flow_parse_fdir_filter },
1007 : : { pattern_fdir_ipv4_esp, i40e_flow_parse_fdir_filter },
1008 : : { pattern_fdir_ipv4_udp_esp, i40e_flow_parse_fdir_filter },
1009 : : { pattern_fdir_ipv6, i40e_flow_parse_fdir_filter },
1010 : : { pattern_fdir_ipv6_udp, i40e_flow_parse_fdir_filter },
1011 : : { pattern_fdir_ipv6_tcp, i40e_flow_parse_fdir_filter },
1012 : : { pattern_fdir_ipv6_sctp, i40e_flow_parse_fdir_filter },
1013 : : { pattern_fdir_ipv6_gtpc, i40e_flow_parse_fdir_filter },
1014 : : { pattern_fdir_ipv6_gtpu, i40e_flow_parse_fdir_filter },
1015 : : { pattern_fdir_ipv6_gtpu_ipv4, i40e_flow_parse_fdir_filter },
1016 : : { pattern_fdir_ipv6_gtpu_ipv6, i40e_flow_parse_fdir_filter },
1017 : : { pattern_fdir_ipv6_esp, i40e_flow_parse_fdir_filter },
1018 : : { pattern_fdir_ipv6_udp_esp, i40e_flow_parse_fdir_filter },
1019 : : /* FDIR - support default flow type with flexible payload */
1020 : : { pattern_fdir_ethertype_raw_1, i40e_flow_parse_fdir_filter },
1021 : : { pattern_fdir_ethertype_raw_2, i40e_flow_parse_fdir_filter },
1022 : : { pattern_fdir_ethertype_raw_3, i40e_flow_parse_fdir_filter },
1023 : : { pattern_fdir_ipv4_raw_1, i40e_flow_parse_fdir_filter },
1024 : : { pattern_fdir_ipv4_raw_2, i40e_flow_parse_fdir_filter },
1025 : : { pattern_fdir_ipv4_raw_3, i40e_flow_parse_fdir_filter },
1026 : : { pattern_fdir_ipv4_udp_raw_1, i40e_flow_parse_fdir_filter },
1027 : : { pattern_fdir_ipv4_udp_raw_2, i40e_flow_parse_fdir_filter },
1028 : : { pattern_fdir_ipv4_udp_raw_3, i40e_flow_parse_fdir_filter },
1029 : : { pattern_fdir_ipv4_tcp_raw_1, i40e_flow_parse_fdir_filter },
1030 : : { pattern_fdir_ipv4_tcp_raw_2, i40e_flow_parse_fdir_filter },
1031 : : { pattern_fdir_ipv4_tcp_raw_3, i40e_flow_parse_fdir_filter },
1032 : : { pattern_fdir_ipv4_sctp_raw_1, i40e_flow_parse_fdir_filter },
1033 : : { pattern_fdir_ipv4_sctp_raw_2, i40e_flow_parse_fdir_filter },
1034 : : { pattern_fdir_ipv4_sctp_raw_3, i40e_flow_parse_fdir_filter },
1035 : : { pattern_fdir_ipv6_raw_1, i40e_flow_parse_fdir_filter },
1036 : : { pattern_fdir_ipv6_raw_2, i40e_flow_parse_fdir_filter },
1037 : : { pattern_fdir_ipv6_raw_3, i40e_flow_parse_fdir_filter },
1038 : : { pattern_fdir_ipv6_udp_raw_1, i40e_flow_parse_fdir_filter },
1039 : : { pattern_fdir_ipv6_udp_raw_2, i40e_flow_parse_fdir_filter },
1040 : : { pattern_fdir_ipv6_udp_raw_3, i40e_flow_parse_fdir_filter },
1041 : : { pattern_fdir_ipv6_tcp_raw_1, i40e_flow_parse_fdir_filter },
1042 : : { pattern_fdir_ipv6_tcp_raw_2, i40e_flow_parse_fdir_filter },
1043 : : { pattern_fdir_ipv6_tcp_raw_3, i40e_flow_parse_fdir_filter },
1044 : : { pattern_fdir_ipv6_sctp_raw_1, i40e_flow_parse_fdir_filter },
1045 : : { pattern_fdir_ipv6_sctp_raw_2, i40e_flow_parse_fdir_filter },
1046 : : { pattern_fdir_ipv6_sctp_raw_3, i40e_flow_parse_fdir_filter },
1047 : : /* FDIR - support single vlan input set */
1048 : : { pattern_fdir_ethertype_vlan, i40e_flow_parse_fdir_filter },
1049 : : { pattern_fdir_vlan_ipv4, i40e_flow_parse_fdir_filter },
1050 : : { pattern_fdir_vlan_ipv4_udp, i40e_flow_parse_fdir_filter },
1051 : : { pattern_fdir_vlan_ipv4_tcp, i40e_flow_parse_fdir_filter },
1052 : : { pattern_fdir_vlan_ipv4_sctp, i40e_flow_parse_fdir_filter },
1053 : : { pattern_fdir_vlan_ipv6, i40e_flow_parse_fdir_filter },
1054 : : { pattern_fdir_vlan_ipv6_udp, i40e_flow_parse_fdir_filter },
1055 : : { pattern_fdir_vlan_ipv6_tcp, i40e_flow_parse_fdir_filter },
1056 : : { pattern_fdir_vlan_ipv6_sctp, i40e_flow_parse_fdir_filter },
1057 : : { pattern_fdir_ethertype_vlan_raw_1, i40e_flow_parse_fdir_filter },
1058 : : { pattern_fdir_ethertype_vlan_raw_2, i40e_flow_parse_fdir_filter },
1059 : : { pattern_fdir_ethertype_vlan_raw_3, i40e_flow_parse_fdir_filter },
1060 : : { pattern_fdir_vlan_ipv4_raw_1, i40e_flow_parse_fdir_filter },
1061 : : { pattern_fdir_vlan_ipv4_raw_2, i40e_flow_parse_fdir_filter },
1062 : : { pattern_fdir_vlan_ipv4_raw_3, i40e_flow_parse_fdir_filter },
1063 : : { pattern_fdir_vlan_ipv4_udp_raw_1, i40e_flow_parse_fdir_filter },
1064 : : { pattern_fdir_vlan_ipv4_udp_raw_2, i40e_flow_parse_fdir_filter },
1065 : : { pattern_fdir_vlan_ipv4_udp_raw_3, i40e_flow_parse_fdir_filter },
1066 : : { pattern_fdir_vlan_ipv4_tcp_raw_1, i40e_flow_parse_fdir_filter },
1067 : : { pattern_fdir_vlan_ipv4_tcp_raw_2, i40e_flow_parse_fdir_filter },
1068 : : { pattern_fdir_vlan_ipv4_tcp_raw_3, i40e_flow_parse_fdir_filter },
1069 : : { pattern_fdir_vlan_ipv4_sctp_raw_1, i40e_flow_parse_fdir_filter },
1070 : : { pattern_fdir_vlan_ipv4_sctp_raw_2, i40e_flow_parse_fdir_filter },
1071 : : { pattern_fdir_vlan_ipv4_sctp_raw_3, i40e_flow_parse_fdir_filter },
1072 : : { pattern_fdir_vlan_ipv6_raw_1, i40e_flow_parse_fdir_filter },
1073 : : { pattern_fdir_vlan_ipv6_raw_2, i40e_flow_parse_fdir_filter },
1074 : : { pattern_fdir_vlan_ipv6_raw_3, i40e_flow_parse_fdir_filter },
1075 : : { pattern_fdir_vlan_ipv6_udp_raw_1, i40e_flow_parse_fdir_filter },
1076 : : { pattern_fdir_vlan_ipv6_udp_raw_2, i40e_flow_parse_fdir_filter },
1077 : : { pattern_fdir_vlan_ipv6_udp_raw_3, i40e_flow_parse_fdir_filter },
1078 : : { pattern_fdir_vlan_ipv6_tcp_raw_1, i40e_flow_parse_fdir_filter },
1079 : : { pattern_fdir_vlan_ipv6_tcp_raw_2, i40e_flow_parse_fdir_filter },
1080 : : { pattern_fdir_vlan_ipv6_tcp_raw_3, i40e_flow_parse_fdir_filter },
1081 : : { pattern_fdir_vlan_ipv6_sctp_raw_1, i40e_flow_parse_fdir_filter },
1082 : : { pattern_fdir_vlan_ipv6_sctp_raw_2, i40e_flow_parse_fdir_filter },
1083 : : { pattern_fdir_vlan_ipv6_sctp_raw_3, i40e_flow_parse_fdir_filter },
1084 : : /* VXLAN */
1085 : : { pattern_vxlan_1, i40e_flow_parse_vxlan_filter },
1086 : : { pattern_vxlan_2, i40e_flow_parse_vxlan_filter },
1087 : : { pattern_vxlan_3, i40e_flow_parse_vxlan_filter },
1088 : : { pattern_vxlan_4, i40e_flow_parse_vxlan_filter },
1089 : : /* NVGRE */
1090 : : { pattern_nvgre_1, i40e_flow_parse_nvgre_filter },
1091 : : { pattern_nvgre_2, i40e_flow_parse_nvgre_filter },
1092 : : { pattern_nvgre_3, i40e_flow_parse_nvgre_filter },
1093 : : { pattern_nvgre_4, i40e_flow_parse_nvgre_filter },
1094 : : /* MPLSoUDP & MPLSoGRE */
1095 : : { pattern_mpls_1, i40e_flow_parse_mpls_filter },
1096 : : { pattern_mpls_2, i40e_flow_parse_mpls_filter },
1097 : : { pattern_mpls_3, i40e_flow_parse_mpls_filter },
1098 : : { pattern_mpls_4, i40e_flow_parse_mpls_filter },
1099 : : /* GTP-C & GTP-U */
1100 : : { pattern_fdir_ipv4_gtpc, i40e_flow_parse_gtp_filter },
1101 : : { pattern_fdir_ipv4_gtpu, i40e_flow_parse_gtp_filter },
1102 : : { pattern_fdir_ipv6_gtpc, i40e_flow_parse_gtp_filter },
1103 : : { pattern_fdir_ipv6_gtpu, i40e_flow_parse_gtp_filter },
1104 : : /* QINQ */
1105 : : { pattern_qinq_1, i40e_flow_parse_qinq_filter },
1106 : : /* L2TPv3 over IP */
1107 : : { pattern_fdir_ipv4_l2tpv3oip, i40e_flow_parse_fdir_filter },
1108 : : { pattern_fdir_ipv6_l2tpv3oip, i40e_flow_parse_fdir_filter },
1109 : : /* L4 over port */
1110 : : { pattern_fdir_ipv4_udp, i40e_flow_parse_l4_cloud_filter },
1111 : : { pattern_fdir_ipv4_tcp, i40e_flow_parse_l4_cloud_filter },
1112 : : { pattern_fdir_ipv4_sctp, i40e_flow_parse_l4_cloud_filter },
1113 : : { pattern_fdir_ipv6_udp, i40e_flow_parse_l4_cloud_filter },
1114 : : { pattern_fdir_ipv6_tcp, i40e_flow_parse_l4_cloud_filter },
1115 : : { pattern_fdir_ipv6_sctp, i40e_flow_parse_l4_cloud_filter },
1116 : : };
1117 : :
1118 : : #define NEXT_ITEM_OF_ACTION(act, actions, index) \
1119 : : do { \
1120 : : act = actions + index; \
1121 : : while (act->type == RTE_FLOW_ACTION_TYPE_VOID) { \
1122 : : index++; \
1123 : : act = actions + index; \
1124 : : } \
1125 : : } while (0)
1126 : :
1127 : : /* Find the first VOID or non-VOID item pointer */
1128 : : static const struct rte_flow_item *
1129 : : i40e_find_first_item(const struct rte_flow_item *item, bool is_void)
1130 : : {
1131 : : bool is_find;
1132 : :
1133 [ # # # # ]: 0 : while (item->type != RTE_FLOW_ITEM_TYPE_END) {
1134 : : if (is_void)
1135 : : is_find = item->type == RTE_FLOW_ITEM_TYPE_VOID;
1136 : : else
1137 : : is_find = item->type != RTE_FLOW_ITEM_TYPE_VOID;
1138 [ # # # # ]: 0 : if (is_find)
1139 : : break;
1140 : 0 : item++;
1141 : : }
1142 : : return item;
1143 : : }
1144 : :
1145 : : /* Skip all VOID items of the pattern */
1146 : : static void
1147 : 0 : i40e_pattern_skip_void_item(struct rte_flow_item *items,
1148 : : const struct rte_flow_item *pattern)
1149 : : {
1150 : : uint32_t cpy_count = 0;
1151 : : const struct rte_flow_item *pb = pattern, *pe = pattern;
1152 : :
1153 : : for (;;) {
1154 : : /* Find a non-void item first */
1155 : 0 : pb = i40e_find_first_item(pb, false);
1156 [ # # ]: 0 : if (pb->type == RTE_FLOW_ITEM_TYPE_END) {
1157 : : pe = pb;
1158 : : break;
1159 : : }
1160 : :
1161 : : /* Find a void item */
1162 : 0 : pe = i40e_find_first_item(pb + 1, true);
1163 : :
1164 : 0 : cpy_count = pe - pb;
1165 [ # # ]: 0 : memcpy(items, pb, sizeof(struct rte_flow_item) * cpy_count);
1166 : :
1167 : 0 : items += cpy_count;
1168 : :
1169 [ # # ]: 0 : if (pe->type == RTE_FLOW_ITEM_TYPE_END) {
1170 : : pb = pe;
1171 : : break;
1172 : : }
1173 : :
1174 : 0 : pb = pe + 1;
1175 : : }
1176 : : /* Copy the END item. */
1177 : : memcpy(items, pe, sizeof(struct rte_flow_item));
1178 : 0 : }
1179 : :
1180 : : /* Check if the pattern matches a supported item type array */
1181 : : static bool
1182 : : i40e_match_pattern(enum rte_flow_item_type *item_array,
1183 : : struct rte_flow_item *pattern)
1184 : : {
1185 : : struct rte_flow_item *item = pattern;
1186 : :
1187 [ # # # # ]: 0 : while ((*item_array == item->type) &&
1188 : : (*item_array != RTE_FLOW_ITEM_TYPE_END)) {
1189 : 0 : item_array++;
1190 : 0 : item++;
1191 : : }
1192 : :
1193 [ # # # # ]: 0 : return (*item_array == RTE_FLOW_ITEM_TYPE_END &&
1194 : : item->type == RTE_FLOW_ITEM_TYPE_END);
1195 : : }
1196 : :
1197 : : /* Find if there's parse filter function matched */
1198 : : static parse_filter_t
1199 : 0 : i40e_find_parse_filter_func(struct rte_flow_item *pattern, uint32_t *idx)
1200 : : {
1201 : : parse_filter_t parse_filter = NULL;
1202 : 0 : uint8_t i = *idx;
1203 : :
1204 [ # # ]: 0 : for (; i < RTE_DIM(i40e_supported_patterns); i++) {
1205 [ # # ]: 0 : if (i40e_match_pattern(i40e_supported_patterns[i].items,
1206 : : pattern)) {
1207 : 0 : parse_filter = i40e_supported_patterns[i].parse_filter;
1208 : 0 : break;
1209 : : }
1210 : : }
1211 : :
1212 : 0 : *idx = ++i;
1213 : :
1214 : 0 : return parse_filter;
1215 : : }
1216 : :
1217 : : /* Parse attributes */
1218 : : static int
1219 : 0 : i40e_flow_parse_attr(const struct rte_flow_attr *attr,
1220 : : struct rte_flow_error *error)
1221 : : {
1222 : : /* Must be input direction */
1223 [ # # ]: 0 : if (!attr->ingress) {
1224 : 0 : rte_flow_error_set(error, EINVAL,
1225 : : RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1226 : : attr, "Only support ingress.");
1227 : 0 : return -rte_errno;
1228 : : }
1229 : :
1230 : : /* Not supported */
1231 [ # # ]: 0 : if (attr->egress) {
1232 : 0 : rte_flow_error_set(error, EINVAL,
1233 : : RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1234 : : attr, "Not support egress.");
1235 : 0 : return -rte_errno;
1236 : : }
1237 : :
1238 : : /* Not supported */
1239 [ # # ]: 0 : if (attr->transfer) {
1240 : 0 : rte_flow_error_set(error, EINVAL,
1241 : : RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1242 : : attr, "Not support transfer.");
1243 : 0 : return -rte_errno;
1244 : : }
1245 : :
1246 : : /* Not supported */
1247 [ # # ]: 0 : if (attr->priority) {
1248 : 0 : rte_flow_error_set(error, EINVAL,
1249 : : RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1250 : : attr, "Not support priority.");
1251 : 0 : return -rte_errno;
1252 : : }
1253 : :
1254 : : /* Not supported */
1255 [ # # ]: 0 : if (attr->group) {
1256 : 0 : rte_flow_error_set(error, EINVAL,
1257 : : RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
1258 : : attr, "Not support group.");
1259 : 0 : return -rte_errno;
1260 : : }
1261 : :
1262 : : return 0;
1263 : : }
1264 : :
1265 : : #define I40E_FLOW_DUMP_CHUNK_BYTES 32
1266 : :
1267 : : static const char *
1268 : : i40e_flow_rule_name(enum rte_filter_type filter_type)
1269 : : {
1270 : 0 : switch (filter_type) {
1271 : : case RTE_ETH_FILTER_ETHERTYPE:
1272 : : return "ethertype";
1273 : 0 : case RTE_ETH_FILTER_FDIR:
1274 : 0 : return "fdir";
1275 : 0 : case RTE_ETH_FILTER_TUNNEL:
1276 : 0 : return "tunnel";
1277 : 0 : case RTE_ETH_FILTER_HASH:
1278 : 0 : return "hash";
1279 : 0 : default:
1280 : 0 : return "unknown";
1281 : : }
1282 : : }
1283 : :
1284 : : static size_t
1285 : : i40e_flow_rule_size(enum rte_filter_type filter_type)
1286 : : {
1287 : : switch (filter_type) {
1288 : : case RTE_ETH_FILTER_ETHERTYPE:
1289 : : return sizeof(struct i40e_ethertype_filter);
1290 : : case RTE_ETH_FILTER_FDIR:
1291 : : return sizeof(struct i40e_fdir_filter);
1292 : : case RTE_ETH_FILTER_TUNNEL:
1293 : : return sizeof(struct i40e_tunnel_filter);
1294 : : case RTE_ETH_FILTER_HASH:
1295 : : return sizeof(struct i40e_rss_filter);
1296 : : default:
1297 : : return 0;
1298 : : }
1299 : : }
1300 : :
1301 : : static void
1302 : 0 : i40e_flow_dump_blob(FILE *file, const char *engine,
1303 : : const void *data, size_t data_len)
1304 : : {
1305 : : const uint8_t *raw = (const uint8_t *)data;
1306 : 0 : const size_t nchunks =
1307 : 0 : (data_len + I40E_FLOW_DUMP_CHUNK_BYTES - 1) /
1308 : : I40E_FLOW_DUMP_CHUNK_BYTES;
1309 : : char title[64];
1310 : : size_t ci;
1311 : :
1312 : : fprintf(file, "FLOW DUMP: driver=i40e engine=%s\n", engine);
1313 : : fprintf(file, "FLOW DUMP: DATA size=%zu chunks=%zu chunk_bytes=%d\n",
1314 : : data_len, nchunks, I40E_FLOW_DUMP_CHUNK_BYTES);
1315 : :
1316 [ # # ]: 0 : for (ci = 0; ci < nchunks; ci++) {
1317 : 0 : const size_t off = ci * I40E_FLOW_DUMP_CHUNK_BYTES;
1318 : : const size_t clen =
1319 : 0 : RTE_MIN((size_t)I40E_FLOW_DUMP_CHUNK_BYTES, data_len - off);
1320 : :
1321 : 0 : snprintf(title, sizeof(title), "FLOW DUMP: chunk %03zu/%03zu",
1322 : : ci + 1, nchunks);
1323 : 0 : rte_memdump(file, title, raw + off, clen);
1324 : : }
1325 : 0 : }
1326 : :
1327 : : static int
1328 : 0 : i40e_flow_dev_dump(struct rte_eth_dev *dev,
1329 : : struct rte_flow *flow,
1330 : : FILE *file,
1331 : : struct rte_flow_error *error)
1332 : : {
1333 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1334 : : struct rte_flow *p_flow;
1335 : : bool found = false;
1336 : :
1337 [ # # ]: 0 : TAILQ_FOREACH(p_flow, &pf->flow_list, node) {
1338 : : size_t rule_size = 0;
1339 : : const void *rule_data = NULL;
1340 : :
1341 [ # # ]: 0 : if (flow != NULL && p_flow != flow)
1342 : 0 : continue;
1343 : :
1344 : : found = true;
1345 [ # # ]: 0 : if (p_flow->rule != NULL) {
1346 [ # # ]: 0 : rule_size = i40e_flow_rule_size(p_flow->filter_type);
1347 : : rule_data = p_flow->rule;
1348 : : }
1349 [ # # # # : 0 : i40e_flow_dump_blob(file,
# ]
1350 : : i40e_flow_rule_name(p_flow->filter_type),
1351 : : rule_data, rule_size);
1352 : : }
1353 : :
1354 [ # # ]: 0 : if (flow != NULL && !found)
1355 : 0 : return rte_flow_error_set(error, ENOENT,
1356 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1357 : : "Flow not found");
1358 : :
1359 : : return 0;
1360 : : }
1361 : :
1362 : : static int
1363 : 0 : i40e_get_outer_vlan(struct rte_eth_dev *dev, uint16_t *tpid)
1364 : : {
1365 : 0 : struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1366 : 0 : int qinq = dev->data->dev_conf.rxmode.offloads &
1367 : : RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
1368 : 0 : uint64_t reg_r = 0;
1369 : : uint16_t reg_id;
1370 : : int ret;
1371 : :
1372 [ # # ]: 0 : if (qinq)
1373 : : reg_id = 2;
1374 : : else
1375 : : reg_id = 3;
1376 : :
1377 : 0 : ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
1378 : : ®_r, NULL);
1379 [ # # ]: 0 : if (ret != I40E_SUCCESS) {
1380 : 0 : PMD_DRV_LOG(ERR, "Failed to read from L2 tag ctrl register [%d]", reg_id);
1381 : 0 : return -EIO;
1382 : : }
1383 : :
1384 : 0 : *tpid = (reg_r >> I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT) & 0xFFFF;
1385 : :
1386 : 0 : return 0;
1387 : : }
1388 : :
1389 : : /* 1. Last in item should be NULL as range is not supported.
1390 : : * 2. Supported filter types: MAC_ETHTYPE and ETHTYPE.
1391 : : * 3. SRC mac_addr mask should be 00:00:00:00:00:00.
1392 : : * 4. DST mac_addr mask should be 00:00:00:00:00:00 or
1393 : : * FF:FF:FF:FF:FF:FF
1394 : : * 5. Ether_type mask should be 0xFFFF.
1395 : : */
1396 : : static int
1397 : 0 : i40e_flow_parse_ethertype_pattern(struct rte_eth_dev *dev,
1398 : : const struct rte_flow_item *pattern,
1399 : : struct rte_flow_error *error,
1400 : : struct rte_eth_ethertype_filter *filter)
1401 : : {
1402 : : const struct rte_flow_item *item = pattern;
1403 : : const struct rte_flow_item_eth *eth_spec;
1404 : : const struct rte_flow_item_eth *eth_mask;
1405 : : enum rte_flow_item_type item_type;
1406 : : int ret;
1407 : : uint16_t tpid;
1408 : :
1409 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
1410 [ # # ]: 0 : if (item->last) {
1411 : 0 : rte_flow_error_set(error, EINVAL,
1412 : : RTE_FLOW_ERROR_TYPE_ITEM,
1413 : : item,
1414 : : "Not support range");
1415 : 0 : return -rte_errno;
1416 : : }
1417 : : item_type = item->type;
1418 [ # # ]: 0 : switch (item_type) {
1419 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
1420 : 0 : eth_spec = item->spec;
1421 : 0 : eth_mask = item->mask;
1422 : : /* Get the MAC info. */
1423 [ # # ]: 0 : if (!eth_spec || !eth_mask) {
1424 : 0 : rte_flow_error_set(error, EINVAL,
1425 : : RTE_FLOW_ERROR_TYPE_ITEM,
1426 : : item,
1427 : : "NULL ETH spec/mask");
1428 : 0 : return -rte_errno;
1429 : : }
1430 : :
1431 : : /* Mask bits of source MAC address must be full of 0.
1432 : : * Mask bits of destination MAC address must be full
1433 : : * of 1 or full of 0.
1434 : : */
1435 [ # # # # ]: 0 : if (!rte_is_zero_ether_addr(ð_mask->hdr.src_addr) ||
1436 [ # # ]: 0 : (!rte_is_zero_ether_addr(ð_mask->hdr.dst_addr) &&
1437 : : !rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr))) {
1438 : 0 : rte_flow_error_set(error, EINVAL,
1439 : : RTE_FLOW_ERROR_TYPE_ITEM,
1440 : : item,
1441 : : "Invalid MAC_addr mask");
1442 : 0 : return -rte_errno;
1443 : : }
1444 : :
1445 [ # # ]: 0 : if ((eth_mask->hdr.ether_type & UINT16_MAX) != UINT16_MAX) {
1446 : 0 : rte_flow_error_set(error, EINVAL,
1447 : : RTE_FLOW_ERROR_TYPE_ITEM,
1448 : : item,
1449 : : "Invalid ethertype mask");
1450 : 0 : return -rte_errno;
1451 : : }
1452 : :
1453 : : /* If mask bits of destination MAC address
1454 : : * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
1455 : : */
1456 [ # # ]: 0 : if (rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr)) {
1457 : 0 : filter->mac_addr = eth_spec->hdr.dst_addr;
1458 : 0 : filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
1459 : : } else {
1460 : 0 : filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
1461 : : }
1462 [ # # ]: 0 : filter->ether_type = rte_be_to_cpu_16(eth_spec->hdr.ether_type);
1463 : :
1464 [ # # ]: 0 : if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
1465 [ # # ]: 0 : filter->ether_type == RTE_ETHER_TYPE_IPV6 ||
1466 : : filter->ether_type == RTE_ETHER_TYPE_LLDP) {
1467 : 0 : rte_flow_error_set(error, EINVAL,
1468 : : RTE_FLOW_ERROR_TYPE_ITEM,
1469 : : item,
1470 : : "Unsupported ether_type in control packet filter.");
1471 : 0 : return -rte_errno;
1472 : : }
1473 : :
1474 : 0 : ret = i40e_get_outer_vlan(dev, &tpid);
1475 [ # # ]: 0 : if (ret != 0) {
1476 : 0 : rte_flow_error_set(error, EIO,
1477 : : RTE_FLOW_ERROR_TYPE_ITEM,
1478 : : item,
1479 : : "Can not get the Ethertype identifying the L2 tag");
1480 : 0 : return -rte_errno;
1481 : : }
1482 [ # # ]: 0 : if (filter->ether_type == tpid) {
1483 : 0 : rte_flow_error_set(error, EINVAL,
1484 : : RTE_FLOW_ERROR_TYPE_ITEM,
1485 : : item,
1486 : : "Unsupported ether_type in"
1487 : : " control packet filter.");
1488 : 0 : return -rte_errno;
1489 : : }
1490 : :
1491 : : break;
1492 : : default:
1493 : : break;
1494 : : }
1495 : : }
1496 : :
1497 : : return 0;
1498 : : }
1499 : :
1500 : : /* Ethertype action only supports QUEUE or DROP. */
1501 : : static int
1502 : 0 : i40e_flow_parse_ethertype_action(struct rte_eth_dev *dev,
1503 : : const struct rte_flow_action *actions,
1504 : : struct rte_flow_error *error,
1505 : : struct rte_eth_ethertype_filter *filter)
1506 : : {
1507 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1508 : : const struct rte_flow_action *act;
1509 : : const struct rte_flow_action_queue *act_q;
1510 : : uint32_t index = 0;
1511 : :
1512 : : /* Check if the first non-void action is QUEUE or DROP. */
1513 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
1514 [ # # ]: 0 : if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
1515 : : act->type != RTE_FLOW_ACTION_TYPE_DROP) {
1516 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
1517 : : act, "Not supported action.");
1518 : 0 : return -rte_errno;
1519 : : }
1520 : :
1521 [ # # ]: 0 : if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
1522 : 0 : act_q = act->conf;
1523 : 0 : filter->queue = act_q->index;
1524 [ # # ]: 0 : if (filter->queue >= pf->dev_data->nb_rx_queues) {
1525 : 0 : rte_flow_error_set(error, EINVAL,
1526 : : RTE_FLOW_ERROR_TYPE_ACTION,
1527 : : act, "Invalid queue ID for"
1528 : : " ethertype_filter.");
1529 : 0 : return -rte_errno;
1530 : : }
1531 : : } else {
1532 : 0 : filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
1533 : : }
1534 : :
1535 : : /* Check if the next non-void item is END */
1536 : 0 : index++;
1537 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
1538 [ # # ]: 0 : if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1539 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
1540 : : act, "Not supported action.");
1541 : 0 : return -rte_errno;
1542 : : }
1543 : :
1544 : : return 0;
1545 : : }
1546 : :
1547 : : static int
1548 : 0 : i40e_flow_parse_ethertype_filter(struct rte_eth_dev *dev,
1549 : : const struct rte_flow_attr *attr,
1550 : : const struct rte_flow_item pattern[],
1551 : : const struct rte_flow_action actions[],
1552 : : struct rte_flow_error *error,
1553 : : struct i40e_filter_ctx *filter)
1554 : : {
1555 : 0 : struct rte_eth_ethertype_filter *ethertype_filter = &filter->ethertype_filter;
1556 : : int ret;
1557 : :
1558 : 0 : ret = i40e_flow_parse_ethertype_pattern(dev, pattern, error,
1559 : : ethertype_filter);
1560 [ # # ]: 0 : if (ret)
1561 : : return ret;
1562 : :
1563 : 0 : ret = i40e_flow_parse_ethertype_action(dev, actions, error,
1564 : : ethertype_filter);
1565 [ # # ]: 0 : if (ret)
1566 : : return ret;
1567 : :
1568 : 0 : ret = i40e_flow_parse_attr(attr, error);
1569 [ # # ]: 0 : if (ret)
1570 : : return ret;
1571 : :
1572 : 0 : filter->type = RTE_ETH_FILTER_ETHERTYPE;
1573 : :
1574 : 0 : return ret;
1575 : : }
1576 : :
1577 : : static int
1578 : 0 : i40e_flow_check_raw_item(const struct rte_flow_item *item,
1579 : : const struct rte_flow_item_raw *raw_spec,
1580 : : struct rte_flow_error *error)
1581 : : {
1582 [ # # ]: 0 : if (!raw_spec->relative) {
1583 : 0 : rte_flow_error_set(error, EINVAL,
1584 : : RTE_FLOW_ERROR_TYPE_ITEM,
1585 : : item,
1586 : : "Relative should be 1.");
1587 : 0 : return -rte_errno;
1588 : : }
1589 : :
1590 [ # # ]: 0 : if (raw_spec->offset % sizeof(uint16_t)) {
1591 : 0 : rte_flow_error_set(error, EINVAL,
1592 : : RTE_FLOW_ERROR_TYPE_ITEM,
1593 : : item,
1594 : : "Offset should be even.");
1595 : 0 : return -rte_errno;
1596 : : }
1597 : :
1598 [ # # # # ]: 0 : if (raw_spec->search || raw_spec->limit) {
1599 : 0 : rte_flow_error_set(error, EINVAL,
1600 : : RTE_FLOW_ERROR_TYPE_ITEM,
1601 : : item,
1602 : : "search or limit is not supported.");
1603 : 0 : return -rte_errno;
1604 : : }
1605 : :
1606 [ # # ]: 0 : if (raw_spec->offset < 0) {
1607 : 0 : rte_flow_error_set(error, EINVAL,
1608 : : RTE_FLOW_ERROR_TYPE_ITEM,
1609 : : item,
1610 : : "Offset should be non-negative.");
1611 : 0 : return -rte_errno;
1612 : : }
1613 : : return 0;
1614 : : }
1615 : :
1616 : :
1617 : : static uint8_t
1618 : 0 : i40e_flow_fdir_get_pctype_value(struct i40e_pf *pf,
1619 : : enum rte_flow_item_type item_type,
1620 : : struct i40e_fdir_filter_conf *filter)
1621 : : {
1622 : : struct i40e_customized_pctype *cus_pctype = NULL;
1623 : :
1624 [ # # # # : 0 : switch (item_type) {
# ]
1625 : 0 : case RTE_FLOW_ITEM_TYPE_GTPC:
1626 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1627 : : I40E_CUSTOMIZED_GTPC);
1628 : 0 : break;
1629 : 0 : case RTE_FLOW_ITEM_TYPE_GTPU:
1630 [ # # ]: 0 : if (!filter->input.flow_ext.inner_ip)
1631 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1632 : : I40E_CUSTOMIZED_GTPU);
1633 [ # # ]: 0 : else if (filter->input.flow_ext.iip_type ==
1634 : : I40E_FDIR_IPTYPE_IPV4)
1635 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1636 : : I40E_CUSTOMIZED_GTPU_IPV4);
1637 [ # # ]: 0 : else if (filter->input.flow_ext.iip_type ==
1638 : : I40E_FDIR_IPTYPE_IPV6)
1639 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1640 : : I40E_CUSTOMIZED_GTPU_IPV6);
1641 : : break;
1642 : 0 : case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
1643 [ # # ]: 0 : if (filter->input.flow_ext.oip_type == I40E_FDIR_IPTYPE_IPV4)
1644 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1645 : : I40E_CUSTOMIZED_IPV4_L2TPV3);
1646 [ # # ]: 0 : else if (filter->input.flow_ext.oip_type ==
1647 : : I40E_FDIR_IPTYPE_IPV6)
1648 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1649 : : I40E_CUSTOMIZED_IPV6_L2TPV3);
1650 : : break;
1651 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
1652 [ # # ]: 0 : if (!filter->input.flow_ext.is_udp) {
1653 [ # # ]: 0 : if (filter->input.flow_ext.oip_type ==
1654 : : I40E_FDIR_IPTYPE_IPV4)
1655 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1656 : : I40E_CUSTOMIZED_ESP_IPV4);
1657 [ # # ]: 0 : else if (filter->input.flow_ext.oip_type ==
1658 : : I40E_FDIR_IPTYPE_IPV6)
1659 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1660 : : I40E_CUSTOMIZED_ESP_IPV6);
1661 : : } else {
1662 [ # # ]: 0 : if (filter->input.flow_ext.oip_type ==
1663 : : I40E_FDIR_IPTYPE_IPV4)
1664 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1665 : : I40E_CUSTOMIZED_ESP_IPV4_UDP);
1666 [ # # ]: 0 : else if (filter->input.flow_ext.oip_type ==
1667 : : I40E_FDIR_IPTYPE_IPV6)
1668 : 0 : cus_pctype = i40e_find_customized_pctype(pf,
1669 : : I40E_CUSTOMIZED_ESP_IPV6_UDP);
1670 : 0 : filter->input.flow_ext.is_udp = false;
1671 : : }
1672 : : break;
1673 : 0 : default:
1674 : 0 : PMD_DRV_LOG(ERR, "Unsupported item type");
1675 : : break;
1676 : : }
1677 : :
1678 [ # # # # ]: 0 : if (cus_pctype && cus_pctype->valid)
1679 : 0 : return cus_pctype->pctype;
1680 : :
1681 : : return I40E_FILTER_PCTYPE_INVALID;
1682 : : }
1683 : :
1684 : : static void
1685 : : i40e_flow_set_filter_spi(struct i40e_fdir_filter_conf *filter,
1686 : : const struct rte_flow_item_esp *esp_spec)
1687 : : {
1688 [ # # ]: 0 : if (filter->input.flow_ext.oip_type ==
1689 : : I40E_FDIR_IPTYPE_IPV4) {
1690 [ # # ]: 0 : if (filter->input.flow_ext.is_udp)
1691 : 0 : filter->input.flow.esp_ipv4_udp_flow.spi =
1692 : 0 : esp_spec->hdr.spi;
1693 : : else
1694 : 0 : filter->input.flow.esp_ipv4_flow.spi =
1695 : 0 : esp_spec->hdr.spi;
1696 : : }
1697 [ # # ]: 0 : if (filter->input.flow_ext.oip_type ==
1698 : : I40E_FDIR_IPTYPE_IPV6) {
1699 [ # # ]: 0 : if (filter->input.flow_ext.is_udp)
1700 : 0 : filter->input.flow.esp_ipv6_udp_flow.spi =
1701 : 0 : esp_spec->hdr.spi;
1702 : : else
1703 : 0 : filter->input.flow.esp_ipv6_flow.spi =
1704 : 0 : esp_spec->hdr.spi;
1705 : : }
1706 : : }
1707 : :
1708 : : /* 1. Last in item should be NULL as range is not supported.
1709 : : * 2. Supported patterns: refer to array i40e_supported_patterns.
1710 : : * 3. Default supported flow type and input set: refer to array
1711 : : * valid_fdir_inset_table in i40e_ethdev.c.
1712 : : * 4. Mask of fields which need to be matched should be
1713 : : * filled with 1.
1714 : : * 5. Mask of fields which needn't to be matched should be
1715 : : * filled with 0.
1716 : : * 6. GTP profile supports GTPv1 only.
1717 : : * 7. GTP-C response message ('source_port' = 2123) is not supported.
1718 : : */
1719 : : static int
1720 : 0 : i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
1721 : : const struct rte_flow_item *pattern,
1722 : : struct rte_flow_error *error,
1723 : : struct i40e_fdir_filter_conf *filter)
1724 : : {
1725 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1726 : : const struct rte_flow_item *item = pattern;
1727 : : const struct rte_flow_item_eth *eth_spec, *eth_mask;
1728 : : const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
1729 : : const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
1730 : : const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
1731 : : const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
1732 : : const struct rte_flow_item_udp *udp_spec, *udp_mask;
1733 : : const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
1734 : : const struct rte_flow_item_gtp *gtp_spec, *gtp_mask;
1735 : : const struct rte_flow_item_esp *esp_spec, *esp_mask;
1736 : : const struct rte_flow_item_raw *raw_spec, *raw_mask;
1737 : : const struct rte_flow_item_l2tpv3oip *l2tpv3oip_spec, *l2tpv3oip_mask;
1738 : :
1739 : : uint8_t pctype = 0;
1740 : : uint64_t input_set = I40E_INSET_NONE;
1741 : : enum rte_flow_item_type item_type;
1742 : : enum rte_flow_item_type next_type;
1743 : : enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
1744 : : enum rte_flow_item_type cus_proto = RTE_FLOW_ITEM_TYPE_END;
1745 : : uint32_t i, j;
1746 : 0 : uint8_t ipv6_addr_mask[16] = {
1747 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1748 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1749 : : enum i40e_flxpld_layer_idx layer_idx = I40E_FLXPLD_L2_IDX;
1750 : : uint8_t raw_id = 0;
1751 : : int32_t off_arr[I40E_MAX_FLXPLD_FIED];
1752 : : uint16_t len_arr[I40E_MAX_FLXPLD_FIED];
1753 : : struct i40e_fdir_flex_pit flex_pit;
1754 : : uint8_t next_dst_off = 0;
1755 : : uint16_t flex_size;
1756 : : uint16_t ether_type;
1757 : : uint32_t vtc_flow_cpu;
1758 : : bool outer_ip = true;
1759 : : uint8_t field_idx;
1760 : : int ret;
1761 : : uint16_t tpid;
1762 : :
1763 : : memset(off_arr, 0, sizeof(off_arr));
1764 : : memset(len_arr, 0, sizeof(len_arr));
1765 : 0 : filter->input.flow_ext.customized_pctype = false;
1766 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
1767 [ # # # # ]: 0 : if (item->last && item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
1768 : 0 : rte_flow_error_set(error, EINVAL,
1769 : : RTE_FLOW_ERROR_TYPE_ITEM,
1770 : : item,
1771 : : "Not support range");
1772 : 0 : return -rte_errno;
1773 : : }
1774 : : item_type = item->type;
1775 [ # # # # : 0 : switch (item_type) {
# # # # #
# # # ]
1776 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
1777 : 0 : eth_spec = item->spec;
1778 : 0 : eth_mask = item->mask;
1779 : 0 : next_type = (item + 1)->type;
1780 : :
1781 [ # # ]: 0 : if (next_type == RTE_FLOW_ITEM_TYPE_END &&
1782 [ # # ]: 0 : (!eth_spec || !eth_mask)) {
1783 : 0 : rte_flow_error_set(error, EINVAL,
1784 : : RTE_FLOW_ERROR_TYPE_ITEM,
1785 : : item,
1786 : : "NULL eth spec/mask.");
1787 : 0 : return -rte_errno;
1788 : : }
1789 : :
1790 [ # # ]: 0 : if (eth_spec && eth_mask) {
1791 [ # # # # ]: 0 : if (rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr) &&
1792 : : rte_is_zero_ether_addr(ð_mask->hdr.src_addr)) {
1793 : 0 : filter->input.flow.l2_flow.dst =
1794 : : eth_spec->hdr.dst_addr;
1795 : 0 : input_set |= I40E_INSET_DMAC;
1796 [ # # # # ]: 0 : } else if (rte_is_zero_ether_addr(ð_mask->hdr.dst_addr) &&
1797 : : rte_is_broadcast_ether_addr(ð_mask->hdr.src_addr)) {
1798 : 0 : filter->input.flow.l2_flow.src =
1799 : : eth_spec->hdr.src_addr;
1800 : 0 : input_set |= I40E_INSET_SMAC;
1801 [ # # # # ]: 0 : } else if (rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr) &&
1802 : : rte_is_broadcast_ether_addr(ð_mask->hdr.src_addr)) {
1803 : 0 : filter->input.flow.l2_flow.dst =
1804 : : eth_spec->hdr.dst_addr;
1805 : 0 : filter->input.flow.l2_flow.src =
1806 : : eth_spec->hdr.src_addr;
1807 : 0 : input_set |= (I40E_INSET_DMAC | I40E_INSET_SMAC);
1808 [ # # # # ]: 0 : } else if (!rte_is_zero_ether_addr(ð_mask->hdr.src_addr) ||
1809 : : !rte_is_zero_ether_addr(ð_mask->hdr.dst_addr)) {
1810 : 0 : rte_flow_error_set(error, EINVAL,
1811 : : RTE_FLOW_ERROR_TYPE_ITEM,
1812 : : item,
1813 : : "Invalid MAC_addr mask.");
1814 : 0 : return -rte_errno;
1815 : : }
1816 : : }
1817 [ # # # # ]: 0 : if (eth_spec && eth_mask &&
1818 : : next_type == RTE_FLOW_ITEM_TYPE_END) {
1819 [ # # ]: 0 : if (eth_mask->hdr.ether_type != RTE_BE16(0xffff)) {
1820 : 0 : rte_flow_error_set(error, EINVAL,
1821 : : RTE_FLOW_ERROR_TYPE_ITEM,
1822 : : item,
1823 : : "Invalid type mask.");
1824 : 0 : return -rte_errno;
1825 : : }
1826 : :
1827 [ # # ]: 0 : ether_type = rte_be_to_cpu_16(eth_spec->hdr.ether_type);
1828 : :
1829 : 0 : if (ether_type == RTE_ETHER_TYPE_IPV4 ||
1830 [ # # ]: 0 : ether_type == RTE_ETHER_TYPE_IPV6) {
1831 : 0 : rte_flow_error_set(error, EINVAL,
1832 : : RTE_FLOW_ERROR_TYPE_ITEM,
1833 : : item,
1834 : : "Unsupported ether_type.");
1835 : 0 : return -rte_errno;
1836 : : }
1837 : 0 : ret = i40e_get_outer_vlan(dev, &tpid);
1838 [ # # ]: 0 : if (ret != 0) {
1839 : 0 : rte_flow_error_set(error, EIO,
1840 : : RTE_FLOW_ERROR_TYPE_ITEM,
1841 : : item,
1842 : : "Can not get the Ethertype identifying the L2 tag");
1843 : 0 : return -rte_errno;
1844 : : }
1845 [ # # ]: 0 : if (ether_type == tpid) {
1846 : 0 : rte_flow_error_set(error, EINVAL,
1847 : : RTE_FLOW_ERROR_TYPE_ITEM,
1848 : : item,
1849 : : "Unsupported ether_type.");
1850 : 0 : return -rte_errno;
1851 : : }
1852 : :
1853 : 0 : input_set |= I40E_INSET_LAST_ETHER_TYPE;
1854 : 0 : filter->input.flow.l2_flow.ether_type =
1855 : 0 : eth_spec->hdr.ether_type;
1856 : : }
1857 : :
1858 : : pctype = I40E_FILTER_PCTYPE_L2_PAYLOAD;
1859 : : layer_idx = I40E_FLXPLD_L2_IDX;
1860 : :
1861 : : break;
1862 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
1863 : 0 : vlan_spec = item->spec;
1864 : 0 : vlan_mask = item->mask;
1865 : :
1866 : : RTE_ASSERT(!(input_set & I40E_INSET_LAST_ETHER_TYPE));
1867 [ # # ]: 0 : if (vlan_spec && vlan_mask) {
1868 [ # # # # ]: 0 : if (vlan_mask->hdr.vlan_tci != 0 &&
1869 : : vlan_mask->hdr.vlan_tci !=
1870 : : rte_cpu_to_be_16(I40E_VLAN_TCI_MASK)) {
1871 : 0 : rte_flow_error_set(error, EINVAL,
1872 : : RTE_FLOW_ERROR_TYPE_ITEM,
1873 : : item,
1874 : : "Unsupported TCI mask.");
1875 : 0 : return -rte_errno;
1876 : : }
1877 [ # # ]: 0 : if (vlan_mask->hdr.vlan_tci != 0) {
1878 : 0 : input_set |= I40E_INSET_VLAN_INNER;
1879 : 0 : filter->input.flow_ext.vlan_tci = vlan_spec->hdr.vlan_tci;
1880 : : }
1881 : : }
1882 [ # # # # ]: 0 : if (vlan_spec && vlan_mask && vlan_mask->hdr.eth_proto) {
1883 [ # # ]: 0 : if (vlan_mask->hdr.eth_proto != RTE_BE16(0xffff)) {
1884 : 0 : rte_flow_error_set(error, EINVAL,
1885 : : RTE_FLOW_ERROR_TYPE_ITEM,
1886 : : item,
1887 : : "Invalid inner_type"
1888 : : " mask.");
1889 : 0 : return -rte_errno;
1890 : : }
1891 : :
1892 : : ether_type =
1893 [ # # ]: 0 : rte_be_to_cpu_16(vlan_spec->hdr.eth_proto);
1894 : :
1895 : 0 : if (ether_type == RTE_ETHER_TYPE_IPV4 ||
1896 [ # # ]: 0 : ether_type == RTE_ETHER_TYPE_IPV6) {
1897 : 0 : rte_flow_error_set(error, EINVAL,
1898 : : RTE_FLOW_ERROR_TYPE_ITEM,
1899 : : item,
1900 : : "Unsupported inner_type.");
1901 : 0 : return -rte_errno;
1902 : : }
1903 : 0 : ret = i40e_get_outer_vlan(dev, &tpid);
1904 [ # # ]: 0 : if (ret != 0) {
1905 : 0 : rte_flow_error_set(error, EIO,
1906 : : RTE_FLOW_ERROR_TYPE_ITEM,
1907 : : item,
1908 : : "Can not get the Ethertype identifying the L2 tag");
1909 : 0 : return -rte_errno;
1910 : : }
1911 [ # # ]: 0 : if (ether_type == tpid) {
1912 : 0 : rte_flow_error_set(error, EINVAL,
1913 : : RTE_FLOW_ERROR_TYPE_ITEM,
1914 : : item,
1915 : : "Unsupported ether_type.");
1916 : 0 : return -rte_errno;
1917 : : }
1918 : :
1919 : 0 : input_set |= I40E_INSET_LAST_ETHER_TYPE;
1920 : 0 : filter->input.flow.l2_flow.ether_type =
1921 : 0 : vlan_spec->hdr.eth_proto;
1922 : : }
1923 : :
1924 : : pctype = I40E_FILTER_PCTYPE_L2_PAYLOAD;
1925 : : layer_idx = I40E_FLXPLD_L2_IDX;
1926 : :
1927 : : break;
1928 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
1929 : : l3 = RTE_FLOW_ITEM_TYPE_IPV4;
1930 : 0 : ipv4_spec = item->spec;
1931 : 0 : ipv4_mask = item->mask;
1932 : : ipv4_last = item->last;
1933 : : pctype = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
1934 : : layer_idx = I40E_FLXPLD_L3_IDX;
1935 : :
1936 [ # # ]: 0 : if (ipv4_last) {
1937 [ # # # # ]: 0 : if (!ipv4_spec || !ipv4_mask || !outer_ip) {
1938 : 0 : rte_flow_error_set(error, EINVAL,
1939 : : RTE_FLOW_ERROR_TYPE_ITEM,
1940 : : item,
1941 : : "Not support range");
1942 : 0 : return -rte_errno;
1943 : : }
1944 : : /* Only fragment_offset supports range */
1945 [ # # ]: 0 : if (ipv4_last->hdr.version_ihl ||
1946 : 0 : ipv4_last->hdr.type_of_service ||
1947 [ # # ]: 0 : ipv4_last->hdr.total_length ||
1948 [ # # ]: 0 : ipv4_last->hdr.packet_id ||
1949 [ # # ]: 0 : ipv4_last->hdr.time_to_live ||
1950 : 0 : ipv4_last->hdr.next_proto_id ||
1951 [ # # ]: 0 : ipv4_last->hdr.hdr_checksum ||
1952 [ # # ]: 0 : ipv4_last->hdr.src_addr ||
1953 [ # # ]: 0 : ipv4_last->hdr.dst_addr) {
1954 : 0 : rte_flow_error_set(error, EINVAL,
1955 : : RTE_FLOW_ERROR_TYPE_ITEM,
1956 : : item,
1957 : : "Not support range");
1958 : 0 : return -rte_errno;
1959 : : }
1960 : : }
1961 [ # # # # ]: 0 : if (ipv4_spec && ipv4_mask && outer_ip) {
1962 : : /* Check IPv4 mask and update input set */
1963 [ # # ]: 0 : if (ipv4_mask->hdr.version_ihl ||
1964 [ # # ]: 0 : ipv4_mask->hdr.total_length ||
1965 [ # # ]: 0 : ipv4_mask->hdr.packet_id ||
1966 [ # # ]: 0 : ipv4_mask->hdr.hdr_checksum) {
1967 : 0 : rte_flow_error_set(error, EINVAL,
1968 : : RTE_FLOW_ERROR_TYPE_ITEM,
1969 : : item,
1970 : : "Invalid IPv4 mask.");
1971 : 0 : return -rte_errno;
1972 : : }
1973 : :
1974 [ # # ]: 0 : if (ipv4_mask->hdr.src_addr == UINT32_MAX)
1975 : 0 : input_set |= I40E_INSET_IPV4_SRC;
1976 [ # # ]: 0 : if (ipv4_mask->hdr.dst_addr == UINT32_MAX)
1977 : 0 : input_set |= I40E_INSET_IPV4_DST;
1978 [ # # ]: 0 : if (ipv4_mask->hdr.type_of_service == UINT8_MAX)
1979 : 0 : input_set |= I40E_INSET_IPV4_TOS;
1980 [ # # ]: 0 : if (ipv4_mask->hdr.time_to_live == UINT8_MAX)
1981 : 0 : input_set |= I40E_INSET_IPV4_TTL;
1982 [ # # ]: 0 : if (ipv4_mask->hdr.next_proto_id == UINT8_MAX)
1983 : 0 : input_set |= I40E_INSET_IPV4_PROTO;
1984 : :
1985 : : /* Check if it is fragment. */
1986 : 0 : uint16_t frag_mask =
1987 : : ipv4_mask->hdr.fragment_offset;
1988 : 0 : uint16_t frag_spec =
1989 : : ipv4_spec->hdr.fragment_offset;
1990 : : uint16_t frag_last = 0;
1991 [ # # ]: 0 : if (ipv4_last)
1992 : 0 : frag_last =
1993 : : ipv4_last->hdr.fragment_offset;
1994 [ # # ]: 0 : if (frag_mask) {
1995 [ # # ]: 0 : frag_mask = rte_be_to_cpu_16(frag_mask);
1996 [ # # ]: 0 : frag_spec = rte_be_to_cpu_16(frag_spec);
1997 [ # # ]: 0 : frag_last = rte_be_to_cpu_16(frag_last);
1998 : : /* frag_off mask has to be 0x3fff */
1999 [ # # ]: 0 : if (frag_mask !=
2000 : : (RTE_IPV4_HDR_OFFSET_MASK |
2001 : : RTE_IPV4_HDR_MF_FLAG)) {
2002 : 0 : rte_flow_error_set(error,
2003 : : EINVAL,
2004 : : RTE_FLOW_ERROR_TYPE_ITEM,
2005 : : item,
2006 : : "Invalid IPv4 fragment_offset mask");
2007 : 0 : return -rte_errno;
2008 : : }
2009 : : /*
2010 : : * non-frag rule:
2011 : : * mask=0x3fff,spec=0
2012 : : * frag rule:
2013 : : * mask=0x3fff,spec=0x8,last=0x2000
2014 : : */
2015 : 0 : if (frag_spec ==
2016 : 0 : (1 << RTE_IPV4_HDR_FO_SHIFT) &&
2017 [ # # ]: 0 : frag_last == RTE_IPV4_HDR_MF_FLAG) {
2018 : : pctype =
2019 : : I40E_FILTER_PCTYPE_FRAG_IPV4;
2020 [ # # ]: 0 : } else if (frag_spec || frag_last) {
2021 : 0 : rte_flow_error_set(error,
2022 : : EINVAL,
2023 : : RTE_FLOW_ERROR_TYPE_ITEM,
2024 : : item,
2025 : : "Invalid IPv4 fragment_offset rule");
2026 : 0 : return -rte_errno;
2027 : : }
2028 [ # # ]: 0 : } else if (frag_spec || frag_last) {
2029 : 0 : rte_flow_error_set(error,
2030 : : EINVAL,
2031 : : RTE_FLOW_ERROR_TYPE_ITEM,
2032 : : item,
2033 : : "Invalid fragment_offset");
2034 : 0 : return -rte_errno;
2035 : : }
2036 : :
2037 [ # # ]: 0 : if (input_set & (I40E_INSET_DMAC | I40E_INSET_SMAC)) {
2038 [ # # ]: 0 : if (input_set & (I40E_INSET_IPV4_SRC |
2039 : : I40E_INSET_IPV4_DST | I40E_INSET_IPV4_TOS |
2040 : : I40E_INSET_IPV4_TTL | I40E_INSET_IPV4_PROTO)) {
2041 : 0 : rte_flow_error_set(error, EINVAL,
2042 : : RTE_FLOW_ERROR_TYPE_ITEM,
2043 : : item,
2044 : : "L2 and L3 input set are exclusive.");
2045 : 0 : return -rte_errno;
2046 : : }
2047 : : } else {
2048 : : /* Get the filter info */
2049 : 0 : filter->input.flow.ip4_flow.proto =
2050 : 0 : ipv4_spec->hdr.next_proto_id;
2051 : 0 : filter->input.flow.ip4_flow.tos =
2052 : 0 : ipv4_spec->hdr.type_of_service;
2053 : 0 : filter->input.flow.ip4_flow.ttl =
2054 : 0 : ipv4_spec->hdr.time_to_live;
2055 : 0 : filter->input.flow.ip4_flow.src_ip =
2056 : 0 : ipv4_spec->hdr.src_addr;
2057 : 0 : filter->input.flow.ip4_flow.dst_ip =
2058 : 0 : ipv4_spec->hdr.dst_addr;
2059 : :
2060 : 0 : filter->input.flow_ext.inner_ip = false;
2061 : 0 : filter->input.flow_ext.oip_type =
2062 : : I40E_FDIR_IPTYPE_IPV4;
2063 : : }
2064 [ # # # # ]: 0 : } else if (!ipv4_spec && !ipv4_mask && !outer_ip) {
2065 : 0 : filter->input.flow_ext.inner_ip = true;
2066 : 0 : filter->input.flow_ext.iip_type =
2067 : : I40E_FDIR_IPTYPE_IPV4;
2068 [ # # # # ]: 0 : } else if (!ipv4_spec && !ipv4_mask && outer_ip) {
2069 : 0 : filter->input.flow_ext.inner_ip = false;
2070 : 0 : filter->input.flow_ext.oip_type =
2071 : : I40E_FDIR_IPTYPE_IPV4;
2072 [ # # # # ]: 0 : } else if ((ipv4_spec || ipv4_mask) && !outer_ip) {
2073 : 0 : rte_flow_error_set(error, EINVAL,
2074 : : RTE_FLOW_ERROR_TYPE_ITEM,
2075 : : item,
2076 : : "Invalid inner IPv4 mask.");
2077 : 0 : return -rte_errno;
2078 : : }
2079 : :
2080 : : if (outer_ip)
2081 : : outer_ip = false;
2082 : :
2083 : : break;
2084 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
2085 : : l3 = RTE_FLOW_ITEM_TYPE_IPV6;
2086 : 0 : ipv6_spec = item->spec;
2087 : 0 : ipv6_mask = item->mask;
2088 : : pctype = I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
2089 : : layer_idx = I40E_FLXPLD_L3_IDX;
2090 : :
2091 [ # # # # ]: 0 : if (ipv6_spec && ipv6_mask && outer_ip) {
2092 : : /* Check IPv6 mask and update input set */
2093 [ # # ]: 0 : if (ipv6_mask->hdr.payload_len) {
2094 : 0 : rte_flow_error_set(error, EINVAL,
2095 : : RTE_FLOW_ERROR_TYPE_ITEM,
2096 : : item,
2097 : : "Invalid IPv6 mask");
2098 : 0 : return -rte_errno;
2099 : : }
2100 : :
2101 [ # # ]: 0 : if (!memcmp(&ipv6_mask->hdr.src_addr,
2102 : : ipv6_addr_mask,
2103 : : sizeof(ipv6_mask->hdr.src_addr)))
2104 : 0 : input_set |= I40E_INSET_IPV6_SRC;
2105 [ # # ]: 0 : if (!memcmp(&ipv6_mask->hdr.dst_addr,
2106 : : ipv6_addr_mask,
2107 : : sizeof(ipv6_mask->hdr.dst_addr)))
2108 : 0 : input_set |= I40E_INSET_IPV6_DST;
2109 : :
2110 [ # # ]: 0 : if ((ipv6_mask->hdr.vtc_flow &
2111 : : rte_cpu_to_be_32(I40E_IPV6_TC_MASK))
2112 : : == rte_cpu_to_be_32(I40E_IPV6_TC_MASK))
2113 : 0 : input_set |= I40E_INSET_IPV6_TC;
2114 [ # # ]: 0 : if (ipv6_mask->hdr.proto == UINT8_MAX)
2115 : 0 : input_set |= I40E_INSET_IPV6_NEXT_HDR;
2116 [ # # ]: 0 : if (ipv6_mask->hdr.hop_limits == UINT8_MAX)
2117 : 0 : input_set |= I40E_INSET_IPV6_HOP_LIMIT;
2118 : :
2119 : : /* Get filter info */
2120 : : vtc_flow_cpu =
2121 [ # # ]: 0 : rte_be_to_cpu_32(ipv6_spec->hdr.vtc_flow);
2122 : 0 : filter->input.flow.ipv6_flow.tc =
2123 : 0 : (uint8_t)(vtc_flow_cpu >>
2124 : : I40E_FDIR_IPv6_TC_OFFSET);
2125 : 0 : filter->input.flow.ipv6_flow.proto =
2126 : 0 : ipv6_spec->hdr.proto;
2127 : 0 : filter->input.flow.ipv6_flow.hop_limits =
2128 : 0 : ipv6_spec->hdr.hop_limits;
2129 : :
2130 : 0 : filter->input.flow_ext.inner_ip = false;
2131 : 0 : filter->input.flow_ext.oip_type =
2132 : : I40E_FDIR_IPTYPE_IPV6;
2133 : :
2134 : 0 : memcpy(filter->input.flow.ipv6_flow.src_ip,
2135 [ # # ]: 0 : &ipv6_spec->hdr.src_addr, 16);
2136 : 0 : memcpy(filter->input.flow.ipv6_flow.dst_ip,
2137 : 0 : &ipv6_spec->hdr.dst_addr, 16);
2138 : :
2139 : : /* Check if it is fragment. */
2140 [ # # ]: 0 : if (ipv6_spec->hdr.proto ==
2141 : : I40E_IPV6_FRAG_HEADER)
2142 : : pctype = I40E_FILTER_PCTYPE_FRAG_IPV6;
2143 [ # # # # ]: 0 : } else if (!ipv6_spec && !ipv6_mask && !outer_ip) {
2144 : 0 : filter->input.flow_ext.inner_ip = true;
2145 : 0 : filter->input.flow_ext.iip_type =
2146 : : I40E_FDIR_IPTYPE_IPV6;
2147 [ # # # # ]: 0 : } else if (!ipv6_spec && !ipv6_mask && outer_ip) {
2148 : 0 : filter->input.flow_ext.inner_ip = false;
2149 : 0 : filter->input.flow_ext.oip_type =
2150 : : I40E_FDIR_IPTYPE_IPV6;
2151 [ # # # # ]: 0 : } else if ((ipv6_spec || ipv6_mask) && !outer_ip) {
2152 : 0 : rte_flow_error_set(error, EINVAL,
2153 : : RTE_FLOW_ERROR_TYPE_ITEM,
2154 : : item,
2155 : : "Invalid inner IPv6 mask");
2156 : 0 : return -rte_errno;
2157 : : }
2158 : :
2159 : : if (outer_ip)
2160 : : outer_ip = false;
2161 : : break;
2162 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
2163 : 0 : tcp_spec = item->spec;
2164 : 0 : tcp_mask = item->mask;
2165 : :
2166 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
2167 : : pctype =
2168 : : I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
2169 [ # # ]: 0 : else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
2170 : : pctype =
2171 : : I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
2172 [ # # ]: 0 : if (tcp_spec && tcp_mask) {
2173 : : /* Check TCP mask and update input set */
2174 [ # # ]: 0 : if (tcp_mask->hdr.sent_seq ||
2175 [ # # ]: 0 : tcp_mask->hdr.recv_ack ||
2176 [ # # ]: 0 : tcp_mask->hdr.data_off ||
2177 [ # # ]: 0 : tcp_mask->hdr.tcp_flags ||
2178 [ # # ]: 0 : tcp_mask->hdr.rx_win ||
2179 [ # # ]: 0 : tcp_mask->hdr.cksum ||
2180 [ # # ]: 0 : tcp_mask->hdr.tcp_urp) {
2181 : 0 : rte_flow_error_set(error, EINVAL,
2182 : : RTE_FLOW_ERROR_TYPE_ITEM,
2183 : : item,
2184 : : "Invalid TCP mask");
2185 : 0 : return -rte_errno;
2186 : : }
2187 : :
2188 [ # # ]: 0 : if (tcp_mask->hdr.src_port == UINT16_MAX)
2189 : 0 : input_set |= I40E_INSET_SRC_PORT;
2190 [ # # ]: 0 : if (tcp_mask->hdr.dst_port == UINT16_MAX)
2191 : 0 : input_set |= I40E_INSET_DST_PORT;
2192 : :
2193 [ # # ]: 0 : if (input_set & (I40E_INSET_DMAC | I40E_INSET_SMAC)) {
2194 [ # # ]: 0 : if (input_set &
2195 : : (I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT)) {
2196 : 0 : rte_flow_error_set(error, EINVAL,
2197 : : RTE_FLOW_ERROR_TYPE_ITEM,
2198 : : item,
2199 : : "L2 and L4 input set are exclusive.");
2200 : 0 : return -rte_errno;
2201 : : }
2202 : : } else {
2203 : : /* Get filter info */
2204 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) {
2205 : 0 : filter->input.flow.tcp4_flow.src_port =
2206 : 0 : tcp_spec->hdr.src_port;
2207 : 0 : filter->input.flow.tcp4_flow.dst_port =
2208 : 0 : tcp_spec->hdr.dst_port;
2209 [ # # ]: 0 : } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) {
2210 : 0 : filter->input.flow.tcp6_flow.src_port =
2211 : 0 : tcp_spec->hdr.src_port;
2212 : 0 : filter->input.flow.tcp6_flow.dst_port =
2213 : 0 : tcp_spec->hdr.dst_port;
2214 : : }
2215 : : }
2216 : : }
2217 : :
2218 : : layer_idx = I40E_FLXPLD_L4_IDX;
2219 : :
2220 : : break;
2221 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
2222 : 0 : udp_spec = item->spec;
2223 : 0 : udp_mask = item->mask;
2224 : :
2225 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
2226 : : pctype =
2227 : : I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
2228 [ # # ]: 0 : else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
2229 : : pctype =
2230 : : I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
2231 : :
2232 [ # # ]: 0 : if (udp_spec && udp_mask) {
2233 : : /* Check UDP mask and update input set*/
2234 [ # # ]: 0 : if (udp_mask->hdr.dgram_len ||
2235 [ # # ]: 0 : udp_mask->hdr.dgram_cksum) {
2236 : 0 : rte_flow_error_set(error, EINVAL,
2237 : : RTE_FLOW_ERROR_TYPE_ITEM,
2238 : : item,
2239 : : "Invalid UDP mask");
2240 : 0 : return -rte_errno;
2241 : : }
2242 : :
2243 [ # # ]: 0 : if (udp_mask->hdr.src_port == UINT16_MAX)
2244 : 0 : input_set |= I40E_INSET_SRC_PORT;
2245 [ # # ]: 0 : if (udp_mask->hdr.dst_port == UINT16_MAX)
2246 : 0 : input_set |= I40E_INSET_DST_PORT;
2247 : :
2248 [ # # ]: 0 : if (input_set & (I40E_INSET_DMAC | I40E_INSET_SMAC)) {
2249 [ # # ]: 0 : if (input_set &
2250 : : (I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT)) {
2251 : 0 : rte_flow_error_set(error, EINVAL,
2252 : : RTE_FLOW_ERROR_TYPE_ITEM,
2253 : : item,
2254 : : "L2 and L4 input set are exclusive.");
2255 : 0 : return -rte_errno;
2256 : : }
2257 : : } else {
2258 : : /* Get filter info */
2259 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) {
2260 : 0 : filter->input.flow.udp4_flow.src_port =
2261 : 0 : udp_spec->hdr.src_port;
2262 : 0 : filter->input.flow.udp4_flow.dst_port =
2263 : 0 : udp_spec->hdr.dst_port;
2264 [ # # ]: 0 : } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) {
2265 : 0 : filter->input.flow.udp6_flow.src_port =
2266 : 0 : udp_spec->hdr.src_port;
2267 : 0 : filter->input.flow.udp6_flow.dst_port =
2268 : 0 : udp_spec->hdr.dst_port;
2269 : : }
2270 : : }
2271 : : }
2272 : 0 : filter->input.flow_ext.is_udp = true;
2273 : : layer_idx = I40E_FLXPLD_L4_IDX;
2274 : :
2275 : 0 : break;
2276 : 0 : case RTE_FLOW_ITEM_TYPE_GTPC:
2277 : : case RTE_FLOW_ITEM_TYPE_GTPU:
2278 [ # # ]: 0 : if (!pf->gtp_support) {
2279 : 0 : rte_flow_error_set(error, EINVAL,
2280 : : RTE_FLOW_ERROR_TYPE_ITEM,
2281 : : item,
2282 : : "Unsupported protocol");
2283 : 0 : return -rte_errno;
2284 : : }
2285 : :
2286 : 0 : gtp_spec = item->spec;
2287 : 0 : gtp_mask = item->mask;
2288 : :
2289 [ # # ]: 0 : if (gtp_spec && gtp_mask) {
2290 : 0 : if (gtp_mask->hdr.gtp_hdr_info ||
2291 [ # # ]: 0 : gtp_mask->hdr.msg_type ||
2292 : 0 : gtp_mask->hdr.plen ||
2293 [ # # ]: 0 : gtp_mask->hdr.teid != UINT32_MAX) {
2294 : 0 : rte_flow_error_set(error, EINVAL,
2295 : : RTE_FLOW_ERROR_TYPE_ITEM,
2296 : : item,
2297 : : "Invalid GTP mask");
2298 : 0 : return -rte_errno;
2299 : : }
2300 : :
2301 : 0 : filter->input.flow.gtp_flow.teid =
2302 : 0 : gtp_spec->hdr.teid;
2303 : 0 : filter->input.flow_ext.customized_pctype = true;
2304 : : cus_proto = item_type;
2305 : : }
2306 : : break;
2307 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
2308 [ # # ]: 0 : if (!pf->esp_support) {
2309 : 0 : rte_flow_error_set(error, EINVAL,
2310 : : RTE_FLOW_ERROR_TYPE_ITEM,
2311 : : item,
2312 : : "Unsupported ESP protocol");
2313 : 0 : return -rte_errno;
2314 : : }
2315 : :
2316 : 0 : esp_spec = item->spec;
2317 : 0 : esp_mask = item->mask;
2318 : :
2319 [ # # ]: 0 : if (!esp_spec || !esp_mask) {
2320 : 0 : rte_flow_error_set(error, EINVAL,
2321 : : RTE_FLOW_ERROR_TYPE_ITEM,
2322 : : item,
2323 : : "Invalid ESP item");
2324 : 0 : return -rte_errno;
2325 : : }
2326 : :
2327 : : if (esp_spec && esp_mask) {
2328 [ # # ]: 0 : if (esp_mask->hdr.spi != UINT32_MAX) {
2329 : 0 : rte_flow_error_set(error, EINVAL,
2330 : : RTE_FLOW_ERROR_TYPE_ITEM,
2331 : : item,
2332 : : "Invalid ESP mask");
2333 : 0 : return -rte_errno;
2334 : : }
2335 : : i40e_flow_set_filter_spi(filter, esp_spec);
2336 : 0 : filter->input.flow_ext.customized_pctype = true;
2337 : : cus_proto = item_type;
2338 : : }
2339 : : break;
2340 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
2341 : 0 : sctp_spec = item->spec;
2342 : 0 : sctp_mask = item->mask;
2343 : :
2344 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
2345 : : pctype =
2346 : : I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
2347 [ # # ]: 0 : else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
2348 : : pctype =
2349 : : I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
2350 : :
2351 [ # # ]: 0 : if (sctp_spec && sctp_mask) {
2352 : : /* Check SCTP mask and update input set */
2353 [ # # ]: 0 : if (sctp_mask->hdr.cksum) {
2354 : 0 : rte_flow_error_set(error, EINVAL,
2355 : : RTE_FLOW_ERROR_TYPE_ITEM,
2356 : : item,
2357 : : "Invalid UDP mask");
2358 : 0 : return -rte_errno;
2359 : : }
2360 : :
2361 [ # # ]: 0 : if (sctp_mask->hdr.src_port == UINT16_MAX)
2362 : 0 : input_set |= I40E_INSET_SRC_PORT;
2363 [ # # ]: 0 : if (sctp_mask->hdr.dst_port == UINT16_MAX)
2364 : 0 : input_set |= I40E_INSET_DST_PORT;
2365 [ # # ]: 0 : if (sctp_mask->hdr.tag == UINT32_MAX)
2366 : 0 : input_set |= I40E_INSET_SCTP_VT;
2367 : :
2368 : : /* Get filter info */
2369 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) {
2370 : 0 : filter->input.flow.sctp4_flow.src_port =
2371 : 0 : sctp_spec->hdr.src_port;
2372 : 0 : filter->input.flow.sctp4_flow.dst_port =
2373 : 0 : sctp_spec->hdr.dst_port;
2374 : : filter->input.flow.sctp4_flow.verify_tag
2375 : 0 : = sctp_spec->hdr.tag;
2376 [ # # ]: 0 : } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) {
2377 : 0 : filter->input.flow.sctp6_flow.src_port =
2378 : 0 : sctp_spec->hdr.src_port;
2379 : 0 : filter->input.flow.sctp6_flow.dst_port =
2380 : 0 : sctp_spec->hdr.dst_port;
2381 : : filter->input.flow.sctp6_flow.verify_tag
2382 : 0 : = sctp_spec->hdr.tag;
2383 : : }
2384 : : }
2385 : :
2386 : : layer_idx = I40E_FLXPLD_L4_IDX;
2387 : :
2388 : : break;
2389 : 0 : case RTE_FLOW_ITEM_TYPE_RAW:
2390 : 0 : raw_spec = item->spec;
2391 : 0 : raw_mask = item->mask;
2392 : :
2393 [ # # ]: 0 : if (!raw_spec || !raw_mask) {
2394 : 0 : rte_flow_error_set(error, EINVAL,
2395 : : RTE_FLOW_ERROR_TYPE_ITEM,
2396 : : item,
2397 : : "NULL RAW spec/mask");
2398 : 0 : return -rte_errno;
2399 : : }
2400 : :
2401 [ # # ]: 0 : if (pf->support_multi_driver) {
2402 : 0 : rte_flow_error_set(error, ENOTSUP,
2403 : : RTE_FLOW_ERROR_TYPE_ITEM,
2404 : : item,
2405 : : "Unsupported flexible payload.");
2406 : 0 : return -rte_errno;
2407 : : }
2408 : :
2409 : 0 : ret = i40e_flow_check_raw_item(item, raw_spec, error);
2410 [ # # ]: 0 : if (ret < 0)
2411 : 0 : return ret;
2412 : :
2413 : 0 : off_arr[raw_id] = raw_spec->offset;
2414 : 0 : len_arr[raw_id] = raw_spec->length;
2415 : :
2416 : : flex_size = 0;
2417 : : memset(&flex_pit, 0, sizeof(struct i40e_fdir_flex_pit));
2418 : 0 : field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
2419 : 0 : flex_pit.size =
2420 : : raw_spec->length / sizeof(uint16_t);
2421 : 0 : flex_pit.dst_offset =
2422 : : next_dst_off / sizeof(uint16_t);
2423 : :
2424 [ # # ]: 0 : for (i = 0; i <= raw_id; i++) {
2425 [ # # ]: 0 : if (i == raw_id)
2426 : 0 : flex_pit.src_offset +=
2427 : 0 : raw_spec->offset /
2428 : : sizeof(uint16_t);
2429 : : else
2430 : 0 : flex_pit.src_offset +=
2431 : 0 : (off_arr[i] + len_arr[i]) /
2432 : : sizeof(uint16_t);
2433 : 0 : flex_size += len_arr[i];
2434 : : }
2435 [ # # ]: 0 : if (((flex_pit.src_offset + flex_pit.size) >=
2436 [ # # ]: 0 : I40E_MAX_FLX_SOURCE_OFF / sizeof(uint16_t)) ||
2437 : : flex_size > I40E_FDIR_MAX_FLEXLEN) {
2438 : 0 : rte_flow_error_set(error, EINVAL,
2439 : : RTE_FLOW_ERROR_TYPE_ITEM,
2440 : : item,
2441 : : "Exceeds maximal payload limit.");
2442 : 0 : return -rte_errno;
2443 : : }
2444 : :
2445 [ # # ]: 0 : if (raw_spec->length != 0) {
2446 [ # # ]: 0 : if (raw_spec->pattern == NULL) {
2447 : 0 : rte_flow_error_set(error, EINVAL,
2448 : : RTE_FLOW_ERROR_TYPE_ITEM,
2449 : : item,
2450 : : "NULL RAW spec pattern");
2451 : 0 : return -rte_errno;
2452 : : }
2453 [ # # ]: 0 : if (raw_mask->pattern == NULL) {
2454 : 0 : rte_flow_error_set(error, EINVAL,
2455 : : RTE_FLOW_ERROR_TYPE_ITEM,
2456 : : item,
2457 : : "NULL RAW mask pattern");
2458 : 0 : return -rte_errno;
2459 : : }
2460 : : }
2461 : :
2462 [ # # ]: 0 : for (i = 0; i < raw_spec->length; i++) {
2463 : 0 : j = i + next_dst_off;
2464 [ # # ]: 0 : if (j >= RTE_ETH_FDIR_MAX_FLEXLEN ||
2465 : : j >= I40E_FDIR_MAX_FLEX_LEN)
2466 : : break;
2467 : 0 : filter->input.flow_ext.flexbytes[j] =
2468 : 0 : raw_spec->pattern[i];
2469 : 0 : filter->input.flow_ext.flex_mask[j] =
2470 : 0 : raw_mask->pattern[i];
2471 : : }
2472 : :
2473 : 0 : next_dst_off += raw_spec->length;
2474 : 0 : raw_id++;
2475 : :
2476 : 0 : filter->input.flow_ext.flex_pit[field_idx] = flex_pit;
2477 : 0 : filter->input.flow_ext.layer_idx = layer_idx;
2478 : 0 : filter->input.flow_ext.raw_id = raw_id;
2479 : 0 : filter->input.flow_ext.is_flex_flow = true;
2480 : 0 : break;
2481 : 0 : case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
2482 : 0 : l2tpv3oip_spec = item->spec;
2483 : 0 : l2tpv3oip_mask = item->mask;
2484 : :
2485 [ # # ]: 0 : if (!l2tpv3oip_spec || !l2tpv3oip_mask)
2486 : : break;
2487 : :
2488 [ # # ]: 0 : if (l2tpv3oip_mask->session_id != UINT32_MAX) {
2489 : 0 : rte_flow_error_set(error, EINVAL,
2490 : : RTE_FLOW_ERROR_TYPE_ITEM,
2491 : : item,
2492 : : "Invalid L2TPv3 mask");
2493 : 0 : return -rte_errno;
2494 : : }
2495 : :
2496 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) {
2497 : 0 : filter->input.flow.ip4_l2tpv3oip_flow.session_id =
2498 : 0 : l2tpv3oip_spec->session_id;
2499 : 0 : filter->input.flow_ext.oip_type =
2500 : : I40E_FDIR_IPTYPE_IPV4;
2501 [ # # ]: 0 : } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) {
2502 : 0 : filter->input.flow.ip6_l2tpv3oip_flow.session_id =
2503 : 0 : l2tpv3oip_spec->session_id;
2504 : 0 : filter->input.flow_ext.oip_type =
2505 : : I40E_FDIR_IPTYPE_IPV6;
2506 : : }
2507 : :
2508 : 0 : filter->input.flow_ext.customized_pctype = true;
2509 : : cus_proto = item_type;
2510 : 0 : break;
2511 : : default:
2512 : : break;
2513 : : }
2514 : : }
2515 : :
2516 : : /* Get customized pctype value */
2517 [ # # ]: 0 : if (filter->input.flow_ext.customized_pctype) {
2518 : 0 : pctype = i40e_flow_fdir_get_pctype_value(pf, cus_proto, filter);
2519 [ # # ]: 0 : if (pctype == I40E_FILTER_PCTYPE_INVALID) {
2520 : 0 : rte_flow_error_set(error, EINVAL,
2521 : : RTE_FLOW_ERROR_TYPE_ITEM,
2522 : : item,
2523 : : "Unsupported pctype");
2524 : 0 : return -rte_errno;
2525 : : }
2526 : : }
2527 : :
2528 : : /* If customized pctype is not used, set fdir configuration.*/
2529 [ # # ]: 0 : if (!filter->input.flow_ext.customized_pctype) {
2530 : : /* Check if the input set is valid */
2531 [ # # ]: 0 : if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
2532 : : input_set) != 0) {
2533 : 0 : rte_flow_error_set(error, EINVAL,
2534 : : RTE_FLOW_ERROR_TYPE_ITEM,
2535 : : item,
2536 : : "Invalid input set");
2537 : 0 : return -rte_errno;
2538 : : }
2539 : :
2540 : 0 : filter->input.flow_ext.input_set = input_set;
2541 : : }
2542 : :
2543 : 0 : filter->input.pctype = pctype;
2544 : :
2545 : 0 : return 0;
2546 : : }
2547 : :
2548 : : /* Parse to get the action info of a FDIR filter.
2549 : : * FDIR action supports QUEUE or (QUEUE + MARK).
2550 : : */
2551 : : static int
2552 : 0 : i40e_flow_parse_fdir_action(struct rte_eth_dev *dev,
2553 : : const struct rte_flow_action *actions,
2554 : : struct rte_flow_error *error,
2555 : : struct i40e_fdir_filter_conf *filter)
2556 : : {
2557 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2558 : : const struct rte_flow_action *act;
2559 : : const struct rte_flow_action_queue *act_q;
2560 : : const struct rte_flow_action_mark *mark_spec = NULL;
2561 : : uint32_t index = 0;
2562 : :
2563 : : /* Check if the first non-void action is QUEUE or DROP or PASSTHRU. */
2564 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
2565 [ # # # # : 0 : switch (act->type) {
# ]
2566 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
2567 : 0 : act_q = act->conf;
2568 : 0 : filter->action.rx_queue = act_q->index;
2569 [ # # ]: 0 : if ((!filter->input.flow_ext.is_vf &&
2570 [ # # # # ]: 0 : filter->action.rx_queue >= pf->dev_data->nb_rx_queues) ||
2571 : 0 : (filter->input.flow_ext.is_vf &&
2572 [ # # ]: 0 : filter->action.rx_queue >= pf->vf_nb_qps)) {
2573 : 0 : rte_flow_error_set(error, EINVAL,
2574 : : RTE_FLOW_ERROR_TYPE_ACTION, act,
2575 : : "Invalid queue ID for FDIR.");
2576 : 0 : return -rte_errno;
2577 : : }
2578 : 0 : filter->action.behavior = I40E_FDIR_ACCEPT;
2579 : 0 : break;
2580 : 0 : case RTE_FLOW_ACTION_TYPE_DROP:
2581 : 0 : filter->action.behavior = I40E_FDIR_REJECT;
2582 : 0 : break;
2583 : 0 : case RTE_FLOW_ACTION_TYPE_PASSTHRU:
2584 : 0 : filter->action.behavior = I40E_FDIR_PASSTHRU;
2585 : 0 : break;
2586 : 0 : case RTE_FLOW_ACTION_TYPE_MARK:
2587 : 0 : filter->action.behavior = I40E_FDIR_PASSTHRU;
2588 : 0 : mark_spec = act->conf;
2589 : 0 : filter->action.report_status = I40E_FDIR_REPORT_ID;
2590 : 0 : filter->soft_id = mark_spec->id;
2591 : 0 : break;
2592 : 0 : default:
2593 : 0 : rte_flow_error_set(error, EINVAL,
2594 : : RTE_FLOW_ERROR_TYPE_ACTION, act,
2595 : : "Invalid action.");
2596 : 0 : return -rte_errno;
2597 : : }
2598 : :
2599 : : /* Check if the next non-void item is MARK or FLAG or END. */
2600 : 0 : index++;
2601 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
2602 [ # # # # : 0 : switch (act->type) {
# ]
2603 : 0 : case RTE_FLOW_ACTION_TYPE_MARK:
2604 [ # # ]: 0 : if (mark_spec) {
2605 : : /* Double MARK actions requested */
2606 : 0 : rte_flow_error_set(error, EINVAL,
2607 : : RTE_FLOW_ERROR_TYPE_ACTION, act,
2608 : : "Invalid action.");
2609 : 0 : return -rte_errno;
2610 : : }
2611 : 0 : mark_spec = act->conf;
2612 : 0 : filter->action.report_status = I40E_FDIR_REPORT_ID;
2613 : 0 : filter->soft_id = mark_spec->id;
2614 : 0 : break;
2615 : 0 : case RTE_FLOW_ACTION_TYPE_FLAG:
2616 [ # # ]: 0 : if (mark_spec) {
2617 : : /* MARK + FLAG not supported */
2618 : 0 : rte_flow_error_set(error, EINVAL,
2619 : : RTE_FLOW_ERROR_TYPE_ACTION, act,
2620 : : "Invalid action.");
2621 : 0 : return -rte_errno;
2622 : : }
2623 : 0 : filter->action.report_status = I40E_FDIR_NO_REPORT_STATUS;
2624 : 0 : break;
2625 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
2626 [ # # ]: 0 : if (filter->action.behavior != I40E_FDIR_PASSTHRU) {
2627 : : /* RSS filter won't be next if FDIR did not pass thru */
2628 : 0 : rte_flow_error_set(error, EINVAL,
2629 : : RTE_FLOW_ERROR_TYPE_ACTION, act,
2630 : : "Invalid action.");
2631 : 0 : return -rte_errno;
2632 : : }
2633 : : break;
2634 : : case RTE_FLOW_ACTION_TYPE_END:
2635 : : return 0;
2636 : 0 : default:
2637 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
2638 : : act, "Invalid action.");
2639 : 0 : return -rte_errno;
2640 : : }
2641 : :
2642 : : /* Check if the next non-void item is END */
2643 : 0 : index++;
2644 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
2645 [ # # ]: 0 : if (act->type != RTE_FLOW_ACTION_TYPE_END) {
2646 : 0 : rte_flow_error_set(error, EINVAL,
2647 : : RTE_FLOW_ERROR_TYPE_ACTION,
2648 : : act, "Invalid action.");
2649 : 0 : return -rte_errno;
2650 : : }
2651 : :
2652 : : return 0;
2653 : : }
2654 : :
2655 : : static int
2656 : 0 : i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
2657 : : const struct rte_flow_attr *attr,
2658 : : const struct rte_flow_item pattern[],
2659 : : const struct rte_flow_action actions[],
2660 : : struct rte_flow_error *error,
2661 : : struct i40e_filter_ctx *filter)
2662 : : {
2663 : 0 : struct i40e_fdir_filter_conf *fdir_filter = &filter->fdir_filter;
2664 : : int ret;
2665 : :
2666 : 0 : ret = i40e_flow_parse_fdir_pattern(dev, pattern, error, fdir_filter);
2667 [ # # ]: 0 : if (ret)
2668 : : return ret;
2669 : :
2670 : 0 : ret = i40e_flow_parse_fdir_action(dev, actions, error, fdir_filter);
2671 [ # # ]: 0 : if (ret)
2672 : : return ret;
2673 : :
2674 : 0 : ret = i40e_flow_parse_attr(attr, error);
2675 [ # # ]: 0 : if (ret)
2676 : : return ret;
2677 : :
2678 : 0 : filter->type = RTE_ETH_FILTER_FDIR;
2679 : :
2680 : 0 : return 0;
2681 : : }
2682 : :
2683 : : /* Parse to get the action info of a tunnel filter
2684 : : * Tunnel action only supports PF, VF and QUEUE.
2685 : : */
2686 : : static int
2687 : 0 : i40e_flow_parse_tunnel_action(struct rte_eth_dev *dev,
2688 : : const struct rte_flow_action *actions,
2689 : : struct rte_flow_error *error,
2690 : : struct i40e_tunnel_filter_conf *filter)
2691 : : {
2692 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2693 : : const struct rte_flow_action *act;
2694 : : const struct rte_flow_action_queue *act_q;
2695 : : const struct rte_flow_action_vf *act_vf;
2696 : : uint32_t index = 0;
2697 : :
2698 : : /* Check if the first non-void action is PF or VF. */
2699 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
2700 [ # # ]: 0 : if (act->type != RTE_FLOW_ACTION_TYPE_PF &&
2701 : : act->type != RTE_FLOW_ACTION_TYPE_VF) {
2702 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
2703 : : act, "Not supported action.");
2704 : 0 : return -rte_errno;
2705 : : }
2706 : :
2707 [ # # ]: 0 : if (act->type == RTE_FLOW_ACTION_TYPE_VF) {
2708 : 0 : act_vf = act->conf;
2709 : 0 : filter->vf_id = act_vf->id;
2710 : 0 : filter->is_to_vf = 1;
2711 [ # # ]: 0 : if (filter->vf_id >= pf->vf_num) {
2712 : 0 : rte_flow_error_set(error, EINVAL,
2713 : : RTE_FLOW_ERROR_TYPE_ACTION,
2714 : : act, "Invalid VF ID for tunnel filter");
2715 : 0 : return -rte_errno;
2716 : : }
2717 : : }
2718 : :
2719 : : /* Check if the next non-void item is QUEUE */
2720 : 0 : index++;
2721 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
2722 [ # # ]: 0 : if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
2723 : 0 : act_q = act->conf;
2724 : 0 : filter->queue_id = act_q->index;
2725 [ # # ]: 0 : if ((!filter->is_to_vf) &&
2726 [ # # ]: 0 : (filter->queue_id >= pf->dev_data->nb_rx_queues)) {
2727 : 0 : rte_flow_error_set(error, EINVAL,
2728 : : RTE_FLOW_ERROR_TYPE_ACTION,
2729 : : act, "Invalid queue ID for tunnel filter");
2730 : 0 : return -rte_errno;
2731 [ # # ]: 0 : } else if (filter->is_to_vf &&
2732 [ # # ]: 0 : (filter->queue_id >= pf->vf_nb_qps)) {
2733 : 0 : rte_flow_error_set(error, EINVAL,
2734 : : RTE_FLOW_ERROR_TYPE_ACTION,
2735 : : act, "Invalid queue ID for tunnel filter");
2736 : 0 : return -rte_errno;
2737 : : }
2738 : : }
2739 : :
2740 : : /* Check if the next non-void item is END */
2741 : 0 : index++;
2742 [ # # ]: 0 : NEXT_ITEM_OF_ACTION(act, actions, index);
2743 [ # # ]: 0 : if (act->type != RTE_FLOW_ACTION_TYPE_END) {
2744 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
2745 : : act, "Not supported action.");
2746 : 0 : return -rte_errno;
2747 : : }
2748 : :
2749 : : return 0;
2750 : : }
2751 : :
2752 : : /* 1. Last in item should be NULL as range is not supported.
2753 : : * 2. Supported filter types: Source port only and Destination port only.
2754 : : * 3. Mask of fields which need to be matched should be
2755 : : * filled with 1.
2756 : : * 4. Mask of fields which needn't to be matched should be
2757 : : * filled with 0.
2758 : : */
2759 : : static int
2760 : 0 : i40e_flow_parse_l4_pattern(const struct rte_flow_item *pattern,
2761 : : struct rte_flow_error *error,
2762 : : struct i40e_tunnel_filter_conf *filter)
2763 : : {
2764 : : const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
2765 : : const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
2766 : : const struct rte_flow_item_udp *udp_spec, *udp_mask;
2767 : : const struct rte_flow_item *item = pattern;
2768 : : enum rte_flow_item_type item_type;
2769 : :
2770 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
2771 [ # # ]: 0 : if (item->last) {
2772 : 0 : rte_flow_error_set(error, EINVAL,
2773 : : RTE_FLOW_ERROR_TYPE_ITEM,
2774 : : item,
2775 : : "Not support range");
2776 : 0 : return -rte_errno;
2777 : : }
2778 : : item_type = item->type;
2779 [ # # # # : 0 : switch (item_type) {
# # # ]
2780 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
2781 [ # # # # ]: 0 : if (item->spec || item->mask) {
2782 : 0 : rte_flow_error_set(error, EINVAL,
2783 : : RTE_FLOW_ERROR_TYPE_ITEM,
2784 : : item,
2785 : : "Invalid ETH item");
2786 : 0 : return -rte_errno;
2787 : : }
2788 : :
2789 : : break;
2790 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
2791 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;
2792 : : /* IPv4 is used to describe protocol,
2793 : : * spec and mask should be NULL.
2794 : : */
2795 [ # # # # ]: 0 : if (item->spec || item->mask) {
2796 : 0 : rte_flow_error_set(error, EINVAL,
2797 : : RTE_FLOW_ERROR_TYPE_ITEM,
2798 : : item,
2799 : : "Invalid IPv4 item");
2800 : 0 : return -rte_errno;
2801 : : }
2802 : :
2803 : : break;
2804 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
2805 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;
2806 : : /* IPv6 is used to describe protocol,
2807 : : * spec and mask should be NULL.
2808 : : */
2809 [ # # # # ]: 0 : if (item->spec || item->mask) {
2810 : 0 : rte_flow_error_set(error, EINVAL,
2811 : : RTE_FLOW_ERROR_TYPE_ITEM,
2812 : : item,
2813 : : "Invalid IPv6 item");
2814 : 0 : return -rte_errno;
2815 : : }
2816 : :
2817 : : break;
2818 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
2819 : 0 : udp_spec = item->spec;
2820 : 0 : udp_mask = item->mask;
2821 : :
2822 [ # # ]: 0 : if (!udp_spec || !udp_mask) {
2823 : 0 : rte_flow_error_set(error, EINVAL,
2824 : : RTE_FLOW_ERROR_TYPE_ITEM,
2825 : : item,
2826 : : "Invalid udp item");
2827 : 0 : return -rte_errno;
2828 : : }
2829 : :
2830 [ # # ]: 0 : if (udp_spec->hdr.src_port != 0 &&
2831 [ # # ]: 0 : udp_spec->hdr.dst_port != 0) {
2832 : 0 : rte_flow_error_set(error, EINVAL,
2833 : : RTE_FLOW_ERROR_TYPE_ITEM,
2834 : : item,
2835 : : "Invalid udp spec");
2836 : 0 : return -rte_errno;
2837 : : }
2838 : :
2839 [ # # ]: 0 : if (udp_spec->hdr.src_port != 0) {
2840 : 0 : filter->l4_port_type =
2841 : : I40E_L4_PORT_TYPE_SRC;
2842 : 0 : filter->tenant_id =
2843 [ # # ]: 0 : rte_be_to_cpu_32(udp_spec->hdr.src_port);
2844 : : }
2845 : :
2846 [ # # ]: 0 : if (udp_spec->hdr.dst_port != 0) {
2847 : 0 : filter->l4_port_type =
2848 : : I40E_L4_PORT_TYPE_DST;
2849 : 0 : filter->tenant_id =
2850 [ # # ]: 0 : rte_be_to_cpu_32(udp_spec->hdr.dst_port);
2851 : : }
2852 : :
2853 : 0 : filter->tunnel_type = I40E_CLOUD_TYPE_UDP;
2854 : :
2855 : 0 : break;
2856 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
2857 : 0 : tcp_spec = item->spec;
2858 : 0 : tcp_mask = item->mask;
2859 : :
2860 [ # # ]: 0 : if (!tcp_spec || !tcp_mask) {
2861 : 0 : rte_flow_error_set(error, EINVAL,
2862 : : RTE_FLOW_ERROR_TYPE_ITEM,
2863 : : item,
2864 : : "Invalid tcp item");
2865 : 0 : return -rte_errno;
2866 : : }
2867 : :
2868 [ # # ]: 0 : if (tcp_spec->hdr.src_port != 0 &&
2869 [ # # ]: 0 : tcp_spec->hdr.dst_port != 0) {
2870 : 0 : rte_flow_error_set(error, EINVAL,
2871 : : RTE_FLOW_ERROR_TYPE_ITEM,
2872 : : item,
2873 : : "Invalid tcp spec");
2874 : 0 : return -rte_errno;
2875 : : }
2876 : :
2877 [ # # ]: 0 : if (tcp_spec->hdr.src_port != 0) {
2878 : 0 : filter->l4_port_type =
2879 : : I40E_L4_PORT_TYPE_SRC;
2880 : 0 : filter->tenant_id =
2881 [ # # ]: 0 : rte_be_to_cpu_32(tcp_spec->hdr.src_port);
2882 : : }
2883 : :
2884 [ # # ]: 0 : if (tcp_spec->hdr.dst_port != 0) {
2885 : 0 : filter->l4_port_type =
2886 : : I40E_L4_PORT_TYPE_DST;
2887 : 0 : filter->tenant_id =
2888 [ # # ]: 0 : rte_be_to_cpu_32(tcp_spec->hdr.dst_port);
2889 : : }
2890 : :
2891 : 0 : filter->tunnel_type = I40E_CLOUD_TYPE_TCP;
2892 : :
2893 : 0 : break;
2894 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
2895 : 0 : sctp_spec = item->spec;
2896 : 0 : sctp_mask = item->mask;
2897 : :
2898 [ # # ]: 0 : if (!sctp_spec || !sctp_mask) {
2899 : 0 : rte_flow_error_set(error, EINVAL,
2900 : : RTE_FLOW_ERROR_TYPE_ITEM,
2901 : : item,
2902 : : "Invalid sctp item");
2903 : 0 : return -rte_errno;
2904 : : }
2905 : :
2906 [ # # ]: 0 : if (sctp_spec->hdr.src_port != 0 &&
2907 [ # # ]: 0 : sctp_spec->hdr.dst_port != 0) {
2908 : 0 : rte_flow_error_set(error, EINVAL,
2909 : : RTE_FLOW_ERROR_TYPE_ITEM,
2910 : : item,
2911 : : "Invalid sctp spec");
2912 : 0 : return -rte_errno;
2913 : : }
2914 : :
2915 [ # # ]: 0 : if (sctp_spec->hdr.src_port != 0) {
2916 : 0 : filter->l4_port_type =
2917 : : I40E_L4_PORT_TYPE_SRC;
2918 : 0 : filter->tenant_id =
2919 [ # # ]: 0 : rte_be_to_cpu_32(sctp_spec->hdr.src_port);
2920 : : }
2921 : :
2922 [ # # ]: 0 : if (sctp_spec->hdr.dst_port != 0) {
2923 : 0 : filter->l4_port_type =
2924 : : I40E_L4_PORT_TYPE_DST;
2925 : 0 : filter->tenant_id =
2926 [ # # ]: 0 : rte_be_to_cpu_32(sctp_spec->hdr.dst_port);
2927 : : }
2928 : :
2929 : 0 : filter->tunnel_type = I40E_CLOUD_TYPE_SCTP;
2930 : :
2931 : 0 : break;
2932 : : default:
2933 : : break;
2934 : : }
2935 : : }
2936 : :
2937 : : return 0;
2938 : : }
2939 : :
2940 : : static int
2941 : 0 : i40e_flow_parse_l4_cloud_filter(struct rte_eth_dev *dev,
2942 : : const struct rte_flow_attr *attr,
2943 : : const struct rte_flow_item pattern[],
2944 : : const struct rte_flow_action actions[],
2945 : : struct rte_flow_error *error,
2946 : : struct i40e_filter_ctx *filter)
2947 : : {
2948 : 0 : struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
2949 : : int ret;
2950 : :
2951 : 0 : ret = i40e_flow_parse_l4_pattern(pattern, error, tunnel_filter);
2952 [ # # ]: 0 : if (ret)
2953 : : return ret;
2954 : :
2955 : 0 : ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
2956 [ # # ]: 0 : if (ret)
2957 : : return ret;
2958 : :
2959 : 0 : ret = i40e_flow_parse_attr(attr, error);
2960 [ # # ]: 0 : if (ret)
2961 : : return ret;
2962 : :
2963 : 0 : filter->type = RTE_ETH_FILTER_TUNNEL;
2964 : :
2965 : 0 : return ret;
2966 : : }
2967 : :
2968 : : static uint16_t i40e_supported_tunnel_filter_types[] = {
2969 : : RTE_ETH_TUNNEL_FILTER_IMAC | RTE_ETH_TUNNEL_FILTER_TENID |
2970 : : RTE_ETH_TUNNEL_FILTER_IVLAN,
2971 : : RTE_ETH_TUNNEL_FILTER_IMAC | RTE_ETH_TUNNEL_FILTER_IVLAN,
2972 : : RTE_ETH_TUNNEL_FILTER_IMAC | RTE_ETH_TUNNEL_FILTER_TENID,
2973 : : RTE_ETH_TUNNEL_FILTER_OMAC | RTE_ETH_TUNNEL_FILTER_TENID |
2974 : : RTE_ETH_TUNNEL_FILTER_IMAC,
2975 : : RTE_ETH_TUNNEL_FILTER_IMAC,
2976 : : };
2977 : :
2978 : : static int
2979 : : i40e_check_tunnel_filter_type(uint8_t filter_type)
2980 : : {
2981 : : uint8_t i;
2982 : :
2983 [ # # # # ]: 0 : for (i = 0; i < RTE_DIM(i40e_supported_tunnel_filter_types); i++) {
2984 [ # # # # ]: 0 : if (filter_type == i40e_supported_tunnel_filter_types[i])
2985 : : return 0;
2986 : : }
2987 : :
2988 : : return -1;
2989 : : }
2990 : :
2991 : : /* 1. Last in item should be NULL as range is not supported.
2992 : : * 2. Supported filter types: IMAC_IVLAN_TENID, IMAC_IVLAN,
2993 : : * IMAC_TENID, OMAC_TENID_IMAC and IMAC.
2994 : : * 3. Mask of fields which need to be matched should be
2995 : : * filled with 1.
2996 : : * 4. Mask of fields which needn't to be matched should be
2997 : : * filled with 0.
2998 : : */
2999 : : static int
3000 : 0 : i40e_flow_parse_vxlan_pattern(__rte_unused struct rte_eth_dev *dev,
3001 : : const struct rte_flow_item *pattern,
3002 : : struct rte_flow_error *error,
3003 : : struct i40e_tunnel_filter_conf *filter)
3004 : : {
3005 : : const struct rte_flow_item *item = pattern;
3006 : : const struct rte_flow_item_eth *eth_spec;
3007 : : const struct rte_flow_item_eth *eth_mask;
3008 : : const struct rte_flow_item_vxlan *vxlan_spec;
3009 : : const struct rte_flow_item_vxlan *vxlan_mask;
3010 : : const struct rte_flow_item_vlan *vlan_spec;
3011 : : const struct rte_flow_item_vlan *vlan_mask;
3012 : : uint8_t filter_type = 0;
3013 : : bool is_vni_masked = 0;
3014 : 0 : uint8_t vni_mask[] = {0xFF, 0xFF, 0xFF};
3015 : : enum rte_flow_item_type item_type;
3016 : : bool vxlan_flag = 0;
3017 : 0 : uint32_t tenant_id_be = 0;
3018 : : int ret;
3019 : :
3020 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
3021 [ # # ]: 0 : if (item->last) {
3022 : 0 : rte_flow_error_set(error, EINVAL,
3023 : : RTE_FLOW_ERROR_TYPE_ITEM,
3024 : : item,
3025 : : "Not support range");
3026 : 0 : return -rte_errno;
3027 : : }
3028 : : item_type = item->type;
3029 [ # # # # : 0 : switch (item_type) {
# # # ]
3030 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
3031 : 0 : eth_spec = item->spec;
3032 : 0 : eth_mask = item->mask;
3033 : :
3034 : : /* Check if ETH item is used for place holder.
3035 : : * If yes, both spec and mask should be NULL.
3036 : : * If no, both spec and mask shouldn't be NULL.
3037 : : */
3038 [ # # ]: 0 : if ((!eth_spec && eth_mask) ||
3039 : : (eth_spec && !eth_mask)) {
3040 : 0 : rte_flow_error_set(error, EINVAL,
3041 : : RTE_FLOW_ERROR_TYPE_ITEM,
3042 : : item,
3043 : : "Invalid ether spec/mask");
3044 : 0 : return -rte_errno;
3045 : : }
3046 : :
3047 [ # # ]: 0 : if (eth_spec && eth_mask) {
3048 : : /* DST address of inner MAC shouldn't be masked.
3049 : : * SRC address of Inner MAC should be masked.
3050 : : */
3051 [ # # # # ]: 0 : if (!rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr) ||
3052 : 0 : !rte_is_zero_ether_addr(ð_mask->hdr.src_addr) ||
3053 [ # # ]: 0 : eth_mask->hdr.ether_type) {
3054 : 0 : rte_flow_error_set(error, EINVAL,
3055 : : RTE_FLOW_ERROR_TYPE_ITEM,
3056 : : item,
3057 : : "Invalid ether spec/mask");
3058 : 0 : return -rte_errno;
3059 : : }
3060 : :
3061 [ # # ]: 0 : if (!vxlan_flag) {
3062 : 0 : memcpy(&filter->outer_mac,
3063 : 0 : ð_spec->hdr.dst_addr,
3064 : : RTE_ETHER_ADDR_LEN);
3065 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_OMAC;
3066 : : } else {
3067 : 0 : memcpy(&filter->inner_mac,
3068 : 0 : ð_spec->hdr.dst_addr,
3069 : : RTE_ETHER_ADDR_LEN);
3070 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_IMAC;
3071 : : }
3072 : : }
3073 : : break;
3074 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
3075 : 0 : vlan_spec = item->spec;
3076 : 0 : vlan_mask = item->mask;
3077 [ # # ]: 0 : if (!(vlan_spec && vlan_mask) ||
3078 [ # # ]: 0 : vlan_mask->hdr.eth_proto) {
3079 : 0 : rte_flow_error_set(error, EINVAL,
3080 : : RTE_FLOW_ERROR_TYPE_ITEM,
3081 : : item,
3082 : : "Invalid vlan item");
3083 : 0 : return -rte_errno;
3084 : : }
3085 : :
3086 : : if (vlan_spec && vlan_mask) {
3087 [ # # ]: 0 : if (vlan_mask->hdr.vlan_tci ==
3088 : : rte_cpu_to_be_16(I40E_VLAN_TCI_MASK))
3089 : 0 : filter->inner_vlan =
3090 [ # # ]: 0 : rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci) &
3091 : : I40E_VLAN_TCI_MASK;
3092 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_IVLAN;
3093 : : }
3094 : : break;
3095 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
3096 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;
3097 : : /* IPv4 is used to describe protocol,
3098 : : * spec and mask should be NULL.
3099 : : */
3100 [ # # # # ]: 0 : if (item->spec || item->mask) {
3101 : 0 : rte_flow_error_set(error, EINVAL,
3102 : : RTE_FLOW_ERROR_TYPE_ITEM,
3103 : : item,
3104 : : "Invalid IPv4 item");
3105 : 0 : return -rte_errno;
3106 : : }
3107 : : break;
3108 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
3109 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;
3110 : : /* IPv6 is used to describe protocol,
3111 : : * spec and mask should be NULL.
3112 : : */
3113 [ # # # # ]: 0 : if (item->spec || item->mask) {
3114 : 0 : rte_flow_error_set(error, EINVAL,
3115 : : RTE_FLOW_ERROR_TYPE_ITEM,
3116 : : item,
3117 : : "Invalid IPv6 item");
3118 : 0 : return -rte_errno;
3119 : : }
3120 : : break;
3121 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
3122 : : /* UDP is used to describe protocol,
3123 : : * spec and mask should be NULL.
3124 : : */
3125 [ # # # # ]: 0 : if (item->spec || item->mask) {
3126 : 0 : rte_flow_error_set(error, EINVAL,
3127 : : RTE_FLOW_ERROR_TYPE_ITEM,
3128 : : item,
3129 : : "Invalid UDP item");
3130 : 0 : return -rte_errno;
3131 : : }
3132 : : break;
3133 : 0 : case RTE_FLOW_ITEM_TYPE_VXLAN:
3134 : 0 : vxlan_spec = item->spec;
3135 : 0 : vxlan_mask = item->mask;
3136 : : /* Check if VXLAN item is used to describe protocol.
3137 : : * If yes, both spec and mask should be NULL.
3138 : : * If no, both spec and mask shouldn't be NULL.
3139 : : */
3140 [ # # ]: 0 : if ((!vxlan_spec && vxlan_mask) ||
3141 : : (vxlan_spec && !vxlan_mask)) {
3142 : 0 : rte_flow_error_set(error, EINVAL,
3143 : : RTE_FLOW_ERROR_TYPE_ITEM,
3144 : : item,
3145 : : "Invalid VXLAN item");
3146 : 0 : return -rte_errno;
3147 : : }
3148 : :
3149 : : /* Check if VNI is masked. */
3150 [ # # ]: 0 : if (vxlan_spec && vxlan_mask) {
3151 : : is_vni_masked =
3152 : 0 : !!memcmp(vxlan_mask->hdr.vni, vni_mask,
3153 : : RTE_DIM(vni_mask));
3154 [ # # ]: 0 : if (is_vni_masked) {
3155 : 0 : rte_flow_error_set(error, EINVAL,
3156 : : RTE_FLOW_ERROR_TYPE_ITEM,
3157 : : item,
3158 : : "Invalid VNI mask");
3159 : 0 : return -rte_errno;
3160 : : }
3161 : :
3162 : : memcpy(((uint8_t *)&tenant_id_be + 1),
3163 [ # # ]: 0 : vxlan_spec->hdr.vni, 3);
3164 : 0 : filter->tenant_id =
3165 [ # # ]: 0 : rte_be_to_cpu_32(tenant_id_be);
3166 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_TENID;
3167 : : }
3168 : :
3169 : : vxlan_flag = 1;
3170 : : break;
3171 : : default:
3172 : : break;
3173 : : }
3174 : : }
3175 : :
3176 : : ret = i40e_check_tunnel_filter_type(filter_type);
3177 [ # # ]: 0 : if (ret < 0) {
3178 : 0 : rte_flow_error_set(error, EINVAL,
3179 : : RTE_FLOW_ERROR_TYPE_ITEM,
3180 : : NULL,
3181 : : "Invalid filter type");
3182 : 0 : return -rte_errno;
3183 : : }
3184 : 0 : filter->filter_type = filter_type;
3185 : :
3186 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_VXLAN;
3187 : :
3188 : 0 : return 0;
3189 : : }
3190 : :
3191 : : static int
3192 : 0 : i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
3193 : : const struct rte_flow_attr *attr,
3194 : : const struct rte_flow_item pattern[],
3195 : : const struct rte_flow_action actions[],
3196 : : struct rte_flow_error *error,
3197 : : struct i40e_filter_ctx *filter)
3198 : : {
3199 : 0 : struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
3200 : : int ret;
3201 : :
3202 : 0 : ret = i40e_flow_parse_vxlan_pattern(dev, pattern,
3203 : : error, tunnel_filter);
3204 [ # # ]: 0 : if (ret)
3205 : : return ret;
3206 : :
3207 : 0 : ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
3208 [ # # ]: 0 : if (ret)
3209 : : return ret;
3210 : :
3211 : 0 : ret = i40e_flow_parse_attr(attr, error);
3212 [ # # ]: 0 : if (ret)
3213 : : return ret;
3214 : :
3215 : 0 : filter->type = RTE_ETH_FILTER_TUNNEL;
3216 : :
3217 : 0 : return ret;
3218 : : }
3219 : :
3220 : : /* 1. Last in item should be NULL as range is not supported.
3221 : : * 2. Supported filter types: IMAC_IVLAN_TENID, IMAC_IVLAN,
3222 : : * IMAC_TENID, OMAC_TENID_IMAC and IMAC.
3223 : : * 3. Mask of fields which need to be matched should be
3224 : : * filled with 1.
3225 : : * 4. Mask of fields which needn't to be matched should be
3226 : : * filled with 0.
3227 : : */
3228 : : static int
3229 : 0 : i40e_flow_parse_nvgre_pattern(__rte_unused struct rte_eth_dev *dev,
3230 : : const struct rte_flow_item *pattern,
3231 : : struct rte_flow_error *error,
3232 : : struct i40e_tunnel_filter_conf *filter)
3233 : : {
3234 : : const struct rte_flow_item *item = pattern;
3235 : : const struct rte_flow_item_eth *eth_spec;
3236 : : const struct rte_flow_item_eth *eth_mask;
3237 : : const struct rte_flow_item_nvgre *nvgre_spec;
3238 : : const struct rte_flow_item_nvgre *nvgre_mask;
3239 : : const struct rte_flow_item_vlan *vlan_spec;
3240 : : const struct rte_flow_item_vlan *vlan_mask;
3241 : : enum rte_flow_item_type item_type;
3242 : : uint8_t filter_type = 0;
3243 : : bool is_tni_masked = 0;
3244 : 0 : uint8_t tni_mask[] = {0xFF, 0xFF, 0xFF};
3245 : : bool nvgre_flag = 0;
3246 : 0 : uint32_t tenant_id_be = 0;
3247 : : int ret;
3248 : :
3249 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
3250 [ # # ]: 0 : if (item->last) {
3251 : 0 : rte_flow_error_set(error, EINVAL,
3252 : : RTE_FLOW_ERROR_TYPE_ITEM,
3253 : : item,
3254 : : "Not support range");
3255 : 0 : return -rte_errno;
3256 : : }
3257 : : item_type = item->type;
3258 [ # # # # : 0 : switch (item_type) {
# # ]
3259 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
3260 : 0 : eth_spec = item->spec;
3261 : 0 : eth_mask = item->mask;
3262 : :
3263 : : /* Check if ETH item is used for place holder.
3264 : : * If yes, both spec and mask should be NULL.
3265 : : * If no, both spec and mask shouldn't be NULL.
3266 : : */
3267 [ # # ]: 0 : if ((!eth_spec && eth_mask) ||
3268 : : (eth_spec && !eth_mask)) {
3269 : 0 : rte_flow_error_set(error, EINVAL,
3270 : : RTE_FLOW_ERROR_TYPE_ITEM,
3271 : : item,
3272 : : "Invalid ether spec/mask");
3273 : 0 : return -rte_errno;
3274 : : }
3275 : :
3276 [ # # ]: 0 : if (eth_spec && eth_mask) {
3277 : : /* DST address of inner MAC shouldn't be masked.
3278 : : * SRC address of Inner MAC should be masked.
3279 : : */
3280 [ # # # # ]: 0 : if (!rte_is_broadcast_ether_addr(ð_mask->hdr.dst_addr) ||
3281 : 0 : !rte_is_zero_ether_addr(ð_mask->hdr.src_addr) ||
3282 [ # # ]: 0 : eth_mask->hdr.ether_type) {
3283 : 0 : rte_flow_error_set(error, EINVAL,
3284 : : RTE_FLOW_ERROR_TYPE_ITEM,
3285 : : item,
3286 : : "Invalid ether spec/mask");
3287 : 0 : return -rte_errno;
3288 : : }
3289 : :
3290 [ # # ]: 0 : if (!nvgre_flag) {
3291 : 0 : memcpy(&filter->outer_mac,
3292 : 0 : ð_spec->hdr.dst_addr,
3293 : : RTE_ETHER_ADDR_LEN);
3294 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_OMAC;
3295 : : } else {
3296 : 0 : memcpy(&filter->inner_mac,
3297 : 0 : ð_spec->hdr.dst_addr,
3298 : : RTE_ETHER_ADDR_LEN);
3299 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_IMAC;
3300 : : }
3301 : : }
3302 : :
3303 : : break;
3304 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
3305 : 0 : vlan_spec = item->spec;
3306 : 0 : vlan_mask = item->mask;
3307 [ # # ]: 0 : if (!(vlan_spec && vlan_mask) ||
3308 [ # # ]: 0 : vlan_mask->hdr.eth_proto) {
3309 : 0 : rte_flow_error_set(error, EINVAL,
3310 : : RTE_FLOW_ERROR_TYPE_ITEM,
3311 : : item,
3312 : : "Invalid vlan item");
3313 : 0 : return -rte_errno;
3314 : : }
3315 : :
3316 : : if (vlan_spec && vlan_mask) {
3317 [ # # ]: 0 : if (vlan_mask->hdr.vlan_tci ==
3318 : : rte_cpu_to_be_16(I40E_VLAN_TCI_MASK))
3319 : 0 : filter->inner_vlan =
3320 [ # # ]: 0 : rte_be_to_cpu_16(vlan_spec->hdr.vlan_tci) &
3321 : : I40E_VLAN_TCI_MASK;
3322 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_IVLAN;
3323 : : }
3324 : : break;
3325 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
3326 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;
3327 : : /* IPv4 is used to describe protocol,
3328 : : * spec and mask should be NULL.
3329 : : */
3330 [ # # # # ]: 0 : if (item->spec || item->mask) {
3331 : 0 : rte_flow_error_set(error, EINVAL,
3332 : : RTE_FLOW_ERROR_TYPE_ITEM,
3333 : : item,
3334 : : "Invalid IPv4 item");
3335 : 0 : return -rte_errno;
3336 : : }
3337 : : break;
3338 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
3339 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;
3340 : : /* IPv6 is used to describe protocol,
3341 : : * spec and mask should be NULL.
3342 : : */
3343 [ # # # # ]: 0 : if (item->spec || item->mask) {
3344 : 0 : rte_flow_error_set(error, EINVAL,
3345 : : RTE_FLOW_ERROR_TYPE_ITEM,
3346 : : item,
3347 : : "Invalid IPv6 item");
3348 : 0 : return -rte_errno;
3349 : : }
3350 : : break;
3351 : 0 : case RTE_FLOW_ITEM_TYPE_NVGRE:
3352 : 0 : nvgre_spec = item->spec;
3353 : 0 : nvgre_mask = item->mask;
3354 : : /* Check if NVGRE item is used to describe protocol.
3355 : : * If yes, both spec and mask should be NULL.
3356 : : * If no, both spec and mask shouldn't be NULL.
3357 : : */
3358 [ # # ]: 0 : if ((!nvgre_spec && nvgre_mask) ||
3359 : : (nvgre_spec && !nvgre_mask)) {
3360 : 0 : rte_flow_error_set(error, EINVAL,
3361 : : RTE_FLOW_ERROR_TYPE_ITEM,
3362 : : item,
3363 : : "Invalid NVGRE item");
3364 : 0 : return -rte_errno;
3365 : : }
3366 : :
3367 [ # # ]: 0 : if (nvgre_spec && nvgre_mask) {
3368 : : is_tni_masked =
3369 : 0 : !!memcmp(nvgre_mask->tni, tni_mask,
3370 : : RTE_DIM(tni_mask));
3371 [ # # ]: 0 : if (is_tni_masked) {
3372 : 0 : rte_flow_error_set(error, EINVAL,
3373 : : RTE_FLOW_ERROR_TYPE_ITEM,
3374 : : item,
3375 : : "Invalid TNI mask");
3376 : 0 : return -rte_errno;
3377 : : }
3378 [ # # ]: 0 : if (nvgre_mask->protocol &&
3379 : : nvgre_mask->protocol != 0xFFFF) {
3380 : 0 : rte_flow_error_set(error, EINVAL,
3381 : : RTE_FLOW_ERROR_TYPE_ITEM,
3382 : : item,
3383 : : "Invalid NVGRE item");
3384 : 0 : return -rte_errno;
3385 : : }
3386 [ # # # # ]: 0 : if (nvgre_mask->c_k_s_rsvd0_ver &&
3387 : : nvgre_mask->c_k_s_rsvd0_ver !=
3388 : : rte_cpu_to_be_16(0xFFFF)) {
3389 : 0 : rte_flow_error_set(error, EINVAL,
3390 : : RTE_FLOW_ERROR_TYPE_ITEM,
3391 : : item,
3392 : : "Invalid NVGRE item");
3393 : 0 : return -rte_errno;
3394 : : }
3395 [ # # ]: 0 : if (nvgre_spec->c_k_s_rsvd0_ver !=
3396 [ # # ]: 0 : rte_cpu_to_be_16(0x2000) &&
3397 : : nvgre_mask->c_k_s_rsvd0_ver) {
3398 : 0 : rte_flow_error_set(error, EINVAL,
3399 : : RTE_FLOW_ERROR_TYPE_ITEM,
3400 : : item,
3401 : : "Invalid NVGRE item");
3402 : 0 : return -rte_errno;
3403 : : }
3404 [ # # ]: 0 : if (nvgre_mask->protocol &&
3405 [ # # ]: 0 : nvgre_spec->protocol !=
3406 : : rte_cpu_to_be_16(0x6558)) {
3407 : 0 : rte_flow_error_set(error, EINVAL,
3408 : : RTE_FLOW_ERROR_TYPE_ITEM,
3409 : : item,
3410 : : "Invalid NVGRE item");
3411 : 0 : return -rte_errno;
3412 : : }
3413 : : memcpy(((uint8_t *)&tenant_id_be + 1),
3414 [ # # ]: 0 : nvgre_spec->tni, 3);
3415 : 0 : filter->tenant_id =
3416 [ # # ]: 0 : rte_be_to_cpu_32(tenant_id_be);
3417 : 0 : filter_type |= RTE_ETH_TUNNEL_FILTER_TENID;
3418 : : }
3419 : :
3420 : : nvgre_flag = 1;
3421 : : break;
3422 : : default:
3423 : : break;
3424 : : }
3425 : : }
3426 : :
3427 : : ret = i40e_check_tunnel_filter_type(filter_type);
3428 [ # # ]: 0 : if (ret < 0) {
3429 : 0 : rte_flow_error_set(error, EINVAL,
3430 : : RTE_FLOW_ERROR_TYPE_ITEM,
3431 : : NULL,
3432 : : "Invalid filter type");
3433 : 0 : return -rte_errno;
3434 : : }
3435 : 0 : filter->filter_type = filter_type;
3436 : :
3437 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_NVGRE;
3438 : :
3439 : 0 : return 0;
3440 : : }
3441 : :
3442 : : static int
3443 : 0 : i40e_flow_parse_nvgre_filter(struct rte_eth_dev *dev,
3444 : : const struct rte_flow_attr *attr,
3445 : : const struct rte_flow_item pattern[],
3446 : : const struct rte_flow_action actions[],
3447 : : struct rte_flow_error *error,
3448 : : struct i40e_filter_ctx *filter)
3449 : : {
3450 : 0 : struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
3451 : : int ret;
3452 : :
3453 : 0 : ret = i40e_flow_parse_nvgre_pattern(dev, pattern,
3454 : : error, tunnel_filter);
3455 [ # # ]: 0 : if (ret)
3456 : : return ret;
3457 : :
3458 : 0 : ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
3459 [ # # ]: 0 : if (ret)
3460 : : return ret;
3461 : :
3462 : 0 : ret = i40e_flow_parse_attr(attr, error);
3463 [ # # ]: 0 : if (ret)
3464 : : return ret;
3465 : :
3466 : 0 : filter->type = RTE_ETH_FILTER_TUNNEL;
3467 : :
3468 : 0 : return ret;
3469 : : }
3470 : :
3471 : : /* 1. Last in item should be NULL as range is not supported.
3472 : : * 2. Supported filter types: MPLS label.
3473 : : * 3. Mask of fields which need to be matched should be
3474 : : * filled with 1.
3475 : : * 4. Mask of fields which needn't to be matched should be
3476 : : * filled with 0.
3477 : : */
3478 : : static int
3479 : 0 : i40e_flow_parse_mpls_pattern(__rte_unused struct rte_eth_dev *dev,
3480 : : const struct rte_flow_item *pattern,
3481 : : struct rte_flow_error *error,
3482 : : struct i40e_tunnel_filter_conf *filter)
3483 : : {
3484 : : const struct rte_flow_item *item = pattern;
3485 : : const struct rte_flow_item_mpls *mpls_spec;
3486 : : const struct rte_flow_item_mpls *mpls_mask;
3487 : : enum rte_flow_item_type item_type;
3488 : : bool is_mplsoudp = 0; /* 1 - MPLSoUDP, 0 - MPLSoGRE */
3489 : 0 : const uint8_t label_mask[3] = {0xFF, 0xFF, 0xF0};
3490 : 0 : uint32_t label_be = 0;
3491 : :
3492 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
3493 [ # # ]: 0 : if (item->last) {
3494 : 0 : rte_flow_error_set(error, EINVAL,
3495 : : RTE_FLOW_ERROR_TYPE_ITEM,
3496 : : item,
3497 : : "Not support range");
3498 : 0 : return -rte_errno;
3499 : : }
3500 : : item_type = item->type;
3501 [ # # # # : 0 : switch (item_type) {
# # # ]
3502 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
3503 [ # # # # ]: 0 : if (item->spec || item->mask) {
3504 : 0 : rte_flow_error_set(error, EINVAL,
3505 : : RTE_FLOW_ERROR_TYPE_ITEM,
3506 : : item,
3507 : : "Invalid ETH item");
3508 : 0 : return -rte_errno;
3509 : : }
3510 : : break;
3511 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
3512 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;
3513 : : /* IPv4 is used to describe protocol,
3514 : : * spec and mask should be NULL.
3515 : : */
3516 [ # # # # ]: 0 : if (item->spec || item->mask) {
3517 : 0 : rte_flow_error_set(error, EINVAL,
3518 : : RTE_FLOW_ERROR_TYPE_ITEM,
3519 : : item,
3520 : : "Invalid IPv4 item");
3521 : 0 : return -rte_errno;
3522 : : }
3523 : : break;
3524 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
3525 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;
3526 : : /* IPv6 is used to describe protocol,
3527 : : * spec and mask should be NULL.
3528 : : */
3529 [ # # # # ]: 0 : if (item->spec || item->mask) {
3530 : 0 : rte_flow_error_set(error, EINVAL,
3531 : : RTE_FLOW_ERROR_TYPE_ITEM,
3532 : : item,
3533 : : "Invalid IPv6 item");
3534 : 0 : return -rte_errno;
3535 : : }
3536 : : break;
3537 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
3538 : : /* UDP is used to describe protocol,
3539 : : * spec and mask should be NULL.
3540 : : */
3541 [ # # # # ]: 0 : if (item->spec || item->mask) {
3542 : 0 : rte_flow_error_set(error, EINVAL,
3543 : : RTE_FLOW_ERROR_TYPE_ITEM,
3544 : : item,
3545 : : "Invalid UDP item");
3546 : 0 : return -rte_errno;
3547 : : }
3548 : : is_mplsoudp = 1;
3549 : : break;
3550 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
3551 : : /* GRE is used to describe protocol,
3552 : : * spec and mask should be NULL.
3553 : : */
3554 [ # # # # ]: 0 : if (item->spec || item->mask) {
3555 : 0 : rte_flow_error_set(error, EINVAL,
3556 : : RTE_FLOW_ERROR_TYPE_ITEM,
3557 : : item,
3558 : : "Invalid GRE item");
3559 : 0 : return -rte_errno;
3560 : : }
3561 : : break;
3562 : 0 : case RTE_FLOW_ITEM_TYPE_MPLS:
3563 : 0 : mpls_spec = item->spec;
3564 : 0 : mpls_mask = item->mask;
3565 : :
3566 [ # # ]: 0 : if (!mpls_spec || !mpls_mask) {
3567 : 0 : rte_flow_error_set(error, EINVAL,
3568 : : RTE_FLOW_ERROR_TYPE_ITEM,
3569 : : item,
3570 : : "Invalid MPLS item");
3571 : 0 : return -rte_errno;
3572 : : }
3573 : :
3574 [ # # ]: 0 : if (memcmp(mpls_mask->label_tc_s, label_mask, 3)) {
3575 : 0 : rte_flow_error_set(error, EINVAL,
3576 : : RTE_FLOW_ERROR_TYPE_ITEM,
3577 : : item,
3578 : : "Invalid MPLS label mask");
3579 : 0 : return -rte_errno;
3580 : : }
3581 : : memcpy(((uint8_t *)&label_be + 1),
3582 [ # # ]: 0 : mpls_spec->label_tc_s, 3);
3583 [ # # ]: 0 : filter->tenant_id = rte_be_to_cpu_32(label_be) >> 4;
3584 : 0 : break;
3585 : : default:
3586 : : break;
3587 : : }
3588 : : }
3589 : :
3590 [ # # ]: 0 : if (is_mplsoudp)
3591 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_MPLSoUDP;
3592 : : else
3593 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_MPLSoGRE;
3594 : :
3595 : : return 0;
3596 : : }
3597 : :
3598 : : static int
3599 : 0 : i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
3600 : : const struct rte_flow_attr *attr,
3601 : : const struct rte_flow_item pattern[],
3602 : : const struct rte_flow_action actions[],
3603 : : struct rte_flow_error *error,
3604 : : struct i40e_filter_ctx *filter)
3605 : : {
3606 : 0 : struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
3607 : : int ret;
3608 : :
3609 : 0 : ret = i40e_flow_parse_mpls_pattern(dev, pattern,
3610 : : error, tunnel_filter);
3611 [ # # ]: 0 : if (ret)
3612 : : return ret;
3613 : :
3614 : 0 : ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
3615 [ # # ]: 0 : if (ret)
3616 : : return ret;
3617 : :
3618 : 0 : ret = i40e_flow_parse_attr(attr, error);
3619 [ # # ]: 0 : if (ret)
3620 : : return ret;
3621 : :
3622 : 0 : filter->type = RTE_ETH_FILTER_TUNNEL;
3623 : :
3624 : 0 : return ret;
3625 : : }
3626 : :
3627 : : /* 1. Last in item should be NULL as range is not supported.
3628 : : * 2. Supported filter types: GTP TEID.
3629 : : * 3. Mask of fields which need to be matched should be
3630 : : * filled with 1.
3631 : : * 4. Mask of fields which needn't to be matched should be
3632 : : * filled with 0.
3633 : : * 5. GTP profile supports GTPv1 only.
3634 : : * 6. GTP-C response message ('source_port' = 2123) is not supported.
3635 : : */
3636 : : static int
3637 : 0 : i40e_flow_parse_gtp_pattern(struct rte_eth_dev *dev,
3638 : : const struct rte_flow_item *pattern,
3639 : : struct rte_flow_error *error,
3640 : : struct i40e_tunnel_filter_conf *filter)
3641 : : {
3642 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3643 : : const struct rte_flow_item *item = pattern;
3644 : : const struct rte_flow_item_gtp *gtp_spec;
3645 : : const struct rte_flow_item_gtp *gtp_mask;
3646 : : enum rte_flow_item_type item_type;
3647 : :
3648 [ # # ]: 0 : if (!pf->gtp_support) {
3649 : 0 : rte_flow_error_set(error, EINVAL,
3650 : : RTE_FLOW_ERROR_TYPE_ITEM,
3651 : : item,
3652 : : "GTP is not supported by default.");
3653 : 0 : return -rte_errno;
3654 : : }
3655 : :
3656 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
3657 [ # # ]: 0 : if (item->last) {
3658 : 0 : rte_flow_error_set(error, EINVAL,
3659 : : RTE_FLOW_ERROR_TYPE_ITEM,
3660 : : item,
3661 : : "Not support range");
3662 : 0 : return -rte_errno;
3663 : : }
3664 : : item_type = item->type;
3665 [ # # # # : 0 : switch (item_type) {
# # ]
3666 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
3667 [ # # # # ]: 0 : if (item->spec || item->mask) {
3668 : 0 : rte_flow_error_set(error, EINVAL,
3669 : : RTE_FLOW_ERROR_TYPE_ITEM,
3670 : : item,
3671 : : "Invalid ETH item");
3672 : 0 : return -rte_errno;
3673 : : }
3674 : : break;
3675 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
3676 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;
3677 : : /* IPv4 is used to describe protocol,
3678 : : * spec and mask should be NULL.
3679 : : */
3680 [ # # # # ]: 0 : if (item->spec || item->mask) {
3681 : 0 : rte_flow_error_set(error, EINVAL,
3682 : : RTE_FLOW_ERROR_TYPE_ITEM,
3683 : : item,
3684 : : "Invalid IPv4 item");
3685 : 0 : return -rte_errno;
3686 : : }
3687 : : break;
3688 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
3689 : 0 : filter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;
3690 : : /* IPv6 is used to describe protocol,
3691 : : * spec and mask should be NULL.
3692 : : */
3693 [ # # # # ]: 0 : if (item->spec || item->mask) {
3694 : 0 : rte_flow_error_set(error, EINVAL,
3695 : : RTE_FLOW_ERROR_TYPE_ITEM,
3696 : : item,
3697 : : "Invalid IPv6 item");
3698 : 0 : return -rte_errno;
3699 : : }
3700 : : break;
3701 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
3702 [ # # # # ]: 0 : if (item->spec || item->mask) {
3703 : 0 : rte_flow_error_set(error, EINVAL,
3704 : : RTE_FLOW_ERROR_TYPE_ITEM,
3705 : : item,
3706 : : "Invalid UDP item");
3707 : 0 : return -rte_errno;
3708 : : }
3709 : : break;
3710 : 0 : case RTE_FLOW_ITEM_TYPE_GTPC:
3711 : : case RTE_FLOW_ITEM_TYPE_GTPU:
3712 : 0 : gtp_spec = item->spec;
3713 : 0 : gtp_mask = item->mask;
3714 : :
3715 [ # # ]: 0 : if (!gtp_spec || !gtp_mask) {
3716 : 0 : rte_flow_error_set(error, EINVAL,
3717 : : RTE_FLOW_ERROR_TYPE_ITEM,
3718 : : item,
3719 : : "Invalid GTP item");
3720 : 0 : return -rte_errno;
3721 : : }
3722 : :
3723 : 0 : if (gtp_mask->hdr.gtp_hdr_info ||
3724 [ # # ]: 0 : gtp_mask->hdr.msg_type ||
3725 : 0 : gtp_mask->hdr.plen ||
3726 [ # # ]: 0 : gtp_mask->hdr.teid != UINT32_MAX) {
3727 : 0 : rte_flow_error_set(error, EINVAL,
3728 : : RTE_FLOW_ERROR_TYPE_ITEM,
3729 : : item,
3730 : : "Invalid GTP mask");
3731 : 0 : return -rte_errno;
3732 : : }
3733 : :
3734 [ # # ]: 0 : if (item_type == RTE_FLOW_ITEM_TYPE_GTPC)
3735 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_GTPC;
3736 : : else if (item_type == RTE_FLOW_ITEM_TYPE_GTPU)
3737 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_GTPU;
3738 : :
3739 [ # # ]: 0 : filter->tenant_id = rte_be_to_cpu_32(gtp_spec->hdr.teid);
3740 : :
3741 : 0 : break;
3742 : : default:
3743 : : break;
3744 : : }
3745 : : }
3746 : :
3747 : : return 0;
3748 : : }
3749 : :
3750 : : static int
3751 : 0 : i40e_flow_parse_gtp_filter(struct rte_eth_dev *dev,
3752 : : const struct rte_flow_attr *attr,
3753 : : const struct rte_flow_item pattern[],
3754 : : const struct rte_flow_action actions[],
3755 : : struct rte_flow_error *error,
3756 : : struct i40e_filter_ctx *filter)
3757 : : {
3758 : 0 : struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
3759 : : int ret;
3760 : :
3761 : 0 : ret = i40e_flow_parse_gtp_pattern(dev, pattern,
3762 : : error, tunnel_filter);
3763 [ # # ]: 0 : if (ret)
3764 : : return ret;
3765 : :
3766 : 0 : ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
3767 [ # # ]: 0 : if (ret)
3768 : : return ret;
3769 : :
3770 : 0 : ret = i40e_flow_parse_attr(attr, error);
3771 [ # # ]: 0 : if (ret)
3772 : : return ret;
3773 : :
3774 : 0 : filter->type = RTE_ETH_FILTER_TUNNEL;
3775 : :
3776 : 0 : return ret;
3777 : : }
3778 : :
3779 : : /* 1. Last in item should be NULL as range is not supported.
3780 : : * 2. Supported filter types: QINQ.
3781 : : * 3. Mask of fields which need to be matched should be
3782 : : * filled with 1.
3783 : : * 4. Mask of fields which needn't to be matched should be
3784 : : * filled with 0.
3785 : : */
3786 : : static int
3787 : 0 : i40e_flow_parse_qinq_pattern(__rte_unused struct rte_eth_dev *dev,
3788 : : const struct rte_flow_item *pattern,
3789 : : struct rte_flow_error *error,
3790 : : struct i40e_tunnel_filter_conf *filter)
3791 : : {
3792 : : const struct rte_flow_item *item = pattern;
3793 : : const struct rte_flow_item_vlan *vlan_spec = NULL;
3794 : : const struct rte_flow_item_vlan *vlan_mask = NULL;
3795 : : const struct rte_flow_item_vlan *i_vlan_spec = NULL;
3796 : : const struct rte_flow_item_vlan *i_vlan_mask = NULL;
3797 : : const struct rte_flow_item_vlan *o_vlan_spec = NULL;
3798 : : const struct rte_flow_item_vlan *o_vlan_mask = NULL;
3799 : :
3800 : : enum rte_flow_item_type item_type;
3801 : : bool vlan_flag = 0;
3802 : :
3803 [ # # ]: 0 : for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
3804 [ # # ]: 0 : if (item->last) {
3805 : 0 : rte_flow_error_set(error, EINVAL,
3806 : : RTE_FLOW_ERROR_TYPE_ITEM,
3807 : : item,
3808 : : "Not support range");
3809 : 0 : return -rte_errno;
3810 : : }
3811 : : item_type = item->type;
3812 [ # # # ]: 0 : switch (item_type) {
3813 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
3814 [ # # # # ]: 0 : if (item->spec || item->mask) {
3815 : 0 : rte_flow_error_set(error, EINVAL,
3816 : : RTE_FLOW_ERROR_TYPE_ITEM,
3817 : : item,
3818 : : "Invalid ETH item");
3819 : 0 : return -rte_errno;
3820 : : }
3821 : : break;
3822 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
3823 : 0 : vlan_spec = item->spec;
3824 : 0 : vlan_mask = item->mask;
3825 : :
3826 [ # # ]: 0 : if (!(vlan_spec && vlan_mask) ||
3827 [ # # ]: 0 : vlan_mask->hdr.eth_proto) {
3828 : 0 : rte_flow_error_set(error, EINVAL,
3829 : : RTE_FLOW_ERROR_TYPE_ITEM,
3830 : : item,
3831 : : "Invalid vlan item");
3832 : 0 : return -rte_errno;
3833 : : }
3834 : :
3835 [ # # ]: 0 : if (!vlan_flag) {
3836 : : o_vlan_spec = vlan_spec;
3837 : : o_vlan_mask = vlan_mask;
3838 : : vlan_flag = 1;
3839 : : } else {
3840 : : i_vlan_spec = vlan_spec;
3841 : : i_vlan_mask = vlan_mask;
3842 : : vlan_flag = 0;
3843 : : }
3844 : : break;
3845 : :
3846 : : default:
3847 : : break;
3848 : : }
3849 : : }
3850 : :
3851 : : /* Get filter specification */
3852 [ # # ]: 0 : if (o_vlan_mask != NULL && i_vlan_mask != NULL) {
3853 [ # # ]: 0 : filter->outer_vlan = rte_be_to_cpu_16(o_vlan_spec->hdr.vlan_tci);
3854 [ # # ]: 0 : filter->inner_vlan = rte_be_to_cpu_16(i_vlan_spec->hdr.vlan_tci);
3855 : : } else {
3856 : 0 : rte_flow_error_set(error, EINVAL,
3857 : : RTE_FLOW_ERROR_TYPE_ITEM,
3858 : : NULL,
3859 : : "Invalid filter type");
3860 : 0 : return -rte_errno;
3861 : : }
3862 : :
3863 : 0 : filter->tunnel_type = I40E_TUNNEL_TYPE_QINQ;
3864 : 0 : return 0;
3865 : : }
3866 : :
3867 : : static int
3868 : 0 : i40e_flow_parse_qinq_filter(struct rte_eth_dev *dev,
3869 : : const struct rte_flow_attr *attr,
3870 : : const struct rte_flow_item pattern[],
3871 : : const struct rte_flow_action actions[],
3872 : : struct rte_flow_error *error,
3873 : : struct i40e_filter_ctx *filter)
3874 : : {
3875 : 0 : struct i40e_tunnel_filter_conf *tunnel_filter = &filter->consistent_tunnel_filter;
3876 : : int ret;
3877 : :
3878 : 0 : ret = i40e_flow_parse_qinq_pattern(dev, pattern,
3879 : : error, tunnel_filter);
3880 [ # # ]: 0 : if (ret)
3881 : : return ret;
3882 : :
3883 : 0 : ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
3884 [ # # ]: 0 : if (ret)
3885 : : return ret;
3886 : :
3887 : 0 : ret = i40e_flow_parse_attr(attr, error);
3888 [ # # ]: 0 : if (ret)
3889 : : return ret;
3890 : :
3891 : 0 : filter->type = RTE_ETH_FILTER_TUNNEL;
3892 : :
3893 : 0 : return ret;
3894 : : }
3895 : :
3896 : : static int
3897 : 0 : i40e_flow_check(struct rte_eth_dev *dev,
3898 : : const struct rte_flow_attr *attr,
3899 : : const struct rte_flow_item pattern[],
3900 : : const struct rte_flow_action actions[],
3901 : : struct i40e_filter_ctx *filter_ctx,
3902 : : struct rte_flow_error *error)
3903 : : {
3904 : : struct rte_flow_item *items; /* internal pattern w/o VOID items */
3905 : : parse_filter_t parse_filter;
3906 : : uint32_t item_num = 0; /* non-void item number of pattern*/
3907 : 0 : uint32_t i = 0;
3908 : : bool flag = false;
3909 : : int ret = I40E_NOT_SUPPORTED;
3910 : :
3911 [ # # ]: 0 : if (!pattern) {
3912 : 0 : rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
3913 : : NULL, "NULL pattern.");
3914 : 0 : return -rte_errno;
3915 : : }
3916 : :
3917 [ # # ]: 0 : if (!actions) {
3918 : 0 : rte_flow_error_set(error, EINVAL,
3919 : : RTE_FLOW_ERROR_TYPE_ACTION_NUM,
3920 : : NULL, "NULL action.");
3921 : 0 : return -rte_errno;
3922 : : }
3923 : :
3924 [ # # ]: 0 : if (!attr) {
3925 : 0 : rte_flow_error_set(error, EINVAL,
3926 : : RTE_FLOW_ERROR_TYPE_ATTR,
3927 : : NULL, "NULL attribute.");
3928 : 0 : return -rte_errno;
3929 : : }
3930 : :
3931 : : /* Get the non-void item of action */
3932 [ # # ]: 0 : while ((actions + i)->type == RTE_FLOW_ACTION_TYPE_VOID)
3933 : 0 : i++;
3934 : :
3935 [ # # ]: 0 : if ((actions + i)->type == RTE_FLOW_ACTION_TYPE_RSS) {
3936 : 0 : ret = i40e_flow_parse_attr(attr, error);
3937 [ # # ]: 0 : if (ret)
3938 : : return ret;
3939 : :
3940 : 0 : filter_ctx->type = RTE_ETH_FILTER_HASH;
3941 : 0 : return i40e_hash_parse(dev, pattern, actions + i, &filter_ctx->rss_conf, error);
3942 : : }
3943 : :
3944 : 0 : i = 0;
3945 : : /* Get the non-void item number of pattern */
3946 [ # # ]: 0 : while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
3947 [ # # ]: 0 : if ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_VOID)
3948 : 0 : item_num++;
3949 : 0 : i++;
3950 : : }
3951 : 0 : item_num++;
3952 : 0 : items = calloc(item_num, sizeof(struct rte_flow_item));
3953 [ # # ]: 0 : if (items == NULL) {
3954 : 0 : rte_flow_error_set(error, ENOMEM,
3955 : : RTE_FLOW_ERROR_TYPE_ITEM_NUM,
3956 : : NULL,
3957 : : "No memory for PMD internal items.");
3958 : 0 : return -ENOMEM;
3959 : : }
3960 : :
3961 : 0 : i40e_pattern_skip_void_item(items, pattern);
3962 : :
3963 : 0 : i = 0;
3964 : : do {
3965 : 0 : parse_filter = i40e_find_parse_filter_func(items, &i);
3966 [ # # ]: 0 : if (!parse_filter && !flag) {
3967 : 0 : rte_flow_error_set(error, EINVAL,
3968 : : RTE_FLOW_ERROR_TYPE_ITEM,
3969 : : pattern, "Unsupported pattern");
3970 : :
3971 : 0 : free(items);
3972 : 0 : return -rte_errno;
3973 : : }
3974 : :
3975 [ # # ]: 0 : if (parse_filter)
3976 : 0 : ret = parse_filter(dev, attr, items, actions, error, filter_ctx);
3977 : :
3978 : : flag = true;
3979 [ # # # # ]: 0 : } while ((ret < 0) && (i < RTE_DIM(i40e_supported_patterns)));
3980 : :
3981 : 0 : free(items);
3982 : :
3983 : 0 : return ret;
3984 : : }
3985 : :
3986 : : static int
3987 : 0 : i40e_flow_validate(struct rte_eth_dev *dev,
3988 : : const struct rte_flow_attr *attr,
3989 : : const struct rte_flow_item pattern[],
3990 : : const struct rte_flow_action actions[],
3991 : : struct rte_flow_error *error)
3992 : : {
3993 : : /* creates dummy context */
3994 : 0 : struct i40e_filter_ctx filter_ctx = {0};
3995 : :
3996 : 0 : return i40e_flow_check(dev, attr, pattern, actions, &filter_ctx, error);
3997 : : }
3998 : :
3999 : : static struct rte_flow *
4000 : 0 : i40e_flow_create(struct rte_eth_dev *dev,
4001 : : const struct rte_flow_attr *attr,
4002 : : const struct rte_flow_item pattern[],
4003 : : const struct rte_flow_action actions[],
4004 : : struct rte_flow_error *error)
4005 : : {
4006 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4007 : 0 : struct i40e_filter_ctx filter_ctx = {0};
4008 : : struct rte_flow *flow = NULL;
4009 : 0 : struct i40e_fdir_info *fdir_info = &pf->fdir;
4010 : : int ret;
4011 : :
4012 : 0 : ret = i40e_flow_check(dev, attr, pattern, actions, &filter_ctx, error);
4013 [ # # ]: 0 : if (ret < 0)
4014 : : return NULL;
4015 : :
4016 [ # # ]: 0 : if (filter_ctx.type == RTE_ETH_FILTER_FDIR) {
4017 : : /* if this is the first time we're creating an fdir flow */
4018 [ # # ]: 0 : if (pf->fdir.fdir_vsi == NULL) {
4019 : 0 : ret = i40e_fdir_setup(pf);
4020 [ # # ]: 0 : if (ret != I40E_SUCCESS) {
4021 : 0 : rte_flow_error_set(error, ENOTSUP,
4022 : : RTE_FLOW_ERROR_TYPE_HANDLE,
4023 : : NULL, "Failed to setup fdir.");
4024 : 0 : return NULL;
4025 : : }
4026 : 0 : ret = i40e_fdir_configure(dev);
4027 [ # # ]: 0 : if (ret < 0) {
4028 : 0 : rte_flow_error_set(error, ENOTSUP,
4029 : : RTE_FLOW_ERROR_TYPE_HANDLE,
4030 : : NULL, "Failed to configure fdir.");
4031 : 0 : i40e_fdir_teardown(pf);
4032 : 0 : return NULL;
4033 : : }
4034 : : }
4035 : : /* If create the first fdir rule, enable fdir check for rx queues */
4036 [ # # ]: 0 : if (TAILQ_EMPTY(&pf->fdir.fdir_list))
4037 : 0 : i40e_fdir_rx_proc_enable(dev, 1);
4038 : :
4039 : 0 : flow = i40e_fdir_entry_pool_get(fdir_info);
4040 [ # # ]: 0 : if (flow == NULL) {
4041 : 0 : rte_flow_error_set(error, ENOBUFS,
4042 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4043 : : "Fdir space full");
4044 : :
4045 : 0 : return flow;
4046 : : }
4047 : : } else {
4048 : 0 : flow = rte_zmalloc("i40e_flow", sizeof(struct rte_flow), 0);
4049 [ # # ]: 0 : if (!flow) {
4050 : 0 : rte_flow_error_set(error, ENOMEM,
4051 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4052 : : "Failed to allocate memory");
4053 : 0 : return flow;
4054 : : }
4055 : : }
4056 : :
4057 [ # # # # : 0 : switch (filter_ctx.type) {
# ]
4058 : 0 : case RTE_ETH_FILTER_ETHERTYPE:
4059 : 0 : ret = i40e_ethertype_filter_set(pf, &filter_ctx.ethertype_filter, 1);
4060 [ # # ]: 0 : if (ret)
4061 : 0 : goto free_flow;
4062 : 0 : flow->rule = TAILQ_LAST(&pf->ethertype.ethertype_list,
4063 : : i40e_ethertype_filter_list);
4064 : 0 : break;
4065 : 0 : case RTE_ETH_FILTER_FDIR:
4066 : 0 : ret = i40e_flow_add_del_fdir_filter(dev, &filter_ctx.fdir_filter, 1);
4067 [ # # ]: 0 : if (ret)
4068 : 0 : goto free_flow;
4069 : 0 : flow->rule = TAILQ_LAST(&pf->fdir.fdir_list,
4070 : : i40e_fdir_filter_list);
4071 : 0 : break;
4072 : 0 : case RTE_ETH_FILTER_TUNNEL:
4073 : 0 : ret = i40e_dev_consistent_tunnel_filter_set(pf,
4074 : : &filter_ctx.consistent_tunnel_filter, 1);
4075 [ # # ]: 0 : if (ret)
4076 : 0 : goto free_flow;
4077 : 0 : flow->rule = TAILQ_LAST(&pf->tunnel.tunnel_list,
4078 : : i40e_tunnel_filter_list);
4079 : 0 : break;
4080 : 0 : case RTE_ETH_FILTER_HASH:
4081 : 0 : ret = i40e_hash_filter_create(pf, &filter_ctx.rss_conf);
4082 [ # # ]: 0 : if (ret)
4083 : 0 : goto free_flow;
4084 : 0 : flow->rule = TAILQ_LAST(&pf->rss_config_list,
4085 : : i40e_rss_conf_list);
4086 : 0 : break;
4087 : 0 : default:
4088 : 0 : goto free_flow;
4089 : : }
4090 : :
4091 : 0 : flow->filter_type = filter_ctx.type;
4092 : 0 : TAILQ_INSERT_TAIL(&pf->flow_list, flow, node);
4093 : 0 : return flow;
4094 : :
4095 : 0 : free_flow:
4096 : 0 : rte_flow_error_set(error, -ret,
4097 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4098 : : "Failed to create flow.");
4099 : :
4100 [ # # ]: 0 : if (filter_ctx.type != RTE_ETH_FILTER_FDIR)
4101 : 0 : rte_free(flow);
4102 : : else
4103 : 0 : i40e_fdir_entry_pool_put(fdir_info, flow);
4104 : :
4105 : : return NULL;
4106 : : }
4107 : :
4108 : : static int
4109 : 0 : i40e_flow_destroy(struct rte_eth_dev *dev,
4110 : : struct rte_flow *flow,
4111 : : struct rte_flow_error *error)
4112 : : {
4113 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4114 : 0 : enum rte_filter_type filter_type = flow->filter_type;
4115 : 0 : struct i40e_fdir_info *fdir_info = &pf->fdir;
4116 : : int ret = 0;
4117 : :
4118 [ # # # # : 0 : switch (filter_type) {
# ]
4119 : 0 : case RTE_ETH_FILTER_ETHERTYPE:
4120 : 0 : ret = i40e_flow_destroy_ethertype_filter(pf,
4121 : 0 : (struct i40e_ethertype_filter *)flow->rule);
4122 : 0 : break;
4123 : 0 : case RTE_ETH_FILTER_TUNNEL:
4124 : 0 : ret = i40e_flow_destroy_tunnel_filter(pf,
4125 : 0 : (struct i40e_tunnel_filter *)flow->rule);
4126 : 0 : break;
4127 : 0 : case RTE_ETH_FILTER_FDIR:
4128 : 0 : ret = i40e_flow_add_del_fdir_filter(dev,
4129 : 0 : &((struct i40e_fdir_filter *)flow->rule)->fdir,
4130 : : 0);
4131 : :
4132 : : /* If the last flow is destroyed, disable fdir. */
4133 [ # # # # ]: 0 : if (!ret && TAILQ_EMPTY(&pf->fdir.fdir_list)) {
4134 : 0 : i40e_fdir_rx_proc_enable(dev, 0);
4135 : : }
4136 : : break;
4137 : 0 : case RTE_ETH_FILTER_HASH:
4138 : 0 : ret = i40e_hash_filter_destroy(pf, flow->rule);
4139 : 0 : break;
4140 : 0 : default:
4141 : 0 : PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
4142 : : filter_type);
4143 : : ret = -EINVAL;
4144 : : break;
4145 : : }
4146 : :
4147 [ # # ]: 0 : if (!ret) {
4148 [ # # ]: 0 : TAILQ_REMOVE(&pf->flow_list, flow, node);
4149 [ # # ]: 0 : if (filter_type == RTE_ETH_FILTER_FDIR)
4150 : 0 : i40e_fdir_entry_pool_put(fdir_info, flow);
4151 : : else
4152 : 0 : rte_free(flow);
4153 : :
4154 : : } else
4155 : 0 : rte_flow_error_set(error, -ret,
4156 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4157 : : "Failed to destroy flow.");
4158 : :
4159 : 0 : return ret;
4160 : : }
4161 : :
4162 : : static int
4163 : 0 : i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
4164 : : struct i40e_ethertype_filter *filter)
4165 : : {
4166 : 0 : struct i40e_hw *hw = I40E_PF_TO_HW(pf);
4167 : 0 : struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
4168 : : struct i40e_ethertype_filter *node;
4169 : : struct i40e_control_filter_stats stats;
4170 : : uint16_t flags = 0;
4171 : : int ret = 0;
4172 : :
4173 [ # # ]: 0 : if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
4174 : : flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
4175 [ # # ]: 0 : if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
4176 : 0 : flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
4177 : 0 : flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
4178 : :
4179 : : memset(&stats, 0, sizeof(stats));
4180 : 0 : ret = i40e_aq_add_rem_control_packet_filter(hw,
4181 : 0 : filter->input.mac_addr.addr_bytes,
4182 : 0 : filter->input.ether_type,
4183 : 0 : flags, pf->main_vsi->seid,
4184 : 0 : filter->queue, 0, &stats, NULL);
4185 [ # # ]: 0 : if (ret < 0)
4186 : : return ret;
4187 : :
4188 : 0 : node = i40e_sw_ethertype_filter_lookup(ethertype_rule, &filter->input);
4189 [ # # ]: 0 : if (!node)
4190 : : return -EINVAL;
4191 : :
4192 : 0 : ret = i40e_sw_ethertype_filter_del(pf, &node->input);
4193 : :
4194 : 0 : return ret;
4195 : : }
4196 : :
4197 : : static int
4198 : 0 : i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
4199 : : struct i40e_tunnel_filter *filter)
4200 : : {
4201 : 0 : struct i40e_hw *hw = I40E_PF_TO_HW(pf);
4202 : : struct i40e_vsi *vsi;
4203 : : struct i40e_pf_vf *vf;
4204 : : struct i40e_aqc_cloud_filters_element_bb cld_filter;
4205 [ # # ]: 0 : struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
4206 : : struct i40e_tunnel_filter *node;
4207 : : bool big_buffer = 0;
4208 : : int ret = 0;
4209 : :
4210 : : memset(&cld_filter, 0, sizeof(cld_filter));
4211 : : rte_ether_addr_copy((struct rte_ether_addr *)&filter->input.outer_mac,
4212 : : (struct rte_ether_addr *)&cld_filter.element.outer_mac);
4213 : : rte_ether_addr_copy((struct rte_ether_addr *)&filter->input.inner_mac,
4214 : : (struct rte_ether_addr *)&cld_filter.element.inner_mac);
4215 : 0 : cld_filter.element.inner_vlan = filter->input.inner_vlan;
4216 : 0 : cld_filter.element.flags = filter->input.flags;
4217 : 0 : cld_filter.element.tenant_id = filter->input.tenant_id;
4218 : 0 : cld_filter.element.queue_number = filter->queue;
4219 : : memcpy(cld_filter.general_fields,
4220 [ # # ]: 0 : filter->input.general_fields,
4221 : : sizeof(cld_filter.general_fields));
4222 : :
4223 [ # # ]: 0 : if (!filter->is_to_vf)
4224 : 0 : vsi = pf->main_vsi;
4225 : : else {
4226 : 0 : vf = &pf->vfs[filter->vf_id];
4227 : 0 : vsi = vf->vsi;
4228 : : }
4229 : :
4230 [ # # ]: 0 : if (((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_0X11) ==
4231 [ # # ]: 0 : I40E_AQC_ADD_CLOUD_FILTER_0X11) ||
4232 : : ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_0X12) ==
4233 [ # # ]: 0 : I40E_AQC_ADD_CLOUD_FILTER_0X12) ||
4234 : : ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_0X10) ==
4235 : : I40E_AQC_ADD_CLOUD_FILTER_0X10))
4236 : : big_buffer = 1;
4237 : :
4238 : : if (big_buffer)
4239 : 0 : ret = i40e_aq_rem_cloud_filters_bb(hw, vsi->seid,
4240 : : &cld_filter, 1);
4241 : : else
4242 : 0 : ret = i40e_aq_rem_cloud_filters(hw, vsi->seid,
4243 : : &cld_filter.element, 1);
4244 [ # # ]: 0 : if (ret < 0)
4245 : : return -ENOTSUP;
4246 : :
4247 : 0 : node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &filter->input);
4248 [ # # ]: 0 : if (!node)
4249 : : return -EINVAL;
4250 : :
4251 : 0 : ret = i40e_sw_tunnel_filter_del(pf, &node->input);
4252 : :
4253 : 0 : return ret;
4254 : : }
4255 : :
4256 : : static int
4257 : 0 : i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
4258 : : {
4259 : 0 : struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4260 : : int ret;
4261 : :
4262 : 0 : ret = i40e_flow_flush_fdir_filter(pf);
4263 [ # # ]: 0 : if (ret) {
4264 : 0 : rte_flow_error_set(error, -ret,
4265 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4266 : : "Failed to flush FDIR flows.");
4267 : 0 : return -rte_errno;
4268 : : }
4269 : :
4270 : 0 : ret = i40e_flow_flush_ethertype_filter(pf);
4271 [ # # ]: 0 : if (ret) {
4272 : 0 : rte_flow_error_set(error, -ret,
4273 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4274 : : "Failed to ethertype flush flows.");
4275 : 0 : return -rte_errno;
4276 : : }
4277 : :
4278 : 0 : ret = i40e_flow_flush_tunnel_filter(pf);
4279 [ # # ]: 0 : if (ret) {
4280 : 0 : rte_flow_error_set(error, -ret,
4281 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4282 : : "Failed to flush tunnel flows.");
4283 : 0 : return -rte_errno;
4284 : : }
4285 : :
4286 : 0 : ret = i40e_hash_filter_flush(pf);
4287 [ # # ]: 0 : if (ret)
4288 : 0 : rte_flow_error_set(error, -ret,
4289 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
4290 : : "Failed to flush RSS flows.");
4291 : : return ret;
4292 : : }
4293 : :
4294 : : static int
4295 : 0 : i40e_flow_flush_fdir_filter(struct i40e_pf *pf)
4296 : : {
4297 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
4298 : : struct i40e_fdir_info *fdir_info = &pf->fdir;
4299 : : struct i40e_fdir_filter *fdir_filter;
4300 : : enum i40e_filter_pctype pctype;
4301 : : struct rte_flow *flow;
4302 : : void *temp;
4303 : : int ret;
4304 : : uint32_t i = 0;
4305 : :
4306 : 0 : ret = i40e_fdir_flush(dev);
4307 [ # # ]: 0 : if (!ret) {
4308 : : /* Delete FDIR filters in FDIR list. */
4309 [ # # ]: 0 : while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list))) {
4310 : 0 : ret = i40e_sw_fdir_filter_del(pf,
4311 : : &fdir_filter->fdir.input);
4312 [ # # ]: 0 : if (ret < 0)
4313 : 0 : return ret;
4314 : : }
4315 : :
4316 : : /* Delete FDIR flows in flow list. */
4317 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(flow, &pf->flow_list, node, temp) {
4318 [ # # ]: 0 : if (flow->filter_type == RTE_ETH_FILTER_FDIR) {
4319 [ # # ]: 0 : TAILQ_REMOVE(&pf->flow_list, flow, node);
4320 : : }
4321 : : }
4322 : :
4323 : : /* reset bitmap */
4324 : 0 : rte_bitmap_reset(fdir_info->fdir_flow_pool.bitmap);
4325 [ # # ]: 0 : for (i = 0; i < fdir_info->fdir_space_size; i++) {
4326 : 0 : fdir_info->fdir_flow_pool.pool[i].idx = i;
4327 : 0 : rte_bitmap_set(fdir_info->fdir_flow_pool.bitmap, i);
4328 : : }
4329 : :
4330 : 0 : fdir_info->fdir_actual_cnt = 0;
4331 : 0 : fdir_info->fdir_guarantee_free_space =
4332 : 0 : fdir_info->fdir_guarantee_total_space;
4333 : 0 : memset(fdir_info->fdir_filter_array,
4334 : : 0,
4335 : : sizeof(struct i40e_fdir_filter) *
4336 : : I40E_MAX_FDIR_FILTER_NUM);
4337 : :
4338 : 0 : for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
4339 [ # # ]: 0 : pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
4340 : 0 : pf->fdir.flow_count[pctype] = 0;
4341 : 0 : pf->fdir.flex_mask_flag[pctype] = 0;
4342 : : }
4343 : :
4344 [ # # ]: 0 : for (i = 0; i < I40E_MAX_FLXPLD_LAYER; i++)
4345 : 0 : pf->fdir.flex_pit_flag[i] = 0;
4346 : :
4347 : : /* Disable FDIR processing as all FDIR rules are now flushed */
4348 : 0 : i40e_fdir_rx_proc_enable(dev, 0);
4349 : : }
4350 : :
4351 : : return ret;
4352 : : }
4353 : :
4354 : : /* Flush all ethertype filters */
4355 : : static int
4356 : 0 : i40e_flow_flush_ethertype_filter(struct i40e_pf *pf)
4357 : : {
4358 : : struct i40e_ethertype_filter_list
4359 : : *ethertype_list = &pf->ethertype.ethertype_list;
4360 : : struct i40e_ethertype_filter *filter;
4361 : : struct rte_flow *flow;
4362 : : void *temp;
4363 : : int ret = 0;
4364 : :
4365 [ # # ]: 0 : while ((filter = TAILQ_FIRST(ethertype_list))) {
4366 : 0 : ret = i40e_flow_destroy_ethertype_filter(pf, filter);
4367 [ # # ]: 0 : if (ret)
4368 : 0 : return ret;
4369 : : }
4370 : :
4371 : : /* Delete ethertype flows in flow list. */
4372 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(flow, &pf->flow_list, node, temp) {
4373 [ # # ]: 0 : if (flow->filter_type == RTE_ETH_FILTER_ETHERTYPE) {
4374 [ # # ]: 0 : TAILQ_REMOVE(&pf->flow_list, flow, node);
4375 : 0 : rte_free(flow);
4376 : : }
4377 : : }
4378 : :
4379 : : return ret;
4380 : : }
4381 : :
4382 : : /* Flush all tunnel filters */
4383 : : static int
4384 : 0 : i40e_flow_flush_tunnel_filter(struct i40e_pf *pf)
4385 : : {
4386 : : struct i40e_tunnel_filter_list
4387 : : *tunnel_list = &pf->tunnel.tunnel_list;
4388 : : struct i40e_tunnel_filter *filter;
4389 : : struct rte_flow *flow;
4390 : : void *temp;
4391 : : int ret = 0;
4392 : :
4393 [ # # ]: 0 : while ((filter = TAILQ_FIRST(tunnel_list))) {
4394 : 0 : ret = i40e_flow_destroy_tunnel_filter(pf, filter);
4395 [ # # ]: 0 : if (ret)
4396 : 0 : return ret;
4397 : : }
4398 : :
4399 : : /* Delete tunnel flows in flow list. */
4400 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(flow, &pf->flow_list, node, temp) {
4401 [ # # ]: 0 : if (flow->filter_type == RTE_ETH_FILTER_TUNNEL) {
4402 [ # # ]: 0 : TAILQ_REMOVE(&pf->flow_list, flow, node);
4403 : 0 : rte_free(flow);
4404 : : }
4405 : : }
4406 : :
4407 : : return ret;
4408 : : }
4409 : :
4410 : : static int
4411 : 0 : i40e_flow_query(struct rte_eth_dev *dev __rte_unused,
4412 : : struct rte_flow *flow,
4413 : : const struct rte_flow_action *actions,
4414 : : void *data, struct rte_flow_error *error)
4415 : : {
4416 : 0 : struct i40e_rss_filter *rss_rule = (struct i40e_rss_filter *)flow->rule;
4417 : 0 : enum rte_filter_type filter_type = flow->filter_type;
4418 : : struct rte_flow_action_rss *rss_conf = data;
4419 : :
4420 [ # # ]: 0 : if (!rss_rule) {
4421 : 0 : rte_flow_error_set(error, EINVAL,
4422 : : RTE_FLOW_ERROR_TYPE_HANDLE,
4423 : : NULL, "Invalid rule");
4424 : 0 : return -rte_errno;
4425 : : }
4426 : :
4427 [ # # ]: 0 : for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
4428 [ # # # ]: 0 : switch (actions->type) {
4429 : : case RTE_FLOW_ACTION_TYPE_VOID:
4430 : : break;
4431 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
4432 [ # # ]: 0 : if (filter_type != RTE_ETH_FILTER_HASH) {
4433 : 0 : rte_flow_error_set(error, ENOTSUP,
4434 : : RTE_FLOW_ERROR_TYPE_ACTION,
4435 : : actions,
4436 : : "action not supported");
4437 : 0 : return -rte_errno;
4438 : : }
4439 : : memcpy(rss_conf,
4440 : 0 : &rss_rule->rss_filter_info.conf,
4441 : : sizeof(struct rte_flow_action_rss));
4442 : : break;
4443 : 0 : default:
4444 : 0 : return rte_flow_error_set(error, ENOTSUP,
4445 : : RTE_FLOW_ERROR_TYPE_ACTION,
4446 : : actions,
4447 : : "action not supported");
4448 : : }
4449 : : }
4450 : :
4451 : : return 0;
4452 : : }
|