@@ -251,6 +251,18 @@ static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
return profile_inline_ops->flow_destroy_profile_inline(dev, flow, error);
}
+static int flow_flush(struct flow_eth_dev *dev, uint16_t caller_id, struct rte_flow_error *error)
+{
+ const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
+
+ if (profile_inline_ops == NULL) {
+ NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized");
+ return -1;
+ }
+
+ return profile_inline_ops->flow_flush_profile_inline(dev, caller_id, error);
+}
+
/*
* Device Management API
*/
@@ -1013,6 +1025,7 @@ static const struct flow_filter_ops ops = {
*/
.flow_create = flow_create,
.flow_destroy = flow_destroy,
+ .flow_flush = flow_flush,
.flow_dev_dump = flow_dev_dump,
};
@@ -3631,6 +3631,48 @@ int flow_destroy_profile_inline(struct flow_eth_dev *dev, struct flow_handle *fl
return err;
}
+int flow_flush_profile_inline(struct flow_eth_dev *dev,
+ uint16_t caller_id,
+ struct rte_flow_error *error)
+{
+ int err = 0;
+
+ flow_nic_set_error(ERR_SUCCESS, error);
+
+ /*
+ * Delete all created FLM flows from this eth device.
+ * FLM flows must be deleted first because normal flows are their parents.
+ */
+ struct flow_handle *flow = dev->ndev->flow_base_flm;
+
+ while (flow && !err) {
+ if (flow->dev == dev && flow->caller_id == caller_id) {
+ struct flow_handle *flow_next = flow->next;
+ err = flow_destroy_profile_inline(dev, flow, error);
+ flow = flow_next;
+
+ } else {
+ flow = flow->next;
+ }
+ }
+
+ /* Delete all created flows from this eth device */
+ flow = dev->ndev->flow_base;
+
+ while (flow && !err) {
+ if (flow->dev == dev && flow->caller_id == caller_id) {
+ struct flow_handle *flow_next = flow->next;
+ err = flow_destroy_profile_inline(dev, flow, error);
+ flow = flow_next;
+
+ } else {
+ flow = flow->next;
+ }
+ }
+
+ return err;
+}
+
static __rte_always_inline bool all_bits_enabled(uint64_t hash_mask, uint64_t hash_bits)
{
return (hash_mask & hash_bits) == hash_bits;
@@ -4391,6 +4433,7 @@ static const struct profile_inline_ops ops = {
.flow_destroy_locked_profile_inline = flow_destroy_locked_profile_inline,
.flow_create_profile_inline = flow_create_profile_inline,
.flow_destroy_profile_inline = flow_destroy_profile_inline,
+ .flow_flush_profile_inline = flow_flush_profile_inline,
.flow_nic_set_hasher_fields_inline = flow_nic_set_hasher_fields_inline,
/*
* NT Flow FLM Meter API
@@ -38,6 +38,10 @@ int flow_destroy_profile_inline(struct flow_eth_dev *dev,
struct flow_handle *flow,
struct rte_flow_error *error);
+int flow_flush_profile_inline(struct flow_eth_dev *dev,
+ uint16_t caller_id,
+ struct rte_flow_error *error);
+
int flow_dev_dump_profile_inline(struct flow_eth_dev *dev,
struct flow_handle *flow,
uint16_t caller_id,
@@ -582,6 +582,43 @@ static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
return flow;
}
+static int eth_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
+{
+ const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops();
+
+ if (flow_filter_ops == NULL) {
+ NT_LOG_DBGX(ERR, FILTER, "flow_filter module uninitialized");
+ return -1;
+ }
+
+ struct pmd_internals *internals = (struct pmd_internals *)eth_dev->data->dev_private;
+
+ static struct rte_flow_error flow_error = {
+ .type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+ int res = 0;
+ /* Main application caller_id is port_id shifted above VDPA ports */
+ uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
+
+ if (internals->flw_dev) {
+ res = flow_filter_ops->flow_flush(internals->flw_dev, caller_id, &flow_error);
+ rte_spinlock_lock(&flow_lock);
+
+ for (int flow = 0; flow < MAX_RTE_FLOWS; flow++) {
+ if (nt_flows[flow].used && nt_flows[flow].caller_id == caller_id) {
+ /* Cleanup recorded flows */
+ nt_flows[flow].used = 0;
+ nt_flows[flow].caller_id = 0;
+ }
+ }
+
+ rte_spinlock_unlock(&flow_lock);
+ }
+
+ convert_error(error, &flow_error);
+
+ return res;
+}
+
static int eth_flow_dev_dump(struct rte_eth_dev *eth_dev,
struct rte_flow *flow,
FILE *file,
@@ -613,6 +650,7 @@ static int eth_flow_dev_dump(struct rte_eth_dev *eth_dev,
static const struct rte_flow_ops dev_flow_ops = {
.create = eth_flow_create,
.destroy = eth_flow_destroy,
+ .flush = eth_flow_flush,
.dev_dump = eth_flow_dev_dump,
};
@@ -253,6 +253,10 @@ struct profile_inline_ops {
struct flow_handle *flow,
struct rte_flow_error *error);
+ int (*flow_flush_profile_inline)(struct flow_eth_dev *dev,
+ uint16_t caller_id,
+ struct rte_flow_error *error);
+
int (*flow_dev_dump_profile_inline)(struct flow_eth_dev *dev,
struct flow_handle *flow,
uint16_t caller_id,
@@ -309,6 +313,9 @@ struct flow_filter_ops {
int (*flow_destroy)(struct flow_eth_dev *dev,
struct flow_handle *flow,
struct rte_flow_error *error);
+
+ int (*flow_flush)(struct flow_eth_dev *dev, uint16_t caller_id,
+ struct rte_flow_error *error);
};
void register_dev_flow_ops(const struct rte_flow_ops *ops);