1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2016 Intel Corporation
11 #include <rte_common.h>
12 #include <rte_interrupts.h>
13 #include <rte_byteorder.h>
15 #include <rte_debug.h>
17 #include <rte_ether.h>
18 #include <rte_ethdev_driver.h>
19 #include <rte_ethdev_pci.h>
20 #include <rte_memory.h>
22 #include <rte_atomic.h>
23 #include <rte_malloc.h>
26 #include <rte_flow_driver.h>
28 #include "e1000_logs.h"
29 #include "base/e1000_api.h"
30 #include "e1000_ethdev.h"
32 #define NEXT_ITEM_OF_PATTERN(item, pattern, index) \
34 item = (pattern) + (index); \
35 while (item->type == RTE_FLOW_ITEM_TYPE_VOID) { \
37 item = (pattern) + (index); \
41 #define NEXT_ITEM_OF_ACTION(act, actions, index) \
43 act = (actions) + (index); \
44 while (act->type == RTE_FLOW_ACTION_TYPE_VOID) {\
46 act = (actions) + (index); \
50 #define IGB_FLEX_RAW_NUM 12
53 * Please aware there's an asumption for all the parsers.
54 * rte_flow_item is using big endian, rte_flow_attr and
55 * rte_flow_action are using CPU order.
56 * Because the pattern is used to describe the packets,
57 * normally the packets should use network order.
61 * Parse the rule to see if it is a n-tuple rule.
62 * And get the n-tuple filter info BTW.
64 * The first not void item can be ETH or IPV4.
65 * The second not void item must be IPV4 if the first one is ETH.
66 * The third not void item must be UDP or TCP or SCTP
67 * The next not void item must be END.
69 * The first not void action should be QUEUE.
70 * The next not void action should be END.
74 * IPV4 src_addr 192.168.1.20 0xFFFFFFFF
75 * dst_addr 192.167.3.50 0xFFFFFFFF
76 * next_proto_id 17 0xFF
77 * UDP/TCP/ src_port 80 0xFFFF
78 * SCTP dst_port 80 0xFFFF
80 * other members in mask and spec should set to 0x00.
81 * item->last should be NULL.
84 cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
85 const struct rte_flow_item pattern[],
86 const struct rte_flow_action actions[],
87 struct rte_eth_ntuple_filter *filter,
88 struct rte_flow_error *error)
90 const struct rte_flow_item *item;
91 const struct rte_flow_action *act;
92 const struct rte_flow_item_ipv4 *ipv4_spec;
93 const struct rte_flow_item_ipv4 *ipv4_mask;
94 const struct rte_flow_item_tcp *tcp_spec;
95 const struct rte_flow_item_tcp *tcp_mask;
96 const struct rte_flow_item_udp *udp_spec;
97 const struct rte_flow_item_udp *udp_mask;
98 const struct rte_flow_item_sctp *sctp_spec;
99 const struct rte_flow_item_sctp *sctp_mask;
103 rte_flow_error_set(error,
104 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
105 NULL, "NULL pattern.");
110 rte_flow_error_set(error, EINVAL,
111 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
112 NULL, "NULL action.");
116 rte_flow_error_set(error, EINVAL,
117 RTE_FLOW_ERROR_TYPE_ATTR,
118 NULL, "NULL attribute.");
125 /* the first not void item can be MAC or IPv4 */
126 NEXT_ITEM_OF_PATTERN(item, pattern, index);
128 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
129 item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
130 rte_flow_error_set(error, EINVAL,
131 RTE_FLOW_ERROR_TYPE_ITEM,
132 item, "Not supported by ntuple filter");
136 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
137 /*Not supported last point for range*/
139 rte_flow_error_set(error,
141 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
142 item, "Not supported last point for range");
145 /* if the first item is MAC, the content should be NULL */
146 if (item->spec || item->mask) {
147 rte_flow_error_set(error, EINVAL,
148 RTE_FLOW_ERROR_TYPE_ITEM,
149 item, "Not supported by ntuple filter");
152 /* check if the next not void item is IPv4 */
154 NEXT_ITEM_OF_PATTERN(item, pattern, index);
155 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
156 rte_flow_error_set(error,
157 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
158 item, "Not supported by ntuple filter");
163 /* get the IPv4 info */
164 if (!item->spec || !item->mask) {
165 rte_flow_error_set(error, EINVAL,
166 RTE_FLOW_ERROR_TYPE_ITEM,
167 item, "Invalid ntuple mask");
170 /* Not supported last point for range */
172 rte_flow_error_set(error, EINVAL,
173 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
174 item, "Not supported last point for range");
178 ipv4_mask = item->mask;
180 * Only support src & dst addresses, protocol,
181 * others should be masked.
184 if (ipv4_mask->hdr.version_ihl ||
185 ipv4_mask->hdr.type_of_service ||
186 ipv4_mask->hdr.total_length ||
187 ipv4_mask->hdr.packet_id ||
188 ipv4_mask->hdr.fragment_offset ||
189 ipv4_mask->hdr.time_to_live ||
190 ipv4_mask->hdr.hdr_checksum) {
191 rte_flow_error_set(error,
192 EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
193 item, "Not supported by ntuple filter");
197 filter->dst_ip_mask = ipv4_mask->hdr.dst_addr;
198 filter->src_ip_mask = ipv4_mask->hdr.src_addr;
199 filter->proto_mask = ipv4_mask->hdr.next_proto_id;
201 ipv4_spec = item->spec;
202 filter->dst_ip = ipv4_spec->hdr.dst_addr;
203 filter->src_ip = ipv4_spec->hdr.src_addr;
204 filter->proto = ipv4_spec->hdr.next_proto_id;
206 /* check if the next not void item is TCP or UDP or SCTP */
208 NEXT_ITEM_OF_PATTERN(item, pattern, index);
209 if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
210 item->type != RTE_FLOW_ITEM_TYPE_UDP &&
211 item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
212 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
213 rte_flow_error_set(error, EINVAL,
214 RTE_FLOW_ERROR_TYPE_ITEM,
215 item, "Not supported by ntuple filter");
219 /* Not supported last point for range */
221 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
222 rte_flow_error_set(error, EINVAL,
223 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
224 item, "Not supported last point for range");
228 /* get the TCP/UDP/SCTP info */
229 if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
230 if (item->spec && item->mask) {
231 tcp_mask = item->mask;
234 * Only support src & dst ports, tcp flags,
235 * others should be masked.
237 if (tcp_mask->hdr.sent_seq ||
238 tcp_mask->hdr.recv_ack ||
239 tcp_mask->hdr.data_off ||
240 tcp_mask->hdr.rx_win ||
241 tcp_mask->hdr.cksum ||
242 tcp_mask->hdr.tcp_urp) {
244 sizeof(struct rte_eth_ntuple_filter));
245 rte_flow_error_set(error, EINVAL,
246 RTE_FLOW_ERROR_TYPE_ITEM,
247 item, "Not supported by ntuple filter");
251 filter->dst_port_mask = tcp_mask->hdr.dst_port;
252 filter->src_port_mask = tcp_mask->hdr.src_port;
253 if (tcp_mask->hdr.tcp_flags == 0xFF) {
254 filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
255 } else if (!tcp_mask->hdr.tcp_flags) {
256 filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG;
259 sizeof(struct rte_eth_ntuple_filter));
260 rte_flow_error_set(error, EINVAL,
261 RTE_FLOW_ERROR_TYPE_ITEM,
262 item, "Not supported by ntuple filter");
266 tcp_spec = item->spec;
267 filter->dst_port = tcp_spec->hdr.dst_port;
268 filter->src_port = tcp_spec->hdr.src_port;
269 filter->tcp_flags = tcp_spec->hdr.tcp_flags;
271 } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
272 if (item->spec && item->mask) {
273 udp_mask = item->mask;
276 * Only support src & dst ports,
277 * others should be masked.
279 if (udp_mask->hdr.dgram_len ||
280 udp_mask->hdr.dgram_cksum) {
282 sizeof(struct rte_eth_ntuple_filter));
283 rte_flow_error_set(error, EINVAL,
284 RTE_FLOW_ERROR_TYPE_ITEM,
285 item, "Not supported by ntuple filter");
289 filter->dst_port_mask = udp_mask->hdr.dst_port;
290 filter->src_port_mask = udp_mask->hdr.src_port;
292 udp_spec = item->spec;
293 filter->dst_port = udp_spec->hdr.dst_port;
294 filter->src_port = udp_spec->hdr.src_port;
297 if (item->spec && item->mask) {
298 sctp_mask = item->mask;
301 * Only support src & dst ports,
302 * others should be masked.
304 if (sctp_mask->hdr.tag ||
305 sctp_mask->hdr.cksum) {
307 sizeof(struct rte_eth_ntuple_filter));
308 rte_flow_error_set(error, EINVAL,
309 RTE_FLOW_ERROR_TYPE_ITEM,
310 item, "Not supported by ntuple filter");
314 filter->dst_port_mask = sctp_mask->hdr.dst_port;
315 filter->src_port_mask = sctp_mask->hdr.src_port;
317 sctp_spec = (const struct rte_flow_item_sctp *)
319 filter->dst_port = sctp_spec->hdr.dst_port;
320 filter->src_port = sctp_spec->hdr.src_port;
323 /* check if the next not void item is END */
325 NEXT_ITEM_OF_PATTERN(item, pattern, index);
326 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
327 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
328 rte_flow_error_set(error, EINVAL,
329 RTE_FLOW_ERROR_TYPE_ITEM,
330 item, "Not supported by ntuple filter");
338 * n-tuple only supports forwarding,
339 * check if the first not void action is QUEUE.
341 NEXT_ITEM_OF_ACTION(act, actions, index);
342 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
343 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
344 rte_flow_error_set(error, EINVAL,
345 RTE_FLOW_ERROR_TYPE_ACTION,
346 item, "Not supported action.");
350 ((const struct rte_flow_action_queue *)act->conf)->index;
352 /* check if the next not void item is END */
354 NEXT_ITEM_OF_ACTION(act, actions, index);
355 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
356 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
357 rte_flow_error_set(error, EINVAL,
358 RTE_FLOW_ERROR_TYPE_ACTION,
359 act, "Not supported action.");
364 /* must be input direction */
365 if (!attr->ingress) {
366 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
367 rte_flow_error_set(error, EINVAL,
368 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
369 attr, "Only support ingress.");
375 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
376 rte_flow_error_set(error, EINVAL,
377 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
378 attr, "Not support egress.");
382 if (attr->priority > 0xFFFF) {
383 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
384 rte_flow_error_set(error, EINVAL,
385 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
386 attr, "Error priority.");
389 filter->priority = (uint16_t)attr->priority;
394 /* a specific function for igb because the flags is specific */
396 igb_parse_ntuple_filter(struct rte_eth_dev *dev,
397 const struct rte_flow_attr *attr,
398 const struct rte_flow_item pattern[],
399 const struct rte_flow_action actions[],
400 struct rte_eth_ntuple_filter *filter,
401 struct rte_flow_error *error)
403 struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
406 MAC_TYPE_FILTER_SUP(hw->mac.type);
408 ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
413 /* Igb doesn't support many priorities. */
414 if (filter->priority > E1000_2TUPLE_MAX_PRI) {
415 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
416 rte_flow_error_set(error, EINVAL,
417 RTE_FLOW_ERROR_TYPE_ITEM,
418 NULL, "Priority not supported by ntuple filter");
422 if (hw->mac.type == e1000_82576) {
423 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
424 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
425 rte_flow_error_set(error, EINVAL,
426 RTE_FLOW_ERROR_TYPE_ITEM,
427 NULL, "queue number not "
428 "supported by ntuple filter");
431 filter->flags |= RTE_5TUPLE_FLAGS;
433 if (filter->src_ip_mask || filter->dst_ip_mask ||
434 filter->src_port_mask) {
435 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
436 rte_flow_error_set(error, EINVAL,
437 RTE_FLOW_ERROR_TYPE_ITEM,
438 NULL, "only two tuple are "
439 "supported by this filter");
442 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
443 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
444 rte_flow_error_set(error, EINVAL,
445 RTE_FLOW_ERROR_TYPE_ITEM,
446 NULL, "queue number not "
447 "supported by ntuple filter");
450 filter->flags |= RTE_2TUPLE_FLAGS;
457 * Parse the rule to see if it is a ethertype rule.
458 * And get the ethertype filter info BTW.
460 * The first not void item can be ETH.
461 * The next not void item must be END.
463 * The first not void action should be QUEUE.
464 * The next not void action should be END.
467 * ETH type 0x0807 0xFFFF
469 * other members in mask and spec should set to 0x00.
470 * item->last should be NULL.
473 cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
474 const struct rte_flow_item *pattern,
475 const struct rte_flow_action *actions,
476 struct rte_eth_ethertype_filter *filter,
477 struct rte_flow_error *error)
479 const struct rte_flow_item *item;
480 const struct rte_flow_action *act;
481 const struct rte_flow_item_eth *eth_spec;
482 const struct rte_flow_item_eth *eth_mask;
483 const struct rte_flow_action_queue *act_q;
487 rte_flow_error_set(error, EINVAL,
488 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
489 NULL, "NULL pattern.");
494 rte_flow_error_set(error, EINVAL,
495 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
496 NULL, "NULL action.");
501 rte_flow_error_set(error, EINVAL,
502 RTE_FLOW_ERROR_TYPE_ATTR,
503 NULL, "NULL attribute.");
510 /* The first non-void item should be MAC. */
511 NEXT_ITEM_OF_PATTERN(item, pattern, index);
512 if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
513 rte_flow_error_set(error, EINVAL,
514 RTE_FLOW_ERROR_TYPE_ITEM,
515 item, "Not supported by ethertype filter");
519 /*Not supported last point for range*/
521 rte_flow_error_set(error, EINVAL,
522 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
523 item, "Not supported last point for range");
527 /* Get the MAC info. */
528 if (!item->spec || !item->mask) {
529 rte_flow_error_set(error, EINVAL,
530 RTE_FLOW_ERROR_TYPE_ITEM,
531 item, "Not supported by ethertype filter");
535 eth_spec = item->spec;
536 eth_mask = item->mask;
538 /* Mask bits of source MAC address must be full of 0.
539 * Mask bits of destination MAC address must be full
542 if (!is_zero_ether_addr(ð_mask->src) ||
543 (!is_zero_ether_addr(ð_mask->dst) &&
544 !is_broadcast_ether_addr(ð_mask->dst))) {
545 rte_flow_error_set(error, EINVAL,
546 RTE_FLOW_ERROR_TYPE_ITEM,
547 item, "Invalid ether address mask");
551 if ((eth_mask->type & UINT16_MAX) != UINT16_MAX) {
552 rte_flow_error_set(error, EINVAL,
553 RTE_FLOW_ERROR_TYPE_ITEM,
554 item, "Invalid ethertype mask");
558 /* If mask bits of destination MAC address
559 * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
561 if (is_broadcast_ether_addr(ð_mask->dst)) {
562 filter->mac_addr = eth_spec->dst;
563 filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
565 filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
567 filter->ether_type = rte_be_to_cpu_16(eth_spec->type);
569 /* Check if the next non-void item is END. */
571 NEXT_ITEM_OF_PATTERN(item, pattern, index);
572 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
573 rte_flow_error_set(error, EINVAL,
574 RTE_FLOW_ERROR_TYPE_ITEM,
575 item, "Not supported by ethertype filter.");
582 /* Check if the first non-void action is QUEUE or DROP. */
583 NEXT_ITEM_OF_ACTION(act, actions, index);
584 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
585 act->type != RTE_FLOW_ACTION_TYPE_DROP) {
586 rte_flow_error_set(error, EINVAL,
587 RTE_FLOW_ERROR_TYPE_ACTION,
588 act, "Not supported action.");
592 if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
593 act_q = (const struct rte_flow_action_queue *)act->conf;
594 filter->queue = act_q->index;
596 filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
599 /* Check if the next non-void item is END */
601 NEXT_ITEM_OF_ACTION(act, actions, index);
602 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
603 rte_flow_error_set(error, EINVAL,
604 RTE_FLOW_ERROR_TYPE_ACTION,
605 act, "Not supported action.");
610 /* Must be input direction */
611 if (!attr->ingress) {
612 rte_flow_error_set(error, EINVAL,
613 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
614 attr, "Only support ingress.");
620 rte_flow_error_set(error, EINVAL,
621 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
622 attr, "Not support egress.");
627 if (attr->priority) {
628 rte_flow_error_set(error, EINVAL,
629 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
630 attr, "Not support priority.");
636 rte_flow_error_set(error, EINVAL,
637 RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
638 attr, "Not support group.");
646 igb_parse_ethertype_filter(struct rte_eth_dev *dev,
647 const struct rte_flow_attr *attr,
648 const struct rte_flow_item pattern[],
649 const struct rte_flow_action actions[],
650 struct rte_eth_ethertype_filter *filter,
651 struct rte_flow_error *error)
653 struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
656 MAC_TYPE_FILTER_SUP(hw->mac.type);
658 ret = cons_parse_ethertype_filter(attr, pattern,
659 actions, filter, error);
664 if (hw->mac.type == e1000_82576) {
665 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
666 memset(filter, 0, sizeof(
667 struct rte_eth_ethertype_filter));
668 rte_flow_error_set(error, EINVAL,
669 RTE_FLOW_ERROR_TYPE_ITEM,
670 NULL, "queue number not supported "
671 "by ethertype filter");
675 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
676 memset(filter, 0, sizeof(
677 struct rte_eth_ethertype_filter));
678 rte_flow_error_set(error, EINVAL,
679 RTE_FLOW_ERROR_TYPE_ITEM,
680 NULL, "queue number not supported "
681 "by ethertype filter");
686 if (filter->ether_type == ETHER_TYPE_IPv4 ||
687 filter->ether_type == ETHER_TYPE_IPv6) {
688 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
689 rte_flow_error_set(error, EINVAL,
690 RTE_FLOW_ERROR_TYPE_ITEM,
691 NULL, "IPv4/IPv6 not supported by ethertype filter");
695 if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
696 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
697 rte_flow_error_set(error, EINVAL,
698 RTE_FLOW_ERROR_TYPE_ITEM,
699 NULL, "mac compare is unsupported");
703 if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
704 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
705 rte_flow_error_set(error, EINVAL,
706 RTE_FLOW_ERROR_TYPE_ITEM,
707 NULL, "drop option is unsupported");
715 * Parse the rule to see if it is a TCP SYN rule.
716 * And get the TCP SYN filter info BTW.
718 * The first not void item must be ETH.
719 * The second not void item must be IPV4 or IPV6.
720 * The third not void item must be TCP.
721 * The next not void item must be END.
723 * The first not void action should be QUEUE.
724 * The next not void action should be END.
728 * IPV4/IPV6 NULL NULL
729 * TCP tcp_flags 0x02 0xFF
731 * other members in mask and spec should set to 0x00.
732 * item->last should be NULL.
735 cons_parse_syn_filter(const struct rte_flow_attr *attr,
736 const struct rte_flow_item pattern[],
737 const struct rte_flow_action actions[],
738 struct rte_eth_syn_filter *filter,
739 struct rte_flow_error *error)
741 const struct rte_flow_item *item;
742 const struct rte_flow_action *act;
743 const struct rte_flow_item_tcp *tcp_spec;
744 const struct rte_flow_item_tcp *tcp_mask;
745 const struct rte_flow_action_queue *act_q;
749 rte_flow_error_set(error, EINVAL,
750 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
751 NULL, "NULL pattern.");
756 rte_flow_error_set(error, EINVAL,
757 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
758 NULL, "NULL action.");
763 rte_flow_error_set(error, EINVAL,
764 RTE_FLOW_ERROR_TYPE_ATTR,
765 NULL, "NULL attribute.");
772 /* the first not void item should be MAC or IPv4 or IPv6 or TCP */
773 NEXT_ITEM_OF_PATTERN(item, pattern, index);
774 if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
775 item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
776 item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
777 item->type != RTE_FLOW_ITEM_TYPE_TCP) {
778 rte_flow_error_set(error, EINVAL,
779 RTE_FLOW_ERROR_TYPE_ITEM,
780 item, "Not supported by syn filter");
783 /*Not supported last point for range*/
785 rte_flow_error_set(error, EINVAL,
786 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
787 item, "Not supported last point for range");
792 if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
793 /* if the item is MAC, the content should be NULL */
794 if (item->spec || item->mask) {
795 rte_flow_error_set(error, EINVAL,
796 RTE_FLOW_ERROR_TYPE_ITEM,
797 item, "Invalid SYN address mask");
801 /* check if the next not void item is IPv4 or IPv6 */
803 NEXT_ITEM_OF_PATTERN(item, pattern, index);
804 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
805 item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
806 rte_flow_error_set(error, EINVAL,
807 RTE_FLOW_ERROR_TYPE_ITEM,
808 item, "Not supported by syn filter");
814 if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
815 item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
816 /* if the item is IP, the content should be NULL */
817 if (item->spec || item->mask) {
818 rte_flow_error_set(error, EINVAL,
819 RTE_FLOW_ERROR_TYPE_ITEM,
820 item, "Invalid SYN mask");
824 /* check if the next not void item is TCP */
826 NEXT_ITEM_OF_PATTERN(item, pattern, index);
827 if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
828 rte_flow_error_set(error, EINVAL,
829 RTE_FLOW_ERROR_TYPE_ITEM,
830 item, "Not supported by syn filter");
835 /* Get the TCP info. Only support SYN. */
836 if (!item->spec || !item->mask) {
837 rte_flow_error_set(error, EINVAL,
838 RTE_FLOW_ERROR_TYPE_ITEM,
839 item, "Invalid SYN mask");
842 /*Not supported last point for range*/
844 rte_flow_error_set(error, EINVAL,
845 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
846 item, "Not supported last point for range");
850 tcp_spec = item->spec;
851 tcp_mask = item->mask;
852 if (!(tcp_spec->hdr.tcp_flags & TCP_SYN_FLAG) ||
853 tcp_mask->hdr.src_port ||
854 tcp_mask->hdr.dst_port ||
855 tcp_mask->hdr.sent_seq ||
856 tcp_mask->hdr.recv_ack ||
857 tcp_mask->hdr.data_off ||
858 tcp_mask->hdr.tcp_flags != TCP_SYN_FLAG ||
859 tcp_mask->hdr.rx_win ||
860 tcp_mask->hdr.cksum ||
861 tcp_mask->hdr.tcp_urp) {
862 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
863 rte_flow_error_set(error, EINVAL,
864 RTE_FLOW_ERROR_TYPE_ITEM,
865 item, "Not supported by syn filter");
869 /* check if the next not void item is END */
871 NEXT_ITEM_OF_PATTERN(item, pattern, index);
872 if (item->type != RTE_FLOW_ITEM_TYPE_END) {
873 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
874 rte_flow_error_set(error, EINVAL,
875 RTE_FLOW_ERROR_TYPE_ITEM,
876 item, "Not supported by syn filter");
883 /* check if the first not void action is QUEUE. */
884 NEXT_ITEM_OF_ACTION(act, actions, index);
885 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
886 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
887 rte_flow_error_set(error, EINVAL,
888 RTE_FLOW_ERROR_TYPE_ACTION,
889 act, "Not supported action.");
893 act_q = (const struct rte_flow_action_queue *)act->conf;
894 filter->queue = act_q->index;
896 /* check if the next not void item is END */
898 NEXT_ITEM_OF_ACTION(act, actions, index);
899 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
900 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
901 rte_flow_error_set(error, EINVAL,
902 RTE_FLOW_ERROR_TYPE_ACTION,
903 act, "Not supported action.");
908 /* must be input direction */
909 if (!attr->ingress) {
910 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
911 rte_flow_error_set(error, EINVAL,
912 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
913 attr, "Only support ingress.");
919 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
920 rte_flow_error_set(error, EINVAL,
921 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
922 attr, "Not support egress.");
926 /* Support 2 priorities, the lowest or highest. */
927 if (!attr->priority) {
929 } else if (attr->priority == (uint32_t)~0U) {
932 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
933 rte_flow_error_set(error, EINVAL,
934 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
935 attr, "Not support priority.");
943 igb_parse_syn_filter(struct rte_eth_dev *dev,
944 const struct rte_flow_attr *attr,
945 const struct rte_flow_item pattern[],
946 const struct rte_flow_action actions[],
947 struct rte_eth_syn_filter *filter,
948 struct rte_flow_error *error)
950 struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
953 MAC_TYPE_FILTER_SUP(hw->mac.type);
955 ret = cons_parse_syn_filter(attr, pattern,
956 actions, filter, error);
958 if (hw->mac.type == e1000_82576) {
959 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
960 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
961 rte_flow_error_set(error, EINVAL,
962 RTE_FLOW_ERROR_TYPE_ITEM,
963 NULL, "queue number not "
964 "supported by syn filter");
968 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
969 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
970 rte_flow_error_set(error, EINVAL,
971 RTE_FLOW_ERROR_TYPE_ITEM,
972 NULL, "queue number not "
973 "supported by syn filter");
985 * Parse the rule to see if it is a flex byte rule.
986 * And get the flex byte filter info BTW.
988 * The first not void item must be RAW.
989 * The second not void item can be RAW or END.
990 * The third not void item can be RAW or END.
991 * The last not void item must be END.
993 * The first not void action should be QUEUE.
994 * The next not void action should be END.
998 * offset 0 0xFFFFFFFF
999 * pattern {0x08, 0x06} {0xFF, 0xFF}
1000 * RAW relative 1 0x1
1001 * offset 100 0xFFFFFFFF
1002 * pattern {0x11, 0x22, 0x33} {0xFF, 0xFF, 0xFF}
1004 * other members in mask and spec should set to 0x00.
1005 * item->last should be NULL.
1008 cons_parse_flex_filter(const struct rte_flow_attr *attr,
1009 const struct rte_flow_item pattern[],
1010 const struct rte_flow_action actions[],
1011 struct rte_eth_flex_filter *filter,
1012 struct rte_flow_error *error)
1014 const struct rte_flow_item *item;
1015 const struct rte_flow_action *act;
1016 const struct rte_flow_item_raw *raw_spec;
1017 const struct rte_flow_item_raw *raw_mask;
1018 const struct rte_flow_action_queue *act_q;
1019 uint32_t index, i, offset, total_offset;
1020 uint32_t max_offset = 0;
1021 int32_t shift, j, raw_index = 0;
1022 int32_t relative[IGB_FLEX_RAW_NUM] = {0};
1023 int32_t raw_offset[IGB_FLEX_RAW_NUM] = {0};
1026 rte_flow_error_set(error, EINVAL,
1027 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
1028 NULL, "NULL pattern.");
1033 rte_flow_error_set(error, EINVAL,
1034 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
1035 NULL, "NULL action.");
1040 rte_flow_error_set(error, EINVAL,
1041 RTE_FLOW_ERROR_TYPE_ATTR,
1042 NULL, "NULL attribute.");
1051 /* the first not void item should be RAW */
1052 NEXT_ITEM_OF_PATTERN(item, pattern, index);
1053 if (item->type != RTE_FLOW_ITEM_TYPE_RAW) {
1054 rte_flow_error_set(error, EINVAL,
1055 RTE_FLOW_ERROR_TYPE_ITEM,
1056 item, "Not supported by flex filter");
1059 /*Not supported last point for range*/
1061 rte_flow_error_set(error, EINVAL,
1062 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1063 item, "Not supported last point for range");
1067 raw_spec = item->spec;
1068 raw_mask = item->mask;
1070 if (!raw_mask->length ||
1071 !raw_mask->relative) {
1072 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1073 rte_flow_error_set(error, EINVAL,
1074 RTE_FLOW_ERROR_TYPE_ITEM,
1075 item, "Not supported by flex filter");
1079 if (raw_mask->offset)
1080 offset = raw_spec->offset;
1084 for (j = 0; j < raw_spec->length; j++) {
1085 if (raw_mask->pattern[j] != 0xFF) {
1086 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1087 rte_flow_error_set(error, EINVAL,
1088 RTE_FLOW_ERROR_TYPE_ITEM,
1089 item, "Not supported by flex filter");
1096 if (raw_spec->relative) {
1097 for (j = raw_index; j > 0; j--) {
1098 total_offset += raw_offset[j - 1];
1099 if (!relative[j - 1])
1102 if (total_offset + raw_spec->length + offset > max_offset)
1103 max_offset = total_offset + raw_spec->length + offset;
1105 if (raw_spec->length + offset > max_offset)
1106 max_offset = raw_spec->length + offset;
1109 if ((raw_spec->length + offset + total_offset) >
1110 RTE_FLEX_FILTER_MAXLEN) {
1111 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1112 rte_flow_error_set(error, EINVAL,
1113 RTE_FLOW_ERROR_TYPE_ITEM,
1114 item, "Not supported by flex filter");
1118 if (raw_spec->relative == 0) {
1119 for (j = 0; j < raw_spec->length; j++)
1120 filter->bytes[offset + j] =
1121 raw_spec->pattern[j];
1122 j = offset / CHAR_BIT;
1123 shift = offset % CHAR_BIT;
1125 for (j = 0; j < raw_spec->length; j++)
1126 filter->bytes[total_offset + offset + j] =
1127 raw_spec->pattern[j];
1128 j = (total_offset + offset) / CHAR_BIT;
1129 shift = (total_offset + offset) % CHAR_BIT;
1134 for ( ; shift < CHAR_BIT; shift++) {
1135 filter->mask[j] |= (0x80 >> shift);
1137 if (i == raw_spec->length)
1139 if (shift == (CHAR_BIT - 1)) {
1145 relative[raw_index] = raw_spec->relative;
1146 raw_offset[raw_index] = offset + raw_spec->length;
1149 /* check if the next not void item is RAW */
1151 NEXT_ITEM_OF_PATTERN(item, pattern, index);
1152 if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
1153 item->type != RTE_FLOW_ITEM_TYPE_END) {
1154 rte_flow_error_set(error, EINVAL,
1155 RTE_FLOW_ERROR_TYPE_ITEM,
1156 item, "Not supported by flex filter");
1160 /* go back to parser */
1161 if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
1162 /* if the item is RAW, the content should be parse */
1166 filter->len = RTE_ALIGN(max_offset, 8);
1171 /* check if the first not void action is QUEUE. */
1172 NEXT_ITEM_OF_ACTION(act, actions, index);
1173 if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
1174 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1175 rte_flow_error_set(error, EINVAL,
1176 RTE_FLOW_ERROR_TYPE_ACTION,
1177 act, "Not supported action.");
1181 act_q = (const struct rte_flow_action_queue *)act->conf;
1182 filter->queue = act_q->index;
1184 /* check if the next not void item is END */
1186 NEXT_ITEM_OF_ACTION(act, actions, index);
1187 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1188 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1189 rte_flow_error_set(error, EINVAL,
1190 RTE_FLOW_ERROR_TYPE_ACTION,
1191 act, "Not supported action.");
1196 /* must be input direction */
1197 if (!attr->ingress) {
1198 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1199 rte_flow_error_set(error, EINVAL,
1200 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1201 attr, "Only support ingress.");
1207 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1208 rte_flow_error_set(error, EINVAL,
1209 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1210 attr, "Not support egress.");
1214 if (attr->priority > 0xFFFF) {
1215 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1216 rte_flow_error_set(error, EINVAL,
1217 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1218 attr, "Error priority.");
1222 filter->priority = (uint16_t)attr->priority;
1228 igb_parse_flex_filter(struct rte_eth_dev *dev,
1229 const struct rte_flow_attr *attr,
1230 const struct rte_flow_item pattern[],
1231 const struct rte_flow_action actions[],
1232 struct rte_eth_flex_filter *filter,
1233 struct rte_flow_error *error)
1235 struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1238 MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
1240 ret = cons_parse_flex_filter(attr, pattern,
1241 actions, filter, error);
1243 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
1244 memset(filter, 0, sizeof(struct rte_eth_flex_filter));
1245 rte_flow_error_set(error, EINVAL,
1246 RTE_FLOW_ERROR_TYPE_ITEM,
1247 NULL, "queue number not supported by flex filter");
1251 if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
1252 filter->len % sizeof(uint64_t) != 0) {
1253 PMD_DRV_LOG(ERR, "filter's length is out of range");
1257 if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
1258 PMD_DRV_LOG(ERR, "filter's priority is out of range");
1269 igb_parse_rss_filter(struct rte_eth_dev *dev,
1270 const struct rte_flow_attr *attr,
1271 const struct rte_flow_action actions[],
1272 struct igb_rte_flow_rss_conf *rss_conf,
1273 struct rte_flow_error *error)
1275 const struct rte_flow_action *act;
1276 const struct rte_flow_action_rss *rss;
1280 * rss only supports forwarding,
1281 * check if the first not void action is RSS.
1284 NEXT_ITEM_OF_ACTION(act, actions, index);
1285 if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
1286 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1287 rte_flow_error_set(error, EINVAL,
1288 RTE_FLOW_ERROR_TYPE_ACTION,
1289 act, "Not supported action.");
1293 rss = (const struct rte_flow_action_rss *)act->conf;
1295 if (!rss || !rss->queue_num) {
1296 rte_flow_error_set(error, EINVAL,
1297 RTE_FLOW_ERROR_TYPE_ACTION,
1303 for (n = 0; n < rss->queue_num; n++) {
1304 if (rss->queue[n] >= dev->data->nb_rx_queues) {
1305 rte_flow_error_set(error, EINVAL,
1306 RTE_FLOW_ERROR_TYPE_ACTION,
1308 "queue id > max number of queues");
1313 if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
1314 return rte_flow_error_set
1315 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1316 "RSS hash key must be exactly 40 bytes");
1317 if (rss->queue_num > RTE_DIM(rss_conf->queue))
1318 return rte_flow_error_set
1319 (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
1320 "too many queues for RSS context");
1321 if (igb_rss_conf_init(rss_conf, rss))
1322 return rte_flow_error_set
1323 (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
1324 "RSS context initialization failure");
1326 /* check if the next not void item is END */
1328 NEXT_ITEM_OF_ACTION(act, actions, index);
1329 if (act->type != RTE_FLOW_ACTION_TYPE_END) {
1330 memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf));
1331 rte_flow_error_set(error, EINVAL,
1332 RTE_FLOW_ERROR_TYPE_ACTION,
1333 act, "Not supported action.");
1338 /* must be input direction */
1339 if (!attr->ingress) {
1340 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1341 rte_flow_error_set(error, EINVAL,
1342 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
1343 attr, "Only support ingress.");
1349 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1350 rte_flow_error_set(error, EINVAL,
1351 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
1352 attr, "Not support egress.");
1356 if (attr->priority > 0xFFFF) {
1357 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1358 rte_flow_error_set(error, EINVAL,
1359 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
1360 attr, "Error priority.");
1368 * Create a flow rule.
1369 * Theorically one rule can match more than one filters.
1370 * We will let it use the filter which it hitt first.
1371 * So, the sequence matters.
1373 static struct rte_flow *
1374 igb_flow_create(struct rte_eth_dev *dev,
1375 const struct rte_flow_attr *attr,
1376 const struct rte_flow_item pattern[],
1377 const struct rte_flow_action actions[],
1378 struct rte_flow_error *error)
1381 struct rte_eth_ntuple_filter ntuple_filter;
1382 struct rte_eth_ethertype_filter ethertype_filter;
1383 struct rte_eth_syn_filter syn_filter;
1384 struct rte_eth_flex_filter flex_filter;
1385 struct igb_rte_flow_rss_conf rss_conf;
1386 struct rte_flow *flow = NULL;
1387 struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1388 struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1389 struct igb_eth_syn_filter_ele *syn_filter_ptr;
1390 struct igb_flex_filter_ele *flex_filter_ptr;
1391 struct igb_rss_conf_ele *rss_filter_ptr;
1392 struct igb_flow_mem *igb_flow_mem_ptr;
1394 flow = rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0);
1396 PMD_DRV_LOG(ERR, "failed to allocate memory");
1397 return (struct rte_flow *)flow;
1399 igb_flow_mem_ptr = rte_zmalloc("igb_flow_mem",
1400 sizeof(struct igb_flow_mem), 0);
1401 if (!igb_flow_mem_ptr) {
1402 PMD_DRV_LOG(ERR, "failed to allocate memory");
1406 igb_flow_mem_ptr->flow = flow;
1407 igb_flow_mem_ptr->dev = dev;
1408 TAILQ_INSERT_TAIL(&igb_flow_list,
1409 igb_flow_mem_ptr, entries);
1411 memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1412 ret = igb_parse_ntuple_filter(dev, attr, pattern,
1413 actions, &ntuple_filter, error);
1415 ret = igb_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
1417 ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
1418 sizeof(struct igb_ntuple_filter_ele), 0);
1419 if (!ntuple_filter_ptr) {
1420 PMD_DRV_LOG(ERR, "failed to allocate memory");
1424 rte_memcpy(&ntuple_filter_ptr->filter_info,
1426 sizeof(struct rte_eth_ntuple_filter));
1427 TAILQ_INSERT_TAIL(&igb_filter_ntuple_list,
1428 ntuple_filter_ptr, entries);
1429 flow->rule = ntuple_filter_ptr;
1430 flow->filter_type = RTE_ETH_FILTER_NTUPLE;
1436 memset(ðertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1437 ret = igb_parse_ethertype_filter(dev, attr, pattern,
1438 actions, ðertype_filter, error);
1440 ret = igb_add_del_ethertype_filter(dev,
1441 ðertype_filter, TRUE);
1443 ethertype_filter_ptr = rte_zmalloc(
1444 "igb_ethertype_filter",
1445 sizeof(struct igb_ethertype_filter_ele), 0);
1446 if (!ethertype_filter_ptr) {
1447 PMD_DRV_LOG(ERR, "failed to allocate memory");
1451 rte_memcpy(ðertype_filter_ptr->filter_info,
1453 sizeof(struct rte_eth_ethertype_filter));
1454 TAILQ_INSERT_TAIL(&igb_filter_ethertype_list,
1455 ethertype_filter_ptr, entries);
1456 flow->rule = ethertype_filter_ptr;
1457 flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
1463 memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1464 ret = igb_parse_syn_filter(dev, attr, pattern,
1465 actions, &syn_filter, error);
1467 ret = eth_igb_syn_filter_set(dev, &syn_filter, TRUE);
1469 syn_filter_ptr = rte_zmalloc("igb_syn_filter",
1470 sizeof(struct igb_eth_syn_filter_ele), 0);
1471 if (!syn_filter_ptr) {
1472 PMD_DRV_LOG(ERR, "failed to allocate memory");
1476 rte_memcpy(&syn_filter_ptr->filter_info,
1478 sizeof(struct rte_eth_syn_filter));
1479 TAILQ_INSERT_TAIL(&igb_filter_syn_list,
1482 flow->rule = syn_filter_ptr;
1483 flow->filter_type = RTE_ETH_FILTER_SYN;
1489 memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1490 ret = igb_parse_flex_filter(dev, attr, pattern,
1491 actions, &flex_filter, error);
1493 ret = eth_igb_add_del_flex_filter(dev, &flex_filter, TRUE);
1495 flex_filter_ptr = rte_zmalloc("igb_flex_filter",
1496 sizeof(struct igb_flex_filter_ele), 0);
1497 if (!flex_filter_ptr) {
1498 PMD_DRV_LOG(ERR, "failed to allocate memory");
1502 rte_memcpy(&flex_filter_ptr->filter_info,
1504 sizeof(struct rte_eth_flex_filter));
1505 TAILQ_INSERT_TAIL(&igb_filter_flex_list,
1506 flex_filter_ptr, entries);
1507 flow->rule = flex_filter_ptr;
1508 flow->filter_type = RTE_ETH_FILTER_FLEXIBLE;
1513 memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1514 ret = igb_parse_rss_filter(dev, attr,
1515 actions, &rss_conf, error);
1517 ret = igb_config_rss_filter(dev, &rss_conf, TRUE);
1519 rss_filter_ptr = rte_zmalloc("igb_rss_filter",
1520 sizeof(struct igb_rss_conf_ele), 0);
1521 if (!rss_filter_ptr) {
1522 PMD_DRV_LOG(ERR, "failed to allocate memory");
1525 igb_rss_conf_init(&rss_filter_ptr->filter_info,
1527 TAILQ_INSERT_TAIL(&igb_filter_rss_list,
1528 rss_filter_ptr, entries);
1529 flow->rule = rss_filter_ptr;
1530 flow->filter_type = RTE_ETH_FILTER_HASH;
1536 TAILQ_REMOVE(&igb_flow_list,
1537 igb_flow_mem_ptr, entries);
1538 rte_flow_error_set(error, -ret,
1539 RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1540 "Failed to create flow.");
1541 rte_free(igb_flow_mem_ptr);
1547 * Check if the flow rule is supported by igb.
1548 * It only checkes the format. Don't guarantee the rule can be programmed into
1549 * the HW. Because there can be no enough room for the rule.
1552 igb_flow_validate(__rte_unused struct rte_eth_dev *dev,
1553 const struct rte_flow_attr *attr,
1554 const struct rte_flow_item pattern[],
1555 const struct rte_flow_action actions[],
1556 struct rte_flow_error *error)
1558 struct rte_eth_ntuple_filter ntuple_filter;
1559 struct rte_eth_ethertype_filter ethertype_filter;
1560 struct rte_eth_syn_filter syn_filter;
1561 struct rte_eth_flex_filter flex_filter;
1562 struct igb_rte_flow_rss_conf rss_conf;
1565 memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
1566 ret = igb_parse_ntuple_filter(dev, attr, pattern,
1567 actions, &ntuple_filter, error);
1571 memset(ðertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
1572 ret = igb_parse_ethertype_filter(dev, attr, pattern,
1573 actions, ðertype_filter, error);
1577 memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
1578 ret = igb_parse_syn_filter(dev, attr, pattern,
1579 actions, &syn_filter, error);
1583 memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter));
1584 ret = igb_parse_flex_filter(dev, attr, pattern,
1585 actions, &flex_filter, error);
1589 memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
1590 ret = igb_parse_rss_filter(dev, attr,
1591 actions, &rss_conf, error);
1596 /* Destroy a flow rule on igb. */
1598 igb_flow_destroy(struct rte_eth_dev *dev,
1599 struct rte_flow *flow,
1600 struct rte_flow_error *error)
1603 struct rte_flow *pmd_flow = flow;
1604 enum rte_filter_type filter_type = pmd_flow->filter_type;
1605 struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1606 struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1607 struct igb_eth_syn_filter_ele *syn_filter_ptr;
1608 struct igb_flex_filter_ele *flex_filter_ptr;
1609 struct igb_flow_mem *igb_flow_mem_ptr;
1610 struct igb_rss_conf_ele *rss_filter_ptr;
1612 switch (filter_type) {
1613 case RTE_ETH_FILTER_NTUPLE:
1614 ntuple_filter_ptr = (struct igb_ntuple_filter_ele *)
1616 ret = igb_add_del_ntuple_filter(dev,
1617 &ntuple_filter_ptr->filter_info, FALSE);
1619 TAILQ_REMOVE(&igb_filter_ntuple_list,
1620 ntuple_filter_ptr, entries);
1621 rte_free(ntuple_filter_ptr);
1624 case RTE_ETH_FILTER_ETHERTYPE:
1625 ethertype_filter_ptr = (struct igb_ethertype_filter_ele *)
1627 ret = igb_add_del_ethertype_filter(dev,
1628 ðertype_filter_ptr->filter_info, FALSE);
1630 TAILQ_REMOVE(&igb_filter_ethertype_list,
1631 ethertype_filter_ptr, entries);
1632 rte_free(ethertype_filter_ptr);
1635 case RTE_ETH_FILTER_SYN:
1636 syn_filter_ptr = (struct igb_eth_syn_filter_ele *)
1638 ret = eth_igb_syn_filter_set(dev,
1639 &syn_filter_ptr->filter_info, FALSE);
1641 TAILQ_REMOVE(&igb_filter_syn_list,
1642 syn_filter_ptr, entries);
1643 rte_free(syn_filter_ptr);
1646 case RTE_ETH_FILTER_FLEXIBLE:
1647 flex_filter_ptr = (struct igb_flex_filter_ele *)
1649 ret = eth_igb_add_del_flex_filter(dev,
1650 &flex_filter_ptr->filter_info, FALSE);
1652 TAILQ_REMOVE(&igb_filter_flex_list,
1653 flex_filter_ptr, entries);
1654 rte_free(flex_filter_ptr);
1657 case RTE_ETH_FILTER_HASH:
1658 rss_filter_ptr = (struct igb_rss_conf_ele *)
1660 ret = igb_config_rss_filter(dev,
1661 &rss_filter_ptr->filter_info, FALSE);
1663 TAILQ_REMOVE(&igb_filter_rss_list,
1664 rss_filter_ptr, entries);
1665 rte_free(rss_filter_ptr);
1669 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
1676 rte_flow_error_set(error, EINVAL,
1677 RTE_FLOW_ERROR_TYPE_HANDLE,
1678 NULL, "Failed to destroy flow");
1682 TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1683 if (igb_flow_mem_ptr->flow == pmd_flow) {
1684 TAILQ_REMOVE(&igb_flow_list,
1685 igb_flow_mem_ptr, entries);
1686 rte_free(igb_flow_mem_ptr);
1694 /* remove all the n-tuple filters */
1696 igb_clear_all_ntuple_filter(struct rte_eth_dev *dev)
1698 struct e1000_filter_info *filter_info =
1699 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1700 struct e1000_5tuple_filter *p_5tuple;
1701 struct e1000_2tuple_filter *p_2tuple;
1703 while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
1704 igb_delete_5tuple_filter_82576(dev, p_5tuple);
1706 while ((p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list)))
1707 igb_delete_2tuple_filter(dev, p_2tuple);
1710 /* remove all the ether type filters */
1712 igb_clear_all_ethertype_filter(struct rte_eth_dev *dev)
1714 struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1715 struct e1000_filter_info *filter_info =
1716 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1719 for (i = 0; i < E1000_MAX_ETQF_FILTERS; i++) {
1720 if (filter_info->ethertype_mask & (1 << i)) {
1721 (void)igb_ethertype_filter_remove(filter_info,
1723 E1000_WRITE_REG(hw, E1000_ETQF(i), 0);
1724 E1000_WRITE_FLUSH(hw);
1729 /* remove the SYN filter */
1731 igb_clear_syn_filter(struct rte_eth_dev *dev)
1733 struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1734 struct e1000_filter_info *filter_info =
1735 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1737 if (filter_info->syn_info & E1000_SYN_FILTER_ENABLE) {
1738 filter_info->syn_info = 0;
1739 E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
1740 E1000_WRITE_FLUSH(hw);
1744 /* remove all the flex filters */
1746 igb_clear_all_flex_filter(struct rte_eth_dev *dev)
1748 struct e1000_filter_info *filter_info =
1749 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1750 struct e1000_flex_filter *flex_filter;
1752 while ((flex_filter = TAILQ_FIRST(&filter_info->flex_list)))
1753 igb_remove_flex_filter(dev, flex_filter);
1756 /* remove the rss filter */
1758 igb_clear_rss_filter(struct rte_eth_dev *dev)
1760 struct e1000_filter_info *filter =
1761 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
1763 if (filter->rss_info.conf.queue_num)
1764 igb_config_rss_filter(dev, &filter->rss_info, FALSE);
1768 igb_filterlist_flush(struct rte_eth_dev *dev)
1770 struct igb_ntuple_filter_ele *ntuple_filter_ptr;
1771 struct igb_ethertype_filter_ele *ethertype_filter_ptr;
1772 struct igb_eth_syn_filter_ele *syn_filter_ptr;
1773 struct igb_flex_filter_ele *flex_filter_ptr;
1774 struct igb_rss_conf_ele *rss_filter_ptr;
1775 struct igb_flow_mem *igb_flow_mem_ptr;
1776 enum rte_filter_type filter_type;
1777 struct rte_flow *pmd_flow;
1779 TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
1780 if (igb_flow_mem_ptr->dev == dev) {
1781 pmd_flow = igb_flow_mem_ptr->flow;
1782 filter_type = pmd_flow->filter_type;
1784 switch (filter_type) {
1785 case RTE_ETH_FILTER_NTUPLE:
1787 (struct igb_ntuple_filter_ele *)
1789 TAILQ_REMOVE(&igb_filter_ntuple_list,
1790 ntuple_filter_ptr, entries);
1791 rte_free(ntuple_filter_ptr);
1793 case RTE_ETH_FILTER_ETHERTYPE:
1794 ethertype_filter_ptr =
1795 (struct igb_ethertype_filter_ele *)
1797 TAILQ_REMOVE(&igb_filter_ethertype_list,
1798 ethertype_filter_ptr, entries);
1799 rte_free(ethertype_filter_ptr);
1801 case RTE_ETH_FILTER_SYN:
1803 (struct igb_eth_syn_filter_ele *)
1805 TAILQ_REMOVE(&igb_filter_syn_list,
1806 syn_filter_ptr, entries);
1807 rte_free(syn_filter_ptr);
1809 case RTE_ETH_FILTER_FLEXIBLE:
1811 (struct igb_flex_filter_ele *)
1813 TAILQ_REMOVE(&igb_filter_flex_list,
1814 flex_filter_ptr, entries);
1815 rte_free(flex_filter_ptr);
1817 case RTE_ETH_FILTER_HASH:
1819 (struct igb_rss_conf_ele *)
1821 TAILQ_REMOVE(&igb_filter_rss_list,
1822 rss_filter_ptr, entries);
1823 rte_free(rss_filter_ptr);
1826 PMD_DRV_LOG(WARNING, "Filter type"
1827 "(%d) not supported", filter_type);
1830 TAILQ_REMOVE(&igb_flow_list,
1833 rte_free(igb_flow_mem_ptr->flow);
1834 rte_free(igb_flow_mem_ptr);
1839 /* Destroy all flow rules associated with a port on igb. */
1841 igb_flow_flush(struct rte_eth_dev *dev,
1842 __rte_unused struct rte_flow_error *error)
1844 igb_clear_all_ntuple_filter(dev);
1845 igb_clear_all_ethertype_filter(dev);
1846 igb_clear_syn_filter(dev);
1847 igb_clear_all_flex_filter(dev);
1848 igb_clear_rss_filter(dev);
1849 igb_filterlist_flush(dev);
1854 const struct rte_flow_ops igb_flow_ops = {
1855 .validate = igb_flow_validate,
1856 .create = igb_flow_create,
1857 .destroy = igb_flow_destroy,
1858 .flush = igb_flow_flush,