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