From 59d64571110b1f6007a90615d9c9958b148ed585 Mon Sep 17 00:00:00 2001 From: Viacheslav Ovsiienko Date: Mon, 12 Nov 2018 20:01:41 +0000 Subject: [PATCH] net/mlx5: prepare to add E-switch rule flags check The tc flower filter rules are used to control E-switch from the application side. In order to gain garanteed rule hardware offload the skip_sw flag should be specified while applying the rule. But some tc rules is rejected by kernel if skip_sw flag is set by design. Currently this regards VXLAN tunneling rules, which are applied to special VXLAN virtual devices. Albeit these rules are applied with skip_sw flag reset kernel tries to perform hardware offload. If kernel succeeded the in_hw flag is set in rule properties and application should check this flag to get know whether the applied rule is actually hardware offloaded. This patch prepares for the rule flags query and check in_hw flag. The driver checks only the rules with skip_sw flag reset, so we need to test the actual flags of rule is being applied. The pointer to flags field into translated rule is introduced and flags are tested directly in the rule body. It is more reliable than save and check flags copy. Also patch swaps the flow_tcf_apply() and flow_tcf_remove(), we are going to call flow_tcf_remove() from flow_tcf_appy() if no in_hw flag set found in applied rule. Signed-off-by: Viacheslav Ovsiienko Acked-by: Shahaf Shuler --- drivers/net/mlx5/mlx5_flow.h | 1 + drivers/net/mlx5/mlx5_flow_tcf.c | 82 +++++++++++++++++--------------- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 51ab47fe44..57b312e7c1 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -219,6 +219,7 @@ struct mlx5_flow_dv { struct mlx5_flow_tcf { struct nlmsghdr *nlh; struct tcmsg *tcm; + uint32_t *ptc_flags; /**< tc rule applied flags. */ union { /**< Tunnel encap/decap descriptor. */ struct flow_tcf_tunnel_hdr *tunnel; struct flow_tcf_vxlan_decap *vxlan_decap; diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 4d154b65ff..5bfb2d879c 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -160,6 +160,9 @@ struct tc_tunnel_key { #ifndef TCA_CLS_FLAGS_SKIP_SW #define TCA_CLS_FLAGS_SKIP_SW (1 << 1) #endif +#ifndef TCA_CLS_FLAGS_IN_HW +#define TCA_CLS_FLAGS_IN_HW (1 << 2) +#endif #ifndef HAVE_TCA_CHAIN #define TCA_CHAIN 11 #endif @@ -3699,6 +3702,8 @@ override_na_vlan_priority: assert(na_flower); assert(na_flower_act); mnl_attr_nest_end(nlh, na_flower_act); + dev_flow->tcf.ptc_flags = mnl_attr_get_payload + (mnl_nlmsg_get_payload_tail(nlh)); mnl_attr_put_u32(nlh, TCA_FLOWER_FLAGS, decap.vxlan ? 0 : TCA_CLS_FLAGS_SKIP_SW); mnl_attr_nest_end(nlh, na_flower); @@ -5077,6 +5082,44 @@ flow_tcf_vtep_release(struct mlx5_flow_tcf_context *tcf, pthread_mutex_unlock(&vtep_list_mutex); } +/** + * Remove flow from E-Switch by sending Netlink message. + * + * @param[in] dev + * Pointer to Ethernet device. + * @param[in, out] flow + * Pointer to the sub flow. + */ +static void +flow_tcf_remove(struct rte_eth_dev *dev, struct rte_flow *flow) +{ + struct priv *priv = dev->data->dev_private; + struct mlx5_flow_tcf_context *ctx = priv->tcf_context; + struct mlx5_flow *dev_flow; + struct nlmsghdr *nlh; + + if (!flow) + return; + dev_flow = LIST_FIRST(&flow->dev_flows); + if (!dev_flow) + return; + /* E-Switch flow can't be expanded. */ + assert(!LIST_NEXT(dev_flow, next)); + if (dev_flow->tcf.applied) { + nlh = dev_flow->tcf.nlh; + nlh->nlmsg_type = RTM_DELTFILTER; + nlh->nlmsg_flags = NLM_F_REQUEST; + flow_tcf_nl_ack(ctx, nlh, NULL, NULL); + if (dev_flow->tcf.tunnel) { + assert(dev_flow->tcf.tunnel->vtep); + flow_tcf_vtep_release(ctx, + dev_flow->tcf.tunnel->vtep, + dev_flow); + dev_flow->tcf.tunnel->vtep = NULL; + } + dev_flow->tcf.applied = 0; + } +} /** * Apply flow to E-Switch by sending Netlink message. @@ -5144,45 +5187,6 @@ flow_tcf_apply(struct rte_eth_dev *dev, struct rte_flow *flow, "netlink: failed to create TC flow rule"); } -/** - * Remove flow from E-Switch by sending Netlink message. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in, out] flow - * Pointer to the sub flow. - */ -static void -flow_tcf_remove(struct rte_eth_dev *dev, struct rte_flow *flow) -{ - struct priv *priv = dev->data->dev_private; - struct mlx5_flow_tcf_context *ctx = priv->tcf_context; - struct mlx5_flow *dev_flow; - struct nlmsghdr *nlh; - - if (!flow) - return; - dev_flow = LIST_FIRST(&flow->dev_flows); - if (!dev_flow) - return; - /* E-Switch flow can't be expanded. */ - assert(!LIST_NEXT(dev_flow, next)); - if (dev_flow->tcf.applied) { - nlh = dev_flow->tcf.nlh; - nlh->nlmsg_type = RTM_DELTFILTER; - nlh->nlmsg_flags = NLM_F_REQUEST; - flow_tcf_nl_ack(ctx, nlh, NULL, NULL); - if (dev_flow->tcf.tunnel) { - assert(dev_flow->tcf.tunnel->vtep); - flow_tcf_vtep_release(ctx, - dev_flow->tcf.tunnel->vtep, - dev_flow); - dev_flow->tcf.tunnel->vtep = NULL; - } - dev_flow->tcf.applied = 0; - } -} - /** * Remove flow from E-Switch and release resources of the device flow. * -- 2.20.1