LCOV - code coverage report
Current view: top level - drivers/net/cpfl - cpfl_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 3 117 2.6 %
Date: 2024-12-01 18:57:19 Functions: 1 13 7.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 73 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2023 Intel Corporation
       3                 :            :  */
       4                 :            : #include <rte_flow_driver.h>
       5                 :            : #include <rte_tailq.h>
       6                 :            : 
       7                 :            : #include "cpfl_flow.h"
       8                 :            : #include "cpfl_flow_parser.h"
       9                 :            : 
      10                 :            : TAILQ_HEAD(cpfl_flow_engine_list, cpfl_flow_engine);
      11                 :            : 
      12                 :            : static struct cpfl_flow_engine_list engine_list = TAILQ_HEAD_INITIALIZER(engine_list);
      13                 :            : 
      14                 :            : void
      15                 :        251 : cpfl_flow_engine_register(struct cpfl_flow_engine *engine)
      16                 :            : {
      17                 :        251 :         TAILQ_INSERT_TAIL(&engine_list, engine, node);
      18                 :        251 : }
      19                 :            : 
      20                 :            : struct cpfl_flow_engine *
      21                 :          0 : cpfl_flow_engine_match(struct rte_eth_dev *dev,
      22                 :            :                        const struct rte_flow_attr *attr,
      23                 :            :                        const struct rte_flow_item pattern[],
      24                 :            :                        const struct rte_flow_action actions[],
      25                 :            :                        void **meta)
      26                 :            : {
      27                 :            :         struct cpfl_flow_engine *engine = NULL;
      28                 :            :         void *temp;
      29                 :            : 
      30         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {
      31         [ #  # ]:          0 :                 if (!engine->parse_pattern_action)
      32                 :          0 :                         continue;
      33                 :            : 
      34         [ #  # ]:          0 :                 if (engine->parse_pattern_action(dev, attr, pattern, actions, meta) < 0)
      35                 :          0 :                         continue;
      36                 :            :                 return engine;
      37                 :            :         }
      38                 :            : 
      39                 :            :         return NULL;
      40                 :            : }
      41                 :            : 
      42                 :            : int
      43                 :          0 : cpfl_flow_engine_init(struct cpfl_adapter_ext *adapter)
      44                 :            : {
      45                 :            :         struct cpfl_flow_engine *engine = NULL;
      46                 :            :         void *temp;
      47                 :            :         int ret;
      48                 :            : 
      49         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {
      50         [ #  # ]:          0 :                 if (!engine->init) {
      51                 :          0 :                         PMD_INIT_LOG(ERR, "Invalid engine type (%d)",
      52                 :            :                                      engine->type);
      53                 :          0 :                         return -ENOTSUP;
      54                 :            :                 }
      55                 :            : 
      56                 :          0 :                 ret = engine->init(adapter);
      57         [ #  # ]:          0 :                 if (ret) {
      58                 :          0 :                         PMD_INIT_LOG(ERR, "Failed to initialize engine %d",
      59                 :            :                                      engine->type);
      60                 :          0 :                         return ret;
      61                 :            :                 }
      62                 :            :         }
      63                 :            : 
      64                 :            :         return 0;
      65                 :            : }
      66                 :            : 
      67                 :            : void
      68                 :          0 : cpfl_flow_engine_uninit(struct cpfl_adapter_ext *adapter)
      69                 :            : {
      70                 :            :         struct cpfl_flow_engine *engine = NULL;
      71                 :            :         void *temp;
      72                 :            : 
      73         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(engine, &engine_list, node, temp) {
      74         [ #  # ]:          0 :                 if (engine->uninit)
      75                 :          0 :                         engine->uninit(adapter);
      76                 :            :         }
      77                 :          0 : }
      78                 :            : 
      79                 :            : static int
      80                 :            : cpfl_flow_attr_valid(const struct rte_flow_attr *attr,
      81                 :            :                      struct rte_flow_error *error)
      82                 :            : {
      83         [ #  # ]:          0 :         if (attr->priority > CPFL_PREC_MAX) {
      84                 :          0 :                 rte_flow_error_set(error, EINVAL,
      85                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
      86                 :            :                                    attr, "Only support priority 0-7.");
      87                 :          0 :                 return -rte_errno;
      88                 :            :         }
      89                 :            : 
      90                 :            :         return 0;
      91                 :            : }
      92                 :            : 
      93                 :            : static int
      94                 :          0 : cpfl_flow_param_valid(const struct rte_flow_attr *attr,
      95                 :            :                       const struct rte_flow_item pattern[],
      96                 :            :                       const struct rte_flow_action actions[],
      97                 :            :                       struct rte_flow_error *error)
      98                 :            : {
      99                 :            :         int ret;
     100                 :            : 
     101         [ #  # ]:          0 :         if (!pattern) {
     102                 :          0 :                 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
     103                 :            :                                    NULL, "NULL pattern.");
     104                 :          0 :                 return -rte_errno;
     105                 :            :         }
     106                 :            : 
     107         [ #  # ]:          0 :         if (!attr) {
     108                 :          0 :                 rte_flow_error_set(error, EINVAL,
     109                 :            :                                    RTE_FLOW_ERROR_TYPE_ATTR,
     110                 :            :                                    NULL, "NULL attribute.");
     111                 :          0 :                 return -rte_errno;
     112                 :            :         }
     113                 :            : 
     114                 :            :         ret = cpfl_flow_attr_valid(attr, error);
     115         [ #  # ]:          0 :         if (ret)
     116                 :            :                 return ret;
     117                 :            : 
     118   [ #  #  #  # ]:          0 :         if (!actions || actions->type == RTE_FLOW_ACTION_TYPE_END) {
     119                 :          0 :                 rte_flow_error_set(error, EINVAL,
     120                 :            :                                    RTE_FLOW_ERROR_TYPE_ACTION_NUM,
     121                 :            :                                    NULL, "NULL action.");
     122                 :          0 :                 return -rte_errno;
     123                 :            :         }
     124                 :            : 
     125                 :            :         return 0;
     126                 :            : }
     127                 :            : 
     128                 :            : static int
     129                 :          0 : __cpfl_flow_validate(struct rte_eth_dev *dev,
     130                 :            :                      const struct rte_flow_attr *attr,
     131                 :            :                      const struct rte_flow_item pattern[],
     132                 :            :                      const struct rte_flow_action actions[],
     133                 :            :                      void **meta,
     134                 :            :                      struct cpfl_flow_engine **engine,
     135                 :            :                      struct rte_flow_error *error)
     136                 :            : {
     137                 :            :         int ret;
     138                 :            : 
     139                 :          0 :         ret = cpfl_flow_param_valid(attr, pattern, actions, error);
     140         [ #  # ]:          0 :         if (ret)
     141                 :            :                 return ret;
     142                 :            : 
     143                 :          0 :         *engine = cpfl_flow_engine_match(dev, attr, pattern, actions, meta);
     144         [ #  # ]:          0 :         if (!*engine) {
     145                 :          0 :                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     146                 :            :                                    NULL, "No matched engine.");
     147                 :          0 :                 return -rte_errno;
     148                 :            :         }
     149                 :            : 
     150                 :            :         return 0;
     151                 :            : }
     152                 :            : 
     153                 :            : int
     154                 :          0 : cpfl_flow_validate(struct rte_eth_dev *dev,
     155                 :            :                    const struct rte_flow_attr *attr,
     156                 :            :                    const struct rte_flow_item pattern[],
     157                 :            :                    const struct rte_flow_action actions[],
     158                 :            :                    struct rte_flow_error *error)
     159                 :            : {
     160                 :          0 :         struct cpfl_flow_engine *engine = NULL;
     161                 :            :         int ret;
     162                 :            : 
     163                 :          0 :         ret = __cpfl_flow_validate(dev, attr, pattern, actions, NULL, &engine, error);
     164                 :            : 
     165                 :          0 :         return ret;
     166                 :            : }
     167                 :            : 
     168                 :            : struct rte_flow *
     169                 :          0 : cpfl_flow_create(struct rte_eth_dev *dev,
     170                 :            :                  const struct rte_flow_attr *attr,
     171                 :            :                  const struct rte_flow_item pattern[],
     172                 :            :                  const struct rte_flow_action actions[],
     173                 :            :                  struct rte_flow_error *error)
     174                 :            : {
     175                 :          0 :         struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
     176                 :          0 :         struct cpfl_flow_engine *engine = NULL;
     177                 :            :         struct rte_flow *flow;
     178                 :            :         void *meta;
     179                 :            :         int ret;
     180                 :            : 
     181                 :          0 :         flow = rte_malloc(NULL, sizeof(struct rte_flow), 0);
     182         [ #  # ]:          0 :         if (!flow) {
     183                 :          0 :                 rte_flow_error_set(error, ENOMEM,
     184                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
     185                 :            :                                    "Failed to allocate memory");
     186                 :          0 :                 return NULL;
     187                 :            :         }
     188                 :            : 
     189                 :          0 :         ret = __cpfl_flow_validate(dev, attr, pattern, actions, &meta, &engine, error);
     190         [ #  # ]:          0 :         if (ret) {
     191                 :          0 :                 rte_free(flow);
     192                 :          0 :                 return NULL;
     193                 :            :         }
     194                 :            : 
     195         [ #  # ]:          0 :         if (!engine->create) {
     196                 :          0 :                 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
     197                 :            :                                    NULL, "No matched flow creation function");
     198                 :          0 :                 rte_free(flow);
     199                 :          0 :                 return NULL;
     200                 :            :         }
     201                 :            : 
     202                 :          0 :         ret = engine->create(dev, flow, meta, error);
     203         [ #  # ]:          0 :         if (ret) {
     204                 :          0 :                 rte_free(flow);
     205                 :          0 :                 return NULL;
     206                 :            :         }
     207                 :            : 
     208                 :          0 :         flow->engine = engine;
     209                 :          0 :         TAILQ_INSERT_TAIL(&itf->flow_list, flow, next);
     210                 :            : 
     211                 :          0 :         return flow;
     212                 :            : }
     213                 :            : 
     214                 :            : int
     215                 :          0 : cpfl_flow_destroy(struct rte_eth_dev *dev,
     216                 :            :                   struct rte_flow *flow,
     217                 :            :                   struct rte_flow_error *error)
     218                 :            : {
     219                 :          0 :         struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
     220                 :            :         int ret = 0;
     221                 :            : 
     222   [ #  #  #  #  :          0 :         if (!flow || !flow->engine || !flow->engine->destroy) {
                   #  # ]
     223                 :          0 :                 rte_flow_error_set(error, EINVAL,
     224                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE,
     225                 :            :                                    NULL, "Invalid flow");
     226                 :          0 :                 return -rte_errno;
     227                 :            :         }
     228                 :            : 
     229                 :          0 :         ret = flow->engine->destroy(dev, flow, error);
     230         [ #  # ]:          0 :         if (!ret)
     231         [ #  # ]:          0 :                 TAILQ_REMOVE(&itf->flow_list, flow, next);
     232                 :            :         else
     233                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to destroy flow");
     234                 :            : 
     235                 :            :         return ret;
     236                 :            : }
     237                 :            : 
     238                 :            : int
     239                 :          0 : cpfl_flow_flush(struct rte_eth_dev *dev,
     240                 :            :                 struct rte_flow_error *error)
     241                 :            : {
     242                 :          0 :         struct cpfl_itf *itf = CPFL_DEV_TO_ITF(dev);
     243                 :            :         struct rte_flow *p_flow;
     244                 :            :         void *temp;
     245                 :            :         int ret = 0;
     246                 :            : 
     247         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(p_flow, &itf->flow_list, next, temp) {
     248                 :          0 :                 ret = cpfl_flow_destroy(dev, p_flow, error);
     249         [ #  # ]:          0 :                 if (ret) {
     250                 :          0 :                         PMD_DRV_LOG(ERR, "Failed to flush flows");
     251                 :          0 :                         return -EINVAL;
     252                 :            :                 }
     253                 :            :         }
     254                 :            : 
     255                 :            :         return ret;
     256                 :            : }
     257                 :            : 
     258                 :            : int
     259                 :          0 : cpfl_flow_query(struct rte_eth_dev *dev,
     260                 :            :                 struct rte_flow *flow,
     261                 :            :                 const struct rte_flow_action *actions,
     262                 :            :                 void *data,
     263                 :            :                 struct rte_flow_error *error)
     264                 :            : {
     265                 :            :         struct rte_flow_query_count *count = data;
     266                 :            :         int ret = -EINVAL;
     267                 :            : 
     268   [ #  #  #  #  :          0 :         if (!flow || !flow->engine || !flow->engine->query_count) {
                   #  # ]
     269                 :          0 :                 rte_flow_error_set(error, EINVAL,
     270                 :            :                                    RTE_FLOW_ERROR_TYPE_HANDLE,
     271                 :            :                                    NULL, "Invalid flow");
     272                 :          0 :                 return -rte_errno;
     273                 :            :         }
     274                 :            : 
     275         [ #  # ]:          0 :         for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
     276      [ #  #  # ]:          0 :                 switch (actions->type) {
     277                 :            :                 case RTE_FLOW_ACTION_TYPE_VOID:
     278                 :            :                         break;
     279                 :          0 :                 case RTE_FLOW_ACTION_TYPE_COUNT:
     280                 :          0 :                         ret = flow->engine->query_count(dev, flow, count, error);
     281                 :          0 :                         break;
     282                 :          0 :                 default:
     283                 :          0 :                         ret = rte_flow_error_set(error, ENOTSUP,
     284                 :            :                                                  RTE_FLOW_ERROR_TYPE_ACTION,
     285                 :            :                                                  actions,
     286                 :            :                                                  "action not supported");
     287                 :          0 :                         break;
     288                 :            :                 }
     289                 :            :         }
     290                 :            : 
     291                 :            :         return ret;
     292                 :            : }
     293                 :            : 
     294                 :            : const struct rte_flow_ops cpfl_flow_ops = {
     295                 :            :         .validate = cpfl_flow_validate,
     296                 :            :         .create = cpfl_flow_create,
     297                 :            :         .destroy = cpfl_flow_destroy,
     298                 :            :         .flush = cpfl_flow_flush,
     299                 :            :         .query = cpfl_flow_query,
     300                 :            : };
     301                 :            : 
     302                 :            : int
     303                 :          0 : cpfl_flow_init(struct cpfl_adapter_ext *ad, struct cpfl_devargs *devargs)
     304                 :            : {
     305                 :            :         int ret;
     306                 :            : 
     307         [ #  # ]:          0 :         if (devargs->flow_parser[0] == '\0') {
     308                 :          0 :                 PMD_INIT_LOG(WARNING, "flow module is not initialized");
     309                 :          0 :                 return 0;
     310                 :            :         }
     311                 :            : 
     312                 :          0 :         ret = cpfl_flow_engine_init(ad);
     313         [ #  # ]:          0 :         if (ret) {
     314                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to init flow engines");
     315                 :          0 :                 goto err;
     316                 :            :         }
     317                 :            : 
     318                 :          0 :         ret = cpfl_parser_create(&ad->flow_parser, devargs->flow_parser);
     319         [ #  # ]:          0 :         if (ret) {
     320                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to create flow parser");
     321                 :          0 :                 goto err;
     322                 :            :         }
     323                 :            : 
     324                 :            :         return ret;
     325                 :            : 
     326                 :          0 : err:
     327                 :          0 :         cpfl_flow_engine_uninit(ad);
     328                 :          0 :         return ret;
     329                 :            : }
     330                 :            : 
     331                 :            : void
     332                 :          0 : cpfl_flow_uninit(struct cpfl_adapter_ext *ad)
     333                 :            : {
     334         [ #  # ]:          0 :         if (ad->flow_parser == NULL)
     335                 :            :                 return;
     336                 :            : 
     337                 :          0 :         cpfl_parser_destroy(ad->flow_parser);
     338                 :          0 :         cpfl_flow_engine_uninit(ad);
     339                 :            : }

Generated by: LCOV version 1.14