@@ -975,6 +975,8 @@ sfc_attach(struct sfc_adapter *sa)
if (rc != 0)
goto fail_rss_attach;
+ sfc_flow_init(sa);
+
rc = sfc_flow_rss_attach(sa);
if (rc != 0)
goto fail_flow_rss_attach;
@@ -1006,8 +1008,6 @@ sfc_attach(struct sfc_adapter *sa)
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
- sfc_flow_init(sa);
-
rc = sfc_sw_xstats_init(sa);
if (rc != 0)
goto fail_sw_xstats_init;
@@ -1030,7 +1030,6 @@ sfc_attach(struct sfc_adapter *sa)
sfc_sw_xstats_close(sa);
fail_sw_xstats_init:
- sfc_flow_fini(sa);
sfc_repr_proxy_detach(sa);
fail_repr_proxy_attach:
@@ -1052,6 +1051,7 @@ sfc_attach(struct sfc_adapter *sa)
sfc_flow_rss_detach(sa);
fail_flow_rss_attach:
+ sfc_flow_fini(sa);
sfc_rss_detach(sa);
fail_rss_attach:
@@ -1099,8 +1099,6 @@ sfc_detach(struct sfc_adapter *sa)
sfc_sriov_vswitch_destroy(sa);
- sfc_flow_fini(sa);
-
sfc_repr_proxy_detach(sa);
sfc_mae_switchdev_fini(sa);
sfc_tbls_detach(sa);
@@ -1108,6 +1106,7 @@ sfc_detach(struct sfc_adapter *sa)
sfc_mae_counter_rxq_detach(sa);
sfc_filter_detach(sa);
sfc_flow_rss_detach(sa);
+ sfc_flow_fini(sa);
sfc_rss_detach(sa);
sfc_port_detach(sa);
sfc_ev_detach(sa);
@@ -7,6 +7,8 @@
* for Solarflare) and Solarflare Communications, Inc.
*/
+#include <stdbool.h>
+
#include <rte_byteorder.h>
#include <rte_tailq.h>
#include <rte_common.h>
@@ -2405,7 +2407,7 @@ sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev,
if (rc != 0)
goto fail;
- rc = sfc_mae_rule_parse_pattern(sa, pattern, spec_mae, error);
+ rc = sfc_mae_rule_parse_pattern(sa, pattern, flow, error);
if (rc != 0)
goto fail;
@@ -2421,7 +2423,7 @@ sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev,
*/
}
- rc = sfc_mae_rule_parse_actions(sa, actions, spec_mae, error);
+ rc = sfc_mae_rule_parse_actions(sa, actions, flow, error);
if (rc != 0)
goto fail;
@@ -2613,14 +2615,14 @@ sfc_flow_create(struct rte_eth_dev *dev,
struct rte_flow *flow;
sfc_adapter_lock(sa);
- flow = sfc_flow_create_locked(sa, attr, pattern, actions, error);
+ flow = sfc_flow_create_locked(sa, false, attr, pattern, actions, error);
sfc_adapter_unlock(sa);
return flow;
}
struct rte_flow *
-sfc_flow_create_locked(struct sfc_adapter *sa,
+sfc_flow_create_locked(struct sfc_adapter *sa, bool internal,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
@@ -2635,13 +2637,15 @@ sfc_flow_create_locked(struct sfc_adapter *sa,
if (flow == NULL)
goto fail_no_mem;
+ flow->internal = internal;
+
rc = sfc_flow_parse(sa->eth_dev, attr, pattern, actions, flow, error);
if (rc != 0)
goto fail_bad_value;
TAILQ_INSERT_TAIL(&sa->flow_list, flow, entries);
- if (sa->state == SFC_ETHDEV_STARTED) {
+ if (flow->internal || sa->state == SFC_ETHDEV_STARTED) {
rc = sfc_flow_insert(sa, flow, error);
if (rc != 0)
goto fail_flow_insert;
@@ -2694,7 +2698,7 @@ sfc_flow_destroy_locked(struct sfc_adapter *sa, struct rte_flow *flow,
goto fail_bad_value;
}
- if (sa->state == SFC_ETHDEV_STARTED)
+ if (flow->internal || sa->state == SFC_ETHDEV_STARTED)
rc = sfc_flow_remove(sa, flow, error);
TAILQ_REMOVE(&sa->flow_list, flow, entries);
@@ -2711,10 +2715,14 @@ sfc_flow_flush(struct rte_eth_dev *dev,
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
struct rte_flow *flow;
int ret = 0;
+ void *tmp;
sfc_adapter_lock(sa);
- while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) {
+ RTE_TAILQ_FOREACH_SAFE(flow, &sa->flow_list, entries, tmp) {
+ if (flow->internal)
+ continue;
+
if (sa->state == SFC_ETHDEV_STARTED) {
int rc;
@@ -2842,10 +2850,14 @@ void
sfc_flow_fini(struct sfc_adapter *sa)
{
struct rte_flow *flow;
+ void *tmp;
SFC_ASSERT(sfc_adapter_is_locked(sa));
- while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) {
+ RTE_TAILQ_FOREACH_SAFE(flow, &sa->flow_list, entries, tmp) {
+ if (flow->internal)
+ continue;
+
TAILQ_REMOVE(&sa->flow_list, flow, entries);
sfc_flow_free(sa, flow);
}
@@ -2858,8 +2870,10 @@ sfc_flow_stop(struct sfc_adapter *sa)
SFC_ASSERT(sfc_adapter_is_locked(sa));
- TAILQ_FOREACH(flow, &sa->flow_list, entries)
- sfc_flow_remove(sa, flow, NULL);
+ TAILQ_FOREACH(flow, &sa->flow_list, entries) {
+ if (!flow->internal)
+ sfc_flow_remove(sa, flow, NULL);
+ }
/*
* MAE counter service is not stopped on flow rule remove to avoid
@@ -2881,6 +2895,9 @@ sfc_flow_start(struct sfc_adapter *sa)
sfc_ft_counters_reset(sa);
TAILQ_FOREACH(flow, &sa->flow_list, entries) {
+ if (flow->internal)
+ continue;
+
rc = sfc_flow_insert(sa, flow, NULL);
if (rc != 0)
goto fail_bad_flow;
@@ -10,6 +10,8 @@
#ifndef _SFC_FLOW_H
#define _SFC_FLOW_H
+#include <stdbool.h>
+
#include <rte_tailq.h>
#include <rte_flow_driver.h>
@@ -101,6 +103,7 @@ struct sfc_flow_spec {
struct rte_flow {
struct sfc_flow_spec spec; /* flow specification */
TAILQ_ENTRY(rte_flow) entries; /* flow list entries */
+ bool internal; /* true for internal rules */
};
TAILQ_HEAD(sfc_flow_list, rte_flow);
@@ -195,7 +198,7 @@ typedef int (sfc_flow_query_cb_t)(struct rte_eth_dev *dev,
void *data,
struct rte_flow_error *error);
-struct rte_flow *sfc_flow_create_locked(struct sfc_adapter *sa,
+struct rte_flow *sfc_flow_create_locked(struct sfc_adapter *sa, bool internal,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
@@ -2537,6 +2537,20 @@ sfc_mae_rule_process_outer(struct sfc_adapter *sa,
efx_mae_rule_id_t invalid_rule_id = { .id = EFX_MAE_RSRC_ID_INVALID };
int rc;
+ if (ctx->internal) {
+ /*
+ * A driver-internal flow may not comprise an outer rule,
+ * but it must not match on invalid outer rule ID since
+ * it must catch all missed packets, including those
+ * that hit an outer rule of another flow entry but
+ * do not hit a higher-priority action rule later.
+ * So do not set match on outer rule ID here.
+ */
+ SFC_ASSERT(ctx->match_spec_outer == NULL);
+ *rulep = NULL;
+ return 0;
+ }
+
if (ctx->encap_type == EFX_TUNNEL_PROTOCOL_NONE) {
*rulep = NULL;
goto no_or_id;
@@ -2823,9 +2837,10 @@ sfc_mae_rule_encap_parse_fini(struct sfc_adapter *sa,
int
sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
const struct rte_flow_item pattern[],
- struct sfc_flow_spec_mae *spec,
+ struct rte_flow *flow,
struct rte_flow_error *error)
{
+ struct sfc_flow_spec_mae *spec = &flow->spec.mae;
struct sfc_mae_parse_ctx ctx_mae;
unsigned int priority_shift = 0;
struct sfc_flow_parse_ctx ctx;
@@ -2833,6 +2848,7 @@ sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
memset(&ctx_mae, 0, sizeof(ctx_mae));
ctx_mae.ft_rule_type = spec->ft_rule_type;
+ ctx_mae.internal = flow->internal;
ctx_mae.priority = spec->priority;
ctx_mae.ft_ctx = spec->ft_ctx;
ctx_mae.sa = sa;
@@ -3642,11 +3658,12 @@ static const char * const action_names[] = {
static int
sfc_mae_rule_parse_action(struct sfc_adapter *sa,
const struct rte_flow_action *action,
- const struct sfc_flow_spec_mae *spec_mae,
+ const struct rte_flow *flow,
struct sfc_mae_actions_bundle *bundle,
struct sfc_mae_aset_ctx *ctx,
struct rte_flow_error *error)
{
+ const struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae;
const struct sfc_mae_outer_rule *outer_rule = spec_mae->outer_rule;
const uint64_t rx_metadata = sa->negotiated_rx_metadata;
efx_mae_actions_t *spec = ctx->spec;
@@ -3770,6 +3787,11 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
switch_port_type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+ if (flow->internal) {
+ switch_port_type_mask |=
+ 1U << SFC_MAE_SWITCH_PORT_REPRESENTOR;
+ }
+
rc = sfc_mae_rule_parse_action_port_representor(sa,
action->conf, switch_port_type_mask, spec);
break;
@@ -3840,9 +3862,10 @@ sfc_mae_process_encap_header(struct sfc_adapter *sa,
int
sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
const struct rte_flow_action actions[],
- struct sfc_flow_spec_mae *spec_mae,
+ struct rte_flow *flow,
struct rte_flow_error *error)
{
+ struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae;
struct sfc_mae_actions_bundle bundle = {0};
const struct rte_flow_action *action;
struct sfc_mae_aset_ctx ctx = {0};
@@ -3899,7 +3922,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
if (rc != 0)
goto fail_rule_parse_action;
- rc = sfc_mae_rule_parse_action(sa, action, spec_mae,
+ rc = sfc_mae_rule_parse_action(sa, action, flow,
&bundle, &ctx, error);
if (rc != 0)
goto fail_rule_parse_action;
@@ -363,6 +363,7 @@ struct sfc_mae_parse_ctx {
size_t tunnel_def_mask_size;
const void *tunnel_def_mask;
bool match_mport_set;
+ bool internal;
enum sfc_ft_rule_type ft_rule_type;
struct sfc_mae_pattern_data pattern_data;
efx_tunnel_protocol_t encap_type;
@@ -376,11 +377,11 @@ void sfc_mae_detach(struct sfc_adapter *sa);
sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup;
int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
const struct rte_flow_item pattern[],
- struct sfc_flow_spec_mae *spec,
+ struct rte_flow *flow,
struct rte_flow_error *error);
int sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
const struct rte_flow_action actions[],
- struct sfc_flow_spec_mae *spec_mae,
+ struct rte_flow *flow,
struct rte_flow_error *error);
sfc_flow_verify_cb_t sfc_mae_flow_verify;
sfc_flow_insert_cb_t sfc_mae_flow_insert;