Commit 79baaec7 authored by Eli Britstein's avatar Eli Britstein Committed by Saeed Mahameed

net/mlx5e: Allow association of a flow to multiple encaps

Currently a flow can be associated with a single encap entry. The
extended destination feature enables the driver to configure multiple
encap entries per flow.

Change the encap flow association field to array as a pre-step towards
supporting multiple encap destinations. Use only the first array
element, with no functional change.
Signed-off-by: default avatarEli Britstein <elibr@mellanox.com>
Reviewed-by: default avatarOz Shlomo <ozsh@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 98b66cb1
...@@ -78,13 +78,39 @@ enum { ...@@ -78,13 +78,39 @@ enum {
#define MLX5E_TC_MAX_SPLITS 1 #define MLX5E_TC_MAX_SPLITS 1
/* Helper struct for accessing a struct containing list_head array.
* Containing struct
* |- Helper array
* [0] Helper item 0
* |- list_head item 0
* |- index (0)
* [1] Helper item 1
* |- list_head item 1
* |- index (1)
* To access the containing struct from one of the list_head items:
* 1. Get the helper item from the list_head item using
* helper item =
* container_of(list_head item, helper struct type, list_head field)
* 2. Get the contining struct from the helper item and its index in the array:
* containing struct =
* container_of(helper item, containing struct type, helper field[index])
*/
struct encap_flow_item {
struct list_head list;
int index;
};
struct mlx5e_tc_flow { struct mlx5e_tc_flow {
struct rhash_head node; struct rhash_head node;
struct mlx5e_priv *priv; struct mlx5e_priv *priv;
u64 cookie; u64 cookie;
u16 flags; u16 flags;
struct mlx5_flow_handle *rule[MLX5E_TC_MAX_SPLITS + 1]; struct mlx5_flow_handle *rule[MLX5E_TC_MAX_SPLITS + 1];
struct list_head encap; /* flows sharing the same encap ID */ /* Flow can be associated with multiple encap IDs.
* The number of encaps is bounded by the number of supported
* destinations.
*/
struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
struct list_head mod_hdr; /* flows sharing the same mod hdr ID */ struct list_head mod_hdr; /* flows sharing the same mod hdr ID */
struct list_head hairpin; /* flows sharing the same hairpin */ struct list_head hairpin; /* flows sharing the same hairpin */
union { union {
...@@ -1043,6 +1069,7 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, ...@@ -1043,6 +1069,7 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
struct mlx5_esw_flow_attr slow_attr, *esw_attr; struct mlx5_esw_flow_attr slow_attr, *esw_attr;
struct mlx5_flow_handle *rule; struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec; struct mlx5_flow_spec *spec;
struct encap_flow_item *efi;
struct mlx5e_tc_flow *flow; struct mlx5e_tc_flow *flow;
int err; int err;
...@@ -1059,7 +1086,8 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, ...@@ -1059,7 +1086,8 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
e->flags |= MLX5_ENCAP_ENTRY_VALID; e->flags |= MLX5_ENCAP_ENTRY_VALID;
mlx5e_rep_queue_neigh_stats_work(priv); mlx5e_rep_queue_neigh_stats_work(priv);
list_for_each_entry(flow, &e->flows, encap) { list_for_each_entry(efi, &e->flows, list) {
flow = container_of(efi, struct mlx5e_tc_flow, encaps[efi->index]);
esw_attr = flow->esw_attr; esw_attr = flow->esw_attr;
esw_attr->encap_id = e->encap_id; esw_attr->encap_id = e->encap_id;
spec = &esw_attr->parse_attr->spec; spec = &esw_attr->parse_attr->spec;
...@@ -1086,10 +1114,12 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv, ...@@ -1086,10 +1114,12 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
struct mlx5_esw_flow_attr slow_attr; struct mlx5_esw_flow_attr slow_attr;
struct mlx5_flow_handle *rule; struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec; struct mlx5_flow_spec *spec;
struct encap_flow_item *efi;
struct mlx5e_tc_flow *flow; struct mlx5e_tc_flow *flow;
int err; int err;
list_for_each_entry(flow, &e->flows, encap) { list_for_each_entry(efi, &e->flows, list) {
flow = container_of(efi, struct mlx5e_tc_flow, encaps[efi->index]);
spec = &flow->esw_attr->parse_attr->spec; spec = &flow->esw_attr->parse_attr->spec;
/* update from encap rule to slow path rule */ /* update from encap rule to slow path rule */
...@@ -1142,9 +1172,12 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) ...@@ -1142,9 +1172,12 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
return; return;
list_for_each_entry(e, &nhe->encap_list, encap_list) { list_for_each_entry(e, &nhe->encap_list, encap_list) {
struct encap_flow_item *efi;
if (!(e->flags & MLX5_ENCAP_ENTRY_VALID)) if (!(e->flags & MLX5_ENCAP_ENTRY_VALID))
continue; continue;
list_for_each_entry(flow, &e->flows, encap) { list_for_each_entry(efi, &e->flows, list) {
flow = container_of(efi, struct mlx5e_tc_flow,
encaps[efi->index]);
if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) { if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
counter = mlx5e_tc_get_counter(flow); counter = mlx5e_tc_get_counter(flow);
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse); mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
...@@ -1176,9 +1209,9 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe) ...@@ -1176,9 +1209,9 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
static void mlx5e_detach_encap(struct mlx5e_priv *priv, static void mlx5e_detach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow) struct mlx5e_tc_flow *flow)
{ {
struct list_head *next = flow->encap.next; struct list_head *next = flow->encaps[0].list.next;
list_del(&flow->encap); list_del(&flow->encaps[0].list);
if (list_empty(next)) { if (list_empty(next)) {
struct mlx5e_encap_entry *e; struct mlx5e_encap_entry *e;
...@@ -2338,7 +2371,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -2338,7 +2371,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key); hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key);
attach_flow: attach_flow:
list_add(&flow->encap, &e->flows); list_add(&flow->encaps[0].list, &e->flows);
flow->encaps[0].index = 0;
*encap_dev = e->out_dev; *encap_dev = e->out_dev;
if (e->flags & MLX5_ENCAP_ENTRY_VALID) if (e->flags & MLX5_ENCAP_ENTRY_VALID)
attr->encap_id = e->encap_id; attr->encap_id = e->encap_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment