1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017 6WIND S.A.
3 * Copyright 2017 Mellanox Technologies, Ltd
8 #include <rte_malloc.h>
11 #include <rte_flow_driver.h>
13 #include "failsafe_private.h"
15 static struct rte_flow *
16 fs_flow_allocate(const struct rte_flow_attr *attr,
17 const struct rte_flow_item *items,
18 const struct rte_flow_action *actions)
20 struct rte_flow *flow;
23 fdsz = rte_flow_copy(NULL, 0, attr, items, actions);
24 flow = rte_zmalloc(NULL,
25 sizeof(struct rte_flow) + fdsz,
28 ERROR("Could not allocate new flow");
31 flow->fd = (void *)((uintptr_t)flow + sizeof(*flow));
32 if (rte_flow_copy(flow->fd, fdsz, attr, items, actions) != fdsz) {
33 ERROR("Failed to copy flow description");
41 fs_flow_release(struct rte_flow **flow)
48 fs_flow_validate(struct rte_eth_dev *dev,
49 const struct rte_flow_attr *attr,
50 const struct rte_flow_item patterns[],
51 const struct rte_flow_action actions[],
52 struct rte_flow_error *error)
54 struct sub_device *sdev;
59 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
60 DEBUG("Calling rte_flow_validate on sub_device %d", i);
61 ret = rte_flow_validate(PORT_ID(sdev),
62 attr, patterns, actions, error);
63 if ((ret = fs_err(sdev, ret))) {
64 ERROR("Operation rte_flow_validate failed for sub_device %d"
65 " with error %d", i, ret);
74 static struct rte_flow *
75 fs_flow_create(struct rte_eth_dev *dev,
76 const struct rte_flow_attr *attr,
77 const struct rte_flow_item patterns[],
78 const struct rte_flow_action actions[],
79 struct rte_flow_error *error)
81 struct sub_device *sdev;
82 struct rte_flow *flow;
86 flow = fs_flow_allocate(attr, patterns, actions);
87 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
88 flow->flows[i] = rte_flow_create(PORT_ID(sdev),
89 attr, patterns, actions, error);
90 if (flow->flows[i] == NULL && fs_err(sdev, -rte_errno)) {
91 ERROR("Failed to create flow on sub_device %d",
96 TAILQ_INSERT_TAIL(&PRIV(dev)->flow_list, flow, next);
100 FOREACH_SUBDEV(sdev, i, dev) {
101 if (flow->flows[i] != NULL)
102 rte_flow_destroy(PORT_ID(sdev),
103 flow->flows[i], error);
105 fs_flow_release(&flow);
111 fs_flow_destroy(struct rte_eth_dev *dev,
112 struct rte_flow *flow,
113 struct rte_flow_error *error)
115 struct sub_device *sdev;
120 ERROR("Invalid flow");
125 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
128 if (flow->flows[i] == NULL)
130 local_ret = rte_flow_destroy(PORT_ID(sdev),
131 flow->flows[i], error);
132 if ((local_ret = fs_err(sdev, local_ret))) {
133 ERROR("Failed to destroy flow on sub_device %d: %d",
139 TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
140 fs_flow_release(&flow);
146 fs_flow_flush(struct rte_eth_dev *dev,
147 struct rte_flow_error *error)
149 struct sub_device *sdev;
150 struct rte_flow *flow;
156 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
157 DEBUG("Calling rte_flow_flush on sub_device %d", i);
158 ret = rte_flow_flush(PORT_ID(sdev), error);
159 if ((ret = fs_err(sdev, ret))) {
160 ERROR("Operation rte_flow_flush failed for sub_device %d"
161 " with error %d", i, ret);
166 TAILQ_FOREACH_SAFE(flow, &PRIV(dev)->flow_list, next, tmp) {
167 TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
168 fs_flow_release(&flow);
175 fs_flow_query(struct rte_eth_dev *dev,
176 struct rte_flow *flow,
177 const struct rte_flow_action *action,
179 struct rte_flow_error *error)
181 struct sub_device *sdev;
184 sdev = TX_SUBDEV(dev);
186 int ret = rte_flow_query(PORT_ID(sdev),
187 flow->flows[SUB_ID(sdev)],
190 if ((ret = fs_err(sdev, ret))) {
196 WARN("No active sub_device to query about its flow");
201 fs_flow_isolate(struct rte_eth_dev *dev,
203 struct rte_flow_error *error)
205 struct sub_device *sdev;
210 FOREACH_SUBDEV(sdev, i, dev) {
211 if (sdev->state < DEV_PROBED)
213 DEBUG("Calling rte_flow_isolate on sub_device %d", i);
214 if (PRIV(dev)->flow_isolated != sdev->flow_isolated)
215 WARN("flow isolation mode of sub_device %d in incoherent state.",
217 ret = rte_flow_isolate(PORT_ID(sdev), set, error);
218 if ((ret = fs_err(sdev, ret))) {
219 ERROR("Operation rte_flow_isolate failed for sub_device %d"
220 " with error %d", i, ret);
224 sdev->flow_isolated = set;
226 PRIV(dev)->flow_isolated = set;
231 const struct rte_flow_ops fs_flow_ops = {
232 .validate = fs_flow_validate,
233 .create = fs_flow_create,
234 .destroy = fs_flow_destroy,
235 .flush = fs_flow_flush,
236 .query = fs_flow_query,
237 .isolate = fs_flow_isolate,