4 * Copyright 2016 6WIND S.A.
5 * Copyright 2016 Mellanox.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of 6WIND S.A. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <rte_errno.h>
37 #include <rte_branch_prediction.h>
38 #include "rte_ethdev.h"
39 #include "rte_flow_driver.h"
42 /* Get generic flow operations structure from a port. */
43 const struct rte_flow_ops *
44 rte_flow_ops_get(uint8_t port_id, struct rte_flow_error *error)
46 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
47 const struct rte_flow_ops *ops;
50 if (unlikely(!rte_eth_dev_is_valid_port(port_id)))
52 else if (unlikely(!dev->dev_ops->filter_ctrl ||
53 dev->dev_ops->filter_ctrl(dev,
54 RTE_ETH_FILTER_GENERIC,
61 rte_flow_error_set(error, code, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
62 NULL, rte_strerror(code));
66 /* Check whether a flow rule can be created on a given port. */
68 rte_flow_validate(uint8_t port_id,
69 const struct rte_flow_attr *attr,
70 const struct rte_flow_item pattern[],
71 const struct rte_flow_action actions[],
72 struct rte_flow_error *error)
74 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
75 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
79 if (likely(!!ops->validate))
80 return ops->validate(dev, attr, pattern, actions, error);
81 return -rte_flow_error_set(error, ENOSYS,
82 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
83 NULL, rte_strerror(ENOSYS));
86 /* Create a flow rule on a given port. */
88 rte_flow_create(uint8_t port_id,
89 const struct rte_flow_attr *attr,
90 const struct rte_flow_item pattern[],
91 const struct rte_flow_action actions[],
92 struct rte_flow_error *error)
94 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
95 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
99 if (likely(!!ops->create))
100 return ops->create(dev, attr, pattern, actions, error);
101 rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
102 NULL, rte_strerror(ENOSYS));
106 /* Destroy a flow rule on a given port. */
108 rte_flow_destroy(uint8_t port_id,
109 struct rte_flow *flow,
110 struct rte_flow_error *error)
112 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
113 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
117 if (likely(!!ops->destroy))
118 return ops->destroy(dev, flow, error);
119 return -rte_flow_error_set(error, ENOSYS,
120 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
121 NULL, rte_strerror(ENOSYS));
124 /* Destroy all flow rules associated with a port. */
126 rte_flow_flush(uint8_t port_id,
127 struct rte_flow_error *error)
129 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
130 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
134 if (likely(!!ops->flush))
135 return ops->flush(dev, error);
136 return -rte_flow_error_set(error, ENOSYS,
137 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
138 NULL, rte_strerror(ENOSYS));
141 /* Query an existing flow rule. */
143 rte_flow_query(uint8_t port_id,
144 struct rte_flow *flow,
145 enum rte_flow_action_type action,
147 struct rte_flow_error *error)
149 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
150 const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
154 if (likely(!!ops->query))
155 return ops->query(dev, flow, action, data, error);
156 return -rte_flow_error_set(error, ENOSYS,
157 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
158 NULL, rte_strerror(ENOSYS));