net/sfc: implement flow insert/remove in MAE backend
Exercise action set allocation / release and action rule insertion / removal in order to let flow API callers actually get created flows functioning. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
This commit is contained in:
parent
b4fac34715
commit
041f22ec34
@ -50,8 +50,8 @@ static const struct sfc_flow_ops_by_spec sfc_flow_ops_mae = {
|
||||
.parse = sfc_flow_parse_rte_to_mae,
|
||||
.verify = sfc_mae_flow_verify,
|
||||
.cleanup = sfc_mae_flow_cleanup,
|
||||
.insert = NULL,
|
||||
.remove = NULL,
|
||||
.insert = sfc_mae_flow_insert,
|
||||
.remove = sfc_mae_flow_remove,
|
||||
};
|
||||
|
||||
static const struct sfc_flow_ops_by_spec *
|
||||
@ -1202,6 +1202,7 @@ sfc_flow_parse_attr(struct sfc_adapter *sa,
|
||||
spec_mae->priority = attr->priority;
|
||||
spec_mae->match_spec = NULL;
|
||||
spec_mae->action_set = NULL;
|
||||
spec_mae->rule_id.id = EFX_MAE_RSRC_ID_INVALID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -67,6 +67,8 @@ struct sfc_flow_spec_mae {
|
||||
efx_mae_match_spec_t *match_spec;
|
||||
/* Action set registry entry */
|
||||
struct sfc_mae_action_set *action_set;
|
||||
/* Firmware-allocated rule ID */
|
||||
efx_mae_rule_id_t rule_id;
|
||||
};
|
||||
|
||||
/* Flow specification */
|
||||
|
@ -113,6 +113,8 @@ sfc_mae_action_set_add(struct sfc_adapter *sa,
|
||||
action_set->refcnt = 1;
|
||||
action_set->spec = spec;
|
||||
|
||||
action_set->fw_rsrc.aset_id.id = EFX_MAE_RSRC_ID_INVALID;
|
||||
|
||||
TAILQ_INSERT_TAIL(&mae->action_sets, action_set, entries);
|
||||
|
||||
*action_setp = action_set;
|
||||
@ -134,11 +136,62 @@ sfc_mae_action_set_del(struct sfc_adapter *sa,
|
||||
if (action_set->refcnt != 0)
|
||||
return;
|
||||
|
||||
SFC_ASSERT(action_set->fw_rsrc.aset_id.id == EFX_MAE_RSRC_ID_INVALID);
|
||||
SFC_ASSERT(action_set->fw_rsrc.refcnt == 0);
|
||||
|
||||
efx_mae_action_set_spec_fini(sa->nic, action_set->spec);
|
||||
TAILQ_REMOVE(&mae->action_sets, action_set, entries);
|
||||
rte_free(action_set);
|
||||
}
|
||||
|
||||
static int
|
||||
sfc_mae_action_set_enable(struct sfc_adapter *sa,
|
||||
struct sfc_mae_action_set *action_set)
|
||||
{
|
||||
struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
|
||||
int rc;
|
||||
|
||||
SFC_ASSERT(sfc_adapter_is_locked(sa));
|
||||
|
||||
if (fw_rsrc->refcnt == 0) {
|
||||
SFC_ASSERT(fw_rsrc->aset_id.id == EFX_MAE_RSRC_ID_INVALID);
|
||||
SFC_ASSERT(action_set->spec != NULL);
|
||||
|
||||
rc = efx_mae_action_set_alloc(sa->nic, action_set->spec,
|
||||
&fw_rsrc->aset_id);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
++(fw_rsrc->refcnt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sfc_mae_action_set_disable(struct sfc_adapter *sa,
|
||||
struct sfc_mae_action_set *action_set)
|
||||
{
|
||||
struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
|
||||
int rc;
|
||||
|
||||
SFC_ASSERT(sfc_adapter_is_locked(sa));
|
||||
SFC_ASSERT(fw_rsrc->aset_id.id != EFX_MAE_RSRC_ID_INVALID);
|
||||
SFC_ASSERT(fw_rsrc->refcnt != 0);
|
||||
|
||||
if (fw_rsrc->refcnt == 1) {
|
||||
rc = efx_mae_action_set_free(sa->nic, &fw_rsrc->aset_id);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
fw_rsrc->aset_id.id = EFX_MAE_RSRC_ID_INVALID;
|
||||
}
|
||||
|
||||
--(fw_rsrc->refcnt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sfc_mae_flow_cleanup(struct sfc_adapter *sa,
|
||||
struct rte_flow *flow)
|
||||
@ -156,6 +209,8 @@ sfc_mae_flow_cleanup(struct sfc_adapter *sa,
|
||||
|
||||
spec_mae = &spec->mae;
|
||||
|
||||
SFC_ASSERT(spec_mae->rule_id.id == EFX_MAE_RSRC_ID_INVALID);
|
||||
|
||||
if (spec_mae->action_set != NULL)
|
||||
sfc_mae_action_set_del(sa, spec_mae->action_set);
|
||||
|
||||
@ -563,3 +618,56 @@ sfc_mae_flow_verify(struct sfc_adapter *sa,
|
||||
|
||||
return sfc_mae_action_rule_class_verify(sa, spec_mae);
|
||||
}
|
||||
|
||||
int
|
||||
sfc_mae_flow_insert(struct sfc_adapter *sa,
|
||||
struct rte_flow *flow)
|
||||
{
|
||||
struct sfc_flow_spec *spec = &flow->spec;
|
||||
struct sfc_flow_spec_mae *spec_mae = &spec->mae;
|
||||
struct sfc_mae_action_set *action_set = spec_mae->action_set;
|
||||
struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
|
||||
int rc;
|
||||
|
||||
SFC_ASSERT(spec_mae->rule_id.id == EFX_MAE_RSRC_ID_INVALID);
|
||||
SFC_ASSERT(action_set != NULL);
|
||||
|
||||
rc = sfc_mae_action_set_enable(sa, action_set);
|
||||
if (rc != 0)
|
||||
goto fail_action_set_enable;
|
||||
|
||||
rc = efx_mae_action_rule_insert(sa->nic, spec_mae->match_spec,
|
||||
NULL, &fw_rsrc->aset_id,
|
||||
&spec_mae->rule_id);
|
||||
if (rc != 0)
|
||||
goto fail_action_rule_insert;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_action_rule_insert:
|
||||
(void)sfc_mae_action_set_disable(sa, action_set);
|
||||
|
||||
fail_action_set_enable:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
sfc_mae_flow_remove(struct sfc_adapter *sa,
|
||||
struct rte_flow *flow)
|
||||
{
|
||||
struct sfc_flow_spec *spec = &flow->spec;
|
||||
struct sfc_flow_spec_mae *spec_mae = &spec->mae;
|
||||
struct sfc_mae_action_set *action_set = spec_mae->action_set;
|
||||
int rc;
|
||||
|
||||
SFC_ASSERT(spec_mae->rule_id.id != EFX_MAE_RSRC_ID_INVALID);
|
||||
SFC_ASSERT(action_set != NULL);
|
||||
|
||||
rc = efx_mae_action_rule_remove(sa->nic, &spec_mae->rule_id);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
spec_mae->rule_id.id = EFX_MAE_RSRC_ID_INVALID;
|
||||
|
||||
return sfc_mae_action_set_disable(sa, action_set);
|
||||
}
|
||||
|
@ -18,11 +18,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** FW-allocatable resource context */
|
||||
struct sfc_mae_fw_rsrc {
|
||||
unsigned int refcnt;
|
||||
RTE_STD_C11
|
||||
union {
|
||||
efx_mae_aset_id_t aset_id;
|
||||
};
|
||||
};
|
||||
|
||||
/** Action set registry entry */
|
||||
struct sfc_mae_action_set {
|
||||
TAILQ_ENTRY(sfc_mae_action_set) entries;
|
||||
unsigned int refcnt;
|
||||
efx_mae_actions_t *spec;
|
||||
struct sfc_mae_fw_rsrc fw_rsrc;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(sfc_mae_action_sets, sfc_mae_action_set);
|
||||
@ -63,6 +73,8 @@ int sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
|
||||
struct sfc_mae_action_set **action_setp,
|
||||
struct rte_flow_error *error);
|
||||
sfc_flow_verify_cb_t sfc_mae_flow_verify;
|
||||
sfc_flow_insert_cb_t sfc_mae_flow_insert;
|
||||
sfc_flow_remove_cb_t sfc_mae_flow_remove;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user