Commit 26c02749 authored by Or Gerlitz's avatar Or Gerlitz Committed by Saeed Mahameed

net/mlx5e: Allow TC csum offload if applied together with pedit action

When offloading header re-writes, the HW re-calculates the relevant L3/L4
checksums. Hence, when upper layers (as done by OVS) ask for TC checksum action
offload together with pedit offload, don't err. This command now works:

tc filter add dev ens1f0 protocol ip parent ffff: prio 20 flower skip_sw
	ip_proto tcp dst_port 9001
	action pedit ex munge tcp dport set 0x1234 pipe
        action csum tcp
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Reported-by: default avatarPaul Blakey <paulb@mellanox.com>
Reviewed-by: default avatarPaul Blakey <paulb@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 3aa42664
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <net/tc_act/tc_vlan.h> #include <net/tc_act/tc_vlan.h>
#include <net/tc_act/tc_tunnel_key.h> #include <net/tc_act/tc_tunnel_key.h>
#include <net/tc_act/tc_pedit.h> #include <net/tc_act/tc_pedit.h>
#include <net/tc_act/tc_csum.h>
#include <net/vxlan.h> #include <net/vxlan.h>
#include <net/arp.h> #include <net/arp.h>
#include "en.h" #include "en.h"
...@@ -1109,6 +1110,28 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv, ...@@ -1109,6 +1110,28 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv,
return err; return err;
} }
static bool csum_offload_supported(struct mlx5e_priv *priv, u32 action, u32 update_flags)
{
u32 prot_flags = TCA_CSUM_UPDATE_FLAG_IPV4HDR | TCA_CSUM_UPDATE_FLAG_TCP |
TCA_CSUM_UPDATE_FLAG_UDP;
/* The HW recalcs checksums only if re-writing headers */
if (!(action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)) {
netdev_warn(priv->netdev,
"TC csum action is only offloaded with pedit\n");
return false;
}
if (update_flags & ~prot_flags) {
netdev_warn(priv->netdev,
"can't offload TC csum action for some header/s - flags %#x\n",
update_flags);
return false;
}
return true;
}
static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
struct mlx5e_tc_flow_parse_attr *parse_attr, struct mlx5e_tc_flow_parse_attr *parse_attr,
struct mlx5e_tc_flow *flow) struct mlx5e_tc_flow *flow)
...@@ -1149,6 +1172,14 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, ...@@ -1149,6 +1172,14 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
continue; continue;
} }
if (is_tcf_csum(a)) {
if (csum_offload_supported(priv, attr->action,
tcf_csum_update_flags(a)))
continue;
return -EOPNOTSUPP;
}
if (is_tcf_skbedit_mark(a)) { if (is_tcf_skbedit_mark(a)) {
u32 mark = tcf_skbedit_mark(a); u32 mark = tcf_skbedit_mark(a);
...@@ -1651,6 +1682,14 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, ...@@ -1651,6 +1682,14 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
continue; continue;
} }
if (is_tcf_csum(a)) {
if (csum_offload_supported(priv, attr->action,
tcf_csum_update_flags(a)))
continue;
return -EOPNOTSUPP;
}
if (is_tcf_mirred_egress_redirect(a)) { if (is_tcf_mirred_egress_redirect(a)) {
int ifindex = tcf_mirred_ifindex(a); int ifindex = tcf_mirred_ifindex(a);
struct net_device *out_dev, *encap_dev = NULL; struct net_device *out_dev, *encap_dev = NULL;
......
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