]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/ixgbe/ixgbe_flow.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / ixgbe / ixgbe_flow.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2016 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 <inttypes.h>
13 #include <netinet/in.h>
14 #include <rte_byteorder.h>
15 #include <rte_common.h>
16 #include <rte_cycles.h>
17
18 #include <rte_interrupts.h>
19 #include <rte_log.h>
20 #include <rte_debug.h>
21 #include <rte_pci.h>
22 #include <rte_atomic.h>
23 #include <rte_branch_prediction.h>
24 #include <rte_memory.h>
25 #include <rte_eal.h>
26 #include <rte_alarm.h>
27 #include <rte_ether.h>
28 #include <rte_ethdev_driver.h>
29 #include <rte_malloc.h>
30 #include <rte_random.h>
31 #include <rte_dev.h>
32 #include <rte_hash_crc.h>
33 #include <rte_flow.h>
34 #include <rte_flow_driver.h>
35
36 #include "ixgbe_logs.h"
37 #include "base/ixgbe_api.h"
38 #include "base/ixgbe_vf.h"
39 #include "base/ixgbe_common.h"
40 #include "ixgbe_ethdev.h"
41 #include "ixgbe_bypass.h"
42 #include "ixgbe_rxtx.h"
43 #include "base/ixgbe_type.h"
44 #include "base/ixgbe_phy.h"
45 #include "rte_pmd_ixgbe.h"
46
47
48 #define IXGBE_MIN_N_TUPLE_PRIO 1
49 #define IXGBE_MAX_N_TUPLE_PRIO 7
50 #define IXGBE_MAX_FLX_SOURCE_OFF 62
51
52 /* ntuple filter list structure */
53 struct ixgbe_ntuple_filter_ele {
54 TAILQ_ENTRY(ixgbe_ntuple_filter_ele) entries;
55 struct rte_eth_ntuple_filter filter_info;
56 };
57 /* ethertype filter list structure */
58 struct ixgbe_ethertype_filter_ele {
59 TAILQ_ENTRY(ixgbe_ethertype_filter_ele) entries;
60 struct rte_eth_ethertype_filter filter_info;
61 };
62 /* syn filter list structure */
63 struct ixgbe_eth_syn_filter_ele {
64 TAILQ_ENTRY(ixgbe_eth_syn_filter_ele) entries;
65 struct rte_eth_syn_filter filter_info;
66 };
67 /* fdir filter list structure */
68 struct ixgbe_fdir_rule_ele {
69 TAILQ_ENTRY(ixgbe_fdir_rule_ele) entries;
70 struct ixgbe_fdir_rule filter_info;
71 };
72 /* l2_tunnel filter list structure */
73 struct ixgbe_eth_l2_tunnel_conf_ele {
74 TAILQ_ENTRY(ixgbe_eth_l2_tunnel_conf_ele) entries;
75 struct rte_eth_l2_tunnel_conf filter_info;
76 };
77 /* rss filter list structure */
78 struct ixgbe_rss_conf_ele {
79 TAILQ_ENTRY(ixgbe_rss_conf_ele) entries;
80 struct ixgbe_rte_flow_rss_conf filter_info;
81 };
82 /* ixgbe_flow memory list structure */
83 struct ixgbe_flow_mem {
84 TAILQ_ENTRY(ixgbe_flow_mem) entries;
85 struct rte_flow *flow;
86 };
87
88 TAILQ_HEAD(ixgbe_ntuple_filter_list, ixgbe_ntuple_filter_ele);
89 TAILQ_HEAD(ixgbe_ethertype_filter_list, ixgbe_ethertype_filter_ele);
90 TAILQ_HEAD(ixgbe_syn_filter_list, ixgbe_eth_syn_filter_ele);
91 TAILQ_HEAD(ixgbe_fdir_rule_filter_list, ixgbe_fdir_rule_ele);
92 TAILQ_HEAD(ixgbe_l2_tunnel_filter_list, ixgbe_eth_l2_tunnel_conf_ele);
93 TAILQ_HEAD(ixgbe_rss_filter_list, ixgbe_rss_conf_ele);
94 TAILQ_HEAD(ixgbe_flow_mem_list, ixgbe_flow_mem);
95
96 static struct ixgbe_ntuple_filter_list filter_ntuple_list;
97 static struct ixgbe_ethertype_filter_list filter_ethertype_list;
98 static struct ixgbe_syn_filter_list filter_syn_list;
99 static struct ixgbe_fdir_rule_filter_list filter_fdir_list;
100 static struct ixgbe_l2_tunnel_filter_list filter_l2_tunnel_list;
101 static struct ixgbe_rss_filter_list filter_rss_list;
102 static struct ixgbe_flow_mem_list ixgbe_flow_list;
103
104 /**
105 * Endless loop will never happen with below assumption
106 * 1. there is at least one no-void item(END)
107 * 2. cur is before END.
108 */
109 static inline
110 const struct rte_flow_item *next_no_void_pattern(
111 const struct rte_flow_item pattern[],
112 const struct rte_flow_item *cur)
113 {
114 const struct rte_flow_item *next =
115 cur ? cur + 1 : &pattern[0];
116 while (1) {
117 if (next->type != RTE_FLOW_ITEM_TYPE_VOID)
118 return next;
119 next++;
120 }
121 }
122
123 static inline
124 const struct rte_flow_action *next_no_void_action(
125 const struct rte_flow_action actions[],
126 const struct rte_flow_action *cur)
127 {
128 const struct rte_flow_action *next =
129 cur ? cur + 1 : &actions[0];
130 while (1) {
131 if (next->type != RTE_FLOW_ACTION_TYPE_VOID)
132 return next;
133 next++;
134 }
135 }
136
137 /**
138 * Please aware there's an asumption for all the parsers.
139 * rte_flow_item is using big endian, rte_flow_attr and
140 * rte_flow_action are using CPU order.
141 * Because the pattern is used to describe the packets,
142 * normally the packets should use network order.
143 */
144
145 /**
146 * Parse the rule to see if it is a n-tuple rule.
147 * And get the n-tuple filter info BTW.
148 * pattern:
149 * The first not void item can be ETH or IPV4.
150 * The second not void item must be IPV4 if the first one is ETH.
151 * The third not void item must be UDP or TCP.
152 * The next not void item must be END.
153 * action:
154 * The first not void action should be QUEUE.
155 * The next not void action should be END.
156 * pattern example:
157 * ITEM Spec Mask
158 * ETH NULL NULL
159 * IPV4 src_addr 192.168.1.20 0xFFFFFFFF
160 * dst_addr 192.167.3.50 0xFFFFFFFF
161 * next_proto_id 17 0xFF
162 * UDP/TCP/ src_port 80 0xFFFF
163 * SCTP dst_port 80 0xFFFF
164 * END
165 * other members in mask and spec should set to 0x00.
166 * item->last should be NULL.
167 *
168 * Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY.
169 *
170 */
171 static int
172 cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
173 const struct rte_flow_item pattern[],
174 const struct rte_flow_action actions[],
175 struct rte_eth_ntuple_filter *filter,
176 struct rte_flow_error *error)
177 {
178 const struct rte_flow_item *item;
179 const struct rte_flow_action *act;
180 const struct rte_flow_item_ipv4 *ipv4_spec;
181 const struct rte_flow_item_ipv4 *ipv4_mask;
182 const struct rte_flow_item_tcp *tcp_spec;
183 const struct rte_flow_item_tcp *tcp_mask;
184 const struct rte_flow_item_udp *udp_spec;
185 const struct rte_flow_item_udp *udp_mask;
186 const struct rte_flow_item_sctp *sctp_spec;
187 const struct rte_flow_item_sctp *sctp_mask;
188 const struct rte_flow_item_eth *eth_spec;
189 const struct rte_flow_item_eth *eth_mask;
190 const struct rte_flow_item_vlan *vlan_spec;
191 const struct rte_flow_item_vlan *vlan_mask;
192 struct rte_flow_item_eth eth_null;
193 struct rte_flow_item_vlan vlan_null;
194
195 if (!pattern) {
196 rte_flow_error_set(error,
197 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
198 NULL, "NULL pattern.");
199 return -rte_errno;
200 }
201
202 if (!actions) {
203 rte_flow_error_set(error, EINVAL,
204 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
205 NULL, "NULL action.");
206 return -rte_errno;
207 }
208 if (!attr) {
209 rte_flow_error_set(error, EINVAL,
210 RTE_FLOW_ERROR_TYPE_ATTR,
211 NULL, "NULL attribute.");
212 return -rte_errno;
213 }
214
215 memset(&eth_null, 0, sizeof(struct rte_flow_item_eth));
216 memset(&vlan_null, 0, sizeof(struct rte_flow_item_vlan));
217
218 #ifdef RTE_LIBRTE_SECURITY
219 /**
220 * Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY
221 */
222 act = next_no_void_action(actions, NULL);
223 if (act->type == RTE_FLOW_ACTION_TYPE_SECURITY) {
224 const void *conf = act->conf;
225 /* check if the next not void item is END */
226 act = next_no_void_action(actions, act);
227 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
228 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
229 rte_flow_error_set(error, EINVAL,
230 RTE_FLOW_ERROR_TYPE_ACTION,
231 act, "Not supported action.");
232 return -rte_errno;
233 }
234
235 /* get the IP pattern*/
236 item = next_no_void_pattern(pattern, NULL);
237 while (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
238 item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
239 if (item->last ||
240 item->type == RTE_FLOW_ITEM_TYPE_END) {
241 rte_flow_error_set(error, EINVAL,
242 RTE_FLOW_ERROR_TYPE_ITEM,
243 item, "IP pattern missing.");
244 return -rte_errno;
245 }
246 item = next_no_void_pattern(pattern, item);
247 }
248
249 filter->proto = IPPROTO_ESP;
250 return ixgbe_crypto_add_ingress_sa_from_flow(conf, item->spec,
251 item->type == RTE_FLOW_ITEM_TYPE_IPV6);
252 }
253 #endif
254
255 /* the first not void item can be MAC or IPv4 */
256 item = next_no_void_pattern(pattern, NULL);
257
258 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
259 item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
260 rte_flow_error_set(error, EINVAL,
261 RTE_FLOW_ERROR_TYPE_ITEM,
262 item, "Not supported by ntuple filter");
263 return -rte_errno;
264 }
265 /* Skip Ethernet */
266 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
267 eth_spec = item->spec;
268 eth_mask = item->mask;
269 /*Not supported last point for range*/
270 if (item->last) {
271 rte_flow_error_set(error,
272 EINVAL,
273 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
274 item, "Not supported last point for range");
275 return -rte_errno;
276
277 }
278 /* if the first item is MAC, the content should be NULL */
279 if ((item->spec || item->mask) &&
280 (memcmp(eth_spec, &eth_null,
281 sizeof(struct rte_flow_item_eth)) ||
282 memcmp(eth_mask, &eth_null,
283 sizeof(struct rte_flow_item_eth)))) {
284 rte_flow_error_set(error, EINVAL,
285 RTE_FLOW_ERROR_TYPE_ITEM,
286 item, "Not supported by ntuple filter");
287 return -rte_errno;
288 }
289 /* check if the next not void item is IPv4 or Vlan */
290 item = next_no_void_pattern(pattern, item);
291 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
292 item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
293 rte_flow_error_set(error,
294 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
295 item, "Not supported by ntuple filter");
296 return -rte_errno;
297 }
298 }
299
300 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
301 vlan_spec = item->spec;
302 vlan_mask = item->mask;
303 /*Not supported last point for range*/
304 if (item->last) {
305 rte_flow_error_set(error,
306 EINVAL,
307 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
308 item, "Not supported last point for range");
309 return -rte_errno;
310 }
311 /* the content should be NULL */
312 if ((item->spec || item->mask) &&
313 (memcmp(vlan_spec, &vlan_null,
314 sizeof(struct rte_flow_item_vlan)) ||
315 memcmp(vlan_mask, &vlan_null,
316 sizeof(struct rte_flow_item_vlan)))) {
317
318 rte_flow_error_set(error, EINVAL,
319 RTE_FLOW_ERROR_TYPE_ITEM,
320 item, "Not supported by ntuple filter");
321 return -rte_errno;
322 }
323 /* check if the next not void item is IPv4 */
324 item = next_no_void_pattern(pattern, item);
325 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
326 rte_flow_error_set(error,
327 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
328 item, "Not supported by ntuple filter");
329 return -rte_errno;
330 }
331 }
332
333 if (item->mask) {
334 /* get the IPv4 info */
335 if (!item->spec || !item->mask) {
336 rte_flow_error_set(error, EINVAL,
337 RTE_FLOW_ERROR_TYPE_ITEM,
338 item, "Invalid ntuple mask");
339 return -rte_errno;
340 }
341 /*Not supported last point for range*/
342 if (item->last) {
343 rte_flow_error_set(error, EINVAL,
344 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
345 item, "Not supported last point for range");
346 return -rte_errno;
347 }
348
349 ipv4_mask = item->mask;
350 /**
351 * Only support src & dst addresses, protocol,
352 * others should be masked.
353 */
354 if (ipv4_mask->hdr.version_ihl ||
355 ipv4_mask->hdr.type_of_service ||
356 ipv4_mask->hdr.total_length ||
357 ipv4_mask->hdr.packet_id ||
358 ipv4_mask->hdr.fragment_offset ||
359 ipv4_mask->hdr.time_to_live ||
360 ipv4_mask->hdr.hdr_checksum) {
361 rte_flow_error_set(error,
362 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
363 item, "Not supported by ntuple filter");
364 return -rte_errno;
365 }
366 if ((ipv4_mask->hdr.src_addr != 0 &&
367 ipv4_mask->hdr.src_addr != UINT32_MAX) ||
368 (ipv4_mask->hdr.dst_addr != 0 &&
369 ipv4_mask->hdr.dst_addr != UINT32_MAX) ||
370 (ipv4_mask->hdr.next_proto_id != UINT8_MAX &&
371 ipv4_mask->hdr.next_proto_id != 0)) {
372 rte_flow_error_set(error,
373 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
374 item, "Not supported by ntuple filter");
375 return -rte_errno;
376 }
377
378 filter->dst_ip_mask = ipv4_mask->hdr.dst_addr;
379 filter->src_ip_mask = ipv4_mask->hdr.src_addr;
380 filter->proto_mask = ipv4_mask->hdr.next_proto_id;
381
382 ipv4_spec = item->spec;
383 filter->dst_ip = ipv4_spec->hdr.dst_addr;
384 filter->src_ip = ipv4_spec->hdr.src_addr;
385 filter->proto = ipv4_spec->hdr.next_proto_id;
386 }
387
388 /* check if the next not void item is TCP or UDP */
389 item = next_no_void_pattern(pattern, item);
390 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
391 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
392 item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
393 item->type != RTE_FLOW_ITEM_TYPE_END) {
394 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
395 rte_flow_error_set(error, EINVAL,
396 RTE_FLOW_ERROR_TYPE_ITEM,
397 item, "Not supported by ntuple filter");
398 return -rte_errno;
399 }
400
401 if ((item->type != RTE_FLOW_ITEM_TYPE_END) &&
402 (!item->spec && !item->mask)) {
403 goto action;
404 }
405
406 /* get the TCP/UDP/SCTP info */
407 if (item->type != RTE_FLOW_ITEM_TYPE_END &&
408 (!item->spec || !item->mask)) {
409 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
410 rte_flow_error_set(error, EINVAL,
411 RTE_FLOW_ERROR_TYPE_ITEM,
412 item, "Invalid ntuple mask");
413 return -rte_errno;
414 }
415
416 /*Not supported last point for range*/
417 if (item->last) {
418 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
419 rte_flow_error_set(error, EINVAL,
420 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
421 item, "Not supported last point for range");
422 return -rte_errno;
423
424 }
425
426 if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
427 tcp_mask = item->mask;
428
429 /**
430 * Only support src & dst ports, tcp flags,
431 * others should be masked.
432 */
433 if (tcp_mask->hdr.sent_seq ||
434 tcp_mask->hdr.recv_ack ||
435 tcp_mask->hdr.data_off ||
436 tcp_mask->hdr.rx_win ||
437 tcp_mask->hdr.cksum ||
438 tcp_mask->hdr.tcp_urp) {
439 memset(filter, 0,
440 sizeof(struct rte_eth_ntuple_filter));
441 rte_flow_error_set(error, EINVAL,
442 RTE_FLOW_ERROR_TYPE_ITEM,
443 item, "Not supported by ntuple filter");
444 return -rte_errno;
445 }
446 if ((tcp_mask->hdr.src_port != 0 &&
447 tcp_mask->hdr.src_port != UINT16_MAX) ||
448 (tcp_mask->hdr.dst_port != 0 &&
449 tcp_mask->hdr.dst_port != UINT16_MAX)) {
450 rte_flow_error_set(error,
451 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
452 item, "Not supported by ntuple filter");
453 return -rte_errno;
454 }
455
456 filter->dst_port_mask = tcp_mask->hdr.dst_port;
457 filter->src_port_mask = tcp_mask->hdr.src_port;
458 if (tcp_mask->hdr.tcp_flags == 0xFF) {
459 filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
460 } else if (!tcp_mask->hdr.tcp_flags) {
461 filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG;
462 } else {
463 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
464 rte_flow_error_set(error, EINVAL,
465 RTE_FLOW_ERROR_TYPE_ITEM,
466 item, "Not supported by ntuple filter");
467 return -rte_errno;
468 }
469
470 tcp_spec = item->spec;
471 filter->dst_port = tcp_spec->hdr.dst_port;
472 filter->src_port = tcp_spec->hdr.src_port;
473 filter->tcp_flags = tcp_spec->hdr.tcp_flags;
474 } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
475 udp_mask = item->mask;
476
477 /**
478 * Only support src & dst ports,
479 * others should be masked.
480 */
481 if (udp_mask->hdr.dgram_len ||
482 udp_mask->hdr.dgram_cksum) {
483 memset(filter, 0,
484 sizeof(struct rte_eth_ntuple_filter));
485 rte_flow_error_set(error, EINVAL,
486 RTE_FLOW_ERROR_TYPE_ITEM,
487 item, "Not supported by ntuple filter");
488 return -rte_errno;
489 }
490 if ((udp_mask->hdr.src_port != 0 &&
491 udp_mask->hdr.src_port != UINT16_MAX) ||
492 (udp_mask->hdr.dst_port != 0 &&
493 udp_mask->hdr.dst_port != UINT16_MAX)) {
494 rte_flow_error_set(error,
495 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
496 item, "Not supported by ntuple filter");
497 return -rte_errno;
498 }
499
500 filter->dst_port_mask = udp_mask->hdr.dst_port;
501 filter->src_port_mask = udp_mask->hdr.src_port;
502
503 udp_spec = item->spec;
504 filter->dst_port = udp_spec->hdr.dst_port;
505 filter->src_port = udp_spec->hdr.src_port;
506 } else if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) {
507 sctp_mask = item->mask;
508
509 /**
510 * Only support src & dst ports,
511 * others should be masked.
512 */
513 if (sctp_mask->hdr.tag ||
514 sctp_mask->hdr.cksum) {
515 memset(filter, 0,
516 sizeof(struct rte_eth_ntuple_filter));
517 rte_flow_error_set(error, EINVAL,
518 RTE_FLOW_ERROR_TYPE_ITEM,
519 item, "Not supported by ntuple filter");
520 return -rte_errno;
521 }
522
523 filter->dst_port_mask = sctp_mask->hdr.dst_port;
524 filter->src_port_mask = sctp_mask->hdr.src_port;
525
526 sctp_spec = item->spec;
527 filter->dst_port = sctp_spec->hdr.dst_port;
528 filter->src_port = sctp_spec->hdr.src_port;
529 } else {
530 goto action;
531 }
532
533 /* check if the next not void item is END */
534 item = next_no_void_pattern(pattern, item);
535 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
536 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
537 rte_flow_error_set(error, EINVAL,
538 RTE_FLOW_ERROR_TYPE_ITEM,
539 item, "Not supported by ntuple filter");
540 return -rte_errno;
541 }
542
543 action:
544
545 /**
546 * n-tuple only supports forwarding,
547 * check if the first not void action is QUEUE.
548 */
549 act = next_no_void_action(actions, NULL);
550 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
551 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
552 rte_flow_error_set(error, EINVAL,
553 RTE_FLOW_ERROR_TYPE_ACTION,
554 item, "Not supported action.");
555 return -rte_errno;
556 }
557 filter->queue =
558 ((const struct rte_flow_action_queue *)act->conf)->index;
559
560 /* check if the next not void item is END */
561 act = next_no_void_action(actions, act);
562 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
563 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
564 rte_flow_error_set(error, EINVAL,
565 RTE_FLOW_ERROR_TYPE_ACTION,
566 act, "Not supported action.");
567 return -rte_errno;
568 }
569
570 /* parse attr */
571 /* must be input direction */
572 if (!attr->ingress) {
573 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
574 rte_flow_error_set(error, EINVAL,
575 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
576 attr, "Only support ingress.");
577 return -rte_errno;
578 }
579
580 /* not supported */
581 if (attr->egress) {
582 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
583 rte_flow_error_set(error, EINVAL,
584 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
585 attr, "Not support egress.");
586 return -rte_errno;
587 }
588
589 /* not supported */
590 if (attr->transfer) {
591 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
592 rte_flow_error_set(error, EINVAL,
593 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
594 attr, "No support for transfer.");
595 return -rte_errno;
596 }
597
598 if (attr->priority > 0xFFFF) {
599 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
600 rte_flow_error_set(error, EINVAL,
601 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
602 attr, "Error priority.");
603 return -rte_errno;
604 }
605 filter->priority = (uint16_t)attr->priority;
606 if (attr->priority < IXGBE_MIN_N_TUPLE_PRIO ||
607 attr->priority > IXGBE_MAX_N_TUPLE_PRIO)
608 filter->priority = 1;
609
610 return 0;
611 }
612
613 /* a specific function for ixgbe because the flags is specific */
614 static int
615 ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
616 const struct rte_flow_attr *attr,
617 const struct rte_flow_item pattern[],
618 const struct rte_flow_action actions[],
619 struct rte_eth_ntuple_filter *filter,
620 struct rte_flow_error *error)
621 {
622 int ret;
623 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
624
625 MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
626
627 ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
628
629 if (ret)
630 return ret;
631
632 #ifdef RTE_LIBRTE_SECURITY
633 /* ESP flow not really a flow*/
634 if (filter->proto == IPPROTO_ESP)
635 return 0;
636 #endif
637
638 /* Ixgbe doesn't support tcp flags. */
639 if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) {
640 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
641 rte_flow_error_set(error, EINVAL,
642 RTE_FLOW_ERROR_TYPE_ITEM,
643 NULL, "Not supported by ntuple filter");
644 return -rte_errno;
645 }
646
647 /* Ixgbe doesn't support many priorities. */
648 if (filter->priority < IXGBE_MIN_N_TUPLE_PRIO ||
649 filter->priority > IXGBE_MAX_N_TUPLE_PRIO) {
650 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
651 rte_flow_error_set(error, EINVAL,
652 RTE_FLOW_ERROR_TYPE_ITEM,
653 NULL, "Priority not supported by ntuple filter");
654 return -rte_errno;
655 }
656
657 if (filter->queue >= dev->data->nb_rx_queues)
658 return -rte_errno;
659
660 /* fixed value for ixgbe */
661 filter->flags = RTE_5TUPLE_FLAGS;
662 return 0;
663 }
664
665 /**
666 * Parse the rule to see if it is a ethertype rule.
667 * And get the ethertype filter info BTW.
668 * pattern:
669 * The first not void item can be ETH.
670 * The next not void item must be END.
671 * action:
672 * The first not void action should be QUEUE.
673 * The next not void action should be END.
674 * pattern example:
675 * ITEM Spec Mask
676 * ETH type 0x0807 0xFFFF
677 * END
678 * other members in mask and spec should set to 0x00.
679 * item->last should be NULL.
680 */
681 static int
682 cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
683 const struct rte_flow_item *pattern,
684 const struct rte_flow_action *actions,
685 struct rte_eth_ethertype_filter *filter,
686 struct rte_flow_error *error)
687 {
688 const struct rte_flow_item *item;
689 const struct rte_flow_action *act;
690 const struct rte_flow_item_eth *eth_spec;
691 const struct rte_flow_item_eth *eth_mask;
692 const struct rte_flow_action_queue *act_q;
693
694 if (!pattern) {
695 rte_flow_error_set(error, EINVAL,
696 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
697 NULL, "NULL pattern.");
698 return -rte_errno;
699 }
700
701 if (!actions) {
702 rte_flow_error_set(error, EINVAL,
703 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
704 NULL, "NULL action.");
705 return -rte_errno;
706 }
707
708 if (!attr) {
709 rte_flow_error_set(error, EINVAL,
710 RTE_FLOW_ERROR_TYPE_ATTR,
711 NULL, "NULL attribute.");
712 return -rte_errno;
713 }
714
715 item = next_no_void_pattern(pattern, NULL);
716 /* The first non-void item should be MAC. */
717 if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
718 rte_flow_error_set(error, EINVAL,
719 RTE_FLOW_ERROR_TYPE_ITEM,
720 item, "Not supported by ethertype filter");
721 return -rte_errno;
722 }
723
724 /*Not supported last point for range*/
725 if (item->last) {
726 rte_flow_error_set(error, EINVAL,
727 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
728 item, "Not supported last point for range");
729 return -rte_errno;
730 }
731
732 /* Get the MAC info. */
733 if (!item->spec || !item->mask) {
734 rte_flow_error_set(error, EINVAL,
735 RTE_FLOW_ERROR_TYPE_ITEM,
736 item, "Not supported by ethertype filter");
737 return -rte_errno;
738 }
739
740 eth_spec = item->spec;
741 eth_mask = item->mask;
742
743 /* Mask bits of source MAC address must be full of 0.
744 * Mask bits of destination MAC address must be full
745 * of 1 or full of 0.
746 */
747 if (!rte_is_zero_ether_addr(&eth_mask->src) ||
748 (!rte_is_zero_ether_addr(&eth_mask->dst) &&
749 !rte_is_broadcast_ether_addr(&eth_mask->dst))) {
750 rte_flow_error_set(error, EINVAL,
751 RTE_FLOW_ERROR_TYPE_ITEM,
752 item, "Invalid ether address mask");
753 return -rte_errno;
754 }
755
756 if ((eth_mask->type & UINT16_MAX) != UINT16_MAX) {
757 rte_flow_error_set(error, EINVAL,
758 RTE_FLOW_ERROR_TYPE_ITEM,
759 item, "Invalid ethertype mask");
760 return -rte_errno;
761 }
762
763 /* If mask bits of destination MAC address
764 * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
765 */
766 if (rte_is_broadcast_ether_addr(&eth_mask->dst)) {
767 filter->mac_addr = eth_spec->dst;
768 filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
769 } else {
770 filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
771 }
772 filter->ether_type = rte_be_to_cpu_16(eth_spec->type);
773
774 /* Check if the next non-void item is END. */
775 item = next_no_void_pattern(pattern, item);
776 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
777 rte_flow_error_set(error, EINVAL,
778 RTE_FLOW_ERROR_TYPE_ITEM,
779 item, "Not supported by ethertype filter.");
780 return -rte_errno;
781 }
782
783 /* Parse action */
784
785 act = next_no_void_action(actions, NULL);
786 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
787 act->type != RTE_FLOW_ACTION_TYPE_DROP) {
788 rte_flow_error_set(error, EINVAL,
789 RTE_FLOW_ERROR_TYPE_ACTION,
790 act, "Not supported action.");
791 return -rte_errno;
792 }
793
794 if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
795 act_q = (const struct rte_flow_action_queue *)act->conf;
796 filter->queue = act_q->index;
797 } else {
798 filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
799 }
800
801 /* Check if the next non-void item is END */
802 act = next_no_void_action(actions, act);
803 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
804 rte_flow_error_set(error, EINVAL,
805 RTE_FLOW_ERROR_TYPE_ACTION,
806 act, "Not supported action.");
807 return -rte_errno;
808 }
809
810 /* Parse attr */
811 /* Must be input direction */
812 if (!attr->ingress) {
813 rte_flow_error_set(error, EINVAL,
814 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
815 attr, "Only support ingress.");
816 return -rte_errno;
817 }
818
819 /* Not supported */
820 if (attr->egress) {
821 rte_flow_error_set(error, EINVAL,
822 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
823 attr, "Not support egress.");
824 return -rte_errno;
825 }
826
827 /* Not supported */
828 if (attr->transfer) {
829 rte_flow_error_set(error, EINVAL,
830 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
831 attr, "No support for transfer.");
832 return -rte_errno;
833 }
834
835 /* Not supported */
836 if (attr->priority) {
837 rte_flow_error_set(error, EINVAL,
838 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
839 attr, "Not support priority.");
840 return -rte_errno;
841 }
842
843 /* Not supported */
844 if (attr->group) {
845 rte_flow_error_set(error, EINVAL,
846 RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
847 attr, "Not support group.");
848 return -rte_errno;
849 }
850
851 return 0;
852 }
853
854 static int
855 ixgbe_parse_ethertype_filter(struct rte_eth_dev *dev,
856 const struct rte_flow_attr *attr,
857 const struct rte_flow_item pattern[],
858 const struct rte_flow_action actions[],
859 struct rte_eth_ethertype_filter *filter,
860 struct rte_flow_error *error)
861 {
862 int ret;
863 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
864
865 MAC_TYPE_FILTER_SUP(hw->mac.type);
866
867 ret = cons_parse_ethertype_filter(attr, pattern,
868 actions, filter, error);
869
870 if (ret)
871 return ret;
872
873 /* Ixgbe doesn't support MAC address. */
874 if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
875 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
876 rte_flow_error_set(error, EINVAL,
877 RTE_FLOW_ERROR_TYPE_ITEM,
878 NULL, "Not supported by ethertype filter");
879 return -rte_errno;
880 }
881
882 if (filter->queue >= dev->data->nb_rx_queues) {
883 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
884 rte_flow_error_set(error, EINVAL,
885 RTE_FLOW_ERROR_TYPE_ITEM,
886 NULL, "queue index much too big");
887 return -rte_errno;
888 }
889
890 if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
891 filter->ether_type == RTE_ETHER_TYPE_IPV6) {
892 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
893 rte_flow_error_set(error, EINVAL,
894 RTE_FLOW_ERROR_TYPE_ITEM,
895 NULL, "IPv4/IPv6 not supported by ethertype filter");
896 return -rte_errno;
897 }
898
899 if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
900 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
901 rte_flow_error_set(error, EINVAL,
902 RTE_FLOW_ERROR_TYPE_ITEM,
903 NULL, "mac compare is unsupported");
904 return -rte_errno;
905 }
906
907 if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
908 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
909 rte_flow_error_set(error, EINVAL,
910 RTE_FLOW_ERROR_TYPE_ITEM,
911 NULL, "drop option is unsupported");
912 return -rte_errno;
913 }
914
915 return 0;
916 }
917
918 /**
919 * Parse the rule to see if it is a TCP SYN rule.
920 * And get the TCP SYN filter info BTW.
921 * pattern:
922 * The first not void item must be ETH.
923 * The second not void item must be IPV4 or IPV6.
924 * The third not void item must be TCP.
925 * The next not void item must be END.
926 * action:
927 * The first not void action should be QUEUE.
928 * The next not void action should be END.
929 * pattern example:
930 * ITEM Spec Mask
931 * ETH NULL NULL
932 * IPV4/IPV6 NULL NULL
933 * TCP tcp_flags 0x02 0xFF
934 * END
935 * other members in mask and spec should set to 0x00.
936 * item->last should be NULL.
937 */
938 static int
939 cons_parse_syn_filter(const struct rte_flow_attr *attr,
940 const struct rte_flow_item pattern[],
941 const struct rte_flow_action actions[],
942 struct rte_eth_syn_filter *filter,
943 struct rte_flow_error *error)
944 {
945 const struct rte_flow_item *item;
946 const struct rte_flow_action *act;
947 const struct rte_flow_item_tcp *tcp_spec;
948 const struct rte_flow_item_tcp *tcp_mask;
949 const struct rte_flow_action_queue *act_q;
950
951 if (!pattern) {
952 rte_flow_error_set(error, EINVAL,
953 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
954 NULL, "NULL pattern.");
955 return -rte_errno;
956 }
957
958 if (!actions) {
959 rte_flow_error_set(error, EINVAL,
960 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
961 NULL, "NULL action.");
962 return -rte_errno;
963 }
964
965 if (!attr) {
966 rte_flow_error_set(error, EINVAL,
967 RTE_FLOW_ERROR_TYPE_ATTR,
968 NULL, "NULL attribute.");
969 return -rte_errno;
970 }
971
972
973 /* the first not void item should be MAC or IPv4 or IPv6 or TCP */
974 item = next_no_void_pattern(pattern, NULL);
975 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
976 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
977 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
978 item->type != RTE_FLOW_ITEM_TYPE_TCP) {
979 rte_flow_error_set(error, EINVAL,
980 RTE_FLOW_ERROR_TYPE_ITEM,
981 item, "Not supported by syn filter");
982 return -rte_errno;
983 }
984 /*Not supported last point for range*/
985 if (item->last) {
986 rte_flow_error_set(error, EINVAL,
987 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
988 item, "Not supported last point for range");
989 return -rte_errno;
990 }
991
992 /* Skip Ethernet */
993 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
994 /* if the item is MAC, the content should be NULL */
995 if (item->spec || item->mask) {
996 rte_flow_error_set(error, EINVAL,
997 RTE_FLOW_ERROR_TYPE_ITEM,
998 item, "Invalid SYN address mask");
999 return -rte_errno;
1000 }
1001
1002 /* check if the next not void item is IPv4 or IPv6 */
1003 item = next_no_void_pattern(pattern, item);
1004 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1005 item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
1006 rte_flow_error_set(error, EINVAL,
1007 RTE_FLOW_ERROR_TYPE_ITEM,
1008 item, "Not supported by syn filter");
1009 return -rte_errno;
1010 }
1011 }
1012
1013 /* Skip IP */
1014 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
1015 item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
1016 /* if the item is IP, the content should be NULL */
1017 if (item->spec || item->mask) {
1018 rte_flow_error_set(error, EINVAL,
1019 RTE_FLOW_ERROR_TYPE_ITEM,
1020 item, "Invalid SYN mask");
1021 return -rte_errno;
1022 }
1023
1024 /* check if the next not void item is TCP */
1025 item = next_no_void_pattern(pattern, item);
1026 if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
1027 rte_flow_error_set(error, EINVAL,
1028 RTE_FLOW_ERROR_TYPE_ITEM,
1029 item, "Not supported by syn filter");
1030 return -rte_errno;
1031 }
1032 }
1033
1034 /* Get the TCP info. Only support SYN. */
1035 if (!item->spec || !item->mask) {
1036 rte_flow_error_set(error, EINVAL,
1037 RTE_FLOW_ERROR_TYPE_ITEM,
1038 item, "Invalid SYN mask");
1039 return -rte_errno;
1040 }
1041 /*Not supported last point for range*/
1042 if (item->last) {
1043 rte_flow_error_set(error, EINVAL,
1044 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1045 item, "Not supported last point for range");
1046 return -rte_errno;
1047 }
1048
1049 tcp_spec = item->spec;
1050 tcp_mask = item->mask;
1051 if (!(tcp_spec->hdr.tcp_flags & RTE_TCP_SYN_FLAG) ||
1052 tcp_mask->hdr.src_port ||
1053 tcp_mask->hdr.dst_port ||
1054 tcp_mask->hdr.sent_seq ||
1055 tcp_mask->hdr.recv_ack ||
1056 tcp_mask->hdr.data_off ||
1057 tcp_mask->hdr.tcp_flags != RTE_TCP_SYN_FLAG ||
1058 tcp_mask->hdr.rx_win ||
1059 tcp_mask->hdr.cksum ||
1060 tcp_mask->hdr.tcp_urp) {
1061 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1062 rte_flow_error_set(error, EINVAL,
1063 RTE_FLOW_ERROR_TYPE_ITEM,
1064 item, "Not supported by syn filter");
1065 return -rte_errno;
1066 }
1067
1068 /* check if the next not void item is END */
1069 item = next_no_void_pattern(pattern, item);
1070 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1071 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1072 rte_flow_error_set(error, EINVAL,
1073 RTE_FLOW_ERROR_TYPE_ITEM,
1074 item, "Not supported by syn filter");
1075 return -rte_errno;
1076 }
1077
1078 /* check if the first not void action is QUEUE. */
1079 act = next_no_void_action(actions, NULL);
1080 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1081 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1082 rte_flow_error_set(error, EINVAL,
1083 RTE_FLOW_ERROR_TYPE_ACTION,
1084 act, "Not supported action.");
1085 return -rte_errno;
1086 }
1087
1088 act_q = (const struct rte_flow_action_queue *)act->conf;
1089 filter->queue = act_q->index;
1090 if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM) {
1091 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1092 rte_flow_error_set(error, EINVAL,
1093 RTE_FLOW_ERROR_TYPE_ACTION,
1094 act, "Not supported action.");
1095 return -rte_errno;
1096 }
1097
1098 /* check if the next not void item is END */
1099 act = next_no_void_action(actions, act);
1100 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1101 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1102 rte_flow_error_set(error, EINVAL,
1103 RTE_FLOW_ERROR_TYPE_ACTION,
1104 act, "Not supported action.");
1105 return -rte_errno;
1106 }
1107
1108 /* parse attr */
1109 /* must be input direction */
1110 if (!attr->ingress) {
1111 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1112 rte_flow_error_set(error, EINVAL,
1113 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1114 attr, "Only support ingress.");
1115 return -rte_errno;
1116 }
1117
1118 /* not supported */
1119 if (attr->egress) {
1120 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1121 rte_flow_error_set(error, EINVAL,
1122 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1123 attr, "Not support egress.");
1124 return -rte_errno;
1125 }
1126
1127 /* not supported */
1128 if (attr->transfer) {
1129 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1130 rte_flow_error_set(error, EINVAL,
1131 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1132 attr, "No support for transfer.");
1133 return -rte_errno;
1134 }
1135
1136 /* Support 2 priorities, the lowest or highest. */
1137 if (!attr->priority) {
1138 filter->hig_pri = 0;
1139 } else if (attr->priority == (uint32_t)~0U) {
1140 filter->hig_pri = 1;
1141 } else {
1142 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1143 rte_flow_error_set(error, EINVAL,
1144 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1145 attr, "Not support priority.");
1146 return -rte_errno;
1147 }
1148
1149 return 0;
1150 }
1151
1152 static int
1153 ixgbe_parse_syn_filter(struct rte_eth_dev *dev,
1154 const struct rte_flow_attr *attr,
1155 const struct rte_flow_item pattern[],
1156 const struct rte_flow_action actions[],
1157 struct rte_eth_syn_filter *filter,
1158 struct rte_flow_error *error)
1159 {
1160 int ret;
1161 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1162
1163 MAC_TYPE_FILTER_SUP(hw->mac.type);
1164
1165 ret = cons_parse_syn_filter(attr, pattern,
1166 actions, filter, error);
1167
1168 if (filter->queue >= dev->data->nb_rx_queues)
1169 return -rte_errno;
1170
1171 if (ret)
1172 return ret;
1173
1174 return 0;
1175 }
1176
1177 /**
1178 * Parse the rule to see if it is a L2 tunnel rule.
1179 * And get the L2 tunnel filter info BTW.
1180 * Only support E-tag now.
1181 * pattern:
1182 * The first not void item can be E_TAG.
1183 * The next not void item must be END.
1184 * action:
1185 * The first not void action should be VF or PF.
1186 * The next not void action should be END.
1187 * pattern example:
1188 * ITEM Spec Mask
1189 * E_TAG grp 0x1 0x3
1190 e_cid_base 0x309 0xFFF
1191 * END
1192 * other members in mask and spec should set to 0x00.
1193 * item->last should be NULL.
1194 */
1195 static int
1196 cons_parse_l2_tn_filter(struct rte_eth_dev *dev,
1197 const struct rte_flow_attr *attr,
1198 const struct rte_flow_item pattern[],
1199 const struct rte_flow_action actions[],
1200 struct rte_eth_l2_tunnel_conf *filter,
1201 struct rte_flow_error *error)
1202 {
1203 const struct rte_flow_item *item;
1204 const struct rte_flow_item_e_tag *e_tag_spec;
1205 const struct rte_flow_item_e_tag *e_tag_mask;
1206 const struct rte_flow_action *act;
1207 const struct rte_flow_action_vf *act_vf;
1208 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1209
1210 if (!pattern) {
1211 rte_flow_error_set(error, EINVAL,
1212 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1213 NULL, "NULL pattern.");
1214 return -rte_errno;
1215 }
1216
1217 if (!actions) {
1218 rte_flow_error_set(error, EINVAL,
1219 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1220 NULL, "NULL action.");
1221 return -rte_errno;
1222 }
1223
1224 if (!attr) {
1225 rte_flow_error_set(error, EINVAL,
1226 RTE_FLOW_ERROR_TYPE_ATTR,
1227 NULL, "NULL attribute.");
1228 return -rte_errno;
1229 }
1230
1231 /* The first not void item should be e-tag. */
1232 item = next_no_void_pattern(pattern, NULL);
1233 if (item->type != RTE_FLOW_ITEM_TYPE_E_TAG) {
1234 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1235 rte_flow_error_set(error, EINVAL,
1236 RTE_FLOW_ERROR_TYPE_ITEM,
1237 item, "Not supported by L2 tunnel filter");
1238 return -rte_errno;
1239 }
1240
1241 if (!item->spec || !item->mask) {
1242 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1243 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1244 item, "Not supported by L2 tunnel filter");
1245 return -rte_errno;
1246 }
1247
1248 /*Not supported last point for range*/
1249 if (item->last) {
1250 rte_flow_error_set(error, EINVAL,
1251 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1252 item, "Not supported last point for range");
1253 return -rte_errno;
1254 }
1255
1256 e_tag_spec = item->spec;
1257 e_tag_mask = item->mask;
1258
1259 /* Only care about GRP and E cid base. */
1260 if (e_tag_mask->epcp_edei_in_ecid_b ||
1261 e_tag_mask->in_ecid_e ||
1262 e_tag_mask->ecid_e ||
1263 e_tag_mask->rsvd_grp_ecid_b != rte_cpu_to_be_16(0x3FFF)) {
1264 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1265 rte_flow_error_set(error, EINVAL,
1266 RTE_FLOW_ERROR_TYPE_ITEM,
1267 item, "Not supported by L2 tunnel filter");
1268 return -rte_errno;
1269 }
1270
1271 filter->l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
1272 /**
1273 * grp and e_cid_base are bit fields and only use 14 bits.
1274 * e-tag id is taken as little endian by HW.
1275 */
1276 filter->tunnel_id = rte_be_to_cpu_16(e_tag_spec->rsvd_grp_ecid_b);
1277
1278 /* check if the next not void item is END */
1279 item = next_no_void_pattern(pattern, item);
1280 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1281 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1282 rte_flow_error_set(error, EINVAL,
1283 RTE_FLOW_ERROR_TYPE_ITEM,
1284 item, "Not supported by L2 tunnel filter");
1285 return -rte_errno;
1286 }
1287
1288 /* parse attr */
1289 /* must be input direction */
1290 if (!attr->ingress) {
1291 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1292 rte_flow_error_set(error, EINVAL,
1293 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1294 attr, "Only support ingress.");
1295 return -rte_errno;
1296 }
1297
1298 /* not supported */
1299 if (attr->egress) {
1300 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1301 rte_flow_error_set(error, EINVAL,
1302 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1303 attr, "Not support egress.");
1304 return -rte_errno;
1305 }
1306
1307 /* not supported */
1308 if (attr->transfer) {
1309 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1310 rte_flow_error_set(error, EINVAL,
1311 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1312 attr, "No support for transfer.");
1313 return -rte_errno;
1314 }
1315
1316 /* not supported */
1317 if (attr->priority) {
1318 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1319 rte_flow_error_set(error, EINVAL,
1320 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1321 attr, "Not support priority.");
1322 return -rte_errno;
1323 }
1324
1325 /* check if the first not void action is VF or PF. */
1326 act = next_no_void_action(actions, NULL);
1327 if (act->type != RTE_FLOW_ACTION_TYPE_VF &&
1328 act->type != RTE_FLOW_ACTION_TYPE_PF) {
1329 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1330 rte_flow_error_set(error, EINVAL,
1331 RTE_FLOW_ERROR_TYPE_ACTION,
1332 act, "Not supported action.");
1333 return -rte_errno;
1334 }
1335
1336 if (act->type == RTE_FLOW_ACTION_TYPE_VF) {
1337 act_vf = (const struct rte_flow_action_vf *)act->conf;
1338 filter->pool = act_vf->id;
1339 } else {
1340 filter->pool = pci_dev->max_vfs;
1341 }
1342
1343 /* check if the next not void item is END */
1344 act = next_no_void_action(actions, act);
1345 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1346 memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1347 rte_flow_error_set(error, EINVAL,
1348 RTE_FLOW_ERROR_TYPE_ACTION,
1349 act, "Not supported action.");
1350 return -rte_errno;
1351 }
1352
1353 return 0;
1354 }
1355
1356 static int
1357 ixgbe_parse_l2_tn_filter(struct rte_eth_dev *dev,
1358 const struct rte_flow_attr *attr,
1359 const struct rte_flow_item pattern[],
1360 const struct rte_flow_action actions[],
1361 struct rte_eth_l2_tunnel_conf *l2_tn_filter,
1362 struct rte_flow_error *error)
1363 {
1364 int ret = 0;
1365 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1366 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1367 uint16_t vf_num;
1368
1369 ret = cons_parse_l2_tn_filter(dev, attr, pattern,
1370 actions, l2_tn_filter, error);
1371
1372 if (hw->mac.type != ixgbe_mac_X550 &&
1373 hw->mac.type != ixgbe_mac_X550EM_x &&
1374 hw->mac.type != ixgbe_mac_X550EM_a) {
1375 memset(l2_tn_filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
1376 rte_flow_error_set(error, EINVAL,
1377 RTE_FLOW_ERROR_TYPE_ITEM,
1378 NULL, "Not supported by L2 tunnel filter");
1379 return -rte_errno;
1380 }
1381
1382 vf_num = pci_dev->max_vfs;
1383
1384 if (l2_tn_filter->pool > vf_num)
1385 return -rte_errno;
1386
1387 return ret;
1388 }
1389
1390 /* Parse to get the attr and action info of flow director rule. */
1391 static int
1392 ixgbe_parse_fdir_act_attr(const struct rte_flow_attr *attr,
1393 const struct rte_flow_action actions[],
1394 struct ixgbe_fdir_rule *rule,
1395 struct rte_flow_error *error)
1396 {
1397 const struct rte_flow_action *act;
1398 const struct rte_flow_action_queue *act_q;
1399 const struct rte_flow_action_mark *mark;
1400
1401 /* parse attr */
1402 /* must be input direction */
1403 if (!attr->ingress) {
1404 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1405 rte_flow_error_set(error, EINVAL,
1406 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1407 attr, "Only support ingress.");
1408 return -rte_errno;
1409 }
1410
1411 /* not supported */
1412 if (attr->egress) {
1413 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1414 rte_flow_error_set(error, EINVAL,
1415 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1416 attr, "Not support egress.");
1417 return -rte_errno;
1418 }
1419
1420 /* not supported */
1421 if (attr->transfer) {
1422 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1423 rte_flow_error_set(error, EINVAL,
1424 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1425 attr, "No support for transfer.");
1426 return -rte_errno;
1427 }
1428
1429 /* not supported */
1430 if (attr->priority) {
1431 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1432 rte_flow_error_set(error, EINVAL,
1433 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1434 attr, "Not support priority.");
1435 return -rte_errno;
1436 }
1437
1438 /* check if the first not void action is QUEUE or DROP. */
1439 act = next_no_void_action(actions, NULL);
1440 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
1441 act->type != RTE_FLOW_ACTION_TYPE_DROP) {
1442 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1443 rte_flow_error_set(error, EINVAL,
1444 RTE_FLOW_ERROR_TYPE_ACTION,
1445 act, "Not supported action.");
1446 return -rte_errno;
1447 }
1448
1449 if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
1450 act_q = (const struct rte_flow_action_queue *)act->conf;
1451 rule->queue = act_q->index;
1452 } else { /* drop */
1453 /* signature mode does not support drop action. */
1454 if (rule->mode == RTE_FDIR_MODE_SIGNATURE) {
1455 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1456 rte_flow_error_set(error, EINVAL,
1457 RTE_FLOW_ERROR_TYPE_ACTION,
1458 act, "Not supported action.");
1459 return -rte_errno;
1460 }
1461 rule->fdirflags = IXGBE_FDIRCMD_DROP;
1462 }
1463
1464 /* check if the next not void item is MARK */
1465 act = next_no_void_action(actions, act);
1466 if ((act->type != RTE_FLOW_ACTION_TYPE_MARK) &&
1467 (act->type != RTE_FLOW_ACTION_TYPE_END)) {
1468 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1469 rte_flow_error_set(error, EINVAL,
1470 RTE_FLOW_ERROR_TYPE_ACTION,
1471 act, "Not supported action.");
1472 return -rte_errno;
1473 }
1474
1475 rule->soft_id = 0;
1476
1477 if (act->type == RTE_FLOW_ACTION_TYPE_MARK) {
1478 mark = (const struct rte_flow_action_mark *)act->conf;
1479 rule->soft_id = mark->id;
1480 act = next_no_void_action(actions, act);
1481 }
1482
1483 /* check if the next not void item is END */
1484 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1485 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1486 rte_flow_error_set(error, EINVAL,
1487 RTE_FLOW_ERROR_TYPE_ACTION,
1488 act, "Not supported action.");
1489 return -rte_errno;
1490 }
1491
1492 return 0;
1493 }
1494
1495 /* search next no void pattern and skip fuzzy */
1496 static inline
1497 const struct rte_flow_item *next_no_fuzzy_pattern(
1498 const struct rte_flow_item pattern[],
1499 const struct rte_flow_item *cur)
1500 {
1501 const struct rte_flow_item *next =
1502 next_no_void_pattern(pattern, cur);
1503 while (1) {
1504 if (next->type != RTE_FLOW_ITEM_TYPE_FUZZY)
1505 return next;
1506 next = next_no_void_pattern(pattern, next);
1507 }
1508 }
1509
1510 static inline uint8_t signature_match(const struct rte_flow_item pattern[])
1511 {
1512 const struct rte_flow_item_fuzzy *spec, *last, *mask;
1513 const struct rte_flow_item *item;
1514 uint32_t sh, lh, mh;
1515 int i = 0;
1516
1517 while (1) {
1518 item = pattern + i;
1519 if (item->type == RTE_FLOW_ITEM_TYPE_END)
1520 break;
1521
1522 if (item->type == RTE_FLOW_ITEM_TYPE_FUZZY) {
1523 spec = item->spec;
1524 last = item->last;
1525 mask = item->mask;
1526
1527 if (!spec || !mask)
1528 return 0;
1529
1530 sh = spec->thresh;
1531
1532 if (!last)
1533 lh = sh;
1534 else
1535 lh = last->thresh;
1536
1537 mh = mask->thresh;
1538 sh = sh & mh;
1539 lh = lh & mh;
1540
1541 if (!sh || sh > lh)
1542 return 0;
1543
1544 return 1;
1545 }
1546
1547 i++;
1548 }
1549
1550 return 0;
1551 }
1552
1553 /**
1554 * Parse the rule to see if it is a IP or MAC VLAN flow director rule.
1555 * And get the flow director filter info BTW.
1556 * UDP/TCP/SCTP PATTERN:
1557 * The first not void item can be ETH or IPV4 or IPV6
1558 * The second not void item must be IPV4 or IPV6 if the first one is ETH.
1559 * The next not void item could be UDP or TCP or SCTP (optional)
1560 * The next not void item could be RAW (for flexbyte, optional)
1561 * The next not void item must be END.
1562 * A Fuzzy Match pattern can appear at any place before END.
1563 * Fuzzy Match is optional for IPV4 but is required for IPV6
1564 * MAC VLAN PATTERN:
1565 * The first not void item must be ETH.
1566 * The second not void item must be MAC VLAN.
1567 * The next not void item must be END.
1568 * ACTION:
1569 * The first not void action should be QUEUE or DROP.
1570 * The second not void optional action should be MARK,
1571 * mark_id is a uint32_t number.
1572 * The next not void action should be END.
1573 * UDP/TCP/SCTP pattern example:
1574 * ITEM Spec Mask
1575 * ETH NULL NULL
1576 * IPV4 src_addr 192.168.1.20 0xFFFFFFFF
1577 * dst_addr 192.167.3.50 0xFFFFFFFF
1578 * UDP/TCP/SCTP src_port 80 0xFFFF
1579 * dst_port 80 0xFFFF
1580 * FLEX relative 0 0x1
1581 * search 0 0x1
1582 * reserved 0 0
1583 * offset 12 0xFFFFFFFF
1584 * limit 0 0xFFFF
1585 * length 2 0xFFFF
1586 * pattern[0] 0x86 0xFF
1587 * pattern[1] 0xDD 0xFF
1588 * END
1589 * MAC VLAN pattern example:
1590 * ITEM Spec Mask
1591 * ETH dst_addr
1592 {0xAC, 0x7B, 0xA1, {0xFF, 0xFF, 0xFF,
1593 0x2C, 0x6D, 0x36} 0xFF, 0xFF, 0xFF}
1594 * MAC VLAN tci 0x2016 0xEFFF
1595 * END
1596 * Other members in mask and spec should set to 0x00.
1597 * Item->last should be NULL.
1598 */
1599 static int
1600 ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev,
1601 const struct rte_flow_attr *attr,
1602 const struct rte_flow_item pattern[],
1603 const struct rte_flow_action actions[],
1604 struct ixgbe_fdir_rule *rule,
1605 struct rte_flow_error *error)
1606 {
1607 const struct rte_flow_item *item;
1608 const struct rte_flow_item_eth *eth_spec;
1609 const struct rte_flow_item_eth *eth_mask;
1610 const struct rte_flow_item_ipv4 *ipv4_spec;
1611 const struct rte_flow_item_ipv4 *ipv4_mask;
1612 const struct rte_flow_item_ipv6 *ipv6_spec;
1613 const struct rte_flow_item_ipv6 *ipv6_mask;
1614 const struct rte_flow_item_tcp *tcp_spec;
1615 const struct rte_flow_item_tcp *tcp_mask;
1616 const struct rte_flow_item_udp *udp_spec;
1617 const struct rte_flow_item_udp *udp_mask;
1618 const struct rte_flow_item_sctp *sctp_spec;
1619 const struct rte_flow_item_sctp *sctp_mask;
1620 const struct rte_flow_item_vlan *vlan_spec;
1621 const struct rte_flow_item_vlan *vlan_mask;
1622 const struct rte_flow_item_raw *raw_mask;
1623 const struct rte_flow_item_raw *raw_spec;
1624 uint8_t j;
1625
1626 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1627
1628 if (!pattern) {
1629 rte_flow_error_set(error, EINVAL,
1630 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1631 NULL, "NULL pattern.");
1632 return -rte_errno;
1633 }
1634
1635 if (!actions) {
1636 rte_flow_error_set(error, EINVAL,
1637 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1638 NULL, "NULL action.");
1639 return -rte_errno;
1640 }
1641
1642 if (!attr) {
1643 rte_flow_error_set(error, EINVAL,
1644 RTE_FLOW_ERROR_TYPE_ATTR,
1645 NULL, "NULL attribute.");
1646 return -rte_errno;
1647 }
1648
1649 /**
1650 * Some fields may not be provided. Set spec to 0 and mask to default
1651 * value. So, we need not do anything for the not provided fields later.
1652 */
1653 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1654 memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
1655 rule->mask.vlan_tci_mask = 0;
1656 rule->mask.flex_bytes_mask = 0;
1657
1658 /**
1659 * The first not void item should be
1660 * MAC or IPv4 or TCP or UDP or SCTP.
1661 */
1662 item = next_no_fuzzy_pattern(pattern, NULL);
1663 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
1664 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1665 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
1666 item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1667 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1668 item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
1669 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1670 rte_flow_error_set(error, EINVAL,
1671 RTE_FLOW_ERROR_TYPE_ITEM,
1672 item, "Not supported by fdir filter");
1673 return -rte_errno;
1674 }
1675
1676 if (signature_match(pattern))
1677 rule->mode = RTE_FDIR_MODE_SIGNATURE;
1678 else
1679 rule->mode = RTE_FDIR_MODE_PERFECT;
1680
1681 /*Not supported last point for range*/
1682 if (item->last) {
1683 rte_flow_error_set(error, EINVAL,
1684 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1685 item, "Not supported last point for range");
1686 return -rte_errno;
1687 }
1688
1689 /* Get the MAC info. */
1690 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
1691 /**
1692 * Only support vlan and dst MAC address,
1693 * others should be masked.
1694 */
1695 if (item->spec && !item->mask) {
1696 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1697 rte_flow_error_set(error, EINVAL,
1698 RTE_FLOW_ERROR_TYPE_ITEM,
1699 item, "Not supported by fdir filter");
1700 return -rte_errno;
1701 }
1702
1703 if (item->spec) {
1704 rule->b_spec = TRUE;
1705 eth_spec = item->spec;
1706
1707 /* Get the dst MAC. */
1708 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
1709 rule->ixgbe_fdir.formatted.inner_mac[j] =
1710 eth_spec->dst.addr_bytes[j];
1711 }
1712 }
1713
1714
1715 if (item->mask) {
1716
1717 rule->b_mask = TRUE;
1718 eth_mask = item->mask;
1719
1720 /* Ether type should be masked. */
1721 if (eth_mask->type ||
1722 rule->mode == RTE_FDIR_MODE_SIGNATURE) {
1723 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1724 rte_flow_error_set(error, EINVAL,
1725 RTE_FLOW_ERROR_TYPE_ITEM,
1726 item, "Not supported by fdir filter");
1727 return -rte_errno;
1728 }
1729
1730 /* If ethernet has meaning, it means MAC VLAN mode. */
1731 rule->mode = RTE_FDIR_MODE_PERFECT_MAC_VLAN;
1732
1733 /**
1734 * src MAC address must be masked,
1735 * and don't support dst MAC address mask.
1736 */
1737 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
1738 if (eth_mask->src.addr_bytes[j] ||
1739 eth_mask->dst.addr_bytes[j] != 0xFF) {
1740 memset(rule, 0,
1741 sizeof(struct ixgbe_fdir_rule));
1742 rte_flow_error_set(error, EINVAL,
1743 RTE_FLOW_ERROR_TYPE_ITEM,
1744 item, "Not supported by fdir filter");
1745 return -rte_errno;
1746 }
1747 }
1748
1749 /* When no VLAN, considered as full mask. */
1750 rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
1751 }
1752 /*** If both spec and mask are item,
1753 * it means don't care about ETH.
1754 * Do nothing.
1755 */
1756
1757 /**
1758 * Check if the next not void item is vlan or ipv4.
1759 * IPv6 is not supported.
1760 */
1761 item = next_no_fuzzy_pattern(pattern, item);
1762 if (rule->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
1763 if (item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
1764 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1765 rte_flow_error_set(error, EINVAL,
1766 RTE_FLOW_ERROR_TYPE_ITEM,
1767 item, "Not supported by fdir filter");
1768 return -rte_errno;
1769 }
1770 } else {
1771 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1772 item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
1773 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1774 rte_flow_error_set(error, EINVAL,
1775 RTE_FLOW_ERROR_TYPE_ITEM,
1776 item, "Not supported by fdir filter");
1777 return -rte_errno;
1778 }
1779 }
1780 }
1781
1782 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1783 if (!(item->spec && item->mask)) {
1784 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1785 rte_flow_error_set(error, EINVAL,
1786 RTE_FLOW_ERROR_TYPE_ITEM,
1787 item, "Not supported by fdir filter");
1788 return -rte_errno;
1789 }
1790
1791 /*Not supported last point for range*/
1792 if (item->last) {
1793 rte_flow_error_set(error, EINVAL,
1794 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1795 item, "Not supported last point for range");
1796 return -rte_errno;
1797 }
1798
1799 vlan_spec = item->spec;
1800 vlan_mask = item->mask;
1801
1802 rule->ixgbe_fdir.formatted.vlan_id = vlan_spec->tci;
1803
1804 rule->mask.vlan_tci_mask = vlan_mask->tci;
1805 rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
1806 /* More than one tags are not supported. */
1807
1808 /* Next not void item must be END */
1809 item = next_no_fuzzy_pattern(pattern, item);
1810 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1811 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1812 rte_flow_error_set(error, EINVAL,
1813 RTE_FLOW_ERROR_TYPE_ITEM,
1814 item, "Not supported by fdir filter");
1815 return -rte_errno;
1816 }
1817 }
1818
1819 /* Get the IPV4 info. */
1820 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1821 /**
1822 * Set the flow type even if there's no content
1823 * as we must have a flow type.
1824 */
1825 rule->ixgbe_fdir.formatted.flow_type =
1826 IXGBE_ATR_FLOW_TYPE_IPV4;
1827 /*Not supported last point for range*/
1828 if (item->last) {
1829 rte_flow_error_set(error, EINVAL,
1830 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1831 item, "Not supported last point for range");
1832 return -rte_errno;
1833 }
1834 /**
1835 * Only care about src & dst addresses,
1836 * others should be masked.
1837 */
1838 if (!item->mask) {
1839 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1840 rte_flow_error_set(error, EINVAL,
1841 RTE_FLOW_ERROR_TYPE_ITEM,
1842 item, "Not supported by fdir filter");
1843 return -rte_errno;
1844 }
1845 rule->b_mask = TRUE;
1846 ipv4_mask = item->mask;
1847 if (ipv4_mask->hdr.version_ihl ||
1848 ipv4_mask->hdr.type_of_service ||
1849 ipv4_mask->hdr.total_length ||
1850 ipv4_mask->hdr.packet_id ||
1851 ipv4_mask->hdr.fragment_offset ||
1852 ipv4_mask->hdr.time_to_live ||
1853 ipv4_mask->hdr.next_proto_id ||
1854 ipv4_mask->hdr.hdr_checksum) {
1855 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1856 rte_flow_error_set(error, EINVAL,
1857 RTE_FLOW_ERROR_TYPE_ITEM,
1858 item, "Not supported by fdir filter");
1859 return -rte_errno;
1860 }
1861 rule->mask.dst_ipv4_mask = ipv4_mask->hdr.dst_addr;
1862 rule->mask.src_ipv4_mask = ipv4_mask->hdr.src_addr;
1863
1864 if (item->spec) {
1865 rule->b_spec = TRUE;
1866 ipv4_spec = item->spec;
1867 rule->ixgbe_fdir.formatted.dst_ip[0] =
1868 ipv4_spec->hdr.dst_addr;
1869 rule->ixgbe_fdir.formatted.src_ip[0] =
1870 ipv4_spec->hdr.src_addr;
1871 }
1872
1873 /**
1874 * Check if the next not void item is
1875 * TCP or UDP or SCTP or END.
1876 */
1877 item = next_no_fuzzy_pattern(pattern, item);
1878 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1879 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1880 item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
1881 item->type != RTE_FLOW_ITEM_TYPE_END &&
1882 item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1883 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1884 rte_flow_error_set(error, EINVAL,
1885 RTE_FLOW_ERROR_TYPE_ITEM,
1886 item, "Not supported by fdir filter");
1887 return -rte_errno;
1888 }
1889 }
1890
1891 /* Get the IPV6 info. */
1892 if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
1893 /**
1894 * Set the flow type even if there's no content
1895 * as we must have a flow type.
1896 */
1897 rule->ixgbe_fdir.formatted.flow_type =
1898 IXGBE_ATR_FLOW_TYPE_IPV6;
1899
1900 /**
1901 * 1. must signature match
1902 * 2. not support last
1903 * 3. mask must not null
1904 */
1905 if (rule->mode != RTE_FDIR_MODE_SIGNATURE ||
1906 item->last ||
1907 !item->mask) {
1908 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1909 rte_flow_error_set(error, EINVAL,
1910 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1911 item, "Not supported last point for range");
1912 return -rte_errno;
1913 }
1914
1915 rule->b_mask = TRUE;
1916 ipv6_mask = item->mask;
1917 if (ipv6_mask->hdr.vtc_flow ||
1918 ipv6_mask->hdr.payload_len ||
1919 ipv6_mask->hdr.proto ||
1920 ipv6_mask->hdr.hop_limits) {
1921 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1922 rte_flow_error_set(error, EINVAL,
1923 RTE_FLOW_ERROR_TYPE_ITEM,
1924 item, "Not supported by fdir filter");
1925 return -rte_errno;
1926 }
1927
1928 /* check src addr mask */
1929 for (j = 0; j < 16; j++) {
1930 if (ipv6_mask->hdr.src_addr[j] == UINT8_MAX) {
1931 rule->mask.src_ipv6_mask |= 1 << j;
1932 } else if (ipv6_mask->hdr.src_addr[j] != 0) {
1933 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1934 rte_flow_error_set(error, EINVAL,
1935 RTE_FLOW_ERROR_TYPE_ITEM,
1936 item, "Not supported by fdir filter");
1937 return -rte_errno;
1938 }
1939 }
1940
1941 /* check dst addr mask */
1942 for (j = 0; j < 16; j++) {
1943 if (ipv6_mask->hdr.dst_addr[j] == UINT8_MAX) {
1944 rule->mask.dst_ipv6_mask |= 1 << j;
1945 } else if (ipv6_mask->hdr.dst_addr[j] != 0) {
1946 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1947 rte_flow_error_set(error, EINVAL,
1948 RTE_FLOW_ERROR_TYPE_ITEM,
1949 item, "Not supported by fdir filter");
1950 return -rte_errno;
1951 }
1952 }
1953
1954 if (item->spec) {
1955 rule->b_spec = TRUE;
1956 ipv6_spec = item->spec;
1957 rte_memcpy(rule->ixgbe_fdir.formatted.src_ip,
1958 ipv6_spec->hdr.src_addr, 16);
1959 rte_memcpy(rule->ixgbe_fdir.formatted.dst_ip,
1960 ipv6_spec->hdr.dst_addr, 16);
1961 }
1962
1963 /**
1964 * Check if the next not void item is
1965 * TCP or UDP or SCTP or END.
1966 */
1967 item = next_no_fuzzy_pattern(pattern, item);
1968 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1969 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1970 item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
1971 item->type != RTE_FLOW_ITEM_TYPE_END &&
1972 item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1973 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1974 rte_flow_error_set(error, EINVAL,
1975 RTE_FLOW_ERROR_TYPE_ITEM,
1976 item, "Not supported by fdir filter");
1977 return -rte_errno;
1978 }
1979 }
1980
1981 /* Get the TCP info. */
1982 if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
1983 /**
1984 * Set the flow type even if there's no content
1985 * as we must have a flow type.
1986 */
1987 rule->ixgbe_fdir.formatted.flow_type |=
1988 IXGBE_ATR_L4TYPE_TCP;
1989 /*Not supported last point for range*/
1990 if (item->last) {
1991 rte_flow_error_set(error, EINVAL,
1992 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1993 item, "Not supported last point for range");
1994 return -rte_errno;
1995 }
1996 /**
1997 * Only care about src & dst ports,
1998 * others should be masked.
1999 */
2000 if (!item->mask) {
2001 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2002 rte_flow_error_set(error, EINVAL,
2003 RTE_FLOW_ERROR_TYPE_ITEM,
2004 item, "Not supported by fdir filter");
2005 return -rte_errno;
2006 }
2007 rule->b_mask = TRUE;
2008 tcp_mask = item->mask;
2009 if (tcp_mask->hdr.sent_seq ||
2010 tcp_mask->hdr.recv_ack ||
2011 tcp_mask->hdr.data_off ||
2012 tcp_mask->hdr.tcp_flags ||
2013 tcp_mask->hdr.rx_win ||
2014 tcp_mask->hdr.cksum ||
2015 tcp_mask->hdr.tcp_urp) {
2016 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2017 rte_flow_error_set(error, EINVAL,
2018 RTE_FLOW_ERROR_TYPE_ITEM,
2019 item, "Not supported by fdir filter");
2020 return -rte_errno;
2021 }
2022 rule->mask.src_port_mask = tcp_mask->hdr.src_port;
2023 rule->mask.dst_port_mask = tcp_mask->hdr.dst_port;
2024
2025 if (item->spec) {
2026 rule->b_spec = TRUE;
2027 tcp_spec = item->spec;
2028 rule->ixgbe_fdir.formatted.src_port =
2029 tcp_spec->hdr.src_port;
2030 rule->ixgbe_fdir.formatted.dst_port =
2031 tcp_spec->hdr.dst_port;
2032 }
2033
2034 item = next_no_fuzzy_pattern(pattern, item);
2035 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
2036 item->type != RTE_FLOW_ITEM_TYPE_END) {
2037 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2038 rte_flow_error_set(error, EINVAL,
2039 RTE_FLOW_ERROR_TYPE_ITEM,
2040 item, "Not supported by fdir filter");
2041 return -rte_errno;
2042 }
2043
2044 }
2045
2046 /* Get the UDP info */
2047 if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
2048 /**
2049 * Set the flow type even if there's no content
2050 * as we must have a flow type.
2051 */
2052 rule->ixgbe_fdir.formatted.flow_type |=
2053 IXGBE_ATR_L4TYPE_UDP;
2054 /*Not supported last point for range*/
2055 if (item->last) {
2056 rte_flow_error_set(error, EINVAL,
2057 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2058 item, "Not supported last point for range");
2059 return -rte_errno;
2060 }
2061 /**
2062 * Only care about src & dst ports,
2063 * others should be masked.
2064 */
2065 if (!item->mask) {
2066 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2067 rte_flow_error_set(error, EINVAL,
2068 RTE_FLOW_ERROR_TYPE_ITEM,
2069 item, "Not supported by fdir filter");
2070 return -rte_errno;
2071 }
2072 rule->b_mask = TRUE;
2073 udp_mask = item->mask;
2074 if (udp_mask->hdr.dgram_len ||
2075 udp_mask->hdr.dgram_cksum) {
2076 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2077 rte_flow_error_set(error, EINVAL,
2078 RTE_FLOW_ERROR_TYPE_ITEM,
2079 item, "Not supported by fdir filter");
2080 return -rte_errno;
2081 }
2082 rule->mask.src_port_mask = udp_mask->hdr.src_port;
2083 rule->mask.dst_port_mask = udp_mask->hdr.dst_port;
2084
2085 if (item->spec) {
2086 rule->b_spec = TRUE;
2087 udp_spec = item->spec;
2088 rule->ixgbe_fdir.formatted.src_port =
2089 udp_spec->hdr.src_port;
2090 rule->ixgbe_fdir.formatted.dst_port =
2091 udp_spec->hdr.dst_port;
2092 }
2093
2094 item = next_no_fuzzy_pattern(pattern, item);
2095 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
2096 item->type != RTE_FLOW_ITEM_TYPE_END) {
2097 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2098 rte_flow_error_set(error, EINVAL,
2099 RTE_FLOW_ERROR_TYPE_ITEM,
2100 item, "Not supported by fdir filter");
2101 return -rte_errno;
2102 }
2103
2104 }
2105
2106 /* Get the SCTP info */
2107 if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) {
2108 /**
2109 * Set the flow type even if there's no content
2110 * as we must have a flow type.
2111 */
2112 rule->ixgbe_fdir.formatted.flow_type |=
2113 IXGBE_ATR_L4TYPE_SCTP;
2114 /*Not supported last point for range*/
2115 if (item->last) {
2116 rte_flow_error_set(error, EINVAL,
2117 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2118 item, "Not supported last point for range");
2119 return -rte_errno;
2120 }
2121
2122 /* only x550 family only support sctp port */
2123 if (hw->mac.type == ixgbe_mac_X550 ||
2124 hw->mac.type == ixgbe_mac_X550EM_x ||
2125 hw->mac.type == ixgbe_mac_X550EM_a) {
2126 /**
2127 * Only care about src & dst ports,
2128 * others should be masked.
2129 */
2130 if (!item->mask) {
2131 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2132 rte_flow_error_set(error, EINVAL,
2133 RTE_FLOW_ERROR_TYPE_ITEM,
2134 item, "Not supported by fdir filter");
2135 return -rte_errno;
2136 }
2137 rule->b_mask = TRUE;
2138 sctp_mask = item->mask;
2139 if (sctp_mask->hdr.tag ||
2140 sctp_mask->hdr.cksum) {
2141 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2142 rte_flow_error_set(error, EINVAL,
2143 RTE_FLOW_ERROR_TYPE_ITEM,
2144 item, "Not supported by fdir filter");
2145 return -rte_errno;
2146 }
2147 rule->mask.src_port_mask = sctp_mask->hdr.src_port;
2148 rule->mask.dst_port_mask = sctp_mask->hdr.dst_port;
2149
2150 if (item->spec) {
2151 rule->b_spec = TRUE;
2152 sctp_spec = item->spec;
2153 rule->ixgbe_fdir.formatted.src_port =
2154 sctp_spec->hdr.src_port;
2155 rule->ixgbe_fdir.formatted.dst_port =
2156 sctp_spec->hdr.dst_port;
2157 }
2158 /* others even sctp port is not supported */
2159 } else {
2160 sctp_mask = item->mask;
2161 if (sctp_mask &&
2162 (sctp_mask->hdr.src_port ||
2163 sctp_mask->hdr.dst_port ||
2164 sctp_mask->hdr.tag ||
2165 sctp_mask->hdr.cksum)) {
2166 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2167 rte_flow_error_set(error, EINVAL,
2168 RTE_FLOW_ERROR_TYPE_ITEM,
2169 item, "Not supported by fdir filter");
2170 return -rte_errno;
2171 }
2172 }
2173
2174 item = next_no_fuzzy_pattern(pattern, item);
2175 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
2176 item->type != RTE_FLOW_ITEM_TYPE_END) {
2177 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2178 rte_flow_error_set(error, EINVAL,
2179 RTE_FLOW_ERROR_TYPE_ITEM,
2180 item, "Not supported by fdir filter");
2181 return -rte_errno;
2182 }
2183 }
2184
2185 /* Get the flex byte info */
2186 if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
2187 /* Not supported last point for range*/
2188 if (item->last) {
2189 rte_flow_error_set(error, EINVAL,
2190 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2191 item, "Not supported last point for range");
2192 return -rte_errno;
2193 }
2194 /* mask should not be null */
2195 if (!item->mask || !item->spec) {
2196 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2197 rte_flow_error_set(error, EINVAL,
2198 RTE_FLOW_ERROR_TYPE_ITEM,
2199 item, "Not supported by fdir filter");
2200 return -rte_errno;
2201 }
2202
2203 raw_mask = item->mask;
2204
2205 /* check mask */
2206 if (raw_mask->relative != 0x1 ||
2207 raw_mask->search != 0x1 ||
2208 raw_mask->reserved != 0x0 ||
2209 (uint32_t)raw_mask->offset != 0xffffffff ||
2210 raw_mask->limit != 0xffff ||
2211 raw_mask->length != 0xffff) {
2212 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2213 rte_flow_error_set(error, EINVAL,
2214 RTE_FLOW_ERROR_TYPE_ITEM,
2215 item, "Not supported by fdir filter");
2216 return -rte_errno;
2217 }
2218
2219 raw_spec = item->spec;
2220
2221 /* check spec */
2222 if (raw_spec->relative != 0 ||
2223 raw_spec->search != 0 ||
2224 raw_spec->reserved != 0 ||
2225 raw_spec->offset > IXGBE_MAX_FLX_SOURCE_OFF ||
2226 raw_spec->offset % 2 ||
2227 raw_spec->limit != 0 ||
2228 raw_spec->length != 2 ||
2229 /* pattern can't be 0xffff */
2230 (raw_spec->pattern[0] == 0xff &&
2231 raw_spec->pattern[1] == 0xff)) {
2232 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2233 rte_flow_error_set(error, EINVAL,
2234 RTE_FLOW_ERROR_TYPE_ITEM,
2235 item, "Not supported by fdir filter");
2236 return -rte_errno;
2237 }
2238
2239 /* check pattern mask */
2240 if (raw_mask->pattern[0] != 0xff ||
2241 raw_mask->pattern[1] != 0xff) {
2242 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2243 rte_flow_error_set(error, EINVAL,
2244 RTE_FLOW_ERROR_TYPE_ITEM,
2245 item, "Not supported by fdir filter");
2246 return -rte_errno;
2247 }
2248
2249 rule->mask.flex_bytes_mask = 0xffff;
2250 rule->ixgbe_fdir.formatted.flex_bytes =
2251 (((uint16_t)raw_spec->pattern[1]) << 8) |
2252 raw_spec->pattern[0];
2253 rule->flex_bytes_offset = raw_spec->offset;
2254 }
2255
2256 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2257 /* check if the next not void item is END */
2258 item = next_no_fuzzy_pattern(pattern, item);
2259 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2260 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2261 rte_flow_error_set(error, EINVAL,
2262 RTE_FLOW_ERROR_TYPE_ITEM,
2263 item, "Not supported by fdir filter");
2264 return -rte_errno;
2265 }
2266 }
2267
2268 return ixgbe_parse_fdir_act_attr(attr, actions, rule, error);
2269 }
2270
2271 #define NVGRE_PROTOCOL 0x6558
2272
2273 /**
2274 * Parse the rule to see if it is a VxLAN or NVGRE flow director rule.
2275 * And get the flow director filter info BTW.
2276 * VxLAN PATTERN:
2277 * The first not void item must be ETH.
2278 * The second not void item must be IPV4/ IPV6.
2279 * The third not void item must be NVGRE.
2280 * The next not void item must be END.
2281 * NVGRE PATTERN:
2282 * The first not void item must be ETH.
2283 * The second not void item must be IPV4/ IPV6.
2284 * The third not void item must be NVGRE.
2285 * The next not void item must be END.
2286 * ACTION:
2287 * The first not void action should be QUEUE or DROP.
2288 * The second not void optional action should be MARK,
2289 * mark_id is a uint32_t number.
2290 * The next not void action should be END.
2291 * VxLAN pattern example:
2292 * ITEM Spec Mask
2293 * ETH NULL NULL
2294 * IPV4/IPV6 NULL NULL
2295 * UDP NULL NULL
2296 * VxLAN vni{0x00, 0x32, 0x54} {0xFF, 0xFF, 0xFF}
2297 * MAC VLAN tci 0x2016 0xEFFF
2298 * END
2299 * NEGRV pattern example:
2300 * ITEM Spec Mask
2301 * ETH NULL NULL
2302 * IPV4/IPV6 NULL NULL
2303 * NVGRE protocol 0x6558 0xFFFF
2304 * tni{0x00, 0x32, 0x54} {0xFF, 0xFF, 0xFF}
2305 * MAC VLAN tci 0x2016 0xEFFF
2306 * END
2307 * other members in mask and spec should set to 0x00.
2308 * item->last should be NULL.
2309 */
2310 static int
2311 ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
2312 const struct rte_flow_item pattern[],
2313 const struct rte_flow_action actions[],
2314 struct ixgbe_fdir_rule *rule,
2315 struct rte_flow_error *error)
2316 {
2317 const struct rte_flow_item *item;
2318 const struct rte_flow_item_vxlan *vxlan_spec;
2319 const struct rte_flow_item_vxlan *vxlan_mask;
2320 const struct rte_flow_item_nvgre *nvgre_spec;
2321 const struct rte_flow_item_nvgre *nvgre_mask;
2322 const struct rte_flow_item_eth *eth_spec;
2323 const struct rte_flow_item_eth *eth_mask;
2324 const struct rte_flow_item_vlan *vlan_spec;
2325 const struct rte_flow_item_vlan *vlan_mask;
2326 uint32_t j;
2327
2328 if (!pattern) {
2329 rte_flow_error_set(error, EINVAL,
2330 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
2331 NULL, "NULL pattern.");
2332 return -rte_errno;
2333 }
2334
2335 if (!actions) {
2336 rte_flow_error_set(error, EINVAL,
2337 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
2338 NULL, "NULL action.");
2339 return -rte_errno;
2340 }
2341
2342 if (!attr) {
2343 rte_flow_error_set(error, EINVAL,
2344 RTE_FLOW_ERROR_TYPE_ATTR,
2345 NULL, "NULL attribute.");
2346 return -rte_errno;
2347 }
2348
2349 /**
2350 * Some fields may not be provided. Set spec to 0 and mask to default
2351 * value. So, we need not do anything for the not provided fields later.
2352 */
2353 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2354 memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
2355 rule->mask.vlan_tci_mask = 0;
2356
2357 /**
2358 * The first not void item should be
2359 * MAC or IPv4 or IPv6 or UDP or VxLAN.
2360 */
2361 item = next_no_void_pattern(pattern, NULL);
2362 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
2363 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
2364 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
2365 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
2366 item->type != RTE_FLOW_ITEM_TYPE_VXLAN &&
2367 item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
2368 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2369 rte_flow_error_set(error, EINVAL,
2370 RTE_FLOW_ERROR_TYPE_ITEM,
2371 item, "Not supported by fdir filter");
2372 return -rte_errno;
2373 }
2374
2375 rule->mode = RTE_FDIR_MODE_PERFECT_TUNNEL;
2376
2377 /* Skip MAC. */
2378 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
2379 /* Only used to describe the protocol stack. */
2380 if (item->spec || item->mask) {
2381 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2382 rte_flow_error_set(error, EINVAL,
2383 RTE_FLOW_ERROR_TYPE_ITEM,
2384 item, "Not supported by fdir filter");
2385 return -rte_errno;
2386 }
2387 /* Not supported last point for range*/
2388 if (item->last) {
2389 rte_flow_error_set(error, EINVAL,
2390 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2391 item, "Not supported last point for range");
2392 return -rte_errno;
2393 }
2394
2395 /* Check if the next not void item is IPv4 or IPv6. */
2396 item = next_no_void_pattern(pattern, item);
2397 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
2398 item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
2399 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2400 rte_flow_error_set(error, EINVAL,
2401 RTE_FLOW_ERROR_TYPE_ITEM,
2402 item, "Not supported by fdir filter");
2403 return -rte_errno;
2404 }
2405 }
2406
2407 /* Skip IP. */
2408 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
2409 item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
2410 /* Only used to describe the protocol stack. */
2411 if (item->spec || item->mask) {
2412 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2413 rte_flow_error_set(error, EINVAL,
2414 RTE_FLOW_ERROR_TYPE_ITEM,
2415 item, "Not supported by fdir filter");
2416 return -rte_errno;
2417 }
2418 /*Not supported last point for range*/
2419 if (item->last) {
2420 rte_flow_error_set(error, EINVAL,
2421 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2422 item, "Not supported last point for range");
2423 return -rte_errno;
2424 }
2425
2426 /* Check if the next not void item is UDP or NVGRE. */
2427 item = next_no_void_pattern(pattern, item);
2428 if (item->type != RTE_FLOW_ITEM_TYPE_UDP &&
2429 item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
2430 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2431 rte_flow_error_set(error, EINVAL,
2432 RTE_FLOW_ERROR_TYPE_ITEM,
2433 item, "Not supported by fdir filter");
2434 return -rte_errno;
2435 }
2436 }
2437
2438 /* Skip UDP. */
2439 if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
2440 /* Only used to describe the protocol stack. */
2441 if (item->spec || item->mask) {
2442 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2443 rte_flow_error_set(error, EINVAL,
2444 RTE_FLOW_ERROR_TYPE_ITEM,
2445 item, "Not supported by fdir filter");
2446 return -rte_errno;
2447 }
2448 /*Not supported last point for range*/
2449 if (item->last) {
2450 rte_flow_error_set(error, EINVAL,
2451 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2452 item, "Not supported last point for range");
2453 return -rte_errno;
2454 }
2455
2456 /* Check if the next not void item is VxLAN. */
2457 item = next_no_void_pattern(pattern, item);
2458 if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
2459 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2460 rte_flow_error_set(error, EINVAL,
2461 RTE_FLOW_ERROR_TYPE_ITEM,
2462 item, "Not supported by fdir filter");
2463 return -rte_errno;
2464 }
2465 }
2466
2467 /* Get the VxLAN info */
2468 if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
2469 rule->ixgbe_fdir.formatted.tunnel_type =
2470 IXGBE_FDIR_VXLAN_TUNNEL_TYPE;
2471
2472 /* Only care about VNI, others should be masked. */
2473 if (!item->mask) {
2474 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2475 rte_flow_error_set(error, EINVAL,
2476 RTE_FLOW_ERROR_TYPE_ITEM,
2477 item, "Not supported by fdir filter");
2478 return -rte_errno;
2479 }
2480 /*Not supported last point for range*/
2481 if (item->last) {
2482 rte_flow_error_set(error, EINVAL,
2483 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2484 item, "Not supported last point for range");
2485 return -rte_errno;
2486 }
2487 rule->b_mask = TRUE;
2488
2489 /* Tunnel type is always meaningful. */
2490 rule->mask.tunnel_type_mask = 1;
2491
2492 vxlan_mask = item->mask;
2493 if (vxlan_mask->flags) {
2494 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2495 rte_flow_error_set(error, EINVAL,
2496 RTE_FLOW_ERROR_TYPE_ITEM,
2497 item, "Not supported by fdir filter");
2498 return -rte_errno;
2499 }
2500 /* VNI must be totally masked or not. */
2501 if ((vxlan_mask->vni[0] || vxlan_mask->vni[1] ||
2502 vxlan_mask->vni[2]) &&
2503 ((vxlan_mask->vni[0] != 0xFF) ||
2504 (vxlan_mask->vni[1] != 0xFF) ||
2505 (vxlan_mask->vni[2] != 0xFF))) {
2506 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2507 rte_flow_error_set(error, EINVAL,
2508 RTE_FLOW_ERROR_TYPE_ITEM,
2509 item, "Not supported by fdir filter");
2510 return -rte_errno;
2511 }
2512
2513 rte_memcpy(&rule->mask.tunnel_id_mask, vxlan_mask->vni,
2514 RTE_DIM(vxlan_mask->vni));
2515
2516 if (item->spec) {
2517 rule->b_spec = TRUE;
2518 vxlan_spec = item->spec;
2519 rte_memcpy(((uint8_t *)
2520 &rule->ixgbe_fdir.formatted.tni_vni),
2521 vxlan_spec->vni, RTE_DIM(vxlan_spec->vni));
2522 }
2523 }
2524
2525 /* Get the NVGRE info */
2526 if (item->type == RTE_FLOW_ITEM_TYPE_NVGRE) {
2527 rule->ixgbe_fdir.formatted.tunnel_type =
2528 IXGBE_FDIR_NVGRE_TUNNEL_TYPE;
2529
2530 /**
2531 * Only care about flags0, flags1, protocol and TNI,
2532 * others should be masked.
2533 */
2534 if (!item->mask) {
2535 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2536 rte_flow_error_set(error, EINVAL,
2537 RTE_FLOW_ERROR_TYPE_ITEM,
2538 item, "Not supported by fdir filter");
2539 return -rte_errno;
2540 }
2541 /*Not supported last point for range*/
2542 if (item->last) {
2543 rte_flow_error_set(error, EINVAL,
2544 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2545 item, "Not supported last point for range");
2546 return -rte_errno;
2547 }
2548 rule->b_mask = TRUE;
2549
2550 /* Tunnel type is always meaningful. */
2551 rule->mask.tunnel_type_mask = 1;
2552
2553 nvgre_mask = item->mask;
2554 if (nvgre_mask->flow_id) {
2555 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2556 rte_flow_error_set(error, EINVAL,
2557 RTE_FLOW_ERROR_TYPE_ITEM,
2558 item, "Not supported by fdir filter");
2559 return -rte_errno;
2560 }
2561 if (nvgre_mask->protocol &&
2562 nvgre_mask->protocol != 0xFFFF) {
2563 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2564 rte_flow_error_set(error, EINVAL,
2565 RTE_FLOW_ERROR_TYPE_ITEM,
2566 item, "Not supported by fdir filter");
2567 return -rte_errno;
2568 }
2569 if (nvgre_mask->c_k_s_rsvd0_ver &&
2570 nvgre_mask->c_k_s_rsvd0_ver !=
2571 rte_cpu_to_be_16(0xFFFF)) {
2572 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2573 rte_flow_error_set(error, EINVAL,
2574 RTE_FLOW_ERROR_TYPE_ITEM,
2575 item, "Not supported by fdir filter");
2576 return -rte_errno;
2577 }
2578 /* TNI must be totally masked or not. */
2579 if (nvgre_mask->tni[0] &&
2580 ((nvgre_mask->tni[0] != 0xFF) ||
2581 (nvgre_mask->tni[1] != 0xFF) ||
2582 (nvgre_mask->tni[2] != 0xFF))) {
2583 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2584 rte_flow_error_set(error, EINVAL,
2585 RTE_FLOW_ERROR_TYPE_ITEM,
2586 item, "Not supported by fdir filter");
2587 return -rte_errno;
2588 }
2589 /* tni is a 24-bits bit field */
2590 rte_memcpy(&rule->mask.tunnel_id_mask, nvgre_mask->tni,
2591 RTE_DIM(nvgre_mask->tni));
2592 rule->mask.tunnel_id_mask <<= 8;
2593
2594 if (item->spec) {
2595 rule->b_spec = TRUE;
2596 nvgre_spec = item->spec;
2597 if (nvgre_spec->c_k_s_rsvd0_ver !=
2598 rte_cpu_to_be_16(0x2000) &&
2599 nvgre_mask->c_k_s_rsvd0_ver) {
2600 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2601 rte_flow_error_set(error, EINVAL,
2602 RTE_FLOW_ERROR_TYPE_ITEM,
2603 item, "Not supported by fdir filter");
2604 return -rte_errno;
2605 }
2606 if (nvgre_mask->protocol &&
2607 nvgre_spec->protocol !=
2608 rte_cpu_to_be_16(NVGRE_PROTOCOL)) {
2609 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2610 rte_flow_error_set(error, EINVAL,
2611 RTE_FLOW_ERROR_TYPE_ITEM,
2612 item, "Not supported by fdir filter");
2613 return -rte_errno;
2614 }
2615 /* tni is a 24-bits bit field */
2616 rte_memcpy(&rule->ixgbe_fdir.formatted.tni_vni,
2617 nvgre_spec->tni, RTE_DIM(nvgre_spec->tni));
2618 }
2619 }
2620
2621 /* check if the next not void item is MAC */
2622 item = next_no_void_pattern(pattern, item);
2623 if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
2624 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2625 rte_flow_error_set(error, EINVAL,
2626 RTE_FLOW_ERROR_TYPE_ITEM,
2627 item, "Not supported by fdir filter");
2628 return -rte_errno;
2629 }
2630
2631 /**
2632 * Only support vlan and dst MAC address,
2633 * others should be masked.
2634 */
2635
2636 if (!item->mask) {
2637 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2638 rte_flow_error_set(error, EINVAL,
2639 RTE_FLOW_ERROR_TYPE_ITEM,
2640 item, "Not supported by fdir filter");
2641 return -rte_errno;
2642 }
2643 /*Not supported last point for range*/
2644 if (item->last) {
2645 rte_flow_error_set(error, EINVAL,
2646 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2647 item, "Not supported last point for range");
2648 return -rte_errno;
2649 }
2650 rule->b_mask = TRUE;
2651 eth_mask = item->mask;
2652
2653 /* Ether type should be masked. */
2654 if (eth_mask->type) {
2655 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2656 rte_flow_error_set(error, EINVAL,
2657 RTE_FLOW_ERROR_TYPE_ITEM,
2658 item, "Not supported by fdir filter");
2659 return -rte_errno;
2660 }
2661
2662 /* src MAC address should be masked. */
2663 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
2664 if (eth_mask->src.addr_bytes[j]) {
2665 memset(rule, 0,
2666 sizeof(struct ixgbe_fdir_rule));
2667 rte_flow_error_set(error, EINVAL,
2668 RTE_FLOW_ERROR_TYPE_ITEM,
2669 item, "Not supported by fdir filter");
2670 return -rte_errno;
2671 }
2672 }
2673 rule->mask.mac_addr_byte_mask = 0;
2674 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
2675 /* It's a per byte mask. */
2676 if (eth_mask->dst.addr_bytes[j] == 0xFF) {
2677 rule->mask.mac_addr_byte_mask |= 0x1 << j;
2678 } else if (eth_mask->dst.addr_bytes[j]) {
2679 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2680 rte_flow_error_set(error, EINVAL,
2681 RTE_FLOW_ERROR_TYPE_ITEM,
2682 item, "Not supported by fdir filter");
2683 return -rte_errno;
2684 }
2685 }
2686
2687 /* When no vlan, considered as full mask. */
2688 rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
2689
2690 if (item->spec) {
2691 rule->b_spec = TRUE;
2692 eth_spec = item->spec;
2693
2694 /* Get the dst MAC. */
2695 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
2696 rule->ixgbe_fdir.formatted.inner_mac[j] =
2697 eth_spec->dst.addr_bytes[j];
2698 }
2699 }
2700
2701 /**
2702 * Check if the next not void item is vlan or ipv4.
2703 * IPv6 is not supported.
2704 */
2705 item = next_no_void_pattern(pattern, item);
2706 if ((item->type != RTE_FLOW_ITEM_TYPE_VLAN) &&
2707 (item->type != RTE_FLOW_ITEM_TYPE_IPV4)) {
2708 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2709 rte_flow_error_set(error, EINVAL,
2710 RTE_FLOW_ERROR_TYPE_ITEM,
2711 item, "Not supported by fdir filter");
2712 return -rte_errno;
2713 }
2714 /*Not supported last point for range*/
2715 if (item->last) {
2716 rte_flow_error_set(error, EINVAL,
2717 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2718 item, "Not supported last point for range");
2719 return -rte_errno;
2720 }
2721
2722 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
2723 if (!(item->spec && item->mask)) {
2724 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2725 rte_flow_error_set(error, EINVAL,
2726 RTE_FLOW_ERROR_TYPE_ITEM,
2727 item, "Not supported by fdir filter");
2728 return -rte_errno;
2729 }
2730
2731 vlan_spec = item->spec;
2732 vlan_mask = item->mask;
2733
2734 rule->ixgbe_fdir.formatted.vlan_id = vlan_spec->tci;
2735
2736 rule->mask.vlan_tci_mask = vlan_mask->tci;
2737 rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
2738 /* More than one tags are not supported. */
2739
2740 /* check if the next not void item is END */
2741 item = next_no_void_pattern(pattern, item);
2742
2743 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2744 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2745 rte_flow_error_set(error, EINVAL,
2746 RTE_FLOW_ERROR_TYPE_ITEM,
2747 item, "Not supported by fdir filter");
2748 return -rte_errno;
2749 }
2750 }
2751
2752 /**
2753 * If the tags is 0, it means don't care about the VLAN.
2754 * Do nothing.
2755 */
2756
2757 return ixgbe_parse_fdir_act_attr(attr, actions, rule, error);
2758 }
2759
2760 static int
2761 ixgbe_parse_fdir_filter(struct rte_eth_dev *dev,
2762 const struct rte_flow_attr *attr,
2763 const struct rte_flow_item pattern[],
2764 const struct rte_flow_action actions[],
2765 struct ixgbe_fdir_rule *rule,
2766 struct rte_flow_error *error)
2767 {
2768 int ret;
2769 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2770 enum rte_fdir_mode fdir_mode = dev->data->dev_conf.fdir_conf.mode;
2771
2772 if (hw->mac.type != ixgbe_mac_82599EB &&
2773 hw->mac.type != ixgbe_mac_X540 &&
2774 hw->mac.type != ixgbe_mac_X550 &&
2775 hw->mac.type != ixgbe_mac_X550EM_x &&
2776 hw->mac.type != ixgbe_mac_X550EM_a)
2777 return -ENOTSUP;
2778
2779 ret = ixgbe_parse_fdir_filter_normal(dev, attr, pattern,
2780 actions, rule, error);
2781
2782 if (!ret)
2783 goto step_next;
2784
2785 ret = ixgbe_parse_fdir_filter_tunnel(attr, pattern,
2786 actions, rule, error);
2787
2788 if (ret)
2789 return ret;
2790
2791 step_next:
2792
2793 if (hw->mac.type == ixgbe_mac_82599EB &&
2794 rule->fdirflags == IXGBE_FDIRCMD_DROP &&
2795 (rule->ixgbe_fdir.formatted.src_port != 0 ||
2796 rule->ixgbe_fdir.formatted.dst_port != 0))
2797 return -ENOTSUP;
2798
2799 if (fdir_mode == RTE_FDIR_MODE_NONE ||
2800 fdir_mode != rule->mode)
2801 return -ENOTSUP;
2802
2803 if (rule->queue >= dev->data->nb_rx_queues)
2804 return -ENOTSUP;
2805
2806 return ret;
2807 }
2808
2809 static int
2810 ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
2811 const struct rte_flow_attr *attr,
2812 const struct rte_flow_action actions[],
2813 struct ixgbe_rte_flow_rss_conf *rss_conf,
2814 struct rte_flow_error *error)
2815 {
2816 const struct rte_flow_action *act;
2817 const struct rte_flow_action_rss *rss;
2818 uint16_t n;
2819
2820 /**
2821 * rss only supports forwarding,
2822 * check if the first not void action is RSS.
2823 */
2824 act = next_no_void_action(actions, NULL);
2825 if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
2826 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2827 rte_flow_error_set(error, EINVAL,
2828 RTE_FLOW_ERROR_TYPE_ACTION,
2829 act, "Not supported action.");
2830 return -rte_errno;
2831 }
2832
2833 rss = (const struct rte_flow_action_rss *)act->conf;
2834
2835 if (!rss || !rss->queue_num) {
2836 rte_flow_error_set(error, EINVAL,
2837 RTE_FLOW_ERROR_TYPE_ACTION,
2838 act,
2839 "no valid queues");
2840 return -rte_errno;
2841 }
2842
2843 for (n = 0; n < rss->queue_num; n++) {
2844 if (rss->queue[n] >= dev->data->nb_rx_queues) {
2845 rte_flow_error_set(error, EINVAL,
2846 RTE_FLOW_ERROR_TYPE_ACTION,
2847 act,
2848 "queue id > max number of queues");
2849 return -rte_errno;
2850 }
2851 }
2852
2853 if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
2854 return rte_flow_error_set
2855 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2856 "non-default RSS hash functions are not supported");
2857 if (rss->level)
2858 return rte_flow_error_set
2859 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2860 "a nonzero RSS encapsulation level is not supported");
2861 if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
2862 return rte_flow_error_set
2863 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2864 "RSS hash key must be exactly 40 bytes");
2865 if (rss->queue_num > RTE_DIM(rss_conf->queue))
2866 return rte_flow_error_set
2867 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2868 "too many queues for RSS context");
2869 if (ixgbe_rss_conf_init(rss_conf, rss))
2870 return rte_flow_error_set
2871 (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
2872 "RSS context initialization failure");
2873
2874 /* check if the next not void item is END */
2875 act = next_no_void_action(actions, act);
2876 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
2877 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2878 rte_flow_error_set(error, EINVAL,
2879 RTE_FLOW_ERROR_TYPE_ACTION,
2880 act, "Not supported action.");
2881 return -rte_errno;
2882 }
2883
2884 /* parse attr */
2885 /* must be input direction */
2886 if (!attr->ingress) {
2887 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2888 rte_flow_error_set(error, EINVAL,
2889 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
2890 attr, "Only support ingress.");
2891 return -rte_errno;
2892 }
2893
2894 /* not supported */
2895 if (attr->egress) {
2896 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2897 rte_flow_error_set(error, EINVAL,
2898 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
2899 attr, "Not support egress.");
2900 return -rte_errno;
2901 }
2902
2903 /* not supported */
2904 if (attr->transfer) {
2905 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2906 rte_flow_error_set(error, EINVAL,
2907 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
2908 attr, "No support for transfer.");
2909 return -rte_errno;
2910 }
2911
2912 if (attr->priority > 0xFFFF) {
2913 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2914 rte_flow_error_set(error, EINVAL,
2915 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
2916 attr, "Error priority.");
2917 return -rte_errno;
2918 }
2919
2920 return 0;
2921 }
2922
2923 /* remove the rss filter */
2924 static void
2925 ixgbe_clear_rss_filter(struct rte_eth_dev *dev)
2926 {
2927 struct ixgbe_filter_info *filter_info =
2928 IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
2929
2930 if (filter_info->rss_info.conf.queue_num)
2931 ixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);
2932 }
2933
2934 void
2935 ixgbe_filterlist_init(void)
2936 {
2937 TAILQ_INIT(&filter_ntuple_list);
2938 TAILQ_INIT(&filter_ethertype_list);
2939 TAILQ_INIT(&filter_syn_list);
2940 TAILQ_INIT(&filter_fdir_list);
2941 TAILQ_INIT(&filter_l2_tunnel_list);
2942 TAILQ_INIT(&filter_rss_list);
2943 TAILQ_INIT(&ixgbe_flow_list);
2944 }
2945
2946 void
2947 ixgbe_filterlist_flush(void)
2948 {
2949 struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
2950 struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
2951 struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
2952 struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
2953 struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
2954 struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
2955 struct ixgbe_rss_conf_ele *rss_filter_ptr;
2956
2957 while ((ntuple_filter_ptr = TAILQ_FIRST(&filter_ntuple_list))) {
2958 TAILQ_REMOVE(&filter_ntuple_list,
2959 ntuple_filter_ptr,
2960 entries);
2961 rte_free(ntuple_filter_ptr);
2962 }
2963
2964 while ((ethertype_filter_ptr = TAILQ_FIRST(&filter_ethertype_list))) {
2965 TAILQ_REMOVE(&filter_ethertype_list,
2966 ethertype_filter_ptr,
2967 entries);
2968 rte_free(ethertype_filter_ptr);
2969 }
2970
2971 while ((syn_filter_ptr = TAILQ_FIRST(&filter_syn_list))) {
2972 TAILQ_REMOVE(&filter_syn_list,
2973 syn_filter_ptr,
2974 entries);
2975 rte_free(syn_filter_ptr);
2976 }
2977
2978 while ((l2_tn_filter_ptr = TAILQ_FIRST(&filter_l2_tunnel_list))) {
2979 TAILQ_REMOVE(&filter_l2_tunnel_list,
2980 l2_tn_filter_ptr,
2981 entries);
2982 rte_free(l2_tn_filter_ptr);
2983 }
2984
2985 while ((fdir_rule_ptr = TAILQ_FIRST(&filter_fdir_list))) {
2986 TAILQ_REMOVE(&filter_fdir_list,
2987 fdir_rule_ptr,
2988 entries);
2989 rte_free(fdir_rule_ptr);
2990 }
2991
2992 while ((rss_filter_ptr = TAILQ_FIRST(&filter_rss_list))) {
2993 TAILQ_REMOVE(&filter_rss_list,
2994 rss_filter_ptr,
2995 entries);
2996 rte_free(rss_filter_ptr);
2997 }
2998
2999 while ((ixgbe_flow_mem_ptr = TAILQ_FIRST(&ixgbe_flow_list))) {
3000 TAILQ_REMOVE(&ixgbe_flow_list,
3001 ixgbe_flow_mem_ptr,
3002 entries);
3003 rte_free(ixgbe_flow_mem_ptr->flow);
3004 rte_free(ixgbe_flow_mem_ptr);
3005 }
3006 }
3007
3008 /**
3009 * Create or destroy a flow rule.
3010 * Theorically one rule can match more than one filters.
3011 * We will let it use the filter which it hitt first.
3012 * So, the sequence matters.
3013 */
3014 static struct rte_flow *
3015 ixgbe_flow_create(struct rte_eth_dev *dev,
3016 const struct rte_flow_attr *attr,
3017 const struct rte_flow_item pattern[],
3018 const struct rte_flow_action actions[],
3019 struct rte_flow_error *error)
3020 {
3021 int ret;
3022 struct rte_eth_ntuple_filter ntuple_filter;
3023 struct rte_eth_ethertype_filter ethertype_filter;
3024 struct rte_eth_syn_filter syn_filter;
3025 struct ixgbe_fdir_rule fdir_rule;
3026 struct rte_eth_l2_tunnel_conf l2_tn_filter;
3027 struct ixgbe_hw_fdir_info *fdir_info =
3028 IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
3029 struct ixgbe_rte_flow_rss_conf rss_conf;
3030 struct rte_flow *flow = NULL;
3031 struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
3032 struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
3033 struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
3034 struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
3035 struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
3036 struct ixgbe_rss_conf_ele *rss_filter_ptr;
3037 struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
3038 uint8_t first_mask = FALSE;
3039
3040 flow = rte_zmalloc("ixgbe_rte_flow", sizeof(struct rte_flow), 0);
3041 if (!flow) {
3042 PMD_DRV_LOG(ERR, "failed to allocate memory");
3043 return (struct rte_flow *)flow;
3044 }
3045 ixgbe_flow_mem_ptr = rte_zmalloc("ixgbe_flow_mem",
3046 sizeof(struct ixgbe_flow_mem), 0);
3047 if (!ixgbe_flow_mem_ptr) {
3048 PMD_DRV_LOG(ERR, "failed to allocate memory");
3049 rte_free(flow);
3050 return NULL;
3051 }
3052 ixgbe_flow_mem_ptr->flow = flow;
3053 TAILQ_INSERT_TAIL(&ixgbe_flow_list,
3054 ixgbe_flow_mem_ptr, entries);
3055
3056 memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
3057 ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
3058 actions, &ntuple_filter, error);
3059
3060 #ifdef RTE_LIBRTE_SECURITY
3061 /* ESP flow not really a flow*/
3062 if (ntuple_filter.proto == IPPROTO_ESP)
3063 return flow;
3064 #endif
3065
3066 if (!ret) {
3067 ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
3068 if (!ret) {
3069 ntuple_filter_ptr = rte_zmalloc("ixgbe_ntuple_filter",
3070 sizeof(struct ixgbe_ntuple_filter_ele), 0);
3071 if (!ntuple_filter_ptr) {
3072 PMD_DRV_LOG(ERR, "failed to allocate memory");
3073 goto out;
3074 }
3075 rte_memcpy(&ntuple_filter_ptr->filter_info,
3076 &ntuple_filter,
3077 sizeof(struct rte_eth_ntuple_filter));
3078 TAILQ_INSERT_TAIL(&filter_ntuple_list,
3079 ntuple_filter_ptr, entries);
3080 flow->rule = ntuple_filter_ptr;
3081 flow->filter_type = RTE_ETH_FILTER_NTUPLE;
3082 return flow;
3083 }
3084 goto out;
3085 }
3086
3087 memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
3088 ret = ixgbe_parse_ethertype_filter(dev, attr, pattern,
3089 actions, &ethertype_filter, error);
3090 if (!ret) {
3091 ret = ixgbe_add_del_ethertype_filter(dev,
3092 &ethertype_filter, TRUE);
3093 if (!ret) {
3094 ethertype_filter_ptr = rte_zmalloc(
3095 "ixgbe_ethertype_filter",
3096 sizeof(struct ixgbe_ethertype_filter_ele), 0);
3097 if (!ethertype_filter_ptr) {
3098 PMD_DRV_LOG(ERR, "failed to allocate memory");
3099 goto out;
3100 }
3101 rte_memcpy(&ethertype_filter_ptr->filter_info,
3102 &ethertype_filter,
3103 sizeof(struct rte_eth_ethertype_filter));
3104 TAILQ_INSERT_TAIL(&filter_ethertype_list,
3105 ethertype_filter_ptr, entries);
3106 flow->rule = ethertype_filter_ptr;
3107 flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
3108 return flow;
3109 }
3110 goto out;
3111 }
3112
3113 memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
3114 ret = ixgbe_parse_syn_filter(dev, attr, pattern,
3115 actions, &syn_filter, error);
3116 if (!ret) {
3117 ret = ixgbe_syn_filter_set(dev, &syn_filter, TRUE);
3118 if (!ret) {
3119 syn_filter_ptr = rte_zmalloc("ixgbe_syn_filter",
3120 sizeof(struct ixgbe_eth_syn_filter_ele), 0);
3121 if (!syn_filter_ptr) {
3122 PMD_DRV_LOG(ERR, "failed to allocate memory");
3123 goto out;
3124 }
3125 rte_memcpy(&syn_filter_ptr->filter_info,
3126 &syn_filter,
3127 sizeof(struct rte_eth_syn_filter));
3128 TAILQ_INSERT_TAIL(&filter_syn_list,
3129 syn_filter_ptr,
3130 entries);
3131 flow->rule = syn_filter_ptr;
3132 flow->filter_type = RTE_ETH_FILTER_SYN;
3133 return flow;
3134 }
3135 goto out;
3136 }
3137
3138 memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule));
3139 ret = ixgbe_parse_fdir_filter(dev, attr, pattern,
3140 actions, &fdir_rule, error);
3141 if (!ret) {
3142 /* A mask cannot be deleted. */
3143 if (fdir_rule.b_mask) {
3144 if (!fdir_info->mask_added) {
3145 /* It's the first time the mask is set. */
3146 rte_memcpy(&fdir_info->mask,
3147 &fdir_rule.mask,
3148 sizeof(struct ixgbe_hw_fdir_mask));
3149 fdir_info->flex_bytes_offset =
3150 fdir_rule.flex_bytes_offset;
3151
3152 if (fdir_rule.mask.flex_bytes_mask)
3153 ixgbe_fdir_set_flexbytes_offset(dev,
3154 fdir_rule.flex_bytes_offset);
3155
3156 ret = ixgbe_fdir_set_input_mask(dev);
3157 if (ret)
3158 goto out;
3159
3160 fdir_info->mask_added = TRUE;
3161 first_mask = TRUE;
3162 } else {
3163 /**
3164 * Only support one global mask,
3165 * all the masks should be the same.
3166 */
3167 ret = memcmp(&fdir_info->mask,
3168 &fdir_rule.mask,
3169 sizeof(struct ixgbe_hw_fdir_mask));
3170 if (ret)
3171 goto out;
3172
3173 if (fdir_info->flex_bytes_offset !=
3174 fdir_rule.flex_bytes_offset)
3175 goto out;
3176 }
3177 }
3178
3179 if (fdir_rule.b_spec) {
3180 ret = ixgbe_fdir_filter_program(dev, &fdir_rule,
3181 FALSE, FALSE);
3182 if (!ret) {
3183 fdir_rule_ptr = rte_zmalloc("ixgbe_fdir_filter",
3184 sizeof(struct ixgbe_fdir_rule_ele), 0);
3185 if (!fdir_rule_ptr) {
3186 PMD_DRV_LOG(ERR, "failed to allocate memory");
3187 goto out;
3188 }
3189 rte_memcpy(&fdir_rule_ptr->filter_info,
3190 &fdir_rule,
3191 sizeof(struct ixgbe_fdir_rule));
3192 TAILQ_INSERT_TAIL(&filter_fdir_list,
3193 fdir_rule_ptr, entries);
3194 flow->rule = fdir_rule_ptr;
3195 flow->filter_type = RTE_ETH_FILTER_FDIR;
3196
3197 return flow;
3198 }
3199
3200 if (ret) {
3201 /**
3202 * clean the mask_added flag if fail to
3203 * program
3204 **/
3205 if (first_mask)
3206 fdir_info->mask_added = FALSE;
3207 goto out;
3208 }
3209 }
3210
3211 goto out;
3212 }
3213
3214 memset(&l2_tn_filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
3215 ret = ixgbe_parse_l2_tn_filter(dev, attr, pattern,
3216 actions, &l2_tn_filter, error);
3217 if (!ret) {
3218 ret = ixgbe_dev_l2_tunnel_filter_add(dev, &l2_tn_filter, FALSE);
3219 if (!ret) {
3220 l2_tn_filter_ptr = rte_zmalloc("ixgbe_l2_tn_filter",
3221 sizeof(struct ixgbe_eth_l2_tunnel_conf_ele), 0);
3222 if (!l2_tn_filter_ptr) {
3223 PMD_DRV_LOG(ERR, "failed to allocate memory");
3224 goto out;
3225 }
3226 rte_memcpy(&l2_tn_filter_ptr->filter_info,
3227 &l2_tn_filter,
3228 sizeof(struct rte_eth_l2_tunnel_conf));
3229 TAILQ_INSERT_TAIL(&filter_l2_tunnel_list,
3230 l2_tn_filter_ptr, entries);
3231 flow->rule = l2_tn_filter_ptr;
3232 flow->filter_type = RTE_ETH_FILTER_L2_TUNNEL;
3233 return flow;
3234 }
3235 }
3236
3237 memset(&rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
3238 ret = ixgbe_parse_rss_filter(dev, attr,
3239 actions, &rss_conf, error);
3240 if (!ret) {
3241 ret = ixgbe_config_rss_filter(dev, &rss_conf, TRUE);
3242 if (!ret) {
3243 rss_filter_ptr = rte_zmalloc("ixgbe_rss_filter",
3244 sizeof(struct ixgbe_rss_conf_ele), 0);
3245 if (!rss_filter_ptr) {
3246 PMD_DRV_LOG(ERR, "failed to allocate memory");
3247 goto out;
3248 }
3249 ixgbe_rss_conf_init(&rss_filter_ptr->filter_info,
3250 &rss_conf.conf);
3251 TAILQ_INSERT_TAIL(&filter_rss_list,
3252 rss_filter_ptr, entries);
3253 flow->rule = rss_filter_ptr;
3254 flow->filter_type = RTE_ETH_FILTER_HASH;
3255 return flow;
3256 }
3257 }
3258
3259 out:
3260 TAILQ_REMOVE(&ixgbe_flow_list,
3261 ixgbe_flow_mem_ptr, entries);
3262 rte_flow_error_set(error, -ret,
3263 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
3264 "Failed to create flow.");
3265 rte_free(ixgbe_flow_mem_ptr);
3266 rte_free(flow);
3267 return NULL;
3268 }
3269
3270 /**
3271 * Check if the flow rule is supported by ixgbe.
3272 * It only checkes the format. Don't guarantee the rule can be programmed into
3273 * the HW. Because there can be no enough room for the rule.
3274 */
3275 static int
3276 ixgbe_flow_validate(struct rte_eth_dev *dev,
3277 const struct rte_flow_attr *attr,
3278 const struct rte_flow_item pattern[],
3279 const struct rte_flow_action actions[],
3280 struct rte_flow_error *error)
3281 {
3282 struct rte_eth_ntuple_filter ntuple_filter;
3283 struct rte_eth_ethertype_filter ethertype_filter;
3284 struct rte_eth_syn_filter syn_filter;
3285 struct rte_eth_l2_tunnel_conf l2_tn_filter;
3286 struct ixgbe_fdir_rule fdir_rule;
3287 struct ixgbe_rte_flow_rss_conf rss_conf;
3288 int ret;
3289
3290 memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
3291 ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
3292 actions, &ntuple_filter, error);
3293 if (!ret)
3294 return 0;
3295
3296 memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
3297 ret = ixgbe_parse_ethertype_filter(dev, attr, pattern,
3298 actions, &ethertype_filter, error);
3299 if (!ret)
3300 return 0;
3301
3302 memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
3303 ret = ixgbe_parse_syn_filter(dev, attr, pattern,
3304 actions, &syn_filter, error);
3305 if (!ret)
3306 return 0;
3307
3308 memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule));
3309 ret = ixgbe_parse_fdir_filter(dev, attr, pattern,
3310 actions, &fdir_rule, error);
3311 if (!ret)
3312 return 0;
3313
3314 memset(&l2_tn_filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
3315 ret = ixgbe_parse_l2_tn_filter(dev, attr, pattern,
3316 actions, &l2_tn_filter, error);
3317 if (!ret)
3318 return 0;
3319
3320 memset(&rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
3321 ret = ixgbe_parse_rss_filter(dev, attr,
3322 actions, &rss_conf, error);
3323
3324 return ret;
3325 }
3326
3327 /* Destroy a flow rule on ixgbe. */
3328 static int
3329 ixgbe_flow_destroy(struct rte_eth_dev *dev,
3330 struct rte_flow *flow,
3331 struct rte_flow_error *error)
3332 {
3333 int ret;
3334 struct rte_flow *pmd_flow = flow;
3335 enum rte_filter_type filter_type = pmd_flow->filter_type;
3336 struct rte_eth_ntuple_filter ntuple_filter;
3337 struct rte_eth_ethertype_filter ethertype_filter;
3338 struct rte_eth_syn_filter syn_filter;
3339 struct ixgbe_fdir_rule fdir_rule;
3340 struct rte_eth_l2_tunnel_conf l2_tn_filter;
3341 struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
3342 struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
3343 struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
3344 struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
3345 struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
3346 struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
3347 struct ixgbe_hw_fdir_info *fdir_info =
3348 IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
3349 struct ixgbe_rss_conf_ele *rss_filter_ptr;
3350
3351 switch (filter_type) {
3352 case RTE_ETH_FILTER_NTUPLE:
3353 ntuple_filter_ptr = (struct ixgbe_ntuple_filter_ele *)
3354 pmd_flow->rule;
3355 rte_memcpy(&ntuple_filter,
3356 &ntuple_filter_ptr->filter_info,
3357 sizeof(struct rte_eth_ntuple_filter));
3358 ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, FALSE);
3359 if (!ret) {
3360 TAILQ_REMOVE(&filter_ntuple_list,
3361 ntuple_filter_ptr, entries);
3362 rte_free(ntuple_filter_ptr);
3363 }
3364 break;
3365 case RTE_ETH_FILTER_ETHERTYPE:
3366 ethertype_filter_ptr = (struct ixgbe_ethertype_filter_ele *)
3367 pmd_flow->rule;
3368 rte_memcpy(&ethertype_filter,
3369 &ethertype_filter_ptr->filter_info,
3370 sizeof(struct rte_eth_ethertype_filter));
3371 ret = ixgbe_add_del_ethertype_filter(dev,
3372 &ethertype_filter, FALSE);
3373 if (!ret) {
3374 TAILQ_REMOVE(&filter_ethertype_list,
3375 ethertype_filter_ptr, entries);
3376 rte_free(ethertype_filter_ptr);
3377 }
3378 break;
3379 case RTE_ETH_FILTER_SYN:
3380 syn_filter_ptr = (struct ixgbe_eth_syn_filter_ele *)
3381 pmd_flow->rule;
3382 rte_memcpy(&syn_filter,
3383 &syn_filter_ptr->filter_info,
3384 sizeof(struct rte_eth_syn_filter));
3385 ret = ixgbe_syn_filter_set(dev, &syn_filter, FALSE);
3386 if (!ret) {
3387 TAILQ_REMOVE(&filter_syn_list,
3388 syn_filter_ptr, entries);
3389 rte_free(syn_filter_ptr);
3390 }
3391 break;
3392 case RTE_ETH_FILTER_FDIR:
3393 fdir_rule_ptr = (struct ixgbe_fdir_rule_ele *)pmd_flow->rule;
3394 rte_memcpy(&fdir_rule,
3395 &fdir_rule_ptr->filter_info,
3396 sizeof(struct ixgbe_fdir_rule));
3397 ret = ixgbe_fdir_filter_program(dev, &fdir_rule, TRUE, FALSE);
3398 if (!ret) {
3399 TAILQ_REMOVE(&filter_fdir_list,
3400 fdir_rule_ptr, entries);
3401 rte_free(fdir_rule_ptr);
3402 if (TAILQ_EMPTY(&filter_fdir_list))
3403 fdir_info->mask_added = false;
3404 }
3405 break;
3406 case RTE_ETH_FILTER_L2_TUNNEL:
3407 l2_tn_filter_ptr = (struct ixgbe_eth_l2_tunnel_conf_ele *)
3408 pmd_flow->rule;
3409 rte_memcpy(&l2_tn_filter, &l2_tn_filter_ptr->filter_info,
3410 sizeof(struct rte_eth_l2_tunnel_conf));
3411 ret = ixgbe_dev_l2_tunnel_filter_del(dev, &l2_tn_filter);
3412 if (!ret) {
3413 TAILQ_REMOVE(&filter_l2_tunnel_list,
3414 l2_tn_filter_ptr, entries);
3415 rte_free(l2_tn_filter_ptr);
3416 }
3417 break;
3418 case RTE_ETH_FILTER_HASH:
3419 rss_filter_ptr = (struct ixgbe_rss_conf_ele *)
3420 pmd_flow->rule;
3421 ret = ixgbe_config_rss_filter(dev,
3422 &rss_filter_ptr->filter_info, FALSE);
3423 if (!ret) {
3424 TAILQ_REMOVE(&filter_rss_list,
3425 rss_filter_ptr, entries);
3426 rte_free(rss_filter_ptr);
3427 }
3428 break;
3429 default:
3430 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
3431 filter_type);
3432 ret = -EINVAL;
3433 break;
3434 }
3435
3436 if (ret) {
3437 rte_flow_error_set(error, EINVAL,
3438 RTE_FLOW_ERROR_TYPE_HANDLE,
3439 NULL, "Failed to destroy flow");
3440 return ret;
3441 }
3442
3443 TAILQ_FOREACH(ixgbe_flow_mem_ptr, &ixgbe_flow_list, entries) {
3444 if (ixgbe_flow_mem_ptr->flow == pmd_flow) {
3445 TAILQ_REMOVE(&ixgbe_flow_list,
3446 ixgbe_flow_mem_ptr, entries);
3447 rte_free(ixgbe_flow_mem_ptr);
3448 }
3449 }
3450 rte_free(flow);
3451
3452 return ret;
3453 }
3454
3455 /* Destroy all flow rules associated with a port on ixgbe. */
3456 static int
3457 ixgbe_flow_flush(struct rte_eth_dev *dev,
3458 struct rte_flow_error *error)
3459 {
3460 int ret = 0;
3461
3462 ixgbe_clear_all_ntuple_filter(dev);
3463 ixgbe_clear_all_ethertype_filter(dev);
3464 ixgbe_clear_syn_filter(dev);
3465
3466 ret = ixgbe_clear_all_fdir_filter(dev);
3467 if (ret < 0) {
3468 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
3469 NULL, "Failed to flush rule");
3470 return ret;
3471 }
3472
3473 ret = ixgbe_clear_all_l2_tn_filter(dev);
3474 if (ret < 0) {
3475 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
3476 NULL, "Failed to flush rule");
3477 return ret;
3478 }
3479
3480 ixgbe_clear_rss_filter(dev);
3481
3482 ixgbe_filterlist_flush();
3483
3484 return 0;
3485 }
3486
3487 const struct rte_flow_ops ixgbe_flow_ops = {
3488 .validate = ixgbe_flow_validate,
3489 .create = ixgbe_flow_create,
3490 .destroy = ixgbe_flow_destroy,
3491 .flush = ixgbe_flow_flush,
3492 };