LCOV - code coverage report
Current view: top level - drivers/net/failsafe - failsafe_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 103 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 7 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 78 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2017 6WIND S.A.
       3                 :            :  * Copyright 2017 Mellanox Technologies, Ltd
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <stddef.h>
       7                 :            : #include <string.h>
       8                 :            : #include <sys/queue.h>
       9                 :            : 
      10                 :            : #include <rte_errno.h>
      11                 :            : #include <rte_malloc.h>
      12                 :            : #include <rte_tailq.h>
      13                 :            : #include <rte_flow.h>
      14                 :            : #include <rte_flow_driver.h>
      15                 :            : 
      16                 :            : #include "failsafe_private.h"
      17                 :            : 
      18                 :            : static struct rte_flow *
      19                 :          0 : fs_flow_allocate(const struct rte_flow_attr *attr,
      20                 :            :                  const struct rte_flow_item *items,
      21                 :            :                  const struct rte_flow_action *actions)
      22                 :            : {
      23                 :            :         struct rte_flow *flow;
      24                 :          0 :         const struct rte_flow_conv_rule rule = {
      25                 :            :                 .attr_ro = attr,
      26                 :            :                 .pattern_ro = items,
      27                 :            :                 .actions_ro = actions,
      28                 :            :         };
      29                 :            :         struct rte_flow_error error;
      30                 :            :         int ret;
      31                 :            : 
      32                 :          0 :         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, &error);
      33         [ #  # ]:          0 :         if (ret < 0) {
      34         [ #  # ]:          0 :                 ERROR("Unable to process flow rule (%s): %s",
      35                 :            :                       error.message ? error.message : "unspecified",
      36                 :            :                       strerror(rte_errno));
      37                 :          0 :                 return NULL;
      38                 :            :         }
      39                 :          0 :         flow = rte_zmalloc(NULL, offsetof(struct rte_flow, rule) + ret,
      40                 :            :                            RTE_CACHE_LINE_SIZE);
      41         [ #  # ]:          0 :         if (flow == NULL) {
      42                 :          0 :                 ERROR("Could not allocate new flow");
      43                 :          0 :                 return NULL;
      44                 :            :         }
      45                 :          0 :         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &flow->rule, ret, &rule,
      46                 :            :                             &error);
      47         [ #  # ]:          0 :         if (ret < 0) {
      48         [ #  # ]:          0 :                 ERROR("Failed to copy flow rule (%s): %s",
      49                 :            :                       error.message ? error.message : "unspecified",
      50                 :            :                       strerror(rte_errno));
      51                 :          0 :                 rte_free(flow);
      52                 :          0 :                 return NULL;
      53                 :            :         }
      54                 :            :         return flow;
      55                 :            : }
      56                 :            : 
      57                 :            : static void
      58                 :            : fs_flow_release(struct rte_flow **flow)
      59                 :            : {
      60                 :          0 :         rte_free(*flow);
      61                 :            :         *flow = NULL;
      62                 :            : }
      63                 :            : 
      64                 :            : static int
      65                 :          0 : fs_flow_validate(struct rte_eth_dev *dev,
      66                 :            :                  const struct rte_flow_attr *attr,
      67                 :            :                  const struct rte_flow_item patterns[],
      68                 :            :                  const struct rte_flow_action actions[],
      69                 :            :                  struct rte_flow_error *error)
      70                 :            : {
      71                 :            :         struct sub_device *sdev;
      72                 :            :         uint8_t i;
      73                 :            :         int ret;
      74                 :            : 
      75                 :          0 :         ret = fs_lock(dev, 0);
      76         [ #  # ]:          0 :         if (ret != 0)
      77                 :            :                 return ret;
      78         [ #  # ]:          0 :         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
      79                 :          0 :                 DEBUG("Calling rte_flow_validate on sub_device %d", i);
      80                 :          0 :                 ret = rte_flow_validate(PORT_ID(sdev),
      81                 :            :                                 attr, patterns, actions, error);
      82         [ #  # ]:          0 :                 if ((ret = fs_err(sdev, ret))) {
      83                 :          0 :                         ERROR("Operation rte_flow_validate failed for sub_device %d"
      84                 :            :                               " with error %d", i, ret);
      85                 :          0 :                         fs_unlock(dev, 0);
      86                 :          0 :                         return ret;
      87                 :            :                 }
      88                 :            :         }
      89                 :          0 :         fs_unlock(dev, 0);
      90                 :          0 :         return 0;
      91                 :            : }
      92                 :            : 
      93                 :            : static struct rte_flow *
      94                 :          0 : fs_flow_create(struct rte_eth_dev *dev,
      95                 :            :                const struct rte_flow_attr *attr,
      96                 :            :                const struct rte_flow_item patterns[],
      97                 :            :                const struct rte_flow_action actions[],
      98                 :            :                struct rte_flow_error *error)
      99                 :            : {
     100                 :            :         struct sub_device *sdev;
     101                 :            :         struct rte_flow *flow;
     102                 :            :         uint8_t i;
     103                 :            : 
     104         [ #  # ]:          0 :         if (fs_lock(dev, 0) != 0)
     105                 :            :                 return NULL;
     106                 :          0 :         flow = fs_flow_allocate(attr, patterns, actions);
     107         [ #  # ]:          0 :         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
     108                 :          0 :                 flow->flows[i] = rte_flow_create(PORT_ID(sdev),
     109                 :            :                                 attr, patterns, actions, error);
     110   [ #  #  #  #  :          0 :                 if (flow->flows[i] == NULL && fs_err(sdev, -rte_errno)) {
                   #  # ]
     111                 :          0 :                         ERROR("Failed to create flow on sub_device %d",
     112                 :            :                                 i);
     113         [ #  # ]:          0 :                         goto err;
     114                 :            :                 }
     115                 :            :         }
     116                 :          0 :         TAILQ_INSERT_TAIL(&PRIV(dev)->flow_list, flow, next);
     117                 :          0 :         fs_unlock(dev, 0);
     118                 :          0 :         return flow;
     119                 :            : err:
     120   [ #  #  #  # ]:          0 :         FOREACH_SUBDEV(sdev, i, dev) {
     121         [ #  # ]:          0 :                 if (flow->flows[i] != NULL)
     122                 :          0 :                         rte_flow_destroy(PORT_ID(sdev),
     123                 :            :                                 flow->flows[i], error);
     124                 :            :         }
     125                 :            :         fs_flow_release(&flow);
     126                 :          0 :         fs_unlock(dev, 0);
     127                 :          0 :         return NULL;
     128                 :            : }
     129                 :            : 
     130                 :            : static int
     131                 :          0 : fs_flow_destroy(struct rte_eth_dev *dev,
     132                 :            :                 struct rte_flow *flow,
     133                 :            :                 struct rte_flow_error *error)
     134                 :            : {
     135                 :            :         struct sub_device *sdev;
     136                 :            :         uint8_t i;
     137                 :            :         int ret;
     138                 :            : 
     139         [ #  # ]:          0 :         if (flow == NULL) {
     140                 :          0 :                 ERROR("Invalid flow");
     141                 :          0 :                 return -EINVAL;
     142                 :            :         }
     143                 :          0 :         ret = fs_lock(dev, 0);
     144         [ #  # ]:          0 :         if (ret != 0)
     145                 :            :                 return ret;
     146         [ #  # ]:          0 :         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
     147                 :            :                 int local_ret;
     148                 :            : 
     149         [ #  # ]:          0 :                 if (flow->flows[i] == NULL)
     150                 :          0 :                         continue;
     151                 :          0 :                 local_ret = rte_flow_destroy(PORT_ID(sdev),
     152                 :            :                                 flow->flows[i], error);
     153         [ #  # ]:          0 :                 if ((local_ret = fs_err(sdev, local_ret))) {
     154                 :          0 :                         ERROR("Failed to destroy flow on sub_device %d: %d",
     155                 :            :                                         i, local_ret);
     156         [ #  # ]:          0 :                         if (ret == 0)
     157                 :            :                                 ret = local_ret;
     158                 :            :                 }
     159                 :            :         }
     160         [ #  # ]:          0 :         TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
     161                 :            :         fs_flow_release(&flow);
     162                 :          0 :         fs_unlock(dev, 0);
     163                 :          0 :         return ret;
     164                 :            : }
     165                 :            : 
     166                 :            : static int
     167                 :          0 : fs_flow_flush(struct rte_eth_dev *dev,
     168                 :            :               struct rte_flow_error *error)
     169                 :            : {
     170                 :            :         struct sub_device *sdev;
     171                 :            :         struct rte_flow *flow;
     172                 :            :         void *tmp;
     173                 :            :         uint8_t i;
     174                 :            :         int ret;
     175                 :            : 
     176                 :          0 :         ret = fs_lock(dev, 0);
     177         [ #  # ]:          0 :         if (ret != 0)
     178                 :            :                 return ret;
     179         [ #  # ]:          0 :         FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
     180                 :          0 :                 DEBUG("Calling rte_flow_flush on sub_device %d", i);
     181                 :          0 :                 ret = rte_flow_flush(PORT_ID(sdev), error);
     182         [ #  # ]:          0 :                 if ((ret = fs_err(sdev, ret))) {
     183                 :          0 :                         ERROR("Operation rte_flow_flush failed for sub_device %d"
     184                 :            :                               " with error %d", i, ret);
     185                 :          0 :                         fs_unlock(dev, 0);
     186                 :          0 :                         return ret;
     187                 :            :                 }
     188                 :            :         }
     189         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(flow, &PRIV(dev)->flow_list, next, tmp) {
     190         [ #  # ]:          0 :                 TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
     191                 :            :                 fs_flow_release(&flow);
     192                 :            :         }
     193                 :          0 :         fs_unlock(dev, 0);
     194                 :          0 :         return 0;
     195                 :            : }
     196                 :            : 
     197                 :            : static int
     198                 :          0 : fs_flow_query(struct rte_eth_dev *dev,
     199                 :            :               struct rte_flow *flow,
     200                 :            :               const struct rte_flow_action *action,
     201                 :            :               void *arg,
     202                 :            :               struct rte_flow_error *error)
     203                 :            : {
     204                 :            :         struct sub_device *sdev;
     205                 :            : 
     206         [ #  # ]:          0 :         if (fs_lock(dev, 0) != 0)
     207                 :            :                 return -1;
     208   [ #  #  #  # ]:          0 :         sdev = TX_SUBDEV(dev);
     209                 :            :         if (sdev != NULL) {
     210                 :          0 :                 int ret = rte_flow_query(PORT_ID(sdev),
     211                 :          0 :                                          flow->flows[SUB_ID(sdev)],
     212                 :            :                                          action, arg, error);
     213                 :            : 
     214         [ #  # ]:          0 :                 if ((ret = fs_err(sdev, ret))) {
     215                 :          0 :                         fs_unlock(dev, 0);
     216                 :          0 :                         return ret;
     217                 :            :                 }
     218                 :            :         }
     219                 :          0 :         fs_unlock(dev, 0);
     220                 :          0 :         WARN("No active sub_device to query about its flow");
     221                 :          0 :         return -1;
     222                 :            : }
     223                 :            : 
     224                 :            : static int
     225                 :          0 : fs_flow_isolate(struct rte_eth_dev *dev,
     226                 :            :                 int set,
     227                 :            :                 struct rte_flow_error *error)
     228                 :            : {
     229                 :            :         struct sub_device *sdev;
     230                 :            :         uint8_t i;
     231                 :            :         int ret;
     232                 :            : 
     233                 :          0 :         ret = fs_lock(dev, 0);
     234         [ #  # ]:          0 :         if (ret != 0)
     235                 :            :                 return ret;
     236   [ #  #  #  # ]:          0 :         FOREACH_SUBDEV(sdev, i, dev) {
     237         [ #  # ]:          0 :                 if (sdev->state < DEV_PROBED)
     238                 :          0 :                         continue;
     239                 :          0 :                 DEBUG("Calling rte_flow_isolate on sub_device %d", i);
     240         [ #  # ]:          0 :                 if (PRIV(dev)->flow_isolated != sdev->flow_isolated)
     241                 :          0 :                         WARN("flow isolation mode of sub_device %d in incoherent state.",
     242                 :            :                                 i);
     243                 :          0 :                 ret = rte_flow_isolate(PORT_ID(sdev), set, error);
     244         [ #  # ]:          0 :                 if ((ret = fs_err(sdev, ret))) {
     245                 :          0 :                         ERROR("Operation rte_flow_isolate failed for sub_device %d"
     246                 :            :                               " with error %d", i, ret);
     247                 :          0 :                         fs_unlock(dev, 0);
     248                 :          0 :                         return ret;
     249                 :            :                 }
     250                 :          0 :                 sdev->flow_isolated = set;
     251                 :            :         }
     252                 :          0 :         PRIV(dev)->flow_isolated = set;
     253                 :          0 :         fs_unlock(dev, 0);
     254                 :          0 :         return 0;
     255                 :            : }
     256                 :            : 
     257                 :            : const struct rte_flow_ops fs_flow_ops = {
     258                 :            :         .validate = fs_flow_validate,
     259                 :            :         .create = fs_flow_create,
     260                 :            :         .destroy = fs_flow_destroy,
     261                 :            :         .flush = fs_flow_flush,
     262                 :            :         .query = fs_flow_query,
     263                 :            :         .isolate = fs_flow_isolate,
     264                 :            : };

Generated by: LCOV version 1.14