1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017 6WIND S.A.
3 * Copyright 2017 Mellanox.
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;
58 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
59 DEBUG("Calling rte_flow_validate on sub_device %d", i);
60 ret = rte_flow_validate(PORT_ID(sdev),
61 attr, patterns, actions, error);
62 if ((ret = fs_err(sdev, ret))) {
63 ERROR("Operation rte_flow_validate failed for sub_device %d"
64 " with error %d", i, ret);
71 static struct rte_flow *
72 fs_flow_create(struct rte_eth_dev *dev,
73 const struct rte_flow_attr *attr,
74 const struct rte_flow_item patterns[],
75 const struct rte_flow_action actions[],
76 struct rte_flow_error *error)
78 struct sub_device *sdev;
79 struct rte_flow *flow;
82 flow = fs_flow_allocate(attr, patterns, actions);
83 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
84 flow->flows[i] = rte_flow_create(PORT_ID(sdev),
85 attr, patterns, actions, error);
86 if (flow->flows[i] == NULL && fs_err(sdev, -rte_errno)) {
87 ERROR("Failed to create flow on sub_device %d",
92 TAILQ_INSERT_TAIL(&PRIV(dev)->flow_list, flow, next);
95 FOREACH_SUBDEV(sdev, i, dev) {
96 if (flow->flows[i] != NULL)
97 rte_flow_destroy(PORT_ID(sdev),
98 flow->flows[i], error);
100 fs_flow_release(&flow);
105 fs_flow_destroy(struct rte_eth_dev *dev,
106 struct rte_flow *flow,
107 struct rte_flow_error *error)
109 struct sub_device *sdev;
114 ERROR("Invalid flow");
118 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
121 if (flow->flows[i] == NULL)
123 local_ret = rte_flow_destroy(PORT_ID(sdev),
124 flow->flows[i], error);
125 if ((local_ret = fs_err(sdev, local_ret))) {
126 ERROR("Failed to destroy flow on sub_device %d: %d",
132 TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
133 fs_flow_release(&flow);
138 fs_flow_flush(struct rte_eth_dev *dev,
139 struct rte_flow_error *error)
141 struct sub_device *sdev;
142 struct rte_flow *flow;
147 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
148 DEBUG("Calling rte_flow_flush on sub_device %d", i);
149 ret = rte_flow_flush(PORT_ID(sdev), error);
150 if ((ret = fs_err(sdev, ret))) {
151 ERROR("Operation rte_flow_flush failed for sub_device %d"
152 " with error %d", i, ret);
156 TAILQ_FOREACH_SAFE(flow, &PRIV(dev)->flow_list, next, tmp) {
157 TAILQ_REMOVE(&PRIV(dev)->flow_list, flow, next);
158 fs_flow_release(&flow);
164 fs_flow_query(struct rte_eth_dev *dev,
165 struct rte_flow *flow,
166 enum rte_flow_action_type type,
168 struct rte_flow_error *error)
170 struct sub_device *sdev;
172 sdev = TX_SUBDEV(dev);
174 int ret = rte_flow_query(PORT_ID(sdev),
175 flow->flows[SUB_ID(sdev)],
178 if ((ret = fs_err(sdev, ret)))
181 WARN("No active sub_device to query about its flow");
186 fs_flow_isolate(struct rte_eth_dev *dev,
188 struct rte_flow_error *error)
190 struct sub_device *sdev;
194 FOREACH_SUBDEV(sdev, i, dev) {
195 if (sdev->state < DEV_PROBED)
197 DEBUG("Calling rte_flow_isolate on sub_device %d", i);
198 if (PRIV(dev)->flow_isolated != sdev->flow_isolated)
199 WARN("flow isolation mode of sub_device %d in incoherent state.",
201 ret = rte_flow_isolate(PORT_ID(sdev), set, error);
202 if ((ret = fs_err(sdev, ret))) {
203 ERROR("Operation rte_flow_isolate failed for sub_device %d"
204 " with error %d", i, ret);
207 sdev->flow_isolated = set;
209 PRIV(dev)->flow_isolated = set;
213 const struct rte_flow_ops fs_flow_ops = {
214 .validate = fs_flow_validate,
215 .create = fs_flow_create,
216 .destroy = fs_flow_destroy,
217 .flush = fs_flow_flush,
218 .query = fs_flow_query,
219 .isolate = fs_flow_isolate,