1
2
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 <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
53struct ixgbe_ntuple_filter_ele {
54 TAILQ_ENTRY(ixgbe_ntuple_filter_ele) entries;
55 struct rte_eth_ntuple_filter filter_info;
56};
57
58struct ixgbe_ethertype_filter_ele {
59 TAILQ_ENTRY(ixgbe_ethertype_filter_ele) entries;
60 struct rte_eth_ethertype_filter filter_info;
61};
62
63struct ixgbe_eth_syn_filter_ele {
64 TAILQ_ENTRY(ixgbe_eth_syn_filter_ele) entries;
65 struct rte_eth_syn_filter filter_info;
66};
67
68struct ixgbe_fdir_rule_ele {
69 TAILQ_ENTRY(ixgbe_fdir_rule_ele) entries;
70 struct ixgbe_fdir_rule filter_info;
71};
72
73struct ixgbe_eth_l2_tunnel_conf_ele {
74 TAILQ_ENTRY(ixgbe_eth_l2_tunnel_conf_ele) entries;
75 struct ixgbe_l2_tunnel_conf filter_info;
76};
77
78struct ixgbe_rss_conf_ele {
79 TAILQ_ENTRY(ixgbe_rss_conf_ele) entries;
80 struct ixgbe_rte_flow_rss_conf filter_info;
81};
82
83struct ixgbe_flow_mem {
84 TAILQ_ENTRY(ixgbe_flow_mem) entries;
85 struct rte_flow *flow;
86};
87
88TAILQ_HEAD(ixgbe_ntuple_filter_list, ixgbe_ntuple_filter_ele);
89TAILQ_HEAD(ixgbe_ethertype_filter_list, ixgbe_ethertype_filter_ele);
90TAILQ_HEAD(ixgbe_syn_filter_list, ixgbe_eth_syn_filter_ele);
91TAILQ_HEAD(ixgbe_fdir_rule_filter_list, ixgbe_fdir_rule_ele);
92TAILQ_HEAD(ixgbe_l2_tunnel_filter_list, ixgbe_eth_l2_tunnel_conf_ele);
93TAILQ_HEAD(ixgbe_rss_filter_list, ixgbe_rss_conf_ele);
94TAILQ_HEAD(ixgbe_flow_mem_list, ixgbe_flow_mem);
95
96static struct ixgbe_ntuple_filter_list filter_ntuple_list;
97static struct ixgbe_ethertype_filter_list filter_ethertype_list;
98static struct ixgbe_syn_filter_list filter_syn_list;
99static struct ixgbe_fdir_rule_filter_list filter_fdir_list;
100static struct ixgbe_l2_tunnel_filter_list filter_l2_tunnel_list;
101static struct ixgbe_rss_filter_list filter_rss_list;
102static struct ixgbe_flow_mem_list ixgbe_flow_list;
103
104
105
106
107
108
109static inline
110const 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
123static inline
124const 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171static int
172cons_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(ð_null, 0, sizeof(struct rte_flow_item_eth));
216 memset(&vlan_null, 0, sizeof(struct rte_flow_item_vlan));
217
218#ifdef RTE_LIB_SECURITY
219
220
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
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
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
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
266 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
267 eth_spec = item->spec;
268 eth_mask = item->mask;
269
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
279 if ((item->spec || item->mask) &&
280 (memcmp(eth_spec, ð_null,
281 sizeof(struct rte_flow_item_eth)) ||
282 memcmp(eth_mask, ð_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
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
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
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
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
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
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
352
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
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
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
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
431
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
479
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
511
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
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
543action:
544
545
546
547
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
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
571
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
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
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
614static int
615ixgbe_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_LIB_SECURITY
633
634 if (filter->proto == IPPROTO_ESP)
635 return 0;
636#endif
637
638
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
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
661 filter->flags = RTE_5TUPLE_FLAGS;
662 return 0;
663}
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681static int
682cons_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
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
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
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
744
745
746
747 if (!rte_is_zero_ether_addr(ð_mask->src) ||
748 (!rte_is_zero_ether_addr(ð_mask->dst) &&
749 !rte_is_broadcast_ether_addr(ð_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
764
765
766 if (rte_is_broadcast_ether_addr(ð_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
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
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
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
811
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
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
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
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
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
854static int
855ixgbe_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 if (filter->queue >= dev->data->nb_rx_queues) {
874 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
875 rte_flow_error_set(error, EINVAL,
876 RTE_FLOW_ERROR_TYPE_ITEM,
877 NULL, "queue index much too big");
878 return -rte_errno;
879 }
880
881 if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
882 filter->ether_type == RTE_ETHER_TYPE_IPV6) {
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, "IPv4/IPv6 not supported by ethertype filter");
887 return -rte_errno;
888 }
889
890 if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
891 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
892 rte_flow_error_set(error, EINVAL,
893 RTE_FLOW_ERROR_TYPE_ITEM,
894 NULL, "mac compare is unsupported");
895 return -rte_errno;
896 }
897
898 if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
899 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
900 rte_flow_error_set(error, EINVAL,
901 RTE_FLOW_ERROR_TYPE_ITEM,
902 NULL, "drop option is unsupported");
903 return -rte_errno;
904 }
905
906 return 0;
907}
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929static int
930cons_parse_syn_filter(const struct rte_flow_attr *attr,
931 const struct rte_flow_item pattern[],
932 const struct rte_flow_action actions[],
933 struct rte_eth_syn_filter *filter,
934 struct rte_flow_error *error)
935{
936 const struct rte_flow_item *item;
937 const struct rte_flow_action *act;
938 const struct rte_flow_item_tcp *tcp_spec;
939 const struct rte_flow_item_tcp *tcp_mask;
940 const struct rte_flow_action_queue *act_q;
941
942 if (!pattern) {
943 rte_flow_error_set(error, EINVAL,
944 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
945 NULL, "NULL pattern.");
946 return -rte_errno;
947 }
948
949 if (!actions) {
950 rte_flow_error_set(error, EINVAL,
951 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
952 NULL, "NULL action.");
953 return -rte_errno;
954 }
955
956 if (!attr) {
957 rte_flow_error_set(error, EINVAL,
958 RTE_FLOW_ERROR_TYPE_ATTR,
959 NULL, "NULL attribute.");
960 return -rte_errno;
961 }
962
963
964
965 item = next_no_void_pattern(pattern, NULL);
966 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
967 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
968 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
969 item->type != RTE_FLOW_ITEM_TYPE_TCP) {
970 rte_flow_error_set(error, EINVAL,
971 RTE_FLOW_ERROR_TYPE_ITEM,
972 item, "Not supported by syn filter");
973 return -rte_errno;
974 }
975
976 if (item->last) {
977 rte_flow_error_set(error, EINVAL,
978 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
979 item, "Not supported last point for range");
980 return -rte_errno;
981 }
982
983
984 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
985
986 if (item->spec || item->mask) {
987 rte_flow_error_set(error, EINVAL,
988 RTE_FLOW_ERROR_TYPE_ITEM,
989 item, "Invalid SYN address mask");
990 return -rte_errno;
991 }
992
993
994 item = next_no_void_pattern(pattern, item);
995 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
996 item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
997 rte_flow_error_set(error, EINVAL,
998 RTE_FLOW_ERROR_TYPE_ITEM,
999 item, "Not supported by syn filter");
1000 return -rte_errno;
1001 }
1002 }
1003
1004
1005 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
1006 item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
1007
1008 if (item->spec || item->mask) {
1009 rte_flow_error_set(error, EINVAL,
1010 RTE_FLOW_ERROR_TYPE_ITEM,
1011 item, "Invalid SYN mask");
1012 return -rte_errno;
1013 }
1014
1015
1016 item = next_no_void_pattern(pattern, item);
1017 if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
1018 rte_flow_error_set(error, EINVAL,
1019 RTE_FLOW_ERROR_TYPE_ITEM,
1020 item, "Not supported by syn filter");
1021 return -rte_errno;
1022 }
1023 }
1024
1025
1026 if (!item->spec || !item->mask) {
1027 rte_flow_error_set(error, EINVAL,
1028 RTE_FLOW_ERROR_TYPE_ITEM,
1029 item, "Invalid SYN mask");
1030 return -rte_errno;
1031 }
1032
1033 if (item->last) {
1034 rte_flow_error_set(error, EINVAL,
1035 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1036 item, "Not supported last point for range");
1037 return -rte_errno;
1038 }
1039
1040 tcp_spec = item->spec;
1041 tcp_mask = item->mask;
1042 if (!(tcp_spec->hdr.tcp_flags & RTE_TCP_SYN_FLAG) ||
1043 tcp_mask->hdr.src_port ||
1044 tcp_mask->hdr.dst_port ||
1045 tcp_mask->hdr.sent_seq ||
1046 tcp_mask->hdr.recv_ack ||
1047 tcp_mask->hdr.data_off ||
1048 tcp_mask->hdr.tcp_flags != RTE_TCP_SYN_FLAG ||
1049 tcp_mask->hdr.rx_win ||
1050 tcp_mask->hdr.cksum ||
1051 tcp_mask->hdr.tcp_urp) {
1052 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1053 rte_flow_error_set(error, EINVAL,
1054 RTE_FLOW_ERROR_TYPE_ITEM,
1055 item, "Not supported by syn filter");
1056 return -rte_errno;
1057 }
1058
1059
1060 item = next_no_void_pattern(pattern, item);
1061 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1062 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1063 rte_flow_error_set(error, EINVAL,
1064 RTE_FLOW_ERROR_TYPE_ITEM,
1065 item, "Not supported by syn filter");
1066 return -rte_errno;
1067 }
1068
1069
1070 act = next_no_void_action(actions, NULL);
1071 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1072 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1073 rte_flow_error_set(error, EINVAL,
1074 RTE_FLOW_ERROR_TYPE_ACTION,
1075 act, "Not supported action.");
1076 return -rte_errno;
1077 }
1078
1079 act_q = (const struct rte_flow_action_queue *)act->conf;
1080 filter->queue = act_q->index;
1081 if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM) {
1082 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1083 rte_flow_error_set(error, EINVAL,
1084 RTE_FLOW_ERROR_TYPE_ACTION,
1085 act, "Not supported action.");
1086 return -rte_errno;
1087 }
1088
1089
1090 act = next_no_void_action(actions, act);
1091 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1092 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1093 rte_flow_error_set(error, EINVAL,
1094 RTE_FLOW_ERROR_TYPE_ACTION,
1095 act, "Not supported action.");
1096 return -rte_errno;
1097 }
1098
1099
1100
1101 if (!attr->ingress) {
1102 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1103 rte_flow_error_set(error, EINVAL,
1104 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1105 attr, "Only support ingress.");
1106 return -rte_errno;
1107 }
1108
1109
1110 if (attr->egress) {
1111 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1112 rte_flow_error_set(error, EINVAL,
1113 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1114 attr, "Not support egress.");
1115 return -rte_errno;
1116 }
1117
1118
1119 if (attr->transfer) {
1120 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1121 rte_flow_error_set(error, EINVAL,
1122 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1123 attr, "No support for transfer.");
1124 return -rte_errno;
1125 }
1126
1127
1128 if (!attr->priority) {
1129 filter->hig_pri = 0;
1130 } else if (attr->priority == (uint32_t)~0U) {
1131 filter->hig_pri = 1;
1132 } else {
1133 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
1134 rte_flow_error_set(error, EINVAL,
1135 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1136 attr, "Not support priority.");
1137 return -rte_errno;
1138 }
1139
1140 return 0;
1141}
1142
1143static int
1144ixgbe_parse_syn_filter(struct rte_eth_dev *dev,
1145 const struct rte_flow_attr *attr,
1146 const struct rte_flow_item pattern[],
1147 const struct rte_flow_action actions[],
1148 struct rte_eth_syn_filter *filter,
1149 struct rte_flow_error *error)
1150{
1151 int ret;
1152 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1153
1154 MAC_TYPE_FILTER_SUP(hw->mac.type);
1155
1156 ret = cons_parse_syn_filter(attr, pattern,
1157 actions, filter, error);
1158
1159 if (filter->queue >= dev->data->nb_rx_queues)
1160 return -rte_errno;
1161
1162 if (ret)
1163 return ret;
1164
1165 return 0;
1166}
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186static int
1187cons_parse_l2_tn_filter(struct rte_eth_dev *dev,
1188 const struct rte_flow_attr *attr,
1189 const struct rte_flow_item pattern[],
1190 const struct rte_flow_action actions[],
1191 struct ixgbe_l2_tunnel_conf *filter,
1192 struct rte_flow_error *error)
1193{
1194 const struct rte_flow_item *item;
1195 const struct rte_flow_item_e_tag *e_tag_spec;
1196 const struct rte_flow_item_e_tag *e_tag_mask;
1197 const struct rte_flow_action *act;
1198 const struct rte_flow_action_vf *act_vf;
1199 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1200
1201 if (!pattern) {
1202 rte_flow_error_set(error, EINVAL,
1203 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1204 NULL, "NULL pattern.");
1205 return -rte_errno;
1206 }
1207
1208 if (!actions) {
1209 rte_flow_error_set(error, EINVAL,
1210 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1211 NULL, "NULL action.");
1212 return -rte_errno;
1213 }
1214
1215 if (!attr) {
1216 rte_flow_error_set(error, EINVAL,
1217 RTE_FLOW_ERROR_TYPE_ATTR,
1218 NULL, "NULL attribute.");
1219 return -rte_errno;
1220 }
1221
1222
1223 item = next_no_void_pattern(pattern, NULL);
1224 if (item->type != RTE_FLOW_ITEM_TYPE_E_TAG) {
1225 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1226 rte_flow_error_set(error, EINVAL,
1227 RTE_FLOW_ERROR_TYPE_ITEM,
1228 item, "Not supported by L2 tunnel filter");
1229 return -rte_errno;
1230 }
1231
1232 if (!item->spec || !item->mask) {
1233 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1234 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1235 item, "Not supported by L2 tunnel filter");
1236 return -rte_errno;
1237 }
1238
1239
1240 if (item->last) {
1241 rte_flow_error_set(error, EINVAL,
1242 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1243 item, "Not supported last point for range");
1244 return -rte_errno;
1245 }
1246
1247 e_tag_spec = item->spec;
1248 e_tag_mask = item->mask;
1249
1250
1251 if (e_tag_mask->epcp_edei_in_ecid_b ||
1252 e_tag_mask->in_ecid_e ||
1253 e_tag_mask->ecid_e ||
1254 e_tag_mask->rsvd_grp_ecid_b != rte_cpu_to_be_16(0x3FFF)) {
1255 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1256 rte_flow_error_set(error, EINVAL,
1257 RTE_FLOW_ERROR_TYPE_ITEM,
1258 item, "Not supported by L2 tunnel filter");
1259 return -rte_errno;
1260 }
1261
1262 filter->l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
1263
1264
1265
1266
1267 filter->tunnel_id = rte_be_to_cpu_16(e_tag_spec->rsvd_grp_ecid_b);
1268
1269
1270 item = next_no_void_pattern(pattern, item);
1271 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1272 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1273 rte_flow_error_set(error, EINVAL,
1274 RTE_FLOW_ERROR_TYPE_ITEM,
1275 item, "Not supported by L2 tunnel filter");
1276 return -rte_errno;
1277 }
1278
1279
1280
1281 if (!attr->ingress) {
1282 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1283 rte_flow_error_set(error, EINVAL,
1284 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1285 attr, "Only support ingress.");
1286 return -rte_errno;
1287 }
1288
1289
1290 if (attr->egress) {
1291 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1292 rte_flow_error_set(error, EINVAL,
1293 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1294 attr, "Not support egress.");
1295 return -rte_errno;
1296 }
1297
1298
1299 if (attr->transfer) {
1300 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1301 rte_flow_error_set(error, EINVAL,
1302 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1303 attr, "No support for transfer.");
1304 return -rte_errno;
1305 }
1306
1307
1308 if (attr->priority) {
1309 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1310 rte_flow_error_set(error, EINVAL,
1311 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1312 attr, "Not support priority.");
1313 return -rte_errno;
1314 }
1315
1316
1317 act = next_no_void_action(actions, NULL);
1318 if (act->type != RTE_FLOW_ACTION_TYPE_VF &&
1319 act->type != RTE_FLOW_ACTION_TYPE_PF) {
1320 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1321 rte_flow_error_set(error, EINVAL,
1322 RTE_FLOW_ERROR_TYPE_ACTION,
1323 act, "Not supported action.");
1324 return -rte_errno;
1325 }
1326
1327 if (act->type == RTE_FLOW_ACTION_TYPE_VF) {
1328 act_vf = (const struct rte_flow_action_vf *)act->conf;
1329 filter->pool = act_vf->id;
1330 } else {
1331 filter->pool = pci_dev->max_vfs;
1332 }
1333
1334
1335 act = next_no_void_action(actions, act);
1336 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1337 memset(filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1338 rte_flow_error_set(error, EINVAL,
1339 RTE_FLOW_ERROR_TYPE_ACTION,
1340 act, "Not supported action.");
1341 return -rte_errno;
1342 }
1343
1344 return 0;
1345}
1346
1347static int
1348ixgbe_parse_l2_tn_filter(struct rte_eth_dev *dev,
1349 const struct rte_flow_attr *attr,
1350 const struct rte_flow_item pattern[],
1351 const struct rte_flow_action actions[],
1352 struct ixgbe_l2_tunnel_conf *l2_tn_filter,
1353 struct rte_flow_error *error)
1354{
1355 int ret = 0;
1356 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1357 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1358 uint16_t vf_num;
1359
1360 ret = cons_parse_l2_tn_filter(dev, attr, pattern,
1361 actions, l2_tn_filter, error);
1362
1363 if (hw->mac.type != ixgbe_mac_X550 &&
1364 hw->mac.type != ixgbe_mac_X550EM_x &&
1365 hw->mac.type != ixgbe_mac_X550EM_a) {
1366 memset(l2_tn_filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
1367 rte_flow_error_set(error, EINVAL,
1368 RTE_FLOW_ERROR_TYPE_ITEM,
1369 NULL, "Not supported by L2 tunnel filter");
1370 return -rte_errno;
1371 }
1372
1373 vf_num = pci_dev->max_vfs;
1374
1375 if (l2_tn_filter->pool > vf_num)
1376 return -rte_errno;
1377
1378 return ret;
1379}
1380
1381
1382static int
1383ixgbe_parse_fdir_act_attr(const struct rte_flow_attr *attr,
1384 const struct rte_flow_action actions[],
1385 struct ixgbe_fdir_rule *rule,
1386 struct rte_flow_error *error)
1387{
1388 const struct rte_flow_action *act;
1389 const struct rte_flow_action_queue *act_q;
1390 const struct rte_flow_action_mark *mark;
1391
1392
1393
1394 if (!attr->ingress) {
1395 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1396 rte_flow_error_set(error, EINVAL,
1397 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1398 attr, "Only support ingress.");
1399 return -rte_errno;
1400 }
1401
1402
1403 if (attr->egress) {
1404 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1405 rte_flow_error_set(error, EINVAL,
1406 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1407 attr, "Not support egress.");
1408 return -rte_errno;
1409 }
1410
1411
1412 if (attr->transfer) {
1413 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1414 rte_flow_error_set(error, EINVAL,
1415 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
1416 attr, "No support for transfer.");
1417 return -rte_errno;
1418 }
1419
1420
1421 if (attr->priority) {
1422 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1423 rte_flow_error_set(error, EINVAL,
1424 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1425 attr, "Not support priority.");
1426 return -rte_errno;
1427 }
1428
1429
1430 act = next_no_void_action(actions, NULL);
1431 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
1432 act->type != RTE_FLOW_ACTION_TYPE_DROP) {
1433 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1434 rte_flow_error_set(error, EINVAL,
1435 RTE_FLOW_ERROR_TYPE_ACTION,
1436 act, "Not supported action.");
1437 return -rte_errno;
1438 }
1439
1440 if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
1441 act_q = (const struct rte_flow_action_queue *)act->conf;
1442 rule->queue = act_q->index;
1443 } else {
1444
1445 if (rule->mode == RTE_FDIR_MODE_SIGNATURE) {
1446 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1447 rte_flow_error_set(error, EINVAL,
1448 RTE_FLOW_ERROR_TYPE_ACTION,
1449 act, "Not supported action.");
1450 return -rte_errno;
1451 }
1452 rule->fdirflags = IXGBE_FDIRCMD_DROP;
1453 }
1454
1455
1456 act = next_no_void_action(actions, act);
1457 if ((act->type != RTE_FLOW_ACTION_TYPE_MARK) &&
1458 (act->type != RTE_FLOW_ACTION_TYPE_END)) {
1459 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1460 rte_flow_error_set(error, EINVAL,
1461 RTE_FLOW_ERROR_TYPE_ACTION,
1462 act, "Not supported action.");
1463 return -rte_errno;
1464 }
1465
1466 rule->soft_id = 0;
1467
1468 if (act->type == RTE_FLOW_ACTION_TYPE_MARK) {
1469 mark = (const struct rte_flow_action_mark *)act->conf;
1470 rule->soft_id = mark->id;
1471 act = next_no_void_action(actions, act);
1472 }
1473
1474
1475 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1476 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1477 rte_flow_error_set(error, EINVAL,
1478 RTE_FLOW_ERROR_TYPE_ACTION,
1479 act, "Not supported action.");
1480 return -rte_errno;
1481 }
1482
1483 return 0;
1484}
1485
1486
1487static inline
1488const struct rte_flow_item *next_no_fuzzy_pattern(
1489 const struct rte_flow_item pattern[],
1490 const struct rte_flow_item *cur)
1491{
1492 const struct rte_flow_item *next =
1493 next_no_void_pattern(pattern, cur);
1494 while (1) {
1495 if (next->type != RTE_FLOW_ITEM_TYPE_FUZZY)
1496 return next;
1497 next = next_no_void_pattern(pattern, next);
1498 }
1499}
1500
1501static inline uint8_t signature_match(const struct rte_flow_item pattern[])
1502{
1503 const struct rte_flow_item_fuzzy *spec, *last, *mask;
1504 const struct rte_flow_item *item;
1505 uint32_t sh, lh, mh;
1506 int i = 0;
1507
1508 while (1) {
1509 item = pattern + i;
1510 if (item->type == RTE_FLOW_ITEM_TYPE_END)
1511 break;
1512
1513 if (item->type == RTE_FLOW_ITEM_TYPE_FUZZY) {
1514 spec = item->spec;
1515 last = item->last;
1516 mask = item->mask;
1517
1518 if (!spec || !mask)
1519 return 0;
1520
1521 sh = spec->thresh;
1522
1523 if (!last)
1524 lh = sh;
1525 else
1526 lh = last->thresh;
1527
1528 mh = mask->thresh;
1529 sh = sh & mh;
1530 lh = lh & mh;
1531
1532 if (!sh || sh > lh)
1533 return 0;
1534
1535 return 1;
1536 }
1537
1538 i++;
1539 }
1540
1541 return 0;
1542}
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590static int
1591ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev,
1592 const struct rte_flow_attr *attr,
1593 const struct rte_flow_item pattern[],
1594 const struct rte_flow_action actions[],
1595 struct ixgbe_fdir_rule *rule,
1596 struct rte_flow_error *error)
1597{
1598 const struct rte_flow_item *item;
1599 const struct rte_flow_item_eth *eth_spec;
1600 const struct rte_flow_item_eth *eth_mask;
1601 const struct rte_flow_item_ipv4 *ipv4_spec;
1602 const struct rte_flow_item_ipv4 *ipv4_mask;
1603 const struct rte_flow_item_ipv6 *ipv6_spec;
1604 const struct rte_flow_item_ipv6 *ipv6_mask;
1605 const struct rte_flow_item_tcp *tcp_spec;
1606 const struct rte_flow_item_tcp *tcp_mask;
1607 const struct rte_flow_item_udp *udp_spec;
1608 const struct rte_flow_item_udp *udp_mask;
1609 const struct rte_flow_item_sctp *sctp_spec;
1610 const struct rte_flow_item_sctp *sctp_mask;
1611 const struct rte_flow_item_vlan *vlan_spec;
1612 const struct rte_flow_item_vlan *vlan_mask;
1613 const struct rte_flow_item_raw *raw_mask;
1614 const struct rte_flow_item_raw *raw_spec;
1615 uint8_t j;
1616
1617 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1618
1619 if (!pattern) {
1620 rte_flow_error_set(error, EINVAL,
1621 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1622 NULL, "NULL pattern.");
1623 return -rte_errno;
1624 }
1625
1626 if (!actions) {
1627 rte_flow_error_set(error, EINVAL,
1628 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1629 NULL, "NULL action.");
1630 return -rte_errno;
1631 }
1632
1633 if (!attr) {
1634 rte_flow_error_set(error, EINVAL,
1635 RTE_FLOW_ERROR_TYPE_ATTR,
1636 NULL, "NULL attribute.");
1637 return -rte_errno;
1638 }
1639
1640
1641
1642
1643
1644 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1645 memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
1646 rule->mask.vlan_tci_mask = 0;
1647 rule->mask.flex_bytes_mask = 0;
1648
1649
1650
1651
1652
1653 item = next_no_fuzzy_pattern(pattern, NULL);
1654 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
1655 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1656 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
1657 item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1658 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1659 item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
1660 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1661 rte_flow_error_set(error, EINVAL,
1662 RTE_FLOW_ERROR_TYPE_ITEM,
1663 item, "Not supported by fdir filter");
1664 return -rte_errno;
1665 }
1666
1667 if (signature_match(pattern))
1668 rule->mode = RTE_FDIR_MODE_SIGNATURE;
1669 else
1670 rule->mode = RTE_FDIR_MODE_PERFECT;
1671
1672
1673 if (item->last) {
1674 rte_flow_error_set(error, EINVAL,
1675 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1676 item, "Not supported last point for range");
1677 return -rte_errno;
1678 }
1679
1680
1681 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
1682
1683
1684
1685
1686 if (item->spec && !item->mask) {
1687 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1688 rte_flow_error_set(error, EINVAL,
1689 RTE_FLOW_ERROR_TYPE_ITEM,
1690 item, "Not supported by fdir filter");
1691 return -rte_errno;
1692 }
1693
1694 if (item->spec) {
1695 rule->b_spec = TRUE;
1696 eth_spec = item->spec;
1697
1698
1699 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
1700 rule->ixgbe_fdir.formatted.inner_mac[j] =
1701 eth_spec->dst.addr_bytes[j];
1702 }
1703 }
1704
1705
1706 if (item->mask) {
1707
1708 rule->b_mask = TRUE;
1709 eth_mask = item->mask;
1710
1711
1712 if (eth_mask->type ||
1713 rule->mode == RTE_FDIR_MODE_SIGNATURE) {
1714 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1715 rte_flow_error_set(error, EINVAL,
1716 RTE_FLOW_ERROR_TYPE_ITEM,
1717 item, "Not supported by fdir filter");
1718 return -rte_errno;
1719 }
1720
1721
1722 rule->mode = RTE_FDIR_MODE_PERFECT_MAC_VLAN;
1723
1724
1725
1726
1727
1728 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
1729 if (eth_mask->src.addr_bytes[j] ||
1730 eth_mask->dst.addr_bytes[j] != 0xFF) {
1731 memset(rule, 0,
1732 sizeof(struct ixgbe_fdir_rule));
1733 rte_flow_error_set(error, EINVAL,
1734 RTE_FLOW_ERROR_TYPE_ITEM,
1735 item, "Not supported by fdir filter");
1736 return -rte_errno;
1737 }
1738 }
1739
1740
1741 rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
1742 }
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752 item = next_no_fuzzy_pattern(pattern, item);
1753 if (rule->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
1754 if (item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
1755 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1756 rte_flow_error_set(error, EINVAL,
1757 RTE_FLOW_ERROR_TYPE_ITEM,
1758 item, "Not supported by fdir filter");
1759 return -rte_errno;
1760 }
1761 } else {
1762 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
1763 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 }
1771 }
1772
1773 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1774 if (!(item->spec && item->mask)) {
1775 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1776 rte_flow_error_set(error, EINVAL,
1777 RTE_FLOW_ERROR_TYPE_ITEM,
1778 item, "Not supported by fdir filter");
1779 return -rte_errno;
1780 }
1781
1782
1783 if (item->last) {
1784 rte_flow_error_set(error, EINVAL,
1785 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1786 item, "Not supported last point for range");
1787 return -rte_errno;
1788 }
1789
1790 vlan_spec = item->spec;
1791 vlan_mask = item->mask;
1792
1793 rule->ixgbe_fdir.formatted.vlan_id = vlan_spec->tci;
1794
1795 rule->mask.vlan_tci_mask = vlan_mask->tci;
1796 rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
1797
1798
1799
1800 item = next_no_fuzzy_pattern(pattern, item);
1801 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
1802 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1803 rte_flow_error_set(error, EINVAL,
1804 RTE_FLOW_ERROR_TYPE_ITEM,
1805 item, "Not supported by fdir filter");
1806 return -rte_errno;
1807 }
1808 }
1809
1810
1811 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1812
1813
1814
1815
1816 rule->ixgbe_fdir.formatted.flow_type =
1817 IXGBE_ATR_FLOW_TYPE_IPV4;
1818
1819 if (item->last) {
1820 rte_flow_error_set(error, EINVAL,
1821 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1822 item, "Not supported last point for range");
1823 return -rte_errno;
1824 }
1825
1826
1827
1828
1829 if (!item->mask) {
1830 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1831 rte_flow_error_set(error, EINVAL,
1832 RTE_FLOW_ERROR_TYPE_ITEM,
1833 item, "Not supported by fdir filter");
1834 return -rte_errno;
1835 }
1836 rule->b_mask = TRUE;
1837 ipv4_mask = item->mask;
1838 if (ipv4_mask->hdr.version_ihl ||
1839 ipv4_mask->hdr.type_of_service ||
1840 ipv4_mask->hdr.total_length ||
1841 ipv4_mask->hdr.packet_id ||
1842 ipv4_mask->hdr.fragment_offset ||
1843 ipv4_mask->hdr.time_to_live ||
1844 ipv4_mask->hdr.next_proto_id ||
1845 ipv4_mask->hdr.hdr_checksum) {
1846 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1847 rte_flow_error_set(error, EINVAL,
1848 RTE_FLOW_ERROR_TYPE_ITEM,
1849 item, "Not supported by fdir filter");
1850 return -rte_errno;
1851 }
1852 rule->mask.dst_ipv4_mask = ipv4_mask->hdr.dst_addr;
1853 rule->mask.src_ipv4_mask = ipv4_mask->hdr.src_addr;
1854
1855 if (item->spec) {
1856 rule->b_spec = TRUE;
1857 ipv4_spec = item->spec;
1858 rule->ixgbe_fdir.formatted.dst_ip[0] =
1859 ipv4_spec->hdr.dst_addr;
1860 rule->ixgbe_fdir.formatted.src_ip[0] =
1861 ipv4_spec->hdr.src_addr;
1862 }
1863
1864
1865
1866
1867
1868 item = next_no_fuzzy_pattern(pattern, item);
1869 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1870 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1871 item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
1872 item->type != RTE_FLOW_ITEM_TYPE_END &&
1873 item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1874 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1875 rte_flow_error_set(error, EINVAL,
1876 RTE_FLOW_ERROR_TYPE_ITEM,
1877 item, "Not supported by fdir filter");
1878 return -rte_errno;
1879 }
1880 }
1881
1882
1883 if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
1884
1885
1886
1887
1888 rule->ixgbe_fdir.formatted.flow_type =
1889 IXGBE_ATR_FLOW_TYPE_IPV6;
1890
1891
1892
1893
1894
1895
1896 if (rule->mode != RTE_FDIR_MODE_SIGNATURE ||
1897 item->last ||
1898 !item->mask) {
1899 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1900 rte_flow_error_set(error, EINVAL,
1901 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1902 item, "Not supported last point for range");
1903 return -rte_errno;
1904 }
1905
1906 rule->b_mask = TRUE;
1907 ipv6_mask = item->mask;
1908 if (ipv6_mask->hdr.vtc_flow ||
1909 ipv6_mask->hdr.payload_len ||
1910 ipv6_mask->hdr.proto ||
1911 ipv6_mask->hdr.hop_limits) {
1912 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1913 rte_flow_error_set(error, EINVAL,
1914 RTE_FLOW_ERROR_TYPE_ITEM,
1915 item, "Not supported by fdir filter");
1916 return -rte_errno;
1917 }
1918
1919
1920 for (j = 0; j < 16; j++) {
1921 if (ipv6_mask->hdr.src_addr[j] == UINT8_MAX) {
1922 rule->mask.src_ipv6_mask |= 1 << j;
1923 } else if (ipv6_mask->hdr.src_addr[j] != 0) {
1924 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1925 rte_flow_error_set(error, EINVAL,
1926 RTE_FLOW_ERROR_TYPE_ITEM,
1927 item, "Not supported by fdir filter");
1928 return -rte_errno;
1929 }
1930 }
1931
1932
1933 for (j = 0; j < 16; j++) {
1934 if (ipv6_mask->hdr.dst_addr[j] == UINT8_MAX) {
1935 rule->mask.dst_ipv6_mask |= 1 << j;
1936 } else if (ipv6_mask->hdr.dst_addr[j] != 0) {
1937 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1938 rte_flow_error_set(error, EINVAL,
1939 RTE_FLOW_ERROR_TYPE_ITEM,
1940 item, "Not supported by fdir filter");
1941 return -rte_errno;
1942 }
1943 }
1944
1945 if (item->spec) {
1946 rule->b_spec = TRUE;
1947 ipv6_spec = item->spec;
1948 rte_memcpy(rule->ixgbe_fdir.formatted.src_ip,
1949 ipv6_spec->hdr.src_addr, 16);
1950 rte_memcpy(rule->ixgbe_fdir.formatted.dst_ip,
1951 ipv6_spec->hdr.dst_addr, 16);
1952 }
1953
1954
1955
1956
1957
1958 item = next_no_fuzzy_pattern(pattern, item);
1959 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
1960 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
1961 item->type != RTE_FLOW_ITEM_TYPE_SCTP &&
1962 item->type != RTE_FLOW_ITEM_TYPE_END &&
1963 item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1964 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1965 rte_flow_error_set(error, EINVAL,
1966 RTE_FLOW_ERROR_TYPE_ITEM,
1967 item, "Not supported by fdir filter");
1968 return -rte_errno;
1969 }
1970 }
1971
1972
1973 if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
1974
1975
1976
1977
1978 rule->ixgbe_fdir.formatted.flow_type |=
1979 IXGBE_ATR_L4TYPE_TCP;
1980
1981 if (item->last) {
1982 rte_flow_error_set(error, EINVAL,
1983 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1984 item, "Not supported last point for range");
1985 return -rte_errno;
1986 }
1987
1988
1989
1990
1991 if (!item->mask) {
1992 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
1993 rte_flow_error_set(error, EINVAL,
1994 RTE_FLOW_ERROR_TYPE_ITEM,
1995 item, "Not supported by fdir filter");
1996 return -rte_errno;
1997 }
1998 rule->b_mask = TRUE;
1999 tcp_mask = item->mask;
2000 if (tcp_mask->hdr.sent_seq ||
2001 tcp_mask->hdr.recv_ack ||
2002 tcp_mask->hdr.data_off ||
2003 tcp_mask->hdr.tcp_flags ||
2004 tcp_mask->hdr.rx_win ||
2005 tcp_mask->hdr.cksum ||
2006 tcp_mask->hdr.tcp_urp) {
2007 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2008 rte_flow_error_set(error, EINVAL,
2009 RTE_FLOW_ERROR_TYPE_ITEM,
2010 item, "Not supported by fdir filter");
2011 return -rte_errno;
2012 }
2013 rule->mask.src_port_mask = tcp_mask->hdr.src_port;
2014 rule->mask.dst_port_mask = tcp_mask->hdr.dst_port;
2015
2016 if (item->spec) {
2017 rule->b_spec = TRUE;
2018 tcp_spec = item->spec;
2019 rule->ixgbe_fdir.formatted.src_port =
2020 tcp_spec->hdr.src_port;
2021 rule->ixgbe_fdir.formatted.dst_port =
2022 tcp_spec->hdr.dst_port;
2023 }
2024
2025 item = next_no_fuzzy_pattern(pattern, item);
2026 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
2027 item->type != RTE_FLOW_ITEM_TYPE_END) {
2028 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2029 rte_flow_error_set(error, EINVAL,
2030 RTE_FLOW_ERROR_TYPE_ITEM,
2031 item, "Not supported by fdir filter");
2032 return -rte_errno;
2033 }
2034
2035 }
2036
2037
2038 if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
2039
2040
2041
2042
2043 rule->ixgbe_fdir.formatted.flow_type |=
2044 IXGBE_ATR_L4TYPE_UDP;
2045
2046 if (item->last) {
2047 rte_flow_error_set(error, EINVAL,
2048 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2049 item, "Not supported last point for range");
2050 return -rte_errno;
2051 }
2052
2053
2054
2055
2056 if (!item->mask) {
2057 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2058 rte_flow_error_set(error, EINVAL,
2059 RTE_FLOW_ERROR_TYPE_ITEM,
2060 item, "Not supported by fdir filter");
2061 return -rte_errno;
2062 }
2063 rule->b_mask = TRUE;
2064 udp_mask = item->mask;
2065 if (udp_mask->hdr.dgram_len ||
2066 udp_mask->hdr.dgram_cksum) {
2067 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2068 rte_flow_error_set(error, EINVAL,
2069 RTE_FLOW_ERROR_TYPE_ITEM,
2070 item, "Not supported by fdir filter");
2071 return -rte_errno;
2072 }
2073 rule->mask.src_port_mask = udp_mask->hdr.src_port;
2074 rule->mask.dst_port_mask = udp_mask->hdr.dst_port;
2075
2076 if (item->spec) {
2077 rule->b_spec = TRUE;
2078 udp_spec = item->spec;
2079 rule->ixgbe_fdir.formatted.src_port =
2080 udp_spec->hdr.src_port;
2081 rule->ixgbe_fdir.formatted.dst_port =
2082 udp_spec->hdr.dst_port;
2083 }
2084
2085 item = next_no_fuzzy_pattern(pattern, item);
2086 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
2087 item->type != RTE_FLOW_ITEM_TYPE_END) {
2088 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2089 rte_flow_error_set(error, EINVAL,
2090 RTE_FLOW_ERROR_TYPE_ITEM,
2091 item, "Not supported by fdir filter");
2092 return -rte_errno;
2093 }
2094
2095 }
2096
2097
2098 if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) {
2099
2100
2101
2102
2103 rule->ixgbe_fdir.formatted.flow_type |=
2104 IXGBE_ATR_L4TYPE_SCTP;
2105
2106 if (item->last) {
2107 rte_flow_error_set(error, EINVAL,
2108 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2109 item, "Not supported last point for range");
2110 return -rte_errno;
2111 }
2112
2113
2114 if (hw->mac.type == ixgbe_mac_X550 ||
2115 hw->mac.type == ixgbe_mac_X550EM_x ||
2116 hw->mac.type == ixgbe_mac_X550EM_a) {
2117
2118
2119
2120
2121 if (!item->mask) {
2122 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2123 rte_flow_error_set(error, EINVAL,
2124 RTE_FLOW_ERROR_TYPE_ITEM,
2125 item, "Not supported by fdir filter");
2126 return -rte_errno;
2127 }
2128 rule->b_mask = TRUE;
2129 sctp_mask = item->mask;
2130 if (sctp_mask->hdr.tag ||
2131 sctp_mask->hdr.cksum) {
2132 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2133 rte_flow_error_set(error, EINVAL,
2134 RTE_FLOW_ERROR_TYPE_ITEM,
2135 item, "Not supported by fdir filter");
2136 return -rte_errno;
2137 }
2138 rule->mask.src_port_mask = sctp_mask->hdr.src_port;
2139 rule->mask.dst_port_mask = sctp_mask->hdr.dst_port;
2140
2141 if (item->spec) {
2142 rule->b_spec = TRUE;
2143 sctp_spec = item->spec;
2144 rule->ixgbe_fdir.formatted.src_port =
2145 sctp_spec->hdr.src_port;
2146 rule->ixgbe_fdir.formatted.dst_port =
2147 sctp_spec->hdr.dst_port;
2148 }
2149
2150 } else {
2151 sctp_mask = item->mask;
2152 if (sctp_mask &&
2153 (sctp_mask->hdr.src_port ||
2154 sctp_mask->hdr.dst_port ||
2155 sctp_mask->hdr.tag ||
2156 sctp_mask->hdr.cksum)) {
2157 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2158 rte_flow_error_set(error, EINVAL,
2159 RTE_FLOW_ERROR_TYPE_ITEM,
2160 item, "Not supported by fdir filter");
2161 return -rte_errno;
2162 }
2163 }
2164
2165 item = next_no_fuzzy_pattern(pattern, item);
2166 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
2167 item->type != RTE_FLOW_ITEM_TYPE_END) {
2168 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2169 rte_flow_error_set(error, EINVAL,
2170 RTE_FLOW_ERROR_TYPE_ITEM,
2171 item, "Not supported by fdir filter");
2172 return -rte_errno;
2173 }
2174 }
2175
2176
2177 if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
2178
2179 if (item->last) {
2180 rte_flow_error_set(error, EINVAL,
2181 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2182 item, "Not supported last point for range");
2183 return -rte_errno;
2184 }
2185
2186 if (!item->mask || !item->spec) {
2187 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2188 rte_flow_error_set(error, EINVAL,
2189 RTE_FLOW_ERROR_TYPE_ITEM,
2190 item, "Not supported by fdir filter");
2191 return -rte_errno;
2192 }
2193
2194 raw_mask = item->mask;
2195
2196
2197 if (raw_mask->relative != 0x1 ||
2198 raw_mask->search != 0x1 ||
2199 raw_mask->reserved != 0x0 ||
2200 (uint32_t)raw_mask->offset != 0xffffffff ||
2201 raw_mask->limit != 0xffff ||
2202 raw_mask->length != 0xffff) {
2203 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2204 rte_flow_error_set(error, EINVAL,
2205 RTE_FLOW_ERROR_TYPE_ITEM,
2206 item, "Not supported by fdir filter");
2207 return -rte_errno;
2208 }
2209
2210 raw_spec = item->spec;
2211
2212
2213 if (raw_spec->relative != 0 ||
2214 raw_spec->search != 0 ||
2215 raw_spec->reserved != 0 ||
2216 raw_spec->offset > IXGBE_MAX_FLX_SOURCE_OFF ||
2217 raw_spec->offset % 2 ||
2218 raw_spec->limit != 0 ||
2219 raw_spec->length != 2 ||
2220
2221 (raw_spec->pattern[0] == 0xff &&
2222 raw_spec->pattern[1] == 0xff)) {
2223 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2224 rte_flow_error_set(error, EINVAL,
2225 RTE_FLOW_ERROR_TYPE_ITEM,
2226 item, "Not supported by fdir filter");
2227 return -rte_errno;
2228 }
2229
2230
2231 if (raw_mask->pattern[0] != 0xff ||
2232 raw_mask->pattern[1] != 0xff) {
2233 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2234 rte_flow_error_set(error, EINVAL,
2235 RTE_FLOW_ERROR_TYPE_ITEM,
2236 item, "Not supported by fdir filter");
2237 return -rte_errno;
2238 }
2239
2240 rule->mask.flex_bytes_mask = 0xffff;
2241 rule->ixgbe_fdir.formatted.flex_bytes =
2242 (((uint16_t)raw_spec->pattern[1]) << 8) |
2243 raw_spec->pattern[0];
2244 rule->flex_bytes_offset = raw_spec->offset;
2245 }
2246
2247 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2248
2249 item = next_no_fuzzy_pattern(pattern, item);
2250 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2251 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2252 rte_flow_error_set(error, EINVAL,
2253 RTE_FLOW_ERROR_TYPE_ITEM,
2254 item, "Not supported by fdir filter");
2255 return -rte_errno;
2256 }
2257 }
2258
2259 return ixgbe_parse_fdir_act_attr(attr, actions, rule, error);
2260}
2261
2262#define NVGRE_PROTOCOL 0x6558
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301static int
2302ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
2303 const struct rte_flow_item pattern[],
2304 const struct rte_flow_action actions[],
2305 struct ixgbe_fdir_rule *rule,
2306 struct rte_flow_error *error)
2307{
2308 const struct rte_flow_item *item;
2309 const struct rte_flow_item_vxlan *vxlan_spec;
2310 const struct rte_flow_item_vxlan *vxlan_mask;
2311 const struct rte_flow_item_nvgre *nvgre_spec;
2312 const struct rte_flow_item_nvgre *nvgre_mask;
2313 const struct rte_flow_item_eth *eth_spec;
2314 const struct rte_flow_item_eth *eth_mask;
2315 const struct rte_flow_item_vlan *vlan_spec;
2316 const struct rte_flow_item_vlan *vlan_mask;
2317 uint32_t j;
2318
2319 if (!pattern) {
2320 rte_flow_error_set(error, EINVAL,
2321 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
2322 NULL, "NULL pattern.");
2323 return -rte_errno;
2324 }
2325
2326 if (!actions) {
2327 rte_flow_error_set(error, EINVAL,
2328 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
2329 NULL, "NULL action.");
2330 return -rte_errno;
2331 }
2332
2333 if (!attr) {
2334 rte_flow_error_set(error, EINVAL,
2335 RTE_FLOW_ERROR_TYPE_ATTR,
2336 NULL, "NULL attribute.");
2337 return -rte_errno;
2338 }
2339
2340
2341
2342
2343
2344 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2345 memset(&rule->mask, 0xFF, sizeof(struct ixgbe_hw_fdir_mask));
2346 rule->mask.vlan_tci_mask = 0;
2347
2348
2349
2350
2351
2352 item = next_no_void_pattern(pattern, NULL);
2353 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
2354 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
2355 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
2356 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
2357 item->type != RTE_FLOW_ITEM_TYPE_VXLAN &&
2358 item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
2359 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2360 rte_flow_error_set(error, EINVAL,
2361 RTE_FLOW_ERROR_TYPE_ITEM,
2362 item, "Not supported by fdir filter");
2363 return -rte_errno;
2364 }
2365
2366 rule->mode = RTE_FDIR_MODE_PERFECT_TUNNEL;
2367
2368
2369 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
2370
2371 if (item->spec || item->mask) {
2372 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2373 rte_flow_error_set(error, EINVAL,
2374 RTE_FLOW_ERROR_TYPE_ITEM,
2375 item, "Not supported by fdir filter");
2376 return -rte_errno;
2377 }
2378
2379 if (item->last) {
2380 rte_flow_error_set(error, EINVAL,
2381 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2382 item, "Not supported last point for range");
2383 return -rte_errno;
2384 }
2385
2386
2387 item = next_no_void_pattern(pattern, item);
2388 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
2389 item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
2390 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2391 rte_flow_error_set(error, EINVAL,
2392 RTE_FLOW_ERROR_TYPE_ITEM,
2393 item, "Not supported by fdir filter");
2394 return -rte_errno;
2395 }
2396 }
2397
2398
2399 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
2400 item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
2401
2402 if (item->spec || item->mask) {
2403 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2404 rte_flow_error_set(error, EINVAL,
2405 RTE_FLOW_ERROR_TYPE_ITEM,
2406 item, "Not supported by fdir filter");
2407 return -rte_errno;
2408 }
2409
2410 if (item->last) {
2411 rte_flow_error_set(error, EINVAL,
2412 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2413 item, "Not supported last point for range");
2414 return -rte_errno;
2415 }
2416
2417
2418 item = next_no_void_pattern(pattern, item);
2419 if (item->type != RTE_FLOW_ITEM_TYPE_UDP &&
2420 item->type != RTE_FLOW_ITEM_TYPE_NVGRE) {
2421 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2422 rte_flow_error_set(error, EINVAL,
2423 RTE_FLOW_ERROR_TYPE_ITEM,
2424 item, "Not supported by fdir filter");
2425 return -rte_errno;
2426 }
2427 }
2428
2429
2430 if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
2431
2432 if (item->spec || item->mask) {
2433 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2434 rte_flow_error_set(error, EINVAL,
2435 RTE_FLOW_ERROR_TYPE_ITEM,
2436 item, "Not supported by fdir filter");
2437 return -rte_errno;
2438 }
2439
2440 if (item->last) {
2441 rte_flow_error_set(error, EINVAL,
2442 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2443 item, "Not supported last point for range");
2444 return -rte_errno;
2445 }
2446
2447
2448 item = next_no_void_pattern(pattern, item);
2449 if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
2450 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2451 rte_flow_error_set(error, EINVAL,
2452 RTE_FLOW_ERROR_TYPE_ITEM,
2453 item, "Not supported by fdir filter");
2454 return -rte_errno;
2455 }
2456 }
2457
2458
2459 if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
2460 rule->ixgbe_fdir.formatted.tunnel_type =
2461 IXGBE_FDIR_VXLAN_TUNNEL_TYPE;
2462
2463
2464 if (!item->mask) {
2465 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2466 rte_flow_error_set(error, EINVAL,
2467 RTE_FLOW_ERROR_TYPE_ITEM,
2468 item, "Not supported by fdir filter");
2469 return -rte_errno;
2470 }
2471
2472 if (item->last) {
2473 rte_flow_error_set(error, EINVAL,
2474 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2475 item, "Not supported last point for range");
2476 return -rte_errno;
2477 }
2478 rule->b_mask = TRUE;
2479
2480
2481 rule->mask.tunnel_type_mask = 1;
2482
2483 vxlan_mask = item->mask;
2484 if (vxlan_mask->flags) {
2485 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2486 rte_flow_error_set(error, EINVAL,
2487 RTE_FLOW_ERROR_TYPE_ITEM,
2488 item, "Not supported by fdir filter");
2489 return -rte_errno;
2490 }
2491
2492 if ((vxlan_mask->vni[0] || vxlan_mask->vni[1] ||
2493 vxlan_mask->vni[2]) &&
2494 ((vxlan_mask->vni[0] != 0xFF) ||
2495 (vxlan_mask->vni[1] != 0xFF) ||
2496 (vxlan_mask->vni[2] != 0xFF))) {
2497 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2498 rte_flow_error_set(error, EINVAL,
2499 RTE_FLOW_ERROR_TYPE_ITEM,
2500 item, "Not supported by fdir filter");
2501 return -rte_errno;
2502 }
2503
2504 rte_memcpy(&rule->mask.tunnel_id_mask, vxlan_mask->vni,
2505 RTE_DIM(vxlan_mask->vni));
2506
2507 if (item->spec) {
2508 rule->b_spec = TRUE;
2509 vxlan_spec = item->spec;
2510 rte_memcpy(((uint8_t *)
2511 &rule->ixgbe_fdir.formatted.tni_vni),
2512 vxlan_spec->vni, RTE_DIM(vxlan_spec->vni));
2513 }
2514 }
2515
2516
2517 if (item->type == RTE_FLOW_ITEM_TYPE_NVGRE) {
2518 rule->ixgbe_fdir.formatted.tunnel_type =
2519 IXGBE_FDIR_NVGRE_TUNNEL_TYPE;
2520
2521
2522
2523
2524
2525 if (!item->mask) {
2526 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2527 rte_flow_error_set(error, EINVAL,
2528 RTE_FLOW_ERROR_TYPE_ITEM,
2529 item, "Not supported by fdir filter");
2530 return -rte_errno;
2531 }
2532
2533 if (item->last) {
2534 rte_flow_error_set(error, EINVAL,
2535 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2536 item, "Not supported last point for range");
2537 return -rte_errno;
2538 }
2539 rule->b_mask = TRUE;
2540
2541
2542 rule->mask.tunnel_type_mask = 1;
2543
2544 nvgre_mask = item->mask;
2545 if (nvgre_mask->flow_id) {
2546 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2547 rte_flow_error_set(error, EINVAL,
2548 RTE_FLOW_ERROR_TYPE_ITEM,
2549 item, "Not supported by fdir filter");
2550 return -rte_errno;
2551 }
2552 if (nvgre_mask->protocol &&
2553 nvgre_mask->protocol != 0xFFFF) {
2554 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2555 rte_flow_error_set(error, EINVAL,
2556 RTE_FLOW_ERROR_TYPE_ITEM,
2557 item, "Not supported by fdir filter");
2558 return -rte_errno;
2559 }
2560 if (nvgre_mask->c_k_s_rsvd0_ver &&
2561 nvgre_mask->c_k_s_rsvd0_ver !=
2562 rte_cpu_to_be_16(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
2570 if (nvgre_mask->tni[0] &&
2571 ((nvgre_mask->tni[0] != 0xFF) ||
2572 (nvgre_mask->tni[1] != 0xFF) ||
2573 (nvgre_mask->tni[2] != 0xFF))) {
2574 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2575 rte_flow_error_set(error, EINVAL,
2576 RTE_FLOW_ERROR_TYPE_ITEM,
2577 item, "Not supported by fdir filter");
2578 return -rte_errno;
2579 }
2580
2581 rte_memcpy(&rule->mask.tunnel_id_mask, nvgre_mask->tni,
2582 RTE_DIM(nvgre_mask->tni));
2583 rule->mask.tunnel_id_mask <<= 8;
2584
2585 if (item->spec) {
2586 rule->b_spec = TRUE;
2587 nvgre_spec = item->spec;
2588 if (nvgre_spec->c_k_s_rsvd0_ver !=
2589 rte_cpu_to_be_16(0x2000) &&
2590 nvgre_mask->c_k_s_rsvd0_ver) {
2591 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2592 rte_flow_error_set(error, EINVAL,
2593 RTE_FLOW_ERROR_TYPE_ITEM,
2594 item, "Not supported by fdir filter");
2595 return -rte_errno;
2596 }
2597 if (nvgre_mask->protocol &&
2598 nvgre_spec->protocol !=
2599 rte_cpu_to_be_16(NVGRE_PROTOCOL)) {
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
2607 rte_memcpy(&rule->ixgbe_fdir.formatted.tni_vni,
2608 nvgre_spec->tni, RTE_DIM(nvgre_spec->tni));
2609 }
2610 }
2611
2612
2613 item = next_no_void_pattern(pattern, item);
2614 if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
2615 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2616 rte_flow_error_set(error, EINVAL,
2617 RTE_FLOW_ERROR_TYPE_ITEM,
2618 item, "Not supported by fdir filter");
2619 return -rte_errno;
2620 }
2621
2622
2623
2624
2625
2626
2627 if (!item->mask) {
2628 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2629 rte_flow_error_set(error, EINVAL,
2630 RTE_FLOW_ERROR_TYPE_ITEM,
2631 item, "Not supported by fdir filter");
2632 return -rte_errno;
2633 }
2634
2635 if (item->last) {
2636 rte_flow_error_set(error, EINVAL,
2637 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2638 item, "Not supported last point for range");
2639 return -rte_errno;
2640 }
2641 rule->b_mask = TRUE;
2642 eth_mask = item->mask;
2643
2644
2645 if (eth_mask->type) {
2646 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2647 rte_flow_error_set(error, EINVAL,
2648 RTE_FLOW_ERROR_TYPE_ITEM,
2649 item, "Not supported by fdir filter");
2650 return -rte_errno;
2651 }
2652
2653
2654 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
2655 if (eth_mask->src.addr_bytes[j]) {
2656 memset(rule, 0,
2657 sizeof(struct ixgbe_fdir_rule));
2658 rte_flow_error_set(error, EINVAL,
2659 RTE_FLOW_ERROR_TYPE_ITEM,
2660 item, "Not supported by fdir filter");
2661 return -rte_errno;
2662 }
2663 }
2664 rule->mask.mac_addr_byte_mask = 0;
2665 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
2666
2667 if (eth_mask->dst.addr_bytes[j] == 0xFF) {
2668 rule->mask.mac_addr_byte_mask |= 0x1 << j;
2669 } else if (eth_mask->dst.addr_bytes[j]) {
2670 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2671 rte_flow_error_set(error, EINVAL,
2672 RTE_FLOW_ERROR_TYPE_ITEM,
2673 item, "Not supported by fdir filter");
2674 return -rte_errno;
2675 }
2676 }
2677
2678
2679 rule->mask.vlan_tci_mask = rte_cpu_to_be_16(0xEFFF);
2680
2681 if (item->spec) {
2682 rule->b_spec = TRUE;
2683 eth_spec = item->spec;
2684
2685
2686 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) {
2687 rule->ixgbe_fdir.formatted.inner_mac[j] =
2688 eth_spec->dst.addr_bytes[j];
2689 }
2690 }
2691
2692
2693
2694
2695
2696 item = next_no_void_pattern(pattern, item);
2697 if ((item->type != RTE_FLOW_ITEM_TYPE_VLAN) &&
2698 (item->type != RTE_FLOW_ITEM_TYPE_IPV4)) {
2699 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2700 rte_flow_error_set(error, EINVAL,
2701 RTE_FLOW_ERROR_TYPE_ITEM,
2702 item, "Not supported by fdir filter");
2703 return -rte_errno;
2704 }
2705
2706 if (item->last) {
2707 rte_flow_error_set(error, EINVAL,
2708 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2709 item, "Not supported last point for range");
2710 return -rte_errno;
2711 }
2712
2713 if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
2714 if (!(item->spec && item->mask)) {
2715 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2716 rte_flow_error_set(error, EINVAL,
2717 RTE_FLOW_ERROR_TYPE_ITEM,
2718 item, "Not supported by fdir filter");
2719 return -rte_errno;
2720 }
2721
2722 vlan_spec = item->spec;
2723 vlan_mask = item->mask;
2724
2725 rule->ixgbe_fdir.formatted.vlan_id = vlan_spec->tci;
2726
2727 rule->mask.vlan_tci_mask = vlan_mask->tci;
2728 rule->mask.vlan_tci_mask &= rte_cpu_to_be_16(0xEFFF);
2729
2730
2731
2732 item = next_no_void_pattern(pattern, item);
2733
2734 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
2735 memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
2736 rte_flow_error_set(error, EINVAL,
2737 RTE_FLOW_ERROR_TYPE_ITEM,
2738 item, "Not supported by fdir filter");
2739 return -rte_errno;
2740 }
2741 }
2742
2743
2744
2745
2746
2747
2748 return ixgbe_parse_fdir_act_attr(attr, actions, rule, error);
2749}
2750
2751static int
2752ixgbe_parse_fdir_filter(struct rte_eth_dev *dev,
2753 const struct rte_flow_attr *attr,
2754 const struct rte_flow_item pattern[],
2755 const struct rte_flow_action actions[],
2756 struct ixgbe_fdir_rule *rule,
2757 struct rte_flow_error *error)
2758{
2759 int ret;
2760 struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2761 enum rte_fdir_mode fdir_mode = dev->data->dev_conf.fdir_conf.mode;
2762
2763 if (hw->mac.type != ixgbe_mac_82599EB &&
2764 hw->mac.type != ixgbe_mac_X540 &&
2765 hw->mac.type != ixgbe_mac_X550 &&
2766 hw->mac.type != ixgbe_mac_X550EM_x &&
2767 hw->mac.type != ixgbe_mac_X550EM_a)
2768 return -ENOTSUP;
2769
2770 ret = ixgbe_parse_fdir_filter_normal(dev, attr, pattern,
2771 actions, rule, error);
2772
2773 if (!ret)
2774 goto step_next;
2775
2776 ret = ixgbe_parse_fdir_filter_tunnel(attr, pattern,
2777 actions, rule, error);
2778
2779 if (ret)
2780 return ret;
2781
2782step_next:
2783
2784 if (hw->mac.type == ixgbe_mac_82599EB &&
2785 rule->fdirflags == IXGBE_FDIRCMD_DROP &&
2786 (rule->ixgbe_fdir.formatted.src_port != 0 ||
2787 rule->ixgbe_fdir.formatted.dst_port != 0))
2788 return -ENOTSUP;
2789
2790 if (fdir_mode == RTE_FDIR_MODE_NONE ||
2791 fdir_mode != rule->mode)
2792 return -ENOTSUP;
2793
2794 if (rule->queue >= dev->data->nb_rx_queues)
2795 return -ENOTSUP;
2796
2797 return ret;
2798}
2799
2800static int
2801ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
2802 const struct rte_flow_attr *attr,
2803 const struct rte_flow_action actions[],
2804 struct ixgbe_rte_flow_rss_conf *rss_conf,
2805 struct rte_flow_error *error)
2806{
2807 const struct rte_flow_action *act;
2808 const struct rte_flow_action_rss *rss;
2809 uint16_t n;
2810
2811
2812
2813
2814
2815 act = next_no_void_action(actions, NULL);
2816 if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
2817 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2818 rte_flow_error_set(error, EINVAL,
2819 RTE_FLOW_ERROR_TYPE_ACTION,
2820 act, "Not supported action.");
2821 return -rte_errno;
2822 }
2823
2824 rss = (const struct rte_flow_action_rss *)act->conf;
2825
2826 if (!rss || !rss->queue_num) {
2827 rte_flow_error_set(error, EINVAL,
2828 RTE_FLOW_ERROR_TYPE_ACTION,
2829 act,
2830 "no valid queues");
2831 return -rte_errno;
2832 }
2833
2834 for (n = 0; n < rss->queue_num; n++) {
2835 if (rss->queue[n] >= dev->data->nb_rx_queues) {
2836 rte_flow_error_set(error, EINVAL,
2837 RTE_FLOW_ERROR_TYPE_ACTION,
2838 act,
2839 "queue id > max number of queues");
2840 return -rte_errno;
2841 }
2842 }
2843
2844 if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
2845 return rte_flow_error_set
2846 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2847 "non-default RSS hash functions are not supported");
2848 if (rss->level)
2849 return rte_flow_error_set
2850 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2851 "a nonzero RSS encapsulation level is not supported");
2852 if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
2853 return rte_flow_error_set
2854 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2855 "RSS hash key must be exactly 40 bytes");
2856 if (rss->queue_num > RTE_DIM(rss_conf->queue))
2857 return rte_flow_error_set
2858 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
2859 "too many queues for RSS context");
2860 if (ixgbe_rss_conf_init(rss_conf, rss))
2861 return rte_flow_error_set
2862 (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
2863 "RSS context initialization failure");
2864
2865
2866 act = next_no_void_action(actions, act);
2867 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
2868 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2869 rte_flow_error_set(error, EINVAL,
2870 RTE_FLOW_ERROR_TYPE_ACTION,
2871 act, "Not supported action.");
2872 return -rte_errno;
2873 }
2874
2875
2876
2877 if (!attr->ingress) {
2878 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2879 rte_flow_error_set(error, EINVAL,
2880 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
2881 attr, "Only support ingress.");
2882 return -rte_errno;
2883 }
2884
2885
2886 if (attr->egress) {
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_EGRESS,
2890 attr, "Not support egress.");
2891 return -rte_errno;
2892 }
2893
2894
2895 if (attr->transfer) {
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_TRANSFER,
2899 attr, "No support for transfer.");
2900 return -rte_errno;
2901 }
2902
2903 if (attr->priority > 0xFFFF) {
2904 memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
2905 rte_flow_error_set(error, EINVAL,
2906 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
2907 attr, "Error priority.");
2908 return -rte_errno;
2909 }
2910
2911 return 0;
2912}
2913
2914
2915static void
2916ixgbe_clear_rss_filter(struct rte_eth_dev *dev)
2917{
2918 struct ixgbe_filter_info *filter_info =
2919 IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
2920
2921 if (filter_info->rss_info.conf.queue_num)
2922 ixgbe_config_rss_filter(dev, &filter_info->rss_info, FALSE);
2923}
2924
2925void
2926ixgbe_filterlist_init(void)
2927{
2928 TAILQ_INIT(&filter_ntuple_list);
2929 TAILQ_INIT(&filter_ethertype_list);
2930 TAILQ_INIT(&filter_syn_list);
2931 TAILQ_INIT(&filter_fdir_list);
2932 TAILQ_INIT(&filter_l2_tunnel_list);
2933 TAILQ_INIT(&filter_rss_list);
2934 TAILQ_INIT(&ixgbe_flow_list);
2935}
2936
2937void
2938ixgbe_filterlist_flush(void)
2939{
2940 struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
2941 struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
2942 struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
2943 struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
2944 struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
2945 struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
2946 struct ixgbe_rss_conf_ele *rss_filter_ptr;
2947
2948 while ((ntuple_filter_ptr = TAILQ_FIRST(&filter_ntuple_list))) {
2949 TAILQ_REMOVE(&filter_ntuple_list,
2950 ntuple_filter_ptr,
2951 entries);
2952 rte_free(ntuple_filter_ptr);
2953 }
2954
2955 while ((ethertype_filter_ptr = TAILQ_FIRST(&filter_ethertype_list))) {
2956 TAILQ_REMOVE(&filter_ethertype_list,
2957 ethertype_filter_ptr,
2958 entries);
2959 rte_free(ethertype_filter_ptr);
2960 }
2961
2962 while ((syn_filter_ptr = TAILQ_FIRST(&filter_syn_list))) {
2963 TAILQ_REMOVE(&filter_syn_list,
2964 syn_filter_ptr,
2965 entries);
2966 rte_free(syn_filter_ptr);
2967 }
2968
2969 while ((l2_tn_filter_ptr = TAILQ_FIRST(&filter_l2_tunnel_list))) {
2970 TAILQ_REMOVE(&filter_l2_tunnel_list,
2971 l2_tn_filter_ptr,
2972 entries);
2973 rte_free(l2_tn_filter_ptr);
2974 }
2975
2976 while ((fdir_rule_ptr = TAILQ_FIRST(&filter_fdir_list))) {
2977 TAILQ_REMOVE(&filter_fdir_list,
2978 fdir_rule_ptr,
2979 entries);
2980 rte_free(fdir_rule_ptr);
2981 }
2982
2983 while ((rss_filter_ptr = TAILQ_FIRST(&filter_rss_list))) {
2984 TAILQ_REMOVE(&filter_rss_list,
2985 rss_filter_ptr,
2986 entries);
2987 rte_free(rss_filter_ptr);
2988 }
2989
2990 while ((ixgbe_flow_mem_ptr = TAILQ_FIRST(&ixgbe_flow_list))) {
2991 TAILQ_REMOVE(&ixgbe_flow_list,
2992 ixgbe_flow_mem_ptr,
2993 entries);
2994 rte_free(ixgbe_flow_mem_ptr->flow);
2995 rte_free(ixgbe_flow_mem_ptr);
2996 }
2997}
2998
2999
3000
3001
3002
3003
3004
3005static struct rte_flow *
3006ixgbe_flow_create(struct rte_eth_dev *dev,
3007 const struct rte_flow_attr *attr,
3008 const struct rte_flow_item pattern[],
3009 const struct rte_flow_action actions[],
3010 struct rte_flow_error *error)
3011{
3012 int ret;
3013 struct rte_eth_ntuple_filter ntuple_filter;
3014 struct rte_eth_ethertype_filter ethertype_filter;
3015 struct rte_eth_syn_filter syn_filter;
3016 struct ixgbe_fdir_rule fdir_rule;
3017 struct ixgbe_l2_tunnel_conf l2_tn_filter;
3018 struct ixgbe_hw_fdir_info *fdir_info =
3019 IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
3020 struct ixgbe_rte_flow_rss_conf rss_conf;
3021 struct rte_flow *flow = NULL;
3022 struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
3023 struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
3024 struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
3025 struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
3026 struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
3027 struct ixgbe_rss_conf_ele *rss_filter_ptr;
3028 struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
3029 uint8_t first_mask = FALSE;
3030
3031 flow = rte_zmalloc("ixgbe_rte_flow", sizeof(struct rte_flow), 0);
3032 if (!flow) {
3033 PMD_DRV_LOG(ERR, "failed to allocate memory");
3034 return (struct rte_flow *)flow;
3035 }
3036 ixgbe_flow_mem_ptr = rte_zmalloc("ixgbe_flow_mem",
3037 sizeof(struct ixgbe_flow_mem), 0);
3038 if (!ixgbe_flow_mem_ptr) {
3039 PMD_DRV_LOG(ERR, "failed to allocate memory");
3040 rte_free(flow);
3041 return NULL;
3042 }
3043 ixgbe_flow_mem_ptr->flow = flow;
3044 TAILQ_INSERT_TAIL(&ixgbe_flow_list,
3045 ixgbe_flow_mem_ptr, entries);
3046
3047 memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
3048 ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
3049 actions, &ntuple_filter, error);
3050
3051#ifdef RTE_LIB_SECURITY
3052
3053 if (ntuple_filter.proto == IPPROTO_ESP)
3054 return flow;
3055#endif
3056
3057 if (!ret) {
3058 ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
3059 if (!ret) {
3060 ntuple_filter_ptr = rte_zmalloc("ixgbe_ntuple_filter",
3061 sizeof(struct ixgbe_ntuple_filter_ele), 0);
3062 if (!ntuple_filter_ptr) {
3063 PMD_DRV_LOG(ERR, "failed to allocate memory");
3064 goto out;
3065 }
3066 rte_memcpy(&ntuple_filter_ptr->filter_info,
3067 &ntuple_filter,
3068 sizeof(struct rte_eth_ntuple_filter));
3069 TAILQ_INSERT_TAIL(&filter_ntuple_list,
3070 ntuple_filter_ptr, entries);
3071 flow->rule = ntuple_filter_ptr;
3072 flow->filter_type = RTE_ETH_FILTER_NTUPLE;
3073 return flow;
3074 }
3075 goto out;
3076 }
3077
3078 memset(ðertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
3079 ret = ixgbe_parse_ethertype_filter(dev, attr, pattern,
3080 actions, ðertype_filter, error);
3081 if (!ret) {
3082 ret = ixgbe_add_del_ethertype_filter(dev,
3083 ðertype_filter, TRUE);
3084 if (!ret) {
3085 ethertype_filter_ptr = rte_zmalloc(
3086 "ixgbe_ethertype_filter",
3087 sizeof(struct ixgbe_ethertype_filter_ele), 0);
3088 if (!ethertype_filter_ptr) {
3089 PMD_DRV_LOG(ERR, "failed to allocate memory");
3090 goto out;
3091 }
3092 rte_memcpy(ðertype_filter_ptr->filter_info,
3093 ðertype_filter,
3094 sizeof(struct rte_eth_ethertype_filter));
3095 TAILQ_INSERT_TAIL(&filter_ethertype_list,
3096 ethertype_filter_ptr, entries);
3097 flow->rule = ethertype_filter_ptr;
3098 flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
3099 return flow;
3100 }
3101 goto out;
3102 }
3103
3104 memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
3105 ret = ixgbe_parse_syn_filter(dev, attr, pattern,
3106 actions, &syn_filter, error);
3107 if (!ret) {
3108 ret = ixgbe_syn_filter_set(dev, &syn_filter, TRUE);
3109 if (!ret) {
3110 syn_filter_ptr = rte_zmalloc("ixgbe_syn_filter",
3111 sizeof(struct ixgbe_eth_syn_filter_ele), 0);
3112 if (!syn_filter_ptr) {
3113 PMD_DRV_LOG(ERR, "failed to allocate memory");
3114 goto out;
3115 }
3116 rte_memcpy(&syn_filter_ptr->filter_info,
3117 &syn_filter,
3118 sizeof(struct rte_eth_syn_filter));
3119 TAILQ_INSERT_TAIL(&filter_syn_list,
3120 syn_filter_ptr,
3121 entries);
3122 flow->rule = syn_filter_ptr;
3123 flow->filter_type = RTE_ETH_FILTER_SYN;
3124 return flow;
3125 }
3126 goto out;
3127 }
3128
3129 memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule));
3130 ret = ixgbe_parse_fdir_filter(dev, attr, pattern,
3131 actions, &fdir_rule, error);
3132 if (!ret) {
3133
3134 if (fdir_rule.b_mask) {
3135 if (!fdir_info->mask_added) {
3136
3137 rte_memcpy(&fdir_info->mask,
3138 &fdir_rule.mask,
3139 sizeof(struct ixgbe_hw_fdir_mask));
3140
3141 if (fdir_rule.mask.flex_bytes_mask) {
3142 ret = ixgbe_fdir_set_flexbytes_offset(dev,
3143 fdir_rule.flex_bytes_offset);
3144 if (ret)
3145 goto out;
3146 }
3147 ret = ixgbe_fdir_set_input_mask(dev);
3148 if (ret)
3149 goto out;
3150
3151 fdir_info->mask_added = TRUE;
3152 first_mask = TRUE;
3153 } else {
3154
3155
3156
3157
3158 ret = memcmp(&fdir_info->mask,
3159 &fdir_rule.mask,
3160 sizeof(struct ixgbe_hw_fdir_mask));
3161 if (ret)
3162 goto out;
3163
3164 if (fdir_rule.mask.flex_bytes_mask &&
3165 fdir_info->flex_bytes_offset !=
3166 fdir_rule.flex_bytes_offset)
3167 goto out;
3168 }
3169 }
3170
3171 if (fdir_rule.b_spec) {
3172 ret = ixgbe_fdir_filter_program(dev, &fdir_rule,
3173 FALSE, FALSE);
3174 if (!ret) {
3175 fdir_rule_ptr = rte_zmalloc("ixgbe_fdir_filter",
3176 sizeof(struct ixgbe_fdir_rule_ele), 0);
3177 if (!fdir_rule_ptr) {
3178 PMD_DRV_LOG(ERR, "failed to allocate memory");
3179 goto out;
3180 }
3181 rte_memcpy(&fdir_rule_ptr->filter_info,
3182 &fdir_rule,
3183 sizeof(struct ixgbe_fdir_rule));
3184 TAILQ_INSERT_TAIL(&filter_fdir_list,
3185 fdir_rule_ptr, entries);
3186 flow->rule = fdir_rule_ptr;
3187 flow->filter_type = RTE_ETH_FILTER_FDIR;
3188
3189 return flow;
3190 }
3191
3192 if (ret) {
3193
3194
3195
3196
3197 if (first_mask)
3198 fdir_info->mask_added = FALSE;
3199 goto out;
3200 }
3201 }
3202
3203 goto out;
3204 }
3205
3206 memset(&l2_tn_filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
3207 ret = ixgbe_parse_l2_tn_filter(dev, attr, pattern,
3208 actions, &l2_tn_filter, error);
3209 if (!ret) {
3210 ret = ixgbe_dev_l2_tunnel_filter_add(dev, &l2_tn_filter, FALSE);
3211 if (!ret) {
3212 l2_tn_filter_ptr = rte_zmalloc("ixgbe_l2_tn_filter",
3213 sizeof(struct ixgbe_eth_l2_tunnel_conf_ele), 0);
3214 if (!l2_tn_filter_ptr) {
3215 PMD_DRV_LOG(ERR, "failed to allocate memory");
3216 goto out;
3217 }
3218 rte_memcpy(&l2_tn_filter_ptr->filter_info,
3219 &l2_tn_filter,
3220 sizeof(struct ixgbe_l2_tunnel_conf));
3221 TAILQ_INSERT_TAIL(&filter_l2_tunnel_list,
3222 l2_tn_filter_ptr, entries);
3223 flow->rule = l2_tn_filter_ptr;
3224 flow->filter_type = RTE_ETH_FILTER_L2_TUNNEL;
3225 return flow;
3226 }
3227 }
3228
3229 memset(&rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
3230 ret = ixgbe_parse_rss_filter(dev, attr,
3231 actions, &rss_conf, error);
3232 if (!ret) {
3233 ret = ixgbe_config_rss_filter(dev, &rss_conf, TRUE);
3234 if (!ret) {
3235 rss_filter_ptr = rte_zmalloc("ixgbe_rss_filter",
3236 sizeof(struct ixgbe_rss_conf_ele), 0);
3237 if (!rss_filter_ptr) {
3238 PMD_DRV_LOG(ERR, "failed to allocate memory");
3239 goto out;
3240 }
3241 ixgbe_rss_conf_init(&rss_filter_ptr->filter_info,
3242 &rss_conf.conf);
3243 TAILQ_INSERT_TAIL(&filter_rss_list,
3244 rss_filter_ptr, entries);
3245 flow->rule = rss_filter_ptr;
3246 flow->filter_type = RTE_ETH_FILTER_HASH;
3247 return flow;
3248 }
3249 }
3250
3251out:
3252 TAILQ_REMOVE(&ixgbe_flow_list,
3253 ixgbe_flow_mem_ptr, entries);
3254 rte_flow_error_set(error, -ret,
3255 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
3256 "Failed to create flow.");
3257 rte_free(ixgbe_flow_mem_ptr);
3258 rte_free(flow);
3259 return NULL;
3260}
3261
3262
3263
3264
3265
3266
3267static int
3268ixgbe_flow_validate(struct rte_eth_dev *dev,
3269 const struct rte_flow_attr *attr,
3270 const struct rte_flow_item pattern[],
3271 const struct rte_flow_action actions[],
3272 struct rte_flow_error *error)
3273{
3274 struct rte_eth_ntuple_filter ntuple_filter;
3275 struct rte_eth_ethertype_filter ethertype_filter;
3276 struct rte_eth_syn_filter syn_filter;
3277 struct ixgbe_l2_tunnel_conf l2_tn_filter;
3278 struct ixgbe_fdir_rule fdir_rule;
3279 struct ixgbe_rte_flow_rss_conf rss_conf;
3280 int ret;
3281
3282 memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
3283 ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
3284 actions, &ntuple_filter, error);
3285 if (!ret)
3286 return 0;
3287
3288 memset(ðertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
3289 ret = ixgbe_parse_ethertype_filter(dev, attr, pattern,
3290 actions, ðertype_filter, error);
3291 if (!ret)
3292 return 0;
3293
3294 memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
3295 ret = ixgbe_parse_syn_filter(dev, attr, pattern,
3296 actions, &syn_filter, error);
3297 if (!ret)
3298 return 0;
3299
3300 memset(&fdir_rule, 0, sizeof(struct ixgbe_fdir_rule));
3301 ret = ixgbe_parse_fdir_filter(dev, attr, pattern,
3302 actions, &fdir_rule, error);
3303 if (!ret)
3304 return 0;
3305
3306 memset(&l2_tn_filter, 0, sizeof(struct ixgbe_l2_tunnel_conf));
3307 ret = ixgbe_parse_l2_tn_filter(dev, attr, pattern,
3308 actions, &l2_tn_filter, error);
3309 if (!ret)
3310 return 0;
3311
3312 memset(&rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
3313 ret = ixgbe_parse_rss_filter(dev, attr,
3314 actions, &rss_conf, error);
3315
3316 return ret;
3317}
3318
3319
3320static int
3321ixgbe_flow_destroy(struct rte_eth_dev *dev,
3322 struct rte_flow *flow,
3323 struct rte_flow_error *error)
3324{
3325 int ret;
3326 struct rte_flow *pmd_flow = flow;
3327 enum rte_filter_type filter_type = pmd_flow->filter_type;
3328 struct rte_eth_ntuple_filter ntuple_filter;
3329 struct rte_eth_ethertype_filter ethertype_filter;
3330 struct rte_eth_syn_filter syn_filter;
3331 struct ixgbe_fdir_rule fdir_rule;
3332 struct ixgbe_l2_tunnel_conf l2_tn_filter;
3333 struct ixgbe_ntuple_filter_ele *ntuple_filter_ptr;
3334 struct ixgbe_ethertype_filter_ele *ethertype_filter_ptr;
3335 struct ixgbe_eth_syn_filter_ele *syn_filter_ptr;
3336 struct ixgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
3337 struct ixgbe_fdir_rule_ele *fdir_rule_ptr;
3338 struct ixgbe_flow_mem *ixgbe_flow_mem_ptr;
3339 struct ixgbe_hw_fdir_info *fdir_info =
3340 IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
3341 struct ixgbe_rss_conf_ele *rss_filter_ptr;
3342
3343 switch (filter_type) {
3344 case RTE_ETH_FILTER_NTUPLE:
3345 ntuple_filter_ptr = (struct ixgbe_ntuple_filter_ele *)
3346 pmd_flow->rule;
3347 rte_memcpy(&ntuple_filter,
3348 &ntuple_filter_ptr->filter_info,
3349 sizeof(struct rte_eth_ntuple_filter));
3350 ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, FALSE);
3351 if (!ret) {
3352 TAILQ_REMOVE(&filter_ntuple_list,
3353 ntuple_filter_ptr, entries);
3354 rte_free(ntuple_filter_ptr);
3355 }
3356 break;
3357 case RTE_ETH_FILTER_ETHERTYPE:
3358 ethertype_filter_ptr = (struct ixgbe_ethertype_filter_ele *)
3359 pmd_flow->rule;
3360 rte_memcpy(ðertype_filter,
3361 ðertype_filter_ptr->filter_info,
3362 sizeof(struct rte_eth_ethertype_filter));
3363 ret = ixgbe_add_del_ethertype_filter(dev,
3364 ðertype_filter, FALSE);
3365 if (!ret) {
3366 TAILQ_REMOVE(&filter_ethertype_list,
3367 ethertype_filter_ptr, entries);
3368 rte_free(ethertype_filter_ptr);
3369 }
3370 break;
3371 case RTE_ETH_FILTER_SYN:
3372 syn_filter_ptr = (struct ixgbe_eth_syn_filter_ele *)
3373 pmd_flow->rule;
3374 rte_memcpy(&syn_filter,
3375 &syn_filter_ptr->filter_info,
3376 sizeof(struct rte_eth_syn_filter));
3377 ret = ixgbe_syn_filter_set(dev, &syn_filter, FALSE);
3378 if (!ret) {
3379 TAILQ_REMOVE(&filter_syn_list,
3380 syn_filter_ptr, entries);
3381 rte_free(syn_filter_ptr);
3382 }
3383 break;
3384 case RTE_ETH_FILTER_FDIR:
3385 fdir_rule_ptr = (struct ixgbe_fdir_rule_ele *)pmd_flow->rule;
3386 rte_memcpy(&fdir_rule,
3387 &fdir_rule_ptr->filter_info,
3388 sizeof(struct ixgbe_fdir_rule));
3389 ret = ixgbe_fdir_filter_program(dev, &fdir_rule, TRUE, FALSE);
3390 if (!ret) {
3391 TAILQ_REMOVE(&filter_fdir_list,
3392 fdir_rule_ptr, entries);
3393 rte_free(fdir_rule_ptr);
3394 if (TAILQ_EMPTY(&filter_fdir_list))
3395 fdir_info->mask_added = false;
3396 }
3397 break;
3398 case RTE_ETH_FILTER_L2_TUNNEL:
3399 l2_tn_filter_ptr = (struct ixgbe_eth_l2_tunnel_conf_ele *)
3400 pmd_flow->rule;
3401 rte_memcpy(&l2_tn_filter, &l2_tn_filter_ptr->filter_info,
3402 sizeof(struct ixgbe_l2_tunnel_conf));
3403 ret = ixgbe_dev_l2_tunnel_filter_del(dev, &l2_tn_filter);
3404 if (!ret) {
3405 TAILQ_REMOVE(&filter_l2_tunnel_list,
3406 l2_tn_filter_ptr, entries);
3407 rte_free(l2_tn_filter_ptr);
3408 }
3409 break;
3410 case RTE_ETH_FILTER_HASH:
3411 rss_filter_ptr = (struct ixgbe_rss_conf_ele *)
3412 pmd_flow->rule;
3413 ret = ixgbe_config_rss_filter(dev,
3414 &rss_filter_ptr->filter_info, FALSE);
3415 if (!ret) {
3416 TAILQ_REMOVE(&filter_rss_list,
3417 rss_filter_ptr, entries);
3418 rte_free(rss_filter_ptr);
3419 }
3420 break;
3421 default:
3422 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
3423 filter_type);
3424 ret = -EINVAL;
3425 break;
3426 }
3427
3428 if (ret) {
3429 rte_flow_error_set(error, EINVAL,
3430 RTE_FLOW_ERROR_TYPE_HANDLE,
3431 NULL, "Failed to destroy flow");
3432 return ret;
3433 }
3434
3435 TAILQ_FOREACH(ixgbe_flow_mem_ptr, &ixgbe_flow_list, entries) {
3436 if (ixgbe_flow_mem_ptr->flow == pmd_flow) {
3437 TAILQ_REMOVE(&ixgbe_flow_list,
3438 ixgbe_flow_mem_ptr, entries);
3439 rte_free(ixgbe_flow_mem_ptr);
3440 }
3441 }
3442 rte_free(flow);
3443
3444 return ret;
3445}
3446
3447
3448static int
3449ixgbe_flow_flush(struct rte_eth_dev *dev,
3450 struct rte_flow_error *error)
3451{
3452 int ret = 0;
3453
3454 ixgbe_clear_all_ntuple_filter(dev);
3455 ixgbe_clear_all_ethertype_filter(dev);
3456 ixgbe_clear_syn_filter(dev);
3457
3458 ret = ixgbe_clear_all_fdir_filter(dev);
3459 if (ret < 0) {
3460 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
3461 NULL, "Failed to flush rule");
3462 return ret;
3463 }
3464
3465 ret = ixgbe_clear_all_l2_tn_filter(dev);
3466 if (ret < 0) {
3467 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
3468 NULL, "Failed to flush rule");
3469 return ret;
3470 }
3471
3472 ixgbe_clear_rss_filter(dev);
3473
3474 ixgbe_filterlist_flush();
3475
3476 return 0;
3477}
3478
3479const struct rte_flow_ops ixgbe_flow_ops = {
3480 .validate = ixgbe_flow_validate,
3481 .create = ixgbe_flow_create,
3482 .destroy = ixgbe_flow_destroy,
3483 .flush = ixgbe_flow_flush,
3484};
3485