LCOV - code coverage report
Current view: top level - drivers/net/bonding - rte_eth_bond_flow.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 88 0.0 %
Date: 2024-02-14 00:53:57 Functions: 0 8 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 50 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2018 Mellanox Technologies, Ltd
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stddef.h>
       6                 :            : #include <string.h>
       7                 :            : #include <sys/queue.h>
       8                 :            : 
       9                 :            : #include <rte_errno.h>
      10                 :            : #include <rte_malloc.h>
      11                 :            : #include <rte_tailq.h>
      12                 :            : #include <rte_flow.h>
      13                 :            : 
      14                 :            : #include "eth_bond_private.h"
      15                 :            : 
      16                 :            : static struct rte_flow *
      17                 :          0 : bond_flow_alloc(int numa_node, const struct rte_flow_attr *attr,
      18                 :            :                    const struct rte_flow_item *items,
      19                 :            :                    const struct rte_flow_action *actions)
      20                 :            : {
      21                 :            :         struct rte_flow *flow;
      22                 :          0 :         const struct rte_flow_conv_rule rule = {
      23                 :            :                 .attr_ro = attr,
      24                 :            :                 .pattern_ro = items,
      25                 :            :                 .actions_ro = actions,
      26                 :            :         };
      27                 :            :         struct rte_flow_error error;
      28                 :            :         int ret;
      29                 :            : 
      30                 :          0 :         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, NULL, 0, &rule, &error);
      31         [ #  # ]:          0 :         if (ret < 0) {
      32         [ #  # ]:          0 :                 RTE_BOND_LOG(ERR, "Unable to process flow rule (%s): %s",
      33                 :            :                              error.message ? error.message : "unspecified",
      34                 :            :                              strerror(rte_errno));
      35                 :          0 :                 return NULL;
      36                 :            :         }
      37                 :          0 :         flow = rte_zmalloc_socket(NULL, offsetof(struct rte_flow, rule) + ret,
      38                 :            :                                   RTE_CACHE_LINE_SIZE, numa_node);
      39         [ #  # ]:          0 :         if (unlikely(flow == NULL)) {
      40                 :          0 :                 RTE_BOND_LOG(ERR, "Could not allocate new flow");
      41                 :          0 :                 return NULL;
      42                 :            :         }
      43                 :          0 :         ret = rte_flow_conv(RTE_FLOW_CONV_OP_RULE, &flow->rule, ret, &rule,
      44                 :            :                             &error);
      45         [ #  # ]:          0 :         if (ret < 0) {
      46         [ #  # ]:          0 :                 RTE_BOND_LOG(ERR, "Failed to copy flow rule (%s): %s",
      47                 :            :                              error.message ? error.message : "unspecified",
      48                 :            :                              strerror(rte_errno));
      49                 :          0 :                 rte_free(flow);
      50                 :          0 :                 return NULL;
      51                 :            :         }
      52                 :            :         return flow;
      53                 :            : }
      54                 :            : 
      55                 :            : static void
      56                 :            : bond_flow_release(struct rte_flow **flow)
      57                 :            : {
      58                 :          0 :         rte_free(*flow);
      59                 :            :         *flow = NULL;
      60                 :            : }
      61                 :            : 
      62                 :            : static int
      63                 :          0 : bond_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
      64                 :            :                    const struct rte_flow_item patterns[],
      65                 :            :                    const struct rte_flow_action actions[],
      66                 :            :                    struct rte_flow_error *err)
      67                 :            : {
      68                 :          0 :         struct bond_dev_private *internals = dev->data->dev_private;
      69                 :            :         int i;
      70                 :            :         int ret;
      71                 :            : 
      72         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++) {
      73                 :          0 :                 ret = rte_flow_validate(internals->members[i].port_id, attr,
      74                 :            :                                         patterns, actions, err);
      75         [ #  # ]:          0 :                 if (ret) {
      76                 :          0 :                         RTE_BOND_LOG(ERR, "Operation rte_flow_validate failed"
      77                 :            :                                      " for member %d with error %d", i, ret);
      78                 :          0 :                         return ret;
      79                 :            :                 }
      80                 :            :         }
      81                 :            :         return 0;
      82                 :            : }
      83                 :            : 
      84                 :            : static struct rte_flow *
      85                 :          0 : bond_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
      86                 :            :                  const struct rte_flow_item patterns[],
      87                 :            :                  const struct rte_flow_action actions[],
      88                 :            :                  struct rte_flow_error *err)
      89                 :            : {
      90                 :          0 :         struct bond_dev_private *internals = dev->data->dev_private;
      91                 :            :         struct rte_flow *flow;
      92                 :            :         int i;
      93                 :            : 
      94                 :          0 :         flow = bond_flow_alloc(dev->data->numa_node, attr, patterns, actions);
      95         [ #  # ]:          0 :         if (unlikely(flow == NULL)) {
      96                 :          0 :                 rte_flow_error_set(err, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
      97                 :            :                                    NULL, rte_strerror(ENOMEM));
      98                 :          0 :                 return NULL;
      99                 :            :         }
     100         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++) {
     101                 :          0 :                 flow->flows[i] = rte_flow_create(internals->members[i].port_id,
     102                 :            :                                                  attr, patterns, actions, err);
     103         [ #  # ]:          0 :                 if (unlikely(flow->flows[i] == NULL)) {
     104                 :          0 :                         RTE_BOND_LOG(ERR, "Failed to create flow on member %d",
     105                 :            :                                      i);
     106                 :          0 :                         goto err;
     107                 :            :                 }
     108                 :            :         }
     109                 :          0 :         TAILQ_INSERT_TAIL(&internals->flow_list, flow, next);
     110                 :          0 :         return flow;
     111                 :            : err:
     112                 :            :         /* Destroy all members flows. */
     113         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++) {
     114         [ #  # ]:          0 :                 if (flow->flows[i] != NULL)
     115                 :          0 :                         rte_flow_destroy(internals->members[i].port_id,
     116                 :            :                                          flow->flows[i], err);
     117                 :            :         }
     118                 :            :         bond_flow_release(&flow);
     119                 :          0 :         return NULL;
     120                 :            : }
     121                 :            : 
     122                 :            : static int
     123                 :          0 : bond_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
     124                 :            :                   struct rte_flow_error *err)
     125                 :            : {
     126                 :          0 :         struct bond_dev_private *internals = dev->data->dev_private;
     127                 :            :         int i;
     128                 :            :         int ret = 0;
     129                 :            : 
     130         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++) {
     131                 :            :                 int lret;
     132                 :            : 
     133         [ #  # ]:          0 :                 if (unlikely(flow->flows[i] == NULL))
     134                 :          0 :                         continue;
     135                 :          0 :                 lret = rte_flow_destroy(internals->members[i].port_id,
     136                 :            :                                         flow->flows[i], err);
     137         [ #  # ]:          0 :                 if (unlikely(lret != 0)) {
     138                 :          0 :                         RTE_BOND_LOG(ERR, "Failed to destroy flow on member %d:"
     139                 :            :                                      " %d", i, lret);
     140                 :            :                         ret = lret;
     141                 :            :                 }
     142                 :            :         }
     143         [ #  # ]:          0 :         TAILQ_REMOVE(&internals->flow_list, flow, next);
     144                 :            :         bond_flow_release(&flow);
     145                 :          0 :         return ret;
     146                 :            : }
     147                 :            : 
     148                 :            : static int
     149                 :          0 : bond_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *err)
     150                 :            : {
     151                 :          0 :         struct bond_dev_private *internals = dev->data->dev_private;
     152                 :            :         struct rte_flow *flow;
     153                 :            :         void *tmp;
     154                 :            :         int ret = 0;
     155                 :            :         int lret;
     156                 :            : 
     157                 :            :         /* Destroy all bond flows from its members instead of flushing them to
     158                 :            :          * keep the LACP flow or any other external flows.
     159                 :            :          */
     160         [ #  # ]:          0 :         RTE_TAILQ_FOREACH_SAFE(flow, &internals->flow_list, next, tmp) {
     161                 :          0 :                 lret = bond_flow_destroy(dev, flow, err);
     162         [ #  # ]:          0 :                 if (unlikely(lret != 0))
     163                 :            :                         ret = lret;
     164                 :            :         }
     165         [ #  # ]:          0 :         if (unlikely(ret != 0))
     166                 :          0 :                 RTE_BOND_LOG(ERR, "Failed to flush flow in all members");
     167                 :          0 :         return ret;
     168                 :            : }
     169                 :            : 
     170                 :            : static int
     171                 :          0 : bond_flow_query_count(struct rte_eth_dev *dev, struct rte_flow *flow,
     172                 :            :                       const struct rte_flow_action *action,
     173                 :            :                       struct rte_flow_query_count *count,
     174                 :            :                       struct rte_flow_error *err)
     175                 :            : {
     176                 :          0 :         struct bond_dev_private *internals = dev->data->dev_private;
     177                 :            :         struct rte_flow_query_count member_count;
     178                 :            :         int i;
     179                 :            :         int ret;
     180                 :            : 
     181                 :          0 :         count->bytes = 0;
     182         [ #  # ]:          0 :         count->hits = 0;
     183                 :            :         rte_memcpy(&member_count, count, sizeof(member_count));
     184         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++) {
     185                 :          0 :                 ret = rte_flow_query(internals->members[i].port_id,
     186                 :            :                                      flow->flows[i], action,
     187                 :            :                                      &member_count, err);
     188         [ #  # ]:          0 :                 if (unlikely(ret != 0)) {
     189                 :          0 :                         RTE_BOND_LOG(ERR, "Failed to query flow on"
     190                 :            :                                      " member %d: %d", i, ret);
     191                 :          0 :                         return ret;
     192                 :            :                 }
     193                 :          0 :                 count->bytes += member_count.bytes;
     194                 :          0 :                 count->hits += member_count.hits;
     195                 :          0 :                 member_count.bytes = 0;
     196                 :          0 :                 member_count.hits = 0;
     197                 :            :         }
     198                 :            :         return 0;
     199                 :            : }
     200                 :            : 
     201                 :            : static int
     202                 :          0 : bond_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,
     203                 :            :                 const struct rte_flow_action *action, void *arg,
     204                 :            :                 struct rte_flow_error *err)
     205                 :            : {
     206         [ #  # ]:          0 :         switch (action->type) {
     207                 :          0 :         case RTE_FLOW_ACTION_TYPE_COUNT:
     208                 :          0 :                 return bond_flow_query_count(dev, flow, action, arg, err);
     209                 :          0 :         default:
     210                 :          0 :                 return rte_flow_error_set(err, ENOTSUP,
     211                 :            :                                           RTE_FLOW_ERROR_TYPE_ACTION, arg,
     212                 :            :                                           rte_strerror(ENOTSUP));
     213                 :            :         }
     214                 :            : }
     215                 :            : 
     216                 :            : static int
     217                 :          0 : bond_flow_isolate(struct rte_eth_dev *dev, int set,
     218                 :            :                   struct rte_flow_error *err)
     219                 :            : {
     220                 :          0 :         struct bond_dev_private *internals = dev->data->dev_private;
     221                 :            :         int i;
     222                 :            :         int ret;
     223                 :            : 
     224         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++) {
     225                 :          0 :                 ret = rte_flow_isolate(internals->members[i].port_id, set, err);
     226         [ #  # ]:          0 :                 if (unlikely(ret != 0)) {
     227                 :          0 :                         RTE_BOND_LOG(ERR, "Operation rte_flow_isolate failed"
     228                 :            :                                      " for member %d with error %d", i, ret);
     229                 :          0 :                         internals->flow_isolated_valid = 0;
     230                 :          0 :                         return ret;
     231                 :            :                 }
     232                 :            :         }
     233                 :          0 :         internals->flow_isolated = set;
     234                 :          0 :         internals->flow_isolated_valid = 1;
     235                 :          0 :         return 0;
     236                 :            : }
     237                 :            : 
     238                 :            : const struct rte_flow_ops bond_flow_ops = {
     239                 :            :         .validate = bond_flow_validate,
     240                 :            :         .create = bond_flow_create,
     241                 :            :         .destroy = bond_flow_destroy,
     242                 :            :         .flush = bond_flow_flush,
     243                 :            :         .query = bond_flow_query,
     244                 :            :         .isolate = bond_flow_isolate,
     245                 :            : };

Generated by: LCOV version 1.14