LCOV - code coverage report
Current view: top level - drivers/net/e1000 - igb_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 697 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 16 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 530 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2016 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <sys/queue.h>
       6                 :            : #include <stdio.h>
       7                 :            : #include <errno.h>
       8                 :            : #include <stdint.h>
       9                 :            : #include <stdarg.h>
      10                 :            : 
      11                 :            : #include <rte_common.h>
      12                 :            : #include <rte_interrupts.h>
      13                 :            : #include <rte_byteorder.h>
      14                 :            : #include <rte_log.h>
      15                 :            : #include <rte_debug.h>
      16                 :            : #include <rte_pci.h>
      17                 :            : #include <rte_ether.h>
      18                 :            : #include <ethdev_driver.h>
      19                 :            : #include <ethdev_pci.h>
      20                 :            : #include <rte_memory.h>
      21                 :            : #include <rte_eal.h>
      22                 :            : #include <rte_atomic.h>
      23                 :            : #include <rte_malloc.h>
      24                 :            : #include <dev_driver.h>
      25                 :            : #include <rte_flow.h>
      26                 :            : #include <rte_flow_driver.h>
      27                 :            : 
      28                 :            : #include "e1000_logs.h"
      29                 :            : #include "base/e1000_api.h"
      30                 :            : #include "e1000_ethdev.h"
      31                 :            : 
      32                 :            : #define NEXT_ITEM_OF_PATTERN(item, pattern, index)              \
      33                 :            :         do {                                                    \
      34                 :            :                 item = (pattern) + (index);                     \
      35                 :            :                 while (item->type == RTE_FLOW_ITEM_TYPE_VOID) {      \
      36                 :            :                 (index)++;                                      \
      37                 :            :                 item = (pattern) + (index);                     \
      38                 :            :                 }                                               \
      39                 :            :         } while (0)
      40                 :            : 
      41                 :            : #define NEXT_ITEM_OF_ACTION(act, actions, index)                \
      42                 :            :         do {                                                    \
      43                 :            :                 act = (actions) + (index);                      \
      44                 :            :                 while (act->type == RTE_FLOW_ACTION_TYPE_VOID) {\
      45                 :            :                 (index)++;                                      \
      46                 :            :                 act = (actions) + (index);                      \
      47                 :            :                 }                                               \
      48                 :            :         } while (0)
      49                 :            : 
      50                 :            : #define IGB_FLEX_RAW_NUM        12
      51                 :            : 
      52                 :            : struct igb_flow_mem_list igb_flow_list;
      53                 :            : struct igb_ntuple_filter_list igb_filter_ntuple_list;
      54                 :            : struct igb_ethertype_filter_list igb_filter_ethertype_list;
      55                 :            : struct igb_syn_filter_list igb_filter_syn_list;
      56                 :            : struct igb_flex_filter_list igb_filter_flex_list;
      57                 :            : struct igb_rss_filter_list igb_filter_rss_list;
      58                 :            : 
      59                 :            : /**
      60                 :            :  * Please be aware there's an assumption for all the parsers.
      61                 :            :  * rte_flow_item is using big endian, rte_flow_attr and
      62                 :            :  * rte_flow_action are using CPU order.
      63                 :            :  * Because the pattern is used to describe the packets,
      64                 :            :  * normally the packets should use network order.
      65                 :            :  */
      66                 :            : 
      67                 :            : /**
      68                 :            :  * Parse the rule to see if it is a n-tuple rule.
      69                 :            :  * And get the n-tuple filter info BTW.
      70                 :            :  * pattern:
      71                 :            :  * The first not void item can be ETH or IPV4.
      72                 :            :  * The second not void item must be IPV4 if the first one is ETH.
      73                 :            :  * The third not void item must be UDP or TCP or SCTP
      74                 :            :  * The next not void item must be END.
      75                 :            :  * action:
      76                 :            :  * The first not void action should be QUEUE.
      77                 :            :  * The next not void action should be END.
      78                 :            :  * pattern example:
      79                 :            :  * ITEM         Spec                    Mask
      80                 :            :  * ETH          NULL                    NULL
      81                 :            :  * IPV4         src_addr 192.168.1.20   0xFFFFFFFF
      82                 :            :  *                      dst_addr 192.167.3.50   0xFFFFFFFF
      83                 :            :  *                      next_proto_id   17      0xFF
      84                 :            :  * UDP/TCP/     src_port        80      0xFFFF
      85                 :            :  * SCTP         dst_port        80      0xFFFF
      86                 :            :  * END
      87                 :            :  * other members in mask and spec should set to 0x00.
      88                 :            :  * item->last should be NULL.
      89                 :            :  */
      90                 :            : static int
      91                 :          0 : cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
      92                 :            :                          const struct rte_flow_item pattern[],
      93                 :            :                          const struct rte_flow_action actions[],
      94                 :            :                          struct rte_eth_ntuple_filter *filter,
      95                 :            :                          struct rte_flow_error *error)
      96                 :            : {
      97                 :            :         const struct rte_flow_item *item;
      98                 :            :         const struct rte_flow_action *act;
      99                 :            :         const struct rte_flow_item_ipv4 *ipv4_spec;
     100                 :            :         const struct rte_flow_item_ipv4 *ipv4_mask;
     101                 :            :         const struct rte_flow_item_tcp *tcp_spec;
     102                 :            :         const struct rte_flow_item_tcp *tcp_mask;
     103                 :            :         const struct rte_flow_item_udp *udp_spec;
     104                 :            :         const struct rte_flow_item_udp *udp_mask;
     105                 :            :         const struct rte_flow_item_sctp *sctp_spec;
     106                 :            :         const struct rte_flow_item_sctp *sctp_mask;
     107                 :            :         uint32_t index;
     108                 :            : 
     109         [ #  # ]:          0 :         if (!pattern) {
     110                 :          0 :                 rte_flow_error_set(error,
     111                 :            :                         EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
     112                 :            :                         NULL, "NULL pattern.");
     113                 :          0 :                 return -rte_errno;
     114                 :            :         }
     115                 :            : 
     116         [ #  # ]:          0 :         if (!actions) {
     117                 :          0 :                 rte_flow_error_set(error, EINVAL,
     118                 :            :                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
     119                 :            :                                    NULL, "NULL action.");
     120                 :          0 :                 return -rte_errno;
     121                 :            :         }
     122         [ #  # ]:          0 :         if (!attr) {
     123                 :          0 :                 rte_flow_error_set(error, EINVAL,
     124                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR,
     125                 :            :                                    NULL, "NULL attribute.");
     126                 :          0 :                 return -rte_errno;
     127                 :            :         }
     128                 :            : 
     129                 :            :         /* parse pattern */
     130                 :            :         index = 0;
     131                 :            : 
     132                 :            :         /* the first not void item can be MAC or IPv4 */
     133         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     134                 :            : 
     135         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
     136                 :            :             item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
     137                 :          0 :                 rte_flow_error_set(error, EINVAL,
     138                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     139                 :            :                         item, "Not supported by ntuple filter");
     140                 :          0 :                 return -rte_errno;
     141                 :            :         }
     142                 :            :         /* Skip Ethernet */
     143         [ #  # ]:          0 :         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
     144                 :            :                 /*Not supported last point for range*/
     145         [ #  # ]:          0 :                 if (item->last) {
     146                 :          0 :                         rte_flow_error_set(error,
     147                 :            :                           EINVAL,
     148                 :            :                           RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     149                 :            :                           item, "Not supported last point for range");
     150                 :          0 :                         return -rte_errno;
     151                 :            :                 }
     152                 :            :                 /* if the first item is MAC, the content should be NULL */
     153   [ #  #  #  # ]:          0 :                 if (item->spec || item->mask) {
     154                 :          0 :                         rte_flow_error_set(error, EINVAL,
     155                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     156                 :            :                                 item, "Not supported by ntuple filter");
     157                 :          0 :                         return -rte_errno;
     158                 :            :                 }
     159                 :            :                 /* check if the next not void item is IPv4 */
     160                 :          0 :                 index++;
     161         [ #  # ]:          0 :                 NEXT_ITEM_OF_PATTERN(item, pattern, index);
     162         [ #  # ]:          0 :                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
     163                 :          0 :                         rte_flow_error_set(error,
     164                 :            :                           EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
     165                 :            :                           item, "Not supported by ntuple filter");
     166                 :          0 :                         return -rte_errno;
     167                 :            :                 }
     168                 :            :         }
     169                 :            : 
     170                 :            :         /* get the IPv4 info */
     171   [ #  #  #  # ]:          0 :         if (!item->spec || !item->mask) {
     172                 :          0 :                 rte_flow_error_set(error, EINVAL,
     173                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     174                 :            :                         item, "Invalid ntuple mask");
     175                 :          0 :                 return -rte_errno;
     176                 :            :         }
     177                 :            :         /* Not supported last point for range */
     178         [ #  # ]:          0 :         if (item->last) {
     179                 :          0 :                 rte_flow_error_set(error, EINVAL,
     180                 :            :                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     181                 :            :                         item, "Not supported last point for range");
     182                 :          0 :                 return -rte_errno;
     183                 :            :         }
     184                 :            : 
     185                 :            :         ipv4_mask = item->mask;
     186                 :            :         /**
     187                 :            :          * Only support src & dst addresses, protocol,
     188                 :            :          * others should be masked.
     189                 :            :          */
     190                 :            : 
     191         [ #  # ]:          0 :         if (ipv4_mask->hdr.version_ihl ||
     192                 :          0 :                 ipv4_mask->hdr.type_of_service ||
     193         [ #  # ]:          0 :                 ipv4_mask->hdr.total_length ||
     194         [ #  # ]:          0 :                 ipv4_mask->hdr.packet_id ||
     195         [ #  # ]:          0 :                 ipv4_mask->hdr.fragment_offset ||
     196         [ #  # ]:          0 :                 ipv4_mask->hdr.time_to_live ||
     197         [ #  # ]:          0 :                 ipv4_mask->hdr.hdr_checksum) {
     198                 :          0 :                 rte_flow_error_set(error,
     199                 :            :                         EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
     200                 :            :                         item, "Not supported by ntuple filter");
     201                 :          0 :                 return -rte_errno;
     202                 :            :         }
     203                 :            : 
     204                 :          0 :         filter->dst_ip_mask = ipv4_mask->hdr.dst_addr;
     205                 :          0 :         filter->src_ip_mask = ipv4_mask->hdr.src_addr;
     206                 :          0 :         filter->proto_mask  = ipv4_mask->hdr.next_proto_id;
     207                 :            : 
     208                 :            :         ipv4_spec = item->spec;
     209                 :          0 :         filter->dst_ip = ipv4_spec->hdr.dst_addr;
     210                 :          0 :         filter->src_ip = ipv4_spec->hdr.src_addr;
     211                 :          0 :         filter->proto  = ipv4_spec->hdr.next_proto_id;
     212                 :            : 
     213                 :            :         /* check if the next not void item is TCP or UDP or SCTP */
     214                 :          0 :         index++;
     215         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     216                 :          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_TCP &&
     217         [ #  # ]:          0 :             item->type != RTE_FLOW_ITEM_TYPE_UDP &&
     218                 :            :             item->type != RTE_FLOW_ITEM_TYPE_SCTP) {
     219                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     220                 :          0 :                 rte_flow_error_set(error, EINVAL,
     221                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     222                 :            :                         item, "Not supported by ntuple filter");
     223                 :          0 :                 return -rte_errno;
     224                 :            :         }
     225                 :            : 
     226                 :            :         /* Not supported last point for range */
     227         [ #  # ]:          0 :         if (item->last) {
     228                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     229                 :          0 :                 rte_flow_error_set(error, EINVAL,
     230                 :            :                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     231                 :            :                         item, "Not supported last point for range");
     232                 :          0 :                 return -rte_errno;
     233                 :            :         }
     234                 :            : 
     235                 :            :         /* get the TCP/UDP/SCTP info */
     236         [ #  # ]:          0 :         if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
     237   [ #  #  #  # ]:          0 :                 if (item->spec && item->mask) {
     238                 :            :                         tcp_mask = item->mask;
     239                 :            : 
     240                 :            :                         /**
     241                 :            :                          * Only support src & dst ports, tcp flags,
     242                 :            :                          * others should be masked.
     243                 :            :                          */
     244         [ #  # ]:          0 :                         if (tcp_mask->hdr.sent_seq ||
     245         [ #  # ]:          0 :                                 tcp_mask->hdr.recv_ack ||
     246         [ #  # ]:          0 :                                 tcp_mask->hdr.data_off ||
     247         [ #  # ]:          0 :                                 tcp_mask->hdr.rx_win ||
     248         [ #  # ]:          0 :                                 tcp_mask->hdr.cksum ||
     249         [ #  # ]:          0 :                                 tcp_mask->hdr.tcp_urp) {
     250                 :            :                                 memset(filter, 0,
     251                 :            :                                         sizeof(struct rte_eth_ntuple_filter));
     252                 :          0 :                                 rte_flow_error_set(error, EINVAL,
     253                 :            :                                         RTE_FLOW_ERROR_TYPE_ITEM,
     254                 :            :                                         item, "Not supported by ntuple filter");
     255                 :          0 :                                 return -rte_errno;
     256                 :            :                         }
     257                 :            : 
     258                 :          0 :                         filter->dst_port_mask  = tcp_mask->hdr.dst_port;
     259                 :          0 :                         filter->src_port_mask  = tcp_mask->hdr.src_port;
     260         [ #  # ]:          0 :                         if (tcp_mask->hdr.tcp_flags == 0xFF) {
     261                 :          0 :                                 filter->flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
     262         [ #  # ]:          0 :                         } else if (!tcp_mask->hdr.tcp_flags) {
     263                 :          0 :                                 filter->flags &= ~RTE_NTUPLE_FLAGS_TCP_FLAG;
     264                 :            :                         } else {
     265                 :            :                                 memset(filter, 0,
     266                 :            :                                         sizeof(struct rte_eth_ntuple_filter));
     267                 :          0 :                                 rte_flow_error_set(error, EINVAL,
     268                 :            :                                         RTE_FLOW_ERROR_TYPE_ITEM,
     269                 :            :                                         item, "Not supported by ntuple filter");
     270                 :          0 :                                 return -rte_errno;
     271                 :            :                         }
     272                 :            : 
     273                 :            :                         tcp_spec = item->spec;
     274                 :          0 :                         filter->dst_port  = tcp_spec->hdr.dst_port;
     275                 :          0 :                         filter->src_port  = tcp_spec->hdr.src_port;
     276                 :          0 :                         filter->tcp_flags = tcp_spec->hdr.tcp_flags;
     277                 :            :                 }
     278         [ #  # ]:          0 :         } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
     279   [ #  #  #  # ]:          0 :                 if (item->spec && item->mask) {
     280                 :            :                         udp_mask = item->mask;
     281                 :            : 
     282                 :            :                         /**
     283                 :            :                          * Only support src & dst ports,
     284                 :            :                          * others should be masked.
     285                 :            :                          */
     286         [ #  # ]:          0 :                         if (udp_mask->hdr.dgram_len ||
     287         [ #  # ]:          0 :                             udp_mask->hdr.dgram_cksum) {
     288                 :            :                                 memset(filter, 0,
     289                 :            :                                         sizeof(struct rte_eth_ntuple_filter));
     290                 :          0 :                                 rte_flow_error_set(error, EINVAL,
     291                 :            :                                         RTE_FLOW_ERROR_TYPE_ITEM,
     292                 :            :                                         item, "Not supported by ntuple filter");
     293                 :          0 :                                 return -rte_errno;
     294                 :            :                         }
     295                 :            : 
     296                 :          0 :                         filter->dst_port_mask = udp_mask->hdr.dst_port;
     297                 :          0 :                         filter->src_port_mask = udp_mask->hdr.src_port;
     298                 :            : 
     299                 :            :                         udp_spec = item->spec;
     300                 :          0 :                         filter->dst_port = udp_spec->hdr.dst_port;
     301                 :          0 :                         filter->src_port = udp_spec->hdr.src_port;
     302                 :            :                 }
     303                 :            :         } else {
     304   [ #  #  #  # ]:          0 :                 if (item->spec && item->mask) {
     305                 :            :                         sctp_mask = item->mask;
     306                 :            : 
     307                 :            :                         /**
     308                 :            :                          * Only support src & dst ports,
     309                 :            :                          * others should be masked.
     310                 :            :                          */
     311         [ #  # ]:          0 :                         if (sctp_mask->hdr.tag ||
     312         [ #  # ]:          0 :                             sctp_mask->hdr.cksum) {
     313                 :            :                                 memset(filter, 0,
     314                 :            :                                         sizeof(struct rte_eth_ntuple_filter));
     315                 :          0 :                                 rte_flow_error_set(error, EINVAL,
     316                 :            :                                         RTE_FLOW_ERROR_TYPE_ITEM,
     317                 :            :                                         item, "Not supported by ntuple filter");
     318                 :          0 :                                 return -rte_errno;
     319                 :            :                         }
     320                 :            : 
     321                 :          0 :                         filter->dst_port_mask = sctp_mask->hdr.dst_port;
     322                 :          0 :                         filter->src_port_mask = sctp_mask->hdr.src_port;
     323                 :            : 
     324                 :            :                         sctp_spec = (const struct rte_flow_item_sctp *)
     325                 :            :                                         item->spec;
     326                 :          0 :                         filter->dst_port = sctp_spec->hdr.dst_port;
     327                 :          0 :                         filter->src_port = sctp_spec->hdr.src_port;
     328                 :            :                 }
     329                 :            :         }
     330                 :            :         /* check if the next not void item is END */
     331                 :          0 :         index++;
     332         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     333         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
     334                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     335                 :          0 :                 rte_flow_error_set(error, EINVAL,
     336                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     337                 :            :                         item, "Not supported by ntuple filter");
     338                 :          0 :                 return -rte_errno;
     339                 :            :         }
     340                 :            : 
     341                 :            :         /* parse action */
     342                 :            :         index = 0;
     343                 :            : 
     344                 :            :         /**
     345                 :            :          * n-tuple only supports forwarding,
     346                 :            :          * check if the first not void action is QUEUE.
     347                 :            :          */
     348         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
     349         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
     350                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     351                 :          0 :                 rte_flow_error_set(error, EINVAL,
     352                 :            :                         RTE_FLOW_ERROR_TYPE_ACTION,
     353                 :            :                         act, "Not supported action.");
     354                 :          0 :                 return -rte_errno;
     355                 :            :         }
     356                 :          0 :         filter->queue =
     357                 :          0 :                 ((const struct rte_flow_action_queue *)act->conf)->index;
     358                 :            : 
     359                 :            :         /* check if the next not void item is END */
     360                 :          0 :         index++;
     361         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
     362         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
     363                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     364                 :          0 :                 rte_flow_error_set(error, EINVAL,
     365                 :            :                         RTE_FLOW_ERROR_TYPE_ACTION,
     366                 :            :                         act, "Not supported action.");
     367                 :          0 :                 return -rte_errno;
     368                 :            :         }
     369                 :            : 
     370                 :            :         /* parse attr */
     371                 :            :         /* must be input direction */
     372         [ #  # ]:          0 :         if (!attr->ingress) {
     373                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     374                 :          0 :                 rte_flow_error_set(error, EINVAL,
     375                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
     376                 :            :                                    attr, "Only support ingress.");
     377                 :          0 :                 return -rte_errno;
     378                 :            :         }
     379                 :            : 
     380                 :            :         /* not supported */
     381         [ #  # ]:          0 :         if (attr->egress) {
     382                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     383                 :          0 :                 rte_flow_error_set(error, EINVAL,
     384                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
     385                 :            :                                    attr, "Not support egress.");
     386                 :          0 :                 return -rte_errno;
     387                 :            :         }
     388                 :            : 
     389                 :            :         /* not supported */
     390         [ #  # ]:          0 :         if (attr->transfer) {
     391                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     392                 :          0 :                 rte_flow_error_set(error, EINVAL,
     393                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
     394                 :            :                                    attr, "No support for transfer.");
     395                 :          0 :                 return -rte_errno;
     396                 :            :         }
     397                 :            : 
     398         [ #  # ]:          0 :         if (attr->priority > 0xFFFF) {
     399                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     400                 :          0 :                 rte_flow_error_set(error, EINVAL,
     401                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
     402                 :            :                                    attr, "Error priority.");
     403                 :          0 :                 return -rte_errno;
     404                 :            :         }
     405                 :          0 :         filter->priority = (uint16_t)attr->priority;
     406                 :            : 
     407                 :          0 :         return 0;
     408                 :            : }
     409                 :            : 
     410                 :            : /* a specific function for igb because the flags is specific */
     411                 :            : static int
     412                 :          0 : igb_parse_ntuple_filter(struct rte_eth_dev *dev,
     413                 :            :                           const struct rte_flow_attr *attr,
     414                 :            :                           const struct rte_flow_item pattern[],
     415                 :            :                           const struct rte_flow_action actions[],
     416                 :            :                           struct rte_eth_ntuple_filter *filter,
     417                 :            :                           struct rte_flow_error *error)
     418                 :            : {
     419                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     420                 :            :         int ret;
     421                 :            : 
     422   [ #  #  #  # ]:          0 :         MAC_TYPE_FILTER_SUP(hw->mac.type);
     423                 :            : 
     424                 :          0 :         ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
     425                 :            : 
     426         [ #  # ]:          0 :         if (ret)
     427                 :            :                 return ret;
     428                 :            : 
     429                 :            :         /* Igb doesn't support many priorities. */
     430         [ #  # ]:          0 :         if (filter->priority > E1000_2TUPLE_MAX_PRI) {
     431                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     432                 :          0 :                 rte_flow_error_set(error, EINVAL,
     433                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     434                 :            :                         NULL, "Priority not supported by ntuple filter");
     435                 :          0 :                 return -rte_errno;
     436                 :            :         }
     437                 :            : 
     438         [ #  # ]:          0 :         if (hw->mac.type == e1000_82576) {
     439         [ #  # ]:          0 :                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
     440                 :            :                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     441                 :          0 :                         rte_flow_error_set(error, EINVAL,
     442                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     443                 :            :                                 NULL, "queue number not "
     444                 :            :                                 "supported by ntuple filter");
     445                 :          0 :                         return -rte_errno;
     446                 :            :                 }
     447                 :          0 :                 filter->flags |= RTE_5TUPLE_FLAGS;
     448                 :            :         } else {
     449   [ #  #  #  # ]:          0 :                 if (filter->src_ip_mask || filter->dst_ip_mask ||
     450         [ #  # ]:          0 :                         filter->src_port_mask) {
     451                 :            :                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     452                 :          0 :                         rte_flow_error_set(error, EINVAL,
     453                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     454                 :            :                                 NULL, "only two tuple are "
     455                 :            :                                 "supported by this filter");
     456                 :          0 :                         return -rte_errno;
     457                 :            :                 }
     458         [ #  # ]:          0 :                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
     459                 :            :                         memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
     460                 :          0 :                         rte_flow_error_set(error, EINVAL,
     461                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     462                 :            :                                 NULL, "queue number not "
     463                 :            :                                 "supported by ntuple filter");
     464                 :          0 :                         return -rte_errno;
     465                 :            :                 }
     466                 :          0 :                 filter->flags |= RTE_2TUPLE_FLAGS;
     467                 :            :         }
     468                 :            : 
     469                 :            :         return 0;
     470                 :            : }
     471                 :            : 
     472                 :            : /**
     473                 :            :  * Parse the rule to see if it is a ethertype rule.
     474                 :            :  * And get the ethertype filter info BTW.
     475                 :            :  * pattern:
     476                 :            :  * The first not void item can be ETH.
     477                 :            :  * The next not void item must be END.
     478                 :            :  * action:
     479                 :            :  * The first not void action should be QUEUE.
     480                 :            :  * The next not void action should be END.
     481                 :            :  * pattern example:
     482                 :            :  * ITEM         Spec                    Mask
     483                 :            :  * ETH          type    0x0807          0xFFFF
     484                 :            :  * END
     485                 :            :  * other members in mask and spec should set to 0x00.
     486                 :            :  * item->last should be NULL.
     487                 :            :  */
     488                 :            : static int
     489                 :          0 : cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
     490                 :            :                             const struct rte_flow_item *pattern,
     491                 :            :                             const struct rte_flow_action *actions,
     492                 :            :                             struct rte_eth_ethertype_filter *filter,
     493                 :            :                             struct rte_flow_error *error)
     494                 :            : {
     495                 :            :         const struct rte_flow_item *item;
     496                 :            :         const struct rte_flow_action *act;
     497                 :            :         const struct rte_flow_item_eth *eth_spec;
     498                 :            :         const struct rte_flow_item_eth *eth_mask;
     499                 :            :         const struct rte_flow_action_queue *act_q;
     500                 :            :         uint32_t index;
     501                 :            : 
     502         [ #  # ]:          0 :         if (!pattern) {
     503                 :          0 :                 rte_flow_error_set(error, EINVAL,
     504                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
     505                 :            :                                 NULL, "NULL pattern.");
     506                 :          0 :                 return -rte_errno;
     507                 :            :         }
     508                 :            : 
     509         [ #  # ]:          0 :         if (!actions) {
     510                 :          0 :                 rte_flow_error_set(error, EINVAL,
     511                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
     512                 :            :                                 NULL, "NULL action.");
     513                 :          0 :                 return -rte_errno;
     514                 :            :         }
     515                 :            : 
     516         [ #  # ]:          0 :         if (!attr) {
     517                 :          0 :                 rte_flow_error_set(error, EINVAL,
     518                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR,
     519                 :            :                                    NULL, "NULL attribute.");
     520                 :          0 :                 return -rte_errno;
     521                 :            :         }
     522                 :            : 
     523                 :            :         /* Parse pattern */
     524                 :            :         index = 0;
     525                 :            : 
     526                 :            :         /* The first non-void item should be MAC. */
     527         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     528         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
     529                 :          0 :                 rte_flow_error_set(error, EINVAL,
     530                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     531                 :            :                         item, "Not supported by ethertype filter");
     532                 :          0 :                 return -rte_errno;
     533                 :            :         }
     534                 :            : 
     535                 :            :         /*Not supported last point for range*/
     536         [ #  # ]:          0 :         if (item->last) {
     537                 :          0 :                 rte_flow_error_set(error, EINVAL,
     538                 :            :                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     539                 :            :                         item, "Not supported last point for range");
     540                 :          0 :                 return -rte_errno;
     541                 :            :         }
     542                 :            : 
     543                 :            :         /* Get the MAC info. */
     544   [ #  #  #  # ]:          0 :         if (!item->spec || !item->mask) {
     545                 :          0 :                 rte_flow_error_set(error, EINVAL,
     546                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     547                 :            :                                 item, "Not supported by ethertype filter");
     548                 :          0 :                 return -rte_errno;
     549                 :            :         }
     550                 :            : 
     551                 :            :         eth_spec = item->spec;
     552                 :            :         eth_mask = item->mask;
     553                 :            : 
     554                 :            :         /* Mask bits of source MAC address must be full of 0.
     555                 :            :          * Mask bits of destination MAC address must be full
     556                 :            :          * of 1 or full of 0.
     557                 :            :          */
     558   [ #  #  #  # ]:          0 :         if (!rte_is_zero_ether_addr(&eth_mask->hdr.src_addr) ||
     559         [ #  # ]:          0 :             (!rte_is_zero_ether_addr(&eth_mask->hdr.dst_addr) &&
     560                 :            :              !rte_is_broadcast_ether_addr(&eth_mask->hdr.dst_addr))) {
     561                 :          0 :                 rte_flow_error_set(error, EINVAL,
     562                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     563                 :            :                                 item, "Invalid ether address mask");
     564                 :          0 :                 return -rte_errno;
     565                 :            :         }
     566                 :            : 
     567         [ #  # ]:          0 :         if ((eth_mask->hdr.ether_type & UINT16_MAX) != UINT16_MAX) {
     568                 :          0 :                 rte_flow_error_set(error, EINVAL,
     569                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     570                 :            :                                 item, "Invalid ethertype mask");
     571                 :          0 :                 return -rte_errno;
     572                 :            :         }
     573                 :            : 
     574                 :            :         /* If mask bits of destination MAC address
     575                 :            :          * are full of 1, set RTE_ETHTYPE_FLAGS_MAC.
     576                 :            :          */
     577         [ #  # ]:          0 :         if (rte_is_broadcast_ether_addr(&eth_mask->hdr.dst_addr)) {
     578                 :          0 :                 filter->mac_addr = eth_spec->hdr.dst_addr;
     579                 :          0 :                 filter->flags |= RTE_ETHTYPE_FLAGS_MAC;
     580                 :            :         } else {
     581                 :          0 :                 filter->flags &= ~RTE_ETHTYPE_FLAGS_MAC;
     582                 :            :         }
     583         [ #  # ]:          0 :         filter->ether_type = rte_be_to_cpu_16(eth_spec->hdr.ether_type);
     584                 :            : 
     585                 :            :         /* Check if the next non-void item is END. */
     586                 :          0 :         index++;
     587         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     588         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
     589                 :          0 :                 rte_flow_error_set(error, EINVAL,
     590                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     591                 :            :                                 item, "Not supported by ethertype filter.");
     592                 :          0 :                 return -rte_errno;
     593                 :            :         }
     594                 :            : 
     595                 :            :         /* Parse action */
     596                 :            : 
     597                 :            :         index = 0;
     598                 :            :         /* Check if the first non-void action is QUEUE or DROP. */
     599         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
     600         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
     601                 :            :             act->type != RTE_FLOW_ACTION_TYPE_DROP) {
     602                 :          0 :                 rte_flow_error_set(error, EINVAL,
     603                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
     604                 :            :                                 act, "Not supported action.");
     605                 :          0 :                 return -rte_errno;
     606                 :            :         }
     607                 :            : 
     608         [ #  # ]:          0 :         if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
     609                 :          0 :                 act_q = (const struct rte_flow_action_queue *)act->conf;
     610                 :          0 :                 filter->queue = act_q->index;
     611                 :            :         } else {
     612                 :          0 :                 filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
     613                 :            :         }
     614                 :            : 
     615                 :            :         /* Check if the next non-void item is END */
     616                 :          0 :         index++;
     617         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
     618         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
     619                 :          0 :                 rte_flow_error_set(error, EINVAL,
     620                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
     621                 :            :                                 act, "Not supported action.");
     622                 :          0 :                 return -rte_errno;
     623                 :            :         }
     624                 :            : 
     625                 :            :         /* Parse attr */
     626                 :            :         /* Must be input direction */
     627         [ #  # ]:          0 :         if (!attr->ingress) {
     628                 :          0 :                 rte_flow_error_set(error, EINVAL,
     629                 :            :                                 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
     630                 :            :                                 attr, "Only support ingress.");
     631                 :          0 :                 return -rte_errno;
     632                 :            :         }
     633                 :            : 
     634                 :            :         /* Not supported */
     635         [ #  # ]:          0 :         if (attr->egress) {
     636                 :          0 :                 rte_flow_error_set(error, EINVAL,
     637                 :            :                                 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
     638                 :            :                                 attr, "Not support egress.");
     639                 :          0 :                 return -rte_errno;
     640                 :            :         }
     641                 :            : 
     642                 :            :         /* Not supported */
     643         [ #  # ]:          0 :         if (attr->transfer) {
     644                 :          0 :                 rte_flow_error_set(error, EINVAL,
     645                 :            :                                 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
     646                 :            :                                 attr, "No support for transfer.");
     647                 :          0 :                 return -rte_errno;
     648                 :            :         }
     649                 :            : 
     650                 :            :         /* Not supported */
     651         [ #  # ]:          0 :         if (attr->priority) {
     652                 :          0 :                 rte_flow_error_set(error, EINVAL,
     653                 :            :                                 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
     654                 :            :                                 attr, "Not support priority.");
     655                 :          0 :                 return -rte_errno;
     656                 :            :         }
     657                 :            : 
     658                 :            :         /* Not supported */
     659         [ #  # ]:          0 :         if (attr->group) {
     660                 :          0 :                 rte_flow_error_set(error, EINVAL,
     661                 :            :                                 RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
     662                 :            :                                 attr, "Not support group.");
     663                 :          0 :                 return -rte_errno;
     664                 :            :         }
     665                 :            : 
     666                 :            :         return 0;
     667                 :            : }
     668                 :            : 
     669                 :            : static int
     670                 :          0 : igb_parse_ethertype_filter(struct rte_eth_dev *dev,
     671                 :            :                                  const struct rte_flow_attr *attr,
     672                 :            :                              const struct rte_flow_item pattern[],
     673                 :            :                              const struct rte_flow_action actions[],
     674                 :            :                              struct rte_eth_ethertype_filter *filter,
     675                 :            :                              struct rte_flow_error *error)
     676                 :            : {
     677                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     678                 :            :         int ret;
     679                 :            : 
     680   [ #  #  #  # ]:          0 :         MAC_TYPE_FILTER_SUP(hw->mac.type);
     681                 :            : 
     682                 :          0 :         ret = cons_parse_ethertype_filter(attr, pattern,
     683                 :            :                                         actions, filter, error);
     684                 :            : 
     685         [ #  # ]:          0 :         if (ret)
     686                 :            :                 return ret;
     687                 :            : 
     688         [ #  # ]:          0 :         if (hw->mac.type == e1000_82576) {
     689         [ #  # ]:          0 :                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
     690                 :            :                         memset(filter, 0, sizeof(
     691                 :            :                                         struct rte_eth_ethertype_filter));
     692                 :          0 :                         rte_flow_error_set(error, EINVAL,
     693                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     694                 :            :                                 NULL, "queue number not supported "
     695                 :            :                                         "by ethertype filter");
     696                 :          0 :                         return -rte_errno;
     697                 :            :                 }
     698                 :            :         } else {
     699         [ #  # ]:          0 :                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
     700                 :            :                         memset(filter, 0, sizeof(
     701                 :            :                                         struct rte_eth_ethertype_filter));
     702                 :          0 :                         rte_flow_error_set(error, EINVAL,
     703                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     704                 :            :                                 NULL, "queue number not supported "
     705                 :            :                                         "by ethertype filter");
     706                 :          0 :                         return -rte_errno;
     707                 :            :                 }
     708                 :            :         }
     709                 :            : 
     710         [ #  # ]:          0 :         if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
     711                 :            :                 filter->ether_type == RTE_ETHER_TYPE_IPV6) {
     712                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
     713                 :          0 :                 rte_flow_error_set(error, EINVAL,
     714                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     715                 :            :                         NULL, "IPv4/IPv6 not supported by ethertype filter");
     716                 :          0 :                 return -rte_errno;
     717                 :            :         }
     718                 :            : 
     719         [ #  # ]:          0 :         if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
     720                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
     721                 :          0 :                 rte_flow_error_set(error, EINVAL,
     722                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     723                 :            :                         NULL, "mac compare is unsupported");
     724                 :          0 :                 return -rte_errno;
     725                 :            :         }
     726                 :            : 
     727         [ #  # ]:          0 :         if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
     728                 :            :                 memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
     729                 :          0 :                 rte_flow_error_set(error, EINVAL,
     730                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
     731                 :            :                         NULL, "drop option is unsupported");
     732                 :          0 :                 return -rte_errno;
     733                 :            :         }
     734                 :            : 
     735                 :            :         return 0;
     736                 :            : }
     737                 :            : 
     738                 :            : /**
     739                 :            :  * Parse the rule to see if it is a TCP SYN rule.
     740                 :            :  * And get the TCP SYN filter info BTW.
     741                 :            :  * pattern:
     742                 :            :  * The first not void item must be ETH.
     743                 :            :  * The second not void item must be IPV4 or IPV6.
     744                 :            :  * The third not void item must be TCP.
     745                 :            :  * The next not void item must be END.
     746                 :            :  * action:
     747                 :            :  * The first not void action should be QUEUE.
     748                 :            :  * The next not void action should be END.
     749                 :            :  * pattern example:
     750                 :            :  * ITEM         Spec                    Mask
     751                 :            :  * ETH          NULL                    NULL
     752                 :            :  * IPV4/IPV6    NULL                    NULL
     753                 :            :  * TCP          tcp_flags       0x02    0xFF
     754                 :            :  * END
     755                 :            :  * other members in mask and spec should set to 0x00.
     756                 :            :  * item->last should be NULL.
     757                 :            :  */
     758                 :            : static int
     759                 :          0 : cons_parse_syn_filter(const struct rte_flow_attr *attr,
     760                 :            :                                 const struct rte_flow_item pattern[],
     761                 :            :                                 const struct rte_flow_action actions[],
     762                 :            :                                 struct rte_eth_syn_filter *filter,
     763                 :            :                                 struct rte_flow_error *error)
     764                 :            : {
     765                 :            :         const struct rte_flow_item *item;
     766                 :            :         const struct rte_flow_action *act;
     767                 :            :         const struct rte_flow_item_tcp *tcp_spec;
     768                 :            :         const struct rte_flow_item_tcp *tcp_mask;
     769                 :            :         const struct rte_flow_action_queue *act_q;
     770                 :            :         uint32_t index;
     771                 :            : 
     772         [ #  # ]:          0 :         if (!pattern) {
     773                 :          0 :                 rte_flow_error_set(error, EINVAL,
     774                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
     775                 :            :                                 NULL, "NULL pattern.");
     776                 :          0 :                 return -rte_errno;
     777                 :            :         }
     778                 :            : 
     779         [ #  # ]:          0 :         if (!actions) {
     780                 :          0 :                 rte_flow_error_set(error, EINVAL,
     781                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
     782                 :            :                                 NULL, "NULL action.");
     783                 :          0 :                 return -rte_errno;
     784                 :            :         }
     785                 :            : 
     786         [ #  # ]:          0 :         if (!attr) {
     787                 :          0 :                 rte_flow_error_set(error, EINVAL,
     788                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR,
     789                 :            :                                    NULL, "NULL attribute.");
     790                 :          0 :                 return -rte_errno;
     791                 :            :         }
     792                 :            : 
     793                 :            :         /* parse pattern */
     794                 :            :         index = 0;
     795                 :            : 
     796                 :            :         /* the first not void item should be MAC or IPv4 or IPv6 or TCP */
     797         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     798         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_ETH &&
     799         [ #  # ]:          0 :             item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
     800         [ #  # ]:          0 :             item->type != RTE_FLOW_ITEM_TYPE_IPV6 &&
     801                 :            :             item->type != RTE_FLOW_ITEM_TYPE_TCP) {
     802                 :          0 :                 rte_flow_error_set(error, EINVAL,
     803                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     804                 :            :                                 item, "Not supported by syn filter");
     805                 :          0 :                 return -rte_errno;
     806                 :            :         }
     807                 :            :                 /*Not supported last point for range*/
     808         [ #  # ]:          0 :         if (item->last) {
     809                 :          0 :                 rte_flow_error_set(error, EINVAL,
     810                 :            :                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     811                 :            :                         item, "Not supported last point for range");
     812                 :          0 :                 return -rte_errno;
     813                 :            :         }
     814                 :            : 
     815                 :            :         /* Skip Ethernet */
     816         [ #  # ]:          0 :         if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
     817                 :            :                 /* if the item is MAC, the content should be NULL */
     818   [ #  #  #  # ]:          0 :                 if (item->spec || item->mask) {
     819                 :          0 :                         rte_flow_error_set(error, EINVAL,
     820                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     821                 :            :                                 item, "Invalid SYN address mask");
     822                 :          0 :                         return -rte_errno;
     823                 :            :                 }
     824                 :            : 
     825                 :            :                 /* check if the next not void item is IPv4 or IPv6 */
     826                 :          0 :                 index++;
     827         [ #  # ]:          0 :                 NEXT_ITEM_OF_PATTERN(item, pattern, index);
     828         [ #  # ]:          0 :                 if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
     829                 :            :                     item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
     830                 :          0 :                         rte_flow_error_set(error, EINVAL,
     831                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     832                 :            :                                 item, "Not supported by syn filter");
     833                 :          0 :                         return -rte_errno;
     834                 :            :                 }
     835                 :            :         }
     836                 :            : 
     837                 :            :         /* Skip IP */
     838         [ #  # ]:          0 :         if (item->type == RTE_FLOW_ITEM_TYPE_IPV4 ||
     839                 :            :             item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
     840                 :            :                 /* if the item is IP, the content should be NULL */
     841   [ #  #  #  # ]:          0 :                 if (item->spec || item->mask) {
     842                 :          0 :                         rte_flow_error_set(error, EINVAL,
     843                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     844                 :            :                                 item, "Invalid SYN mask");
     845                 :          0 :                         return -rte_errno;
     846                 :            :                 }
     847                 :            : 
     848                 :            :                 /* check if the next not void item is TCP */
     849                 :          0 :                 index++;
     850         [ #  # ]:          0 :                 NEXT_ITEM_OF_PATTERN(item, pattern, index);
     851         [ #  # ]:          0 :                 if (item->type != RTE_FLOW_ITEM_TYPE_TCP) {
     852                 :          0 :                         rte_flow_error_set(error, EINVAL,
     853                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     854                 :            :                                 item, "Not supported by syn filter");
     855                 :          0 :                         return -rte_errno;
     856                 :            :                 }
     857                 :            :         }
     858                 :            : 
     859                 :            :         /* Get the TCP info. Only support SYN. */
     860   [ #  #  #  # ]:          0 :         if (!item->spec || !item->mask) {
     861                 :          0 :                 rte_flow_error_set(error, EINVAL,
     862                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     863                 :            :                                 item, "Invalid SYN mask");
     864                 :          0 :                 return -rte_errno;
     865                 :            :         }
     866                 :            :         /*Not supported last point for range*/
     867         [ #  # ]:          0 :         if (item->last) {
     868                 :          0 :                 rte_flow_error_set(error, EINVAL,
     869                 :            :                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     870                 :            :                         item, "Not supported last point for range");
     871                 :          0 :                 return -rte_errno;
     872                 :            :         }
     873                 :            : 
     874                 :            :         tcp_spec = item->spec;
     875                 :            :         tcp_mask = item->mask;
     876         [ #  # ]:          0 :         if (!(tcp_spec->hdr.tcp_flags & RTE_TCP_SYN_FLAG) ||
     877         [ #  # ]:          0 :             tcp_mask->hdr.src_port ||
     878         [ #  # ]:          0 :             tcp_mask->hdr.dst_port ||
     879         [ #  # ]:          0 :             tcp_mask->hdr.sent_seq ||
     880         [ #  # ]:          0 :             tcp_mask->hdr.recv_ack ||
     881         [ #  # ]:          0 :             tcp_mask->hdr.data_off ||
     882         [ #  # ]:          0 :             tcp_mask->hdr.tcp_flags != RTE_TCP_SYN_FLAG ||
     883         [ #  # ]:          0 :             tcp_mask->hdr.rx_win ||
     884         [ #  # ]:          0 :             tcp_mask->hdr.cksum ||
     885         [ #  # ]:          0 :             tcp_mask->hdr.tcp_urp) {
     886                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     887                 :          0 :                 rte_flow_error_set(error, EINVAL,
     888                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     889                 :            :                                 item, "Not supported by syn filter");
     890                 :          0 :                 return -rte_errno;
     891                 :            :         }
     892                 :            : 
     893                 :            :         /* check if the next not void item is END */
     894                 :          0 :         index++;
     895         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
     896         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_END) {
     897                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     898                 :          0 :                 rte_flow_error_set(error, EINVAL,
     899                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     900                 :            :                                 item, "Not supported by syn filter");
     901                 :          0 :                 return -rte_errno;
     902                 :            :         }
     903                 :            : 
     904                 :            :         /* parse action */
     905                 :            :         index = 0;
     906                 :            : 
     907                 :            :         /* check if the first not void action is QUEUE. */
     908         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
     909         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
     910                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     911                 :          0 :                 rte_flow_error_set(error, EINVAL,
     912                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
     913                 :            :                                 act, "Not supported action.");
     914                 :          0 :                 return -rte_errno;
     915                 :            :         }
     916                 :            : 
     917                 :          0 :         act_q = (const struct rte_flow_action_queue *)act->conf;
     918                 :          0 :         filter->queue = act_q->index;
     919                 :            : 
     920                 :            :         /* check if the next not void item is END */
     921                 :          0 :         index++;
     922         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
     923         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
     924                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     925                 :          0 :                 rte_flow_error_set(error, EINVAL,
     926                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
     927                 :            :                                 act, "Not supported action.");
     928                 :          0 :                 return -rte_errno;
     929                 :            :         }
     930                 :            : 
     931                 :            :         /* parse attr */
     932                 :            :         /* must be input direction */
     933         [ #  # ]:          0 :         if (!attr->ingress) {
     934                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     935                 :          0 :                 rte_flow_error_set(error, EINVAL,
     936                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
     937                 :            :                         attr, "Only support ingress.");
     938                 :          0 :                 return -rte_errno;
     939                 :            :         }
     940                 :            : 
     941                 :            :         /* not supported */
     942         [ #  # ]:          0 :         if (attr->egress) {
     943                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     944                 :          0 :                 rte_flow_error_set(error, EINVAL,
     945                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
     946                 :            :                         attr, "Not support egress.");
     947                 :          0 :                 return -rte_errno;
     948                 :            :         }
     949                 :            : 
     950                 :            :         /* not supported */
     951         [ #  # ]:          0 :         if (attr->transfer) {
     952                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     953                 :          0 :                 rte_flow_error_set(error, EINVAL,
     954                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
     955                 :            :                         attr, "No support for transfer.");
     956                 :          0 :                 return -rte_errno;
     957                 :            :         }
     958                 :            : 
     959                 :            :         /* Support 2 priorities, the lowest or highest. */
     960         [ #  # ]:          0 :         if (!attr->priority) {
     961                 :          0 :                 filter->hig_pri = 0;
     962         [ #  # ]:          0 :         } else if (attr->priority == (uint32_t)~0U) {
     963                 :          0 :                 filter->hig_pri = 1;
     964                 :            :         } else {
     965                 :            :                 memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     966                 :          0 :                 rte_flow_error_set(error, EINVAL,
     967                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
     968                 :            :                         attr, "Not support priority.");
     969                 :          0 :                 return -rte_errno;
     970                 :            :         }
     971                 :            : 
     972                 :            :         return 0;
     973                 :            : }
     974                 :            : 
     975                 :            : static int
     976                 :          0 : igb_parse_syn_filter(struct rte_eth_dev *dev,
     977                 :            :                                  const struct rte_flow_attr *attr,
     978                 :            :                              const struct rte_flow_item pattern[],
     979                 :            :                              const struct rte_flow_action actions[],
     980                 :            :                              struct rte_eth_syn_filter *filter,
     981                 :            :                              struct rte_flow_error *error)
     982                 :            : {
     983                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
     984                 :            :         int ret;
     985                 :            : 
     986   [ #  #  #  # ]:          0 :         MAC_TYPE_FILTER_SUP(hw->mac.type);
     987                 :            : 
     988                 :          0 :         ret = cons_parse_syn_filter(attr, pattern,
     989                 :            :                                         actions, filter, error);
     990                 :            : 
     991         [ #  # ]:          0 :         if (hw->mac.type == e1000_82576) {
     992         [ #  # ]:          0 :                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576) {
     993                 :            :                         memset(filter, 0, sizeof(struct rte_eth_syn_filter));
     994                 :          0 :                         rte_flow_error_set(error, EINVAL,
     995                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
     996                 :            :                                 NULL, "queue number not "
     997                 :            :                                         "supported by syn filter");
     998                 :          0 :                         return -rte_errno;
     999                 :            :                 }
    1000                 :            :         } else {
    1001         [ #  # ]:          0 :                 if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
    1002                 :            :                         memset(filter, 0, sizeof(struct rte_eth_syn_filter));
    1003                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1004                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
    1005                 :            :                                 NULL, "queue number not "
    1006                 :            :                                         "supported by syn filter");
    1007                 :          0 :                         return -rte_errno;
    1008                 :            :                 }
    1009                 :            :         }
    1010                 :            : 
    1011         [ #  # ]:          0 :         if (ret)
    1012                 :          0 :                 return ret;
    1013                 :            : 
    1014                 :            :         return 0;
    1015                 :            : }
    1016                 :            : 
    1017                 :            : /**
    1018                 :            :  * Parse the rule to see if it is a flex byte rule.
    1019                 :            :  * And get the flex byte filter info BTW.
    1020                 :            :  * pattern:
    1021                 :            :  * The first not void item must be RAW.
    1022                 :            :  * The second not void item can be RAW or END.
    1023                 :            :  * The third not void item can be RAW or END.
    1024                 :            :  * The last not void item must be END.
    1025                 :            :  * action:
    1026                 :            :  * The first not void action should be QUEUE.
    1027                 :            :  * The next not void action should be END.
    1028                 :            :  * pattern example:
    1029                 :            :  * ITEM         Spec                    Mask
    1030                 :            :  * RAW          relative        0               0x1
    1031                 :            :  *                      offset  0               0xFFFFFFFF
    1032                 :            :  *                      pattern {0x08, 0x06}            {0xFF, 0xFF}
    1033                 :            :  * RAW          relative        1               0x1
    1034                 :            :  *                      offset  100             0xFFFFFFFF
    1035                 :            :  *                      pattern {0x11, 0x22, 0x33}      {0xFF, 0xFF, 0xFF}
    1036                 :            :  * END
    1037                 :            :  * other members in mask and spec should set to 0x00.
    1038                 :            :  * item->last should be NULL.
    1039                 :            :  */
    1040                 :            : static int
    1041                 :          0 : cons_parse_flex_filter(const struct rte_flow_attr *attr,
    1042                 :            :                                 const struct rte_flow_item pattern[],
    1043                 :            :                                 const struct rte_flow_action actions[],
    1044                 :            :                                 struct igb_flex_filter *filter,
    1045                 :            :                                 struct rte_flow_error *error)
    1046                 :            : {
    1047                 :            :         const struct rte_flow_item *item;
    1048                 :            :         const struct rte_flow_action *act;
    1049                 :            :         const struct rte_flow_item_raw *raw_spec;
    1050                 :            :         const struct rte_flow_item_raw *raw_mask;
    1051                 :            :         const struct rte_flow_action_queue *act_q;
    1052                 :            :         uint32_t index, i, offset, total_offset;
    1053                 :            :         uint32_t max_offset = 0;
    1054                 :            :         int32_t shift, j, raw_index = 0;
    1055                 :          0 :         int32_t relative[IGB_FLEX_RAW_NUM] = {0};
    1056                 :          0 :         int32_t raw_offset[IGB_FLEX_RAW_NUM] = {0};
    1057                 :            : 
    1058         [ #  # ]:          0 :         if (!pattern) {
    1059                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1060                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM_NUM,
    1061                 :            :                                 NULL, "NULL pattern.");
    1062                 :          0 :                 return -rte_errno;
    1063                 :            :         }
    1064                 :            : 
    1065         [ #  # ]:          0 :         if (!actions) {
    1066                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1067                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION_NUM,
    1068                 :            :                                 NULL, "NULL action.");
    1069                 :          0 :                 return -rte_errno;
    1070                 :            :         }
    1071                 :            : 
    1072         [ #  # ]:          0 :         if (!attr) {
    1073                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1074                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR,
    1075                 :            :                                    NULL, "NULL attribute.");
    1076                 :          0 :                 return -rte_errno;
    1077                 :            :         }
    1078                 :            : 
    1079                 :            :         /* parse pattern */
    1080                 :            :         index = 0;
    1081                 :            : 
    1082                 :          0 : item_loop:
    1083                 :            : 
    1084                 :            :         /* the first not void item should be RAW */
    1085         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
    1086         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_RAW) {
    1087                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1088                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
    1089                 :            :                                 item, "Not supported by flex filter");
    1090                 :          0 :                 return -rte_errno;
    1091                 :            :         }
    1092                 :            :                 /*Not supported last point for range*/
    1093         [ #  # ]:          0 :         if (item->last) {
    1094                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1095                 :            :                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
    1096                 :            :                         item, "Not supported last point for range");
    1097                 :          0 :                 return -rte_errno;
    1098                 :            :         }
    1099                 :            : 
    1100                 :          0 :         raw_spec = item->spec;
    1101                 :          0 :         raw_mask = item->mask;
    1102                 :            : 
    1103         [ #  # ]:          0 :         if (!raw_mask->length ||
    1104         [ #  # ]:          0 :             !raw_mask->relative) {
    1105                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1106                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1107                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
    1108                 :            :                                 item, "Not supported by flex filter");
    1109                 :          0 :                 return -rte_errno;
    1110                 :            :         }
    1111                 :            : 
    1112         [ #  # ]:          0 :         if (raw_mask->offset)
    1113                 :          0 :                 offset = raw_spec->offset;
    1114                 :            :         else
    1115                 :            :                 offset = 0;
    1116                 :            : 
    1117         [ #  # ]:          0 :         for (j = 0; j < raw_spec->length; j++) {
    1118         [ #  # ]:          0 :                 if (raw_mask->pattern[j] != 0xFF) {
    1119                 :            :                         memset(filter, 0, sizeof(struct igb_flex_filter));
    1120                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1121                 :            :                                         RTE_FLOW_ERROR_TYPE_ITEM,
    1122                 :            :                                         item, "Not supported by flex filter");
    1123                 :          0 :                         return -rte_errno;
    1124                 :            :                 }
    1125                 :            :         }
    1126                 :            : 
    1127                 :            :         total_offset = 0;
    1128                 :            : 
    1129         [ #  # ]:          0 :         if (raw_spec->relative) {
    1130         [ #  # ]:          0 :                 for (j = raw_index; j > 0; j--) {
    1131                 :          0 :                         total_offset += raw_offset[j - 1];
    1132         [ #  # ]:          0 :                         if (!relative[j - 1])
    1133                 :            :                                 break;
    1134                 :            :                 }
    1135                 :          0 :                 if (total_offset + raw_spec->length + offset > max_offset)
    1136                 :            :                         max_offset = total_offset + raw_spec->length + offset;
    1137                 :            :         } else {
    1138                 :          0 :                 if (raw_spec->length + offset > max_offset)
    1139                 :            :                         max_offset = raw_spec->length + offset;
    1140                 :            :         }
    1141                 :            : 
    1142         [ #  # ]:          0 :         if ((raw_spec->length + offset + total_offset) >
    1143                 :            :                         IGB_FLEX_FILTER_MAXLEN) {
    1144                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1145                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1146                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
    1147                 :            :                                 item, "Not supported by flex filter");
    1148                 :          0 :                 return -rte_errno;
    1149                 :            :         }
    1150                 :            : 
    1151         [ #  # ]:          0 :         if (raw_spec->relative == 0) {
    1152         [ #  # ]:          0 :                 for (j = 0; j < raw_spec->length; j++)
    1153                 :          0 :                         filter->bytes[offset + j] =
    1154                 :          0 :                         raw_spec->pattern[j];
    1155                 :          0 :                 j = offset / CHAR_BIT;
    1156                 :          0 :                 shift = offset % CHAR_BIT;
    1157                 :            :         } else {
    1158         [ #  # ]:          0 :                 for (j = 0; j < raw_spec->length; j++)
    1159                 :          0 :                         filter->bytes[total_offset + offset + j] =
    1160                 :          0 :                                 raw_spec->pattern[j];
    1161                 :          0 :                 j = (total_offset + offset) / CHAR_BIT;
    1162                 :          0 :                 shift = (total_offset + offset) % CHAR_BIT;
    1163                 :            :         }
    1164                 :            : 
    1165                 :            :         i = 0;
    1166                 :            : 
    1167                 :          0 :         for ( ; shift < CHAR_BIT; shift++) {
    1168                 :          0 :                 filter->mask[j] |= (0x80 >> shift);
    1169                 :          0 :                 i++;
    1170         [ #  # ]:          0 :                 if (i == raw_spec->length)
    1171                 :            :                         break;
    1172         [ #  # ]:          0 :                 if (shift == (CHAR_BIT - 1)) {
    1173                 :          0 :                         j++;
    1174                 :            :                         shift = -1;
    1175                 :            :                 }
    1176                 :            :         }
    1177                 :            : 
    1178                 :          0 :         relative[raw_index] = raw_spec->relative;
    1179                 :          0 :         raw_offset[raw_index] = offset + raw_spec->length;
    1180                 :          0 :         raw_index++;
    1181                 :            : 
    1182                 :            :         /* check if the next not void item is RAW */
    1183                 :          0 :         index++;
    1184         [ #  # ]:          0 :         NEXT_ITEM_OF_PATTERN(item, pattern, index);
    1185         [ #  # ]:          0 :         if (item->type != RTE_FLOW_ITEM_TYPE_RAW &&
    1186                 :            :                 item->type != RTE_FLOW_ITEM_TYPE_END) {
    1187                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1188                 :            :                                 RTE_FLOW_ERROR_TYPE_ITEM,
    1189                 :            :                                 item, "Not supported by flex filter");
    1190                 :          0 :                 return -rte_errno;
    1191                 :            :         }
    1192                 :            : 
    1193                 :            :         /* go back to parser */
    1194         [ #  # ]:          0 :         if (item->type == RTE_FLOW_ITEM_TYPE_RAW) {
    1195                 :            :                 /* if the item is RAW, the content should be parse */
    1196                 :          0 :                 goto item_loop;
    1197                 :            :         }
    1198                 :            : 
    1199                 :          0 :         filter->len = RTE_ALIGN(max_offset, 8);
    1200                 :            : 
    1201                 :            :         /* parse action */
    1202                 :            :         index = 0;
    1203                 :            : 
    1204                 :            :         /* check if the first not void action is QUEUE. */
    1205         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
    1206         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE) {
    1207                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1208                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1209                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    1210                 :            :                                 act, "Not supported action.");
    1211                 :          0 :                 return -rte_errno;
    1212                 :            :         }
    1213                 :            : 
    1214                 :          0 :         act_q = (const struct rte_flow_action_queue *)act->conf;
    1215                 :          0 :         filter->queue = act_q->index;
    1216                 :            : 
    1217                 :            :         /* check if the next not void item is END */
    1218                 :          0 :         index++;
    1219         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
    1220         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
    1221                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1222                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1223                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    1224                 :            :                                 act, "Not supported action.");
    1225                 :          0 :                 return -rte_errno;
    1226                 :            :         }
    1227                 :            : 
    1228                 :            :         /* parse attr */
    1229                 :            :         /* must be input direction */
    1230         [ #  # ]:          0 :         if (!attr->ingress) {
    1231                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1232                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1233                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
    1234                 :            :                         attr, "Only support ingress.");
    1235                 :          0 :                 return -rte_errno;
    1236                 :            :         }
    1237                 :            : 
    1238                 :            :         /* not supported */
    1239         [ #  # ]:          0 :         if (attr->egress) {
    1240                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1241                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1242                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
    1243                 :            :                         attr, "Not support egress.");
    1244                 :          0 :                 return -rte_errno;
    1245                 :            :         }
    1246                 :            : 
    1247                 :            :         /* not supported */
    1248         [ #  # ]:          0 :         if (attr->transfer) {
    1249                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1250                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1251                 :            :                         RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
    1252                 :            :                         attr, "No support for transfer.");
    1253                 :          0 :                 return -rte_errno;
    1254                 :            :         }
    1255                 :            : 
    1256         [ #  # ]:          0 :         if (attr->priority > 0xFFFF) {
    1257                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1258                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1259                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
    1260                 :            :                                    attr, "Error priority.");
    1261                 :          0 :                 return -rte_errno;
    1262                 :            :         }
    1263                 :            : 
    1264                 :          0 :         filter->priority = (uint16_t)attr->priority;
    1265                 :            : 
    1266                 :          0 :         return 0;
    1267                 :            : }
    1268                 :            : 
    1269                 :            : static int
    1270                 :          0 : igb_parse_flex_filter(struct rte_eth_dev *dev,
    1271                 :            :                                  const struct rte_flow_attr *attr,
    1272                 :            :                              const struct rte_flow_item pattern[],
    1273                 :            :                              const struct rte_flow_action actions[],
    1274                 :            :                              struct igb_flex_filter *filter,
    1275                 :            :                              struct rte_flow_error *error)
    1276                 :            : {
    1277                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1278                 :            :         int ret;
    1279                 :            : 
    1280   [ #  #  #  # ]:          0 :         MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
    1281                 :            : 
    1282                 :          0 :         ret = cons_parse_flex_filter(attr, pattern,
    1283                 :            :                                         actions, filter, error);
    1284                 :            : 
    1285         [ #  # ]:          0 :         if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) {
    1286                 :            :                 memset(filter, 0, sizeof(struct igb_flex_filter));
    1287                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1288                 :            :                         RTE_FLOW_ERROR_TYPE_ITEM,
    1289                 :            :                         NULL, "queue number not supported by flex filter");
    1290                 :          0 :                 return -rte_errno;
    1291                 :            :         }
    1292                 :            : 
    1293         [ #  # ]:          0 :         if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
    1294         [ #  # ]:          0 :                 filter->len % sizeof(uint64_t) != 0) {
    1295                 :          0 :                 PMD_DRV_LOG(ERR, "filter's length is out of range");
    1296                 :          0 :                 return -EINVAL;
    1297                 :            :         }
    1298                 :            : 
    1299         [ #  # ]:          0 :         if (filter->priority > E1000_MAX_FLEX_FILTER_PRI) {
    1300                 :          0 :                 PMD_DRV_LOG(ERR, "filter's priority is out of range");
    1301                 :          0 :                 return -EINVAL;
    1302                 :            :         }
    1303                 :            : 
    1304         [ #  # ]:          0 :         if (ret)
    1305                 :          0 :                 return ret;
    1306                 :            : 
    1307                 :            :         return 0;
    1308                 :            : }
    1309                 :            : 
    1310                 :            : static int
    1311                 :          0 : igb_parse_rss_filter(struct rte_eth_dev *dev,
    1312                 :            :                         const struct rte_flow_attr *attr,
    1313                 :            :                         const struct rte_flow_action actions[],
    1314                 :            :                         struct igb_rte_flow_rss_conf *rss_conf,
    1315                 :            :                         struct rte_flow_error *error)
    1316                 :            : {
    1317                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1318                 :            :         const struct rte_flow_action *act;
    1319                 :            :         const struct rte_flow_action_rss *rss;
    1320                 :            :         uint16_t n, index;
    1321                 :            : 
    1322                 :            :         /**
    1323                 :            :          * rss only supports forwarding,
    1324                 :            :          * check if the first not void action is RSS.
    1325                 :            :          */
    1326                 :            :         index = 0;
    1327         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
    1328         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
    1329                 :            :                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1330                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1331                 :            :                         RTE_FLOW_ERROR_TYPE_ACTION,
    1332                 :            :                         act, "Not supported action.");
    1333                 :          0 :                 return -rte_errno;
    1334                 :            :         }
    1335                 :            : 
    1336                 :          0 :         rss = (const struct rte_flow_action_rss *)act->conf;
    1337                 :            : 
    1338   [ #  #  #  # ]:          0 :         if (!rss || !rss->queue_num) {
    1339                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1340                 :            :                                 RTE_FLOW_ERROR_TYPE_ACTION,
    1341                 :            :                                 act,
    1342                 :            :                            "no valid queues");
    1343                 :          0 :                 return -rte_errno;
    1344                 :            :         }
    1345                 :            : 
    1346         [ #  # ]:          0 :         for (n = 0; n < rss->queue_num; n++) {
    1347         [ #  # ]:          0 :                 if (rss->queue[n] >= dev->data->nb_rx_queues) {
    1348                 :          0 :                         rte_flow_error_set(error, EINVAL,
    1349                 :            :                                    RTE_FLOW_ERROR_TYPE_ACTION,
    1350                 :            :                                    act,
    1351                 :            :                                    "queue id > max number of queues");
    1352                 :          0 :                         return -rte_errno;
    1353                 :            :                 }
    1354                 :            :         }
    1355                 :            : 
    1356         [ #  # ]:          0 :         if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
    1357                 :          0 :                 return rte_flow_error_set
    1358                 :            :                         (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
    1359                 :            :                          "non-default RSS hash functions are not supported");
    1360         [ #  # ]:          0 :         if (rss->level)
    1361                 :          0 :                 return rte_flow_error_set
    1362                 :            :                         (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
    1363                 :            :                          "a nonzero RSS encapsulation level is not supported");
    1364         [ #  # ]:          0 :         if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
    1365                 :          0 :                 return rte_flow_error_set
    1366                 :            :                         (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
    1367                 :            :                          "RSS hash key must be exactly 40 bytes");
    1368   [ #  #  #  # ]:          0 :         if (((hw->mac.type == e1000_82576) &&
    1369         [ #  # ]:          0 :              (rss->queue_num > IGB_MAX_RX_QUEUE_NUM_82576)) ||
    1370         [ #  # ]:          0 :             ((hw->mac.type != e1000_82576) &&
    1371                 :            :              (rss->queue_num > IGB_MAX_RX_QUEUE_NUM)))
    1372                 :          0 :                 return rte_flow_error_set
    1373                 :            :                         (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
    1374                 :            :                          "too many queues for RSS context");
    1375         [ #  # ]:          0 :         if (igb_rss_conf_init(dev, rss_conf, rss))
    1376                 :          0 :                 return rte_flow_error_set
    1377                 :            :                         (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
    1378                 :            :                          "RSS context initialization failure");
    1379                 :            : 
    1380                 :            :         /* check if the next not void item is END */
    1381                 :          0 :         index++;
    1382         [ #  # ]:          0 :         NEXT_ITEM_OF_ACTION(act, actions, index);
    1383         [ #  # ]:          0 :         if (act->type != RTE_FLOW_ACTION_TYPE_END) {
    1384                 :            :                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1385                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1386                 :            :                         RTE_FLOW_ERROR_TYPE_ACTION,
    1387                 :            :                         act, "Not supported action.");
    1388                 :          0 :                 return -rte_errno;
    1389                 :            :         }
    1390                 :            : 
    1391                 :            :         /* parse attr */
    1392                 :            :         /* must be input direction */
    1393         [ #  # ]:          0 :         if (!attr->ingress) {
    1394                 :            :                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1395                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1396                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
    1397                 :            :                                    attr, "Only support ingress.");
    1398                 :          0 :                 return -rte_errno;
    1399                 :            :         }
    1400                 :            : 
    1401                 :            :         /* not supported */
    1402         [ #  # ]:          0 :         if (attr->egress) {
    1403                 :            :                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1404                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1405                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
    1406                 :            :                                    attr, "Not support egress.");
    1407                 :          0 :                 return -rte_errno;
    1408                 :            :         }
    1409                 :            : 
    1410                 :            :         /* not supported */
    1411         [ #  # ]:          0 :         if (attr->transfer) {
    1412                 :            :                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1413                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1414                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
    1415                 :            :                                    attr, "No support for transfer.");
    1416                 :          0 :                 return -rte_errno;
    1417                 :            :         }
    1418                 :            : 
    1419         [ #  # ]:          0 :         if (attr->priority > 0xFFFF) {
    1420                 :            :                 memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1421                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1422                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
    1423                 :            :                                    attr, "Error priority.");
    1424                 :          0 :                 return -rte_errno;
    1425                 :            :         }
    1426                 :            : 
    1427                 :            :         return 0;
    1428                 :            : }
    1429                 :            : 
    1430                 :            : /**
    1431                 :            :  * Create a flow rule.
    1432                 :            :  * Theorically one rule can match more than one filters.
    1433                 :            :  * We will let it use the filter which it hitt first.
    1434                 :            :  * So, the sequence matters.
    1435                 :            :  */
    1436                 :            : static struct rte_flow *
    1437                 :          0 : igb_flow_create(struct rte_eth_dev *dev,
    1438                 :            :                   const struct rte_flow_attr *attr,
    1439                 :            :                   const struct rte_flow_item pattern[],
    1440                 :            :                   const struct rte_flow_action actions[],
    1441                 :            :                   struct rte_flow_error *error)
    1442                 :            : {
    1443                 :            :         int ret;
    1444                 :            :         struct rte_eth_ntuple_filter ntuple_filter;
    1445                 :            :         struct rte_eth_ethertype_filter ethertype_filter;
    1446                 :            :         struct rte_eth_syn_filter syn_filter;
    1447                 :            :         struct igb_flex_filter flex_filter;
    1448                 :            :         struct igb_rte_flow_rss_conf rss_conf;
    1449                 :            :         struct rte_flow *flow = NULL;
    1450                 :            :         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
    1451                 :            :         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
    1452                 :            :         struct igb_eth_syn_filter_ele *syn_filter_ptr;
    1453                 :            :         struct igb_flex_filter_ele *flex_filter_ptr;
    1454                 :            :         struct igb_rss_conf_ele *rss_filter_ptr;
    1455                 :            :         struct igb_flow_mem *igb_flow_mem_ptr;
    1456                 :            : 
    1457                 :          0 :         flow = rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0);
    1458         [ #  # ]:          0 :         if (!flow) {
    1459                 :          0 :                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1460                 :          0 :                 return (struct rte_flow *)flow;
    1461                 :            :         }
    1462                 :          0 :         igb_flow_mem_ptr = rte_zmalloc("igb_flow_mem",
    1463                 :            :                         sizeof(struct igb_flow_mem), 0);
    1464         [ #  # ]:          0 :         if (!igb_flow_mem_ptr) {
    1465                 :          0 :                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1466                 :          0 :                 rte_free(flow);
    1467                 :          0 :                 return NULL;
    1468                 :            :         }
    1469                 :          0 :         igb_flow_mem_ptr->flow = flow;
    1470                 :          0 :         igb_flow_mem_ptr->dev = dev;
    1471                 :          0 :         TAILQ_INSERT_TAIL(&igb_flow_list,
    1472                 :            :                                 igb_flow_mem_ptr, entries);
    1473                 :            : 
    1474                 :            :         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
    1475                 :          0 :         ret = igb_parse_ntuple_filter(dev, attr, pattern,
    1476                 :            :                         actions, &ntuple_filter, error);
    1477         [ #  # ]:          0 :         if (!ret) {
    1478                 :          0 :                 ret = igb_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
    1479         [ #  # ]:          0 :                 if (!ret) {
    1480                 :          0 :                         ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
    1481                 :            :                                 sizeof(struct igb_ntuple_filter_ele), 0);
    1482         [ #  # ]:          0 :                         if (!ntuple_filter_ptr) {
    1483                 :          0 :                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1484                 :          0 :                                 goto out;
    1485                 :            :                         }
    1486                 :            : 
    1487         [ #  # ]:          0 :                         rte_memcpy(&ntuple_filter_ptr->filter_info,
    1488                 :            :                                 &ntuple_filter,
    1489                 :            :                                 sizeof(struct rte_eth_ntuple_filter));
    1490                 :          0 :                         TAILQ_INSERT_TAIL(&igb_filter_ntuple_list,
    1491                 :            :                                 ntuple_filter_ptr, entries);
    1492                 :          0 :                         flow->rule = ntuple_filter_ptr;
    1493                 :          0 :                         flow->filter_type = RTE_ETH_FILTER_NTUPLE;
    1494                 :          0 :                         return flow;
    1495                 :            :                 }
    1496                 :          0 :                 goto out;
    1497                 :            :         }
    1498                 :            : 
    1499                 :            :         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
    1500                 :          0 :         ret = igb_parse_ethertype_filter(dev, attr, pattern,
    1501                 :            :                                 actions, &ethertype_filter, error);
    1502         [ #  # ]:          0 :         if (!ret) {
    1503                 :          0 :                 ret = igb_add_del_ethertype_filter(dev,
    1504                 :            :                                 &ethertype_filter, TRUE);
    1505         [ #  # ]:          0 :                 if (!ret) {
    1506                 :          0 :                         ethertype_filter_ptr = rte_zmalloc(
    1507                 :            :                                 "igb_ethertype_filter",
    1508                 :            :                                 sizeof(struct igb_ethertype_filter_ele), 0);
    1509         [ #  # ]:          0 :                         if (!ethertype_filter_ptr) {
    1510                 :          0 :                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1511                 :          0 :                                 goto out;
    1512                 :            :                         }
    1513                 :            : 
    1514         [ #  # ]:          0 :                         rte_memcpy(&ethertype_filter_ptr->filter_info,
    1515                 :            :                                 &ethertype_filter,
    1516                 :            :                                 sizeof(struct rte_eth_ethertype_filter));
    1517                 :          0 :                         TAILQ_INSERT_TAIL(&igb_filter_ethertype_list,
    1518                 :            :                                 ethertype_filter_ptr, entries);
    1519                 :          0 :                         flow->rule = ethertype_filter_ptr;
    1520                 :          0 :                         flow->filter_type = RTE_ETH_FILTER_ETHERTYPE;
    1521                 :          0 :                         return flow;
    1522                 :            :                 }
    1523                 :          0 :                 goto out;
    1524                 :            :         }
    1525                 :            : 
    1526                 :            :         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
    1527                 :          0 :         ret = igb_parse_syn_filter(dev, attr, pattern,
    1528                 :            :                                 actions, &syn_filter, error);
    1529         [ #  # ]:          0 :         if (!ret) {
    1530                 :          0 :                 ret = eth_igb_syn_filter_set(dev, &syn_filter, TRUE);
    1531         [ #  # ]:          0 :                 if (!ret) {
    1532                 :          0 :                         syn_filter_ptr = rte_zmalloc("igb_syn_filter",
    1533                 :            :                                 sizeof(struct igb_eth_syn_filter_ele), 0);
    1534         [ #  # ]:          0 :                         if (!syn_filter_ptr) {
    1535                 :          0 :                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1536                 :          0 :                                 goto out;
    1537                 :            :                         }
    1538                 :            : 
    1539         [ #  # ]:          0 :                         rte_memcpy(&syn_filter_ptr->filter_info,
    1540                 :            :                                 &syn_filter,
    1541                 :            :                                 sizeof(struct rte_eth_syn_filter));
    1542                 :          0 :                         TAILQ_INSERT_TAIL(&igb_filter_syn_list,
    1543                 :            :                                 syn_filter_ptr,
    1544                 :            :                                 entries);
    1545                 :          0 :                         flow->rule = syn_filter_ptr;
    1546                 :          0 :                         flow->filter_type = RTE_ETH_FILTER_SYN;
    1547                 :          0 :                         return flow;
    1548                 :            :                 }
    1549                 :          0 :                 goto out;
    1550                 :            :         }
    1551                 :            : 
    1552                 :            :         memset(&flex_filter, 0, sizeof(struct igb_flex_filter));
    1553                 :          0 :         ret = igb_parse_flex_filter(dev, attr, pattern,
    1554                 :            :                                         actions, &flex_filter, error);
    1555         [ #  # ]:          0 :         if (!ret) {
    1556                 :          0 :                 ret = eth_igb_add_del_flex_filter(dev, &flex_filter, TRUE);
    1557         [ #  # ]:          0 :                 if (!ret) {
    1558                 :          0 :                         flex_filter_ptr = rte_zmalloc("igb_flex_filter",
    1559                 :            :                                 sizeof(struct igb_flex_filter_ele), 0);
    1560         [ #  # ]:          0 :                         if (!flex_filter_ptr) {
    1561                 :          0 :                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1562                 :          0 :                                 goto out;
    1563                 :            :                         }
    1564                 :            : 
    1565         [ #  # ]:          0 :                         rte_memcpy(&flex_filter_ptr->filter_info,
    1566                 :            :                                 &flex_filter,
    1567                 :            :                                 sizeof(struct igb_flex_filter));
    1568                 :          0 :                         TAILQ_INSERT_TAIL(&igb_filter_flex_list,
    1569                 :            :                                 flex_filter_ptr, entries);
    1570                 :          0 :                         flow->rule = flex_filter_ptr;
    1571                 :          0 :                         flow->filter_type = RTE_ETH_FILTER_FLEXIBLE;
    1572                 :          0 :                         return flow;
    1573                 :            :                 }
    1574                 :            :         }
    1575                 :            : 
    1576                 :            :         memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1577                 :          0 :         ret = igb_parse_rss_filter(dev, attr,
    1578                 :            :                                         actions, &rss_conf, error);
    1579         [ #  # ]:          0 :         if (!ret) {
    1580                 :          0 :                 ret = igb_config_rss_filter(dev, &rss_conf, TRUE);
    1581         [ #  # ]:          0 :                 if (!ret) {
    1582                 :          0 :                         rss_filter_ptr = rte_zmalloc("igb_rss_filter",
    1583                 :            :                                 sizeof(struct igb_rss_conf_ele), 0);
    1584         [ #  # ]:          0 :                         if (!rss_filter_ptr) {
    1585                 :          0 :                                 PMD_DRV_LOG(ERR, "failed to allocate memory");
    1586                 :          0 :                                 goto out;
    1587                 :            :                         }
    1588                 :          0 :                         igb_rss_conf_init(dev, &rss_filter_ptr->filter_info,
    1589                 :            :                                           &rss_conf.conf);
    1590                 :          0 :                         TAILQ_INSERT_TAIL(&igb_filter_rss_list,
    1591                 :            :                                 rss_filter_ptr, entries);
    1592                 :          0 :                         flow->rule = rss_filter_ptr;
    1593                 :          0 :                         flow->filter_type = RTE_ETH_FILTER_HASH;
    1594                 :          0 :                         return flow;
    1595                 :            :                 }
    1596                 :            :         }
    1597                 :            : 
    1598                 :          0 : out:
    1599         [ #  # ]:          0 :         TAILQ_REMOVE(&igb_flow_list,
    1600                 :            :                 igb_flow_mem_ptr, entries);
    1601                 :          0 :         rte_flow_error_set(error, -ret,
    1602                 :            :                            RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
    1603                 :            :                            "Failed to create flow.");
    1604                 :          0 :         rte_free(igb_flow_mem_ptr);
    1605                 :          0 :         rte_free(flow);
    1606                 :          0 :         return NULL;
    1607                 :            : }
    1608                 :            : 
    1609                 :            : /**
    1610                 :            :  * Check if the flow rule is supported by igb.
    1611                 :            :  * It only checks the format. Don't guarantee the rule can be programmed into
    1612                 :            :  * the HW. Because there can be no enough room for the rule.
    1613                 :            :  */
    1614                 :            : static int
    1615                 :          0 : igb_flow_validate(__rte_unused struct rte_eth_dev *dev,
    1616                 :            :                 const struct rte_flow_attr *attr,
    1617                 :            :                 const struct rte_flow_item pattern[],
    1618                 :            :                 const struct rte_flow_action actions[],
    1619                 :            :                 struct rte_flow_error *error)
    1620                 :            : {
    1621                 :            :         struct rte_eth_ntuple_filter ntuple_filter;
    1622                 :            :         struct rte_eth_ethertype_filter ethertype_filter;
    1623                 :            :         struct rte_eth_syn_filter syn_filter;
    1624                 :            :         struct igb_flex_filter flex_filter;
    1625                 :            :         struct igb_rte_flow_rss_conf rss_conf;
    1626                 :            :         int ret;
    1627                 :            : 
    1628                 :            :         memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
    1629                 :          0 :         ret = igb_parse_ntuple_filter(dev, attr, pattern,
    1630                 :            :                                 actions, &ntuple_filter, error);
    1631         [ #  # ]:          0 :         if (!ret)
    1632                 :            :                 return 0;
    1633                 :            : 
    1634                 :            :         memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
    1635                 :          0 :         ret = igb_parse_ethertype_filter(dev, attr, pattern,
    1636                 :            :                                 actions, &ethertype_filter, error);
    1637         [ #  # ]:          0 :         if (!ret)
    1638                 :            :                 return 0;
    1639                 :            : 
    1640                 :            :         memset(&syn_filter, 0, sizeof(struct rte_eth_syn_filter));
    1641                 :          0 :         ret = igb_parse_syn_filter(dev, attr, pattern,
    1642                 :            :                                 actions, &syn_filter, error);
    1643         [ #  # ]:          0 :         if (!ret)
    1644                 :            :                 return 0;
    1645                 :            : 
    1646                 :            :         memset(&flex_filter, 0, sizeof(struct igb_flex_filter));
    1647                 :          0 :         ret = igb_parse_flex_filter(dev, attr, pattern,
    1648                 :            :                                 actions, &flex_filter, error);
    1649         [ #  # ]:          0 :         if (!ret)
    1650                 :            :                 return 0;
    1651                 :            : 
    1652                 :            :         memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
    1653                 :          0 :         ret = igb_parse_rss_filter(dev, attr,
    1654                 :            :                                         actions, &rss_conf, error);
    1655                 :            : 
    1656                 :          0 :         return ret;
    1657                 :            : }
    1658                 :            : 
    1659                 :            : /* Destroy a flow rule on igb. */
    1660                 :            : static int
    1661                 :          0 : igb_flow_destroy(struct rte_eth_dev *dev,
    1662                 :            :                 struct rte_flow *flow,
    1663                 :            :                 struct rte_flow_error *error)
    1664                 :            : {
    1665                 :            :         int ret;
    1666                 :            :         struct rte_flow *pmd_flow = flow;
    1667                 :          0 :         enum rte_filter_type filter_type = pmd_flow->filter_type;
    1668                 :            :         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
    1669                 :            :         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
    1670                 :            :         struct igb_eth_syn_filter_ele *syn_filter_ptr;
    1671                 :            :         struct igb_flex_filter_ele *flex_filter_ptr;
    1672                 :            :         struct igb_flow_mem *igb_flow_mem_ptr;
    1673                 :            :         struct igb_rss_conf_ele *rss_filter_ptr;
    1674                 :            : 
    1675   [ #  #  #  #  :          0 :         switch (filter_type) {
                   #  # ]
    1676                 :          0 :         case RTE_ETH_FILTER_NTUPLE:
    1677                 :          0 :                 ntuple_filter_ptr = (struct igb_ntuple_filter_ele *)
    1678                 :            :                                         pmd_flow->rule;
    1679                 :          0 :                 ret = igb_add_del_ntuple_filter(dev,
    1680                 :            :                                 &ntuple_filter_ptr->filter_info, FALSE);
    1681         [ #  # ]:          0 :                 if (!ret) {
    1682         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_filter_ntuple_list,
    1683                 :            :                         ntuple_filter_ptr, entries);
    1684                 :          0 :                         rte_free(ntuple_filter_ptr);
    1685                 :            :                 }
    1686                 :            :                 break;
    1687                 :          0 :         case RTE_ETH_FILTER_ETHERTYPE:
    1688                 :          0 :                 ethertype_filter_ptr = (struct igb_ethertype_filter_ele *)
    1689                 :            :                                         pmd_flow->rule;
    1690                 :          0 :                 ret = igb_add_del_ethertype_filter(dev,
    1691                 :            :                                 &ethertype_filter_ptr->filter_info, FALSE);
    1692         [ #  # ]:          0 :                 if (!ret) {
    1693         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_filter_ethertype_list,
    1694                 :            :                                 ethertype_filter_ptr, entries);
    1695                 :          0 :                         rte_free(ethertype_filter_ptr);
    1696                 :            :                 }
    1697                 :            :                 break;
    1698                 :          0 :         case RTE_ETH_FILTER_SYN:
    1699                 :          0 :                 syn_filter_ptr = (struct igb_eth_syn_filter_ele *)
    1700                 :            :                                 pmd_flow->rule;
    1701                 :          0 :                 ret = eth_igb_syn_filter_set(dev,
    1702                 :            :                                 &syn_filter_ptr->filter_info, FALSE);
    1703         [ #  # ]:          0 :                 if (!ret) {
    1704         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_filter_syn_list,
    1705                 :            :                                 syn_filter_ptr, entries);
    1706                 :          0 :                         rte_free(syn_filter_ptr);
    1707                 :            :                 }
    1708                 :            :                 break;
    1709                 :          0 :         case RTE_ETH_FILTER_FLEXIBLE:
    1710                 :          0 :                 flex_filter_ptr = (struct igb_flex_filter_ele *)
    1711                 :            :                                 pmd_flow->rule;
    1712                 :          0 :                 ret = eth_igb_add_del_flex_filter(dev,
    1713                 :            :                                 &flex_filter_ptr->filter_info, FALSE);
    1714         [ #  # ]:          0 :                 if (!ret) {
    1715         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_filter_flex_list,
    1716                 :            :                                 flex_filter_ptr, entries);
    1717                 :          0 :                         rte_free(flex_filter_ptr);
    1718                 :            :                 }
    1719                 :            :                 break;
    1720                 :          0 :         case RTE_ETH_FILTER_HASH:
    1721                 :          0 :                 rss_filter_ptr = (struct igb_rss_conf_ele *)
    1722                 :            :                                 pmd_flow->rule;
    1723                 :          0 :                 ret = igb_config_rss_filter(dev,
    1724                 :            :                                         &rss_filter_ptr->filter_info, FALSE);
    1725         [ #  # ]:          0 :                 if (!ret) {
    1726         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_filter_rss_list,
    1727                 :            :                                 rss_filter_ptr, entries);
    1728                 :          0 :                         rte_free(rss_filter_ptr);
    1729                 :            :                 }
    1730                 :            :                 break;
    1731                 :          0 :         default:
    1732                 :          0 :                 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
    1733                 :            :                             filter_type);
    1734                 :            :                 ret = -EINVAL;
    1735                 :            :                 break;
    1736                 :            :         }
    1737                 :            : 
    1738         [ #  # ]:          0 :         if (ret) {
    1739                 :          0 :                 rte_flow_error_set(error, EINVAL,
    1740                 :            :                                 RTE_FLOW_ERROR_TYPE_HANDLE,
    1741                 :            :                                 NULL, "Failed to destroy flow");
    1742                 :          0 :                 return ret;
    1743                 :            :         }
    1744                 :            : 
    1745         [ #  # ]:          0 :         TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
    1746         [ #  # ]:          0 :                 if (igb_flow_mem_ptr->flow == pmd_flow) {
    1747         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_flow_list,
    1748                 :            :                                 igb_flow_mem_ptr, entries);
    1749                 :          0 :                         rte_free(igb_flow_mem_ptr);
    1750                 :            :                 }
    1751                 :            :         }
    1752                 :          0 :         rte_free(flow);
    1753                 :            : 
    1754                 :          0 :         return ret;
    1755                 :            : }
    1756                 :            : 
    1757                 :            : /* remove all the n-tuple filters */
    1758                 :            : static void
    1759                 :          0 : igb_clear_all_ntuple_filter(struct rte_eth_dev *dev)
    1760                 :            : {
    1761                 :            :         struct e1000_filter_info *filter_info =
    1762                 :          0 :                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
    1763                 :            :         struct e1000_5tuple_filter *p_5tuple;
    1764                 :            :         struct e1000_2tuple_filter *p_2tuple;
    1765                 :            : 
    1766         [ #  # ]:          0 :         while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
    1767                 :          0 :                 igb_delete_5tuple_filter_82576(dev, p_5tuple);
    1768                 :            : 
    1769         [ #  # ]:          0 :         while ((p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list)))
    1770                 :          0 :                 igb_delete_2tuple_filter(dev, p_2tuple);
    1771                 :          0 : }
    1772                 :            : 
    1773                 :            : /* remove all the ether type filters */
    1774                 :            : static void
    1775                 :          0 : igb_clear_all_ethertype_filter(struct rte_eth_dev *dev)
    1776                 :            : {
    1777                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1778                 :          0 :         struct e1000_filter_info *filter_info =
    1779                 :            :                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
    1780                 :            :         int i;
    1781                 :            : 
    1782         [ #  # ]:          0 :         for (i = 0; i < E1000_MAX_ETQF_FILTERS; i++) {
    1783         [ #  # ]:          0 :                 if (filter_info->ethertype_mask & (1 << i)) {
    1784                 :          0 :                         (void)igb_ethertype_filter_remove(filter_info,
    1785                 :            :                                                             (uint8_t)i);
    1786                 :          0 :                         E1000_WRITE_REG(hw, E1000_ETQF(i), 0);
    1787                 :          0 :                         E1000_WRITE_FLUSH(hw);
    1788                 :            :                 }
    1789                 :            :         }
    1790                 :          0 : }
    1791                 :            : 
    1792                 :            : /* remove the SYN filter */
    1793                 :            : static void
    1794                 :            : igb_clear_syn_filter(struct rte_eth_dev *dev)
    1795                 :            : {
    1796                 :          0 :         struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
    1797                 :            :         struct e1000_filter_info *filter_info =
    1798                 :            :                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
    1799                 :            : 
    1800         [ #  # ]:          0 :         if (filter_info->syn_info & E1000_SYN_FILTER_ENABLE) {
    1801                 :          0 :                 filter_info->syn_info = 0;
    1802                 :          0 :                 E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
    1803                 :          0 :                 E1000_WRITE_FLUSH(hw);
    1804                 :            :         }
    1805                 :            : }
    1806                 :            : 
    1807                 :            : /* remove all the flex filters */
    1808                 :            : static void
    1809                 :            : igb_clear_all_flex_filter(struct rte_eth_dev *dev)
    1810                 :            : {
    1811                 :            :         struct e1000_filter_info *filter_info =
    1812                 :          0 :                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
    1813                 :            :         struct e1000_flex_filter *flex_filter;
    1814                 :            : 
    1815         [ #  # ]:          0 :         while ((flex_filter = TAILQ_FIRST(&filter_info->flex_list)))
    1816                 :          0 :                 igb_remove_flex_filter(dev, flex_filter);
    1817                 :            : }
    1818                 :            : 
    1819                 :            : /* remove the rss filter */
    1820                 :            : static void
    1821                 :            : igb_clear_rss_filter(struct rte_eth_dev *dev)
    1822                 :            : {
    1823                 :            :         struct e1000_filter_info *filter =
    1824                 :          0 :                 E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
    1825                 :            : 
    1826         [ #  # ]:          0 :         if (filter->rss_info.conf.queue_num)
    1827                 :          0 :                 igb_config_rss_filter(dev, &filter->rss_info, FALSE);
    1828                 :            : }
    1829                 :            : 
    1830                 :            : void
    1831                 :          0 : igb_filterlist_flush(struct rte_eth_dev *dev)
    1832                 :            : {
    1833                 :            :         struct igb_ntuple_filter_ele *ntuple_filter_ptr;
    1834                 :            :         struct igb_ethertype_filter_ele *ethertype_filter_ptr;
    1835                 :            :         struct igb_eth_syn_filter_ele *syn_filter_ptr;
    1836                 :            :         struct igb_flex_filter_ele *flex_filter_ptr;
    1837                 :            :         struct igb_rss_conf_ele  *rss_filter_ptr;
    1838                 :            :         struct igb_flow_mem *igb_flow_mem_ptr;
    1839                 :            :         enum rte_filter_type filter_type;
    1840                 :            :         struct rte_flow *pmd_flow;
    1841                 :            : 
    1842         [ #  # ]:          0 :         TAILQ_FOREACH(igb_flow_mem_ptr, &igb_flow_list, entries) {
    1843         [ #  # ]:          0 :                 if (igb_flow_mem_ptr->dev == dev) {
    1844                 :          0 :                         pmd_flow = igb_flow_mem_ptr->flow;
    1845                 :          0 :                         filter_type = pmd_flow->filter_type;
    1846                 :            : 
    1847   [ #  #  #  #  :          0 :                         switch (filter_type) {
                   #  # ]
    1848                 :          0 :                         case RTE_ETH_FILTER_NTUPLE:
    1849                 :          0 :                                 ntuple_filter_ptr =
    1850                 :            :                                 (struct igb_ntuple_filter_ele *)
    1851                 :            :                                         pmd_flow->rule;
    1852         [ #  # ]:          0 :                                 TAILQ_REMOVE(&igb_filter_ntuple_list,
    1853                 :            :                                                 ntuple_filter_ptr, entries);
    1854                 :          0 :                                 rte_free(ntuple_filter_ptr);
    1855                 :          0 :                                 break;
    1856                 :          0 :                         case RTE_ETH_FILTER_ETHERTYPE:
    1857                 :          0 :                                 ethertype_filter_ptr =
    1858                 :            :                                 (struct igb_ethertype_filter_ele *)
    1859                 :            :                                         pmd_flow->rule;
    1860         [ #  # ]:          0 :                                 TAILQ_REMOVE(&igb_filter_ethertype_list,
    1861                 :            :                                                 ethertype_filter_ptr, entries);
    1862                 :          0 :                                 rte_free(ethertype_filter_ptr);
    1863                 :          0 :                                 break;
    1864                 :          0 :                         case RTE_ETH_FILTER_SYN:
    1865                 :          0 :                                 syn_filter_ptr =
    1866                 :            :                                         (struct igb_eth_syn_filter_ele *)
    1867                 :            :                                                 pmd_flow->rule;
    1868         [ #  # ]:          0 :                                 TAILQ_REMOVE(&igb_filter_syn_list,
    1869                 :            :                                                 syn_filter_ptr, entries);
    1870                 :          0 :                                 rte_free(syn_filter_ptr);
    1871                 :          0 :                                 break;
    1872                 :          0 :                         case RTE_ETH_FILTER_FLEXIBLE:
    1873                 :          0 :                                 flex_filter_ptr =
    1874                 :            :                                         (struct igb_flex_filter_ele *)
    1875                 :            :                                                 pmd_flow->rule;
    1876         [ #  # ]:          0 :                                 TAILQ_REMOVE(&igb_filter_flex_list,
    1877                 :            :                                                 flex_filter_ptr, entries);
    1878                 :          0 :                                 rte_free(flex_filter_ptr);
    1879                 :          0 :                                 break;
    1880                 :          0 :                         case RTE_ETH_FILTER_HASH:
    1881                 :          0 :                                 rss_filter_ptr =
    1882                 :            :                                         (struct igb_rss_conf_ele *)
    1883                 :            :                                                 pmd_flow->rule;
    1884         [ #  # ]:          0 :                                 TAILQ_REMOVE(&igb_filter_rss_list,
    1885                 :            :                                                 rss_filter_ptr, entries);
    1886                 :          0 :                                 rte_free(rss_filter_ptr);
    1887                 :          0 :                                 break;
    1888                 :          0 :                         default:
    1889                 :          0 :                                 PMD_DRV_LOG(WARNING, "Filter type"
    1890                 :            :                                         "(%d) not supported", filter_type);
    1891                 :          0 :                                 break;
    1892                 :            :                         }
    1893         [ #  # ]:          0 :                         TAILQ_REMOVE(&igb_flow_list,
    1894                 :            :                                  igb_flow_mem_ptr,
    1895                 :            :                                  entries);
    1896                 :          0 :                         rte_free(igb_flow_mem_ptr->flow);
    1897                 :          0 :                         rte_free(igb_flow_mem_ptr);
    1898                 :            :                 }
    1899                 :            :         }
    1900                 :          0 : }
    1901                 :            : 
    1902                 :            : /*  Destroy all flow rules associated with a port on igb. */
    1903                 :            : static int
    1904                 :          0 : igb_flow_flush(struct rte_eth_dev *dev,
    1905                 :            :                 __rte_unused struct rte_flow_error *error)
    1906                 :            : {
    1907                 :          0 :         igb_clear_all_ntuple_filter(dev);
    1908                 :          0 :         igb_clear_all_ethertype_filter(dev);
    1909                 :            :         igb_clear_syn_filter(dev);
    1910                 :            :         igb_clear_all_flex_filter(dev);
    1911                 :            :         igb_clear_rss_filter(dev);
    1912                 :          0 :         igb_filterlist_flush(dev);
    1913                 :            : 
    1914                 :          0 :         return 0;
    1915                 :            : }
    1916                 :            : 
    1917                 :            : const struct rte_flow_ops igb_flow_ops = {
    1918                 :            :         .validate = igb_flow_validate,
    1919                 :            :         .create = igb_flow_create,
    1920                 :            :         .destroy = igb_flow_destroy,
    1921                 :            :         .flush = igb_flow_flush,
    1922                 :            : };

Generated by: LCOV version 1.14