mlx5-updates-2021-09-24
mlx5 misc updates and fixes to net-next branch: 1) Roi Dayan provided some cleanups in mlx5e TC module, and some code improvements to fwd/drop actions handling. 2) Tariq, Add TX max rate support for MQPRIO channel mode 3) Dima adds the support for TC egress/ingress offload of macvlan interfaces 4) misc cleanup -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAmFOHSEACgkQSD+KveBX +j7tHwgAvS2x9UFamtn0hk0h1ACwhvhDSc4WOa1Y06PpJyop5nCvr9S4+7NmgMOJ e7Bs4twjEcx5YEYO7e+kLk+s1W+vbzkqghBqXJYjCj8FXDtTenVBgFnkfBzO/BB9 CV3upYuG6WPZ1cHxVur10ne2TgkloGd17IqKqItQHUVH1y0EdqR8m4VBNWu6wgFj eG9Us+JC3XuW9vipnfKahI9DJI+32oADgCR7MeVfEV8D2VQlNhdggLNO6XTO6F/O tQrtJr84/BGVJDuGgkUn++fgFn8h+gc+zyOb6j7nkUnQuXa2Ay/IAsOthA9ZyIzv pycrMgE7yVYz4WTs4cLdSQ950C05XA== =x70v -----END PGP SIGNATURE----- Merge tag 'mlx5-updates-2021-09-24' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5-updates-2021-09-24 mlx5 misc updates and fixes to net-next branch: 1) Roi Dayan provided some cleanups in mlx5e TC module, and some code improvements to fwd/drop actions handling. 2) Tariq, Add TX max rate support for MQPRIO channel mode 3) Dima adds the support for TC egress/ingress offload of macvlan interfaces 4) misc cleanup ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8765de69e7
@ -220,8 +220,6 @@ struct mlx5e_umr_wqe {
|
||||
struct mlx5_mtt inline_mtts[0];
|
||||
};
|
||||
|
||||
extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];
|
||||
|
||||
enum mlx5e_priv_flag {
|
||||
MLX5E_PFLAG_RX_CQE_BASED_MODER,
|
||||
MLX5E_PFLAG_TX_CQE_BASED_MODER,
|
||||
@ -916,6 +914,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
|
||||
|
||||
void mlx5e_init_l2_addr(struct mlx5e_priv *priv);
|
||||
int mlx5e_self_test_num(struct mlx5e_priv *priv);
|
||||
int mlx5e_self_test_fill_strings(struct mlx5e_priv *priv, u8 *data);
|
||||
void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
|
||||
u64 *buf);
|
||||
void mlx5e_set_rx_mode_work(struct work_struct *work);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <net/dst_metadata.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_macvlan.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
@ -409,6 +410,13 @@ static void mlx5e_rep_indr_block_unbind(void *cb_priv)
|
||||
|
||||
static LIST_HEAD(mlx5e_block_cb_list);
|
||||
|
||||
static bool mlx5e_rep_macvlan_mode_supported(const struct net_device *dev)
|
||||
{
|
||||
struct macvlan_dev *macvlan = netdev_priv(dev);
|
||||
|
||||
return macvlan->mode == MACVLAN_MODE_PASSTHRU;
|
||||
}
|
||||
|
||||
static int
|
||||
mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch,
|
||||
struct mlx5e_rep_priv *rpriv,
|
||||
@ -422,8 +430,14 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch,
|
||||
struct flow_block_cb *block_cb;
|
||||
|
||||
if (!mlx5e_tc_tun_device_to_offload(priv, netdev) &&
|
||||
!(is_vlan_dev(netdev) && vlan_dev_real_dev(netdev) == rpriv->netdev))
|
||||
return -EOPNOTSUPP;
|
||||
!(is_vlan_dev(netdev) && vlan_dev_real_dev(netdev) == rpriv->netdev)) {
|
||||
if (!(netif_is_macvlan(netdev) && macvlan_dev_real_dev(netdev) == rpriv->netdev))
|
||||
return -EOPNOTSUPP;
|
||||
if (!mlx5e_rep_macvlan_mode_supported(netdev)) {
|
||||
netdev_warn(netdev, "Offloading ingress filter is supported only with macvlan passthru mode");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
|
||||
return -EOPNOTSUPP;
|
||||
@ -647,9 +661,7 @@ static void mlx5e_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *sk
|
||||
"Failed to restore tunnel info for sampled packet\n");
|
||||
return;
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
mlx5e_tc_sample_skb(skb, mapped_obj);
|
||||
#endif /* CONFIG_MLX5_TC_SAMPLE */
|
||||
mlx5_rep_tc_post_napi_receive(tc_priv);
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
|
||||
static int mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
|
||||
{
|
||||
int err;
|
||||
|
||||
@ -399,6 +399,7 @@ static void mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_r
|
||||
if (err)
|
||||
mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to channels: err = %d\n",
|
||||
mlx5e_rqt_get_rqtn(&rss->rqt), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
|
||||
@ -490,6 +491,14 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
|
||||
{
|
||||
bool changed_indir = false;
|
||||
bool changed_hash = false;
|
||||
struct mlx5e_rss *old_rss;
|
||||
int err = 0;
|
||||
|
||||
old_rss = mlx5e_rss_alloc();
|
||||
if (!old_rss)
|
||||
return -ENOMEM;
|
||||
|
||||
*old_rss = *rss;
|
||||
|
||||
if (hfunc && *hfunc != rss->hash.hfunc) {
|
||||
switch (*hfunc) {
|
||||
@ -497,7 +506,8 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
|
||||
case ETH_RSS_HASH_TOP:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
changed_hash = true;
|
||||
changed_indir = true;
|
||||
@ -520,13 +530,20 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
|
||||
rss->indir.table[i] = indir[i];
|
||||
}
|
||||
|
||||
if (changed_indir && rss->enabled)
|
||||
mlx5e_rss_apply(rss, rqns, num_rqns);
|
||||
if (changed_indir && rss->enabled) {
|
||||
err = mlx5e_rss_apply(rss, rqns, num_rqns);
|
||||
if (err) {
|
||||
*rss = *old_rss;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed_hash)
|
||||
mlx5e_rss_update_tirs(rss);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
mlx5e_rss_free(old_rss);
|
||||
return err;
|
||||
}
|
||||
|
||||
struct mlx5e_rss_params_hash mlx5e_rss_get_hash(struct mlx5e_rss *rss)
|
||||
|
@ -19,6 +19,8 @@ struct mlx5e_sample_attr {
|
||||
struct mlx5e_sample_flow *sample_flow;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
|
||||
void mlx5e_tc_sample_skb(struct sk_buff *skb, struct mlx5_mapped_obj *mapped_obj);
|
||||
|
||||
struct mlx5_flow_handle *
|
||||
@ -38,4 +40,29 @@ mlx5e_tc_sample_init(struct mlx5_eswitch *esw, struct mlx5e_post_act *post_act);
|
||||
void
|
||||
mlx5e_tc_sample_cleanup(struct mlx5e_tc_psample *tc_psample);
|
||||
|
||||
#else /* CONFIG_MLX5_TC_SAMPLE */
|
||||
|
||||
static inline struct mlx5_flow_handle *
|
||||
mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
|
||||
struct mlx5_flow_spec *spec,
|
||||
struct mlx5_flow_attr *attr,
|
||||
u32 tunnel_id)
|
||||
{ return ERR_PTR(-EOPNOTSUPP); }
|
||||
|
||||
static inline void
|
||||
mlx5e_tc_sample_unoffload(struct mlx5e_tc_psample *tc_psample,
|
||||
struct mlx5_flow_handle *rule,
|
||||
struct mlx5_flow_attr *attr) {}
|
||||
|
||||
static inline struct mlx5e_tc_psample *
|
||||
mlx5e_tc_sample_init(struct mlx5_eswitch *esw, struct mlx5e_post_act *post_act)
|
||||
{ return ERR_PTR(-EOPNOTSUPP); }
|
||||
|
||||
static inline void
|
||||
mlx5e_tc_sample_cleanup(struct mlx5e_tc_psample *tc_psample) {}
|
||||
|
||||
static inline void
|
||||
mlx5e_tc_sample_skb(struct sk_buff *skb, struct mlx5_mapped_obj *mapped_obj) {}
|
||||
|
||||
#endif /* CONFIG_MLX5_TC_SAMPLE */
|
||||
#endif /* __MLX5_EN_TC_SAMPLE_H__ */
|
||||
|
@ -267,9 +267,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
|
||||
break;
|
||||
|
||||
case ETH_SS_TEST:
|
||||
for (i = 0; i < mlx5e_self_test_num(priv); i++)
|
||||
strcpy(data + i * ETH_GSTRING_LEN,
|
||||
mlx5e_self_tests[i]);
|
||||
mlx5e_self_test_fill_strings(priv, data);
|
||||
break;
|
||||
|
||||
case ETH_SS_STATS:
|
||||
|
@ -35,30 +35,7 @@
|
||||
#include <net/udp.h>
|
||||
#include "en.h"
|
||||
#include "en/port.h"
|
||||
|
||||
enum {
|
||||
MLX5E_ST_LINK_STATE,
|
||||
MLX5E_ST_LINK_SPEED,
|
||||
MLX5E_ST_HEALTH_INFO,
|
||||
#ifdef CONFIG_INET
|
||||
MLX5E_ST_LOOPBACK,
|
||||
#endif
|
||||
MLX5E_ST_NUM,
|
||||
};
|
||||
|
||||
const char mlx5e_self_tests[MLX5E_ST_NUM][ETH_GSTRING_LEN] = {
|
||||
"Link Test",
|
||||
"Speed Test",
|
||||
"Health Test",
|
||||
#ifdef CONFIG_INET
|
||||
"Loopback Test",
|
||||
#endif
|
||||
};
|
||||
|
||||
int mlx5e_self_test_num(struct mlx5e_priv *priv)
|
||||
{
|
||||
return ARRAY_SIZE(mlx5e_self_tests);
|
||||
}
|
||||
#include "eswitch.h"
|
||||
|
||||
static int mlx5e_test_health_info(struct mlx5e_priv *priv)
|
||||
{
|
||||
@ -265,6 +242,14 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
|
||||
mlx5e_refresh_tirs(priv, false, false);
|
||||
}
|
||||
|
||||
static int mlx5e_cond_loopback(struct mlx5e_priv *priv)
|
||||
{
|
||||
if (is_mdev_switchdev_mode(priv->mdev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MLX5E_LB_VERIFY_TIMEOUT (msecs_to_jiffies(200))
|
||||
static int mlx5e_test_loopback(struct mlx5e_priv *priv)
|
||||
{
|
||||
@ -313,37 +298,47 @@ out:
|
||||
}
|
||||
#endif
|
||||
|
||||
static int (*mlx5e_st_func[MLX5E_ST_NUM])(struct mlx5e_priv *) = {
|
||||
mlx5e_test_link_state,
|
||||
mlx5e_test_link_speed,
|
||||
mlx5e_test_health_info,
|
||||
typedef int (*mlx5e_st_func)(struct mlx5e_priv *);
|
||||
|
||||
struct mlx5e_st {
|
||||
char name[ETH_GSTRING_LEN];
|
||||
mlx5e_st_func st_func;
|
||||
mlx5e_st_func cond_func;
|
||||
};
|
||||
|
||||
static struct mlx5e_st mlx5e_sts[] = {
|
||||
{ "Link Test", mlx5e_test_link_state },
|
||||
{ "Speed Test", mlx5e_test_link_speed },
|
||||
{ "Health Test", mlx5e_test_health_info },
|
||||
#ifdef CONFIG_INET
|
||||
mlx5e_test_loopback,
|
||||
{ "Loopback Test", mlx5e_test_loopback, mlx5e_cond_loopback },
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MLX5E_ST_NUM ARRAY_SIZE(mlx5e_sts)
|
||||
|
||||
void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
|
||||
u64 *buf)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(ndev);
|
||||
int i;
|
||||
|
||||
memset(buf, 0, sizeof(u64) * MLX5E_ST_NUM);
|
||||
int i, count = 0;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
netdev_info(ndev, "Self test begin..\n");
|
||||
|
||||
for (i = 0; i < MLX5E_ST_NUM; i++) {
|
||||
netdev_info(ndev, "\t[%d] %s start..\n",
|
||||
i, mlx5e_self_tests[i]);
|
||||
buf[i] = mlx5e_st_func[i](priv);
|
||||
netdev_info(ndev, "\t[%d] %s end: result(%lld)\n",
|
||||
i, mlx5e_self_tests[i], buf[i]);
|
||||
struct mlx5e_st st = mlx5e_sts[i];
|
||||
|
||||
if (st.cond_func && st.cond_func(priv))
|
||||
continue;
|
||||
netdev_info(ndev, "\t[%d] %s start..\n", i, st.name);
|
||||
buf[count] = st.st_func(priv);
|
||||
netdev_info(ndev, "\t[%d] %s end: result(%lld)\n", i, st.name, buf[count]);
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->state_lock);
|
||||
|
||||
for (i = 0; i < MLX5E_ST_NUM; i++) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (buf[i]) {
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
break;
|
||||
@ -352,3 +347,24 @@ void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
|
||||
netdev_info(ndev, "Self test out: status flags(0x%x)\n",
|
||||
etest->flags);
|
||||
}
|
||||
|
||||
int mlx5e_self_test_fill_strings(struct mlx5e_priv *priv, u8 *data)
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
for (i = 0; i < MLX5E_ST_NUM; i++) {
|
||||
struct mlx5e_st st = mlx5e_sts[i];
|
||||
|
||||
if (st.cond_func && st.cond_func(priv))
|
||||
continue;
|
||||
if (data)
|
||||
strcpy(data + count * ETH_GSTRING_LEN, st.name);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int mlx5e_self_test_num(struct mlx5e_priv *priv)
|
||||
{
|
||||
return mlx5e_self_test_fill_strings(priv, NULL);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <linux/rhashtable.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/if_macvlan.h>
|
||||
#include <net/tc_act/tc_pedit.h>
|
||||
#include <net/tc_act/tc_csum.h>
|
||||
#include <net/psample.h>
|
||||
@ -246,7 +247,6 @@ get_ct_priv(struct mlx5e_priv *priv)
|
||||
return priv->fs.tc.ct;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
static struct mlx5e_tc_psample *
|
||||
get_sample_priv(struct mlx5e_priv *priv)
|
||||
{
|
||||
@ -263,7 +263,6 @@ get_sample_priv(struct mlx5e_priv *priv)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct mlx5_flow_handle *
|
||||
mlx5_tc_rule_insert(struct mlx5e_priv *priv,
|
||||
@ -1146,11 +1145,9 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
|
||||
rule = mlx5_tc_ct_flow_offload(get_ct_priv(flow->priv),
|
||||
flow, spec, attr,
|
||||
mod_hdr_acts);
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
} else if (flow_flag_test(flow, SAMPLE)) {
|
||||
rule = mlx5e_tc_sample_offload(get_sample_priv(flow->priv), spec, attr,
|
||||
mlx5e_tc_get_flow_tun_id(flow));
|
||||
#endif
|
||||
} else {
|
||||
rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
|
||||
}
|
||||
@ -1186,12 +1183,10 @@ void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
|
||||
return;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
if (flow_flag_test(flow, SAMPLE)) {
|
||||
mlx5e_tc_sample_unoffload(get_sample_priv(flow->priv), flow->rule[0], attr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (attr->esw_attr->split_count)
|
||||
mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr);
|
||||
@ -1688,8 +1683,8 @@ enc_opts_is_dont_care_or_full_match(struct mlx5e_priv *priv,
|
||||
|
||||
if (opt->opt_class != htons(U16_MAX) ||
|
||||
opt->type != U8_MAX) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Partial match of tunnel options in chain > 0 isn't supported");
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Partial match of tunnel options in chain > 0 isn't supported");
|
||||
netdev_warn(priv->netdev,
|
||||
"Partial match of tunnel options in chain > 0 isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
@ -1905,8 +1900,8 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
|
||||
|
||||
if ((needs_mapping || sets_mapping) &&
|
||||
!mlx5_eswitch_reg_c1_loopback_enabled(esw)) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Chains on tunnel devices isn't supported without register loopback support");
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Chains on tunnel devices isn't supported without register loopback support");
|
||||
netdev_warn(priv->netdev,
|
||||
"Chains on tunnel devices isn't supported without register loopback support");
|
||||
return -EOPNOTSUPP;
|
||||
@ -2910,8 +2905,7 @@ out_err:
|
||||
}
|
||||
|
||||
static int
|
||||
parse_pedit_to_reformat(struct mlx5e_priv *priv,
|
||||
const struct flow_action_entry *act,
|
||||
parse_pedit_to_reformat(const struct flow_action_entry *act,
|
||||
struct mlx5e_tc_flow_parse_attr *parse_attr,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@ -2943,7 +2937,7 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flow && flow_flag_test(flow, L3_TO_L2_DECAP))
|
||||
return parse_pedit_to_reformat(priv, act, parse_attr, extack);
|
||||
return parse_pedit_to_reformat(act, parse_attr, extack);
|
||||
|
||||
return parse_pedit_to_modify_hdr(priv, act, namespace,
|
||||
parse_attr, hdrs, extack);
|
||||
@ -3025,10 +3019,10 @@ struct ipv6_hoplimit_word {
|
||||
__u8 hop_limit;
|
||||
};
|
||||
|
||||
static int is_action_keys_supported(const struct flow_action_entry *act,
|
||||
bool ct_flow, bool *modify_ip_header,
|
||||
bool *modify_tuple,
|
||||
struct netlink_ext_ack *extack)
|
||||
static bool
|
||||
is_action_keys_supported(const struct flow_action_entry *act, bool ct_flow,
|
||||
bool *modify_ip_header, bool *modify_tuple,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
u32 mask, offset;
|
||||
u8 htype;
|
||||
@ -3056,7 +3050,7 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
|
||||
if (ct_flow && *modify_tuple) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"can't offload re-write of ipv4 address with action ct");
|
||||
return -EOPNOTSUPP;
|
||||
return false;
|
||||
}
|
||||
} else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) {
|
||||
struct ipv6_hoplimit_word *hoplimit_word =
|
||||
@ -3074,7 +3068,7 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
|
||||
if (ct_flow && *modify_tuple) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"can't offload re-write of ipv6 address with action ct");
|
||||
return -EOPNOTSUPP;
|
||||
return false;
|
||||
}
|
||||
} else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP ||
|
||||
htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP) {
|
||||
@ -3082,11 +3076,11 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
|
||||
if (ct_flow) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"can't offload re-write of transport header ports with action ct");
|
||||
return -EOPNOTSUPP;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool modify_tuple_supported(bool modify_tuple, bool ct_clear,
|
||||
@ -3133,7 +3127,7 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv,
|
||||
void *headers_v;
|
||||
u16 ethertype;
|
||||
u8 ip_proto;
|
||||
int i, err;
|
||||
int i;
|
||||
|
||||
headers_c = get_match_headers_criteria(actions, spec);
|
||||
headers_v = get_match_headers_value(actions, spec);
|
||||
@ -3151,11 +3145,10 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv,
|
||||
act->id != FLOW_ACTION_ADD)
|
||||
continue;
|
||||
|
||||
err = is_action_keys_supported(act, ct_flow,
|
||||
&modify_ip_header,
|
||||
&modify_tuple, extack);
|
||||
if (err)
|
||||
return err;
|
||||
if (!is_action_keys_supported(act, ct_flow,
|
||||
&modify_ip_header,
|
||||
&modify_tuple, extack))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!modify_tuple_supported(modify_tuple, ct_clear, ct_flow, extack,
|
||||
@ -3190,6 +3183,12 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
|
||||
ct_flow = flow_flag_test(flow, CT) && !ct_clear;
|
||||
actions = flow->attr->action;
|
||||
|
||||
if (!(actions &
|
||||
(MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Rule must have at least one forward/drop action");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mlx5e_is_eswitch_flow(flow)) {
|
||||
if (flow->attr->esw_attr->split_count && ct_flow &&
|
||||
!MLX5_CAP_GEN(flow->attr->esw_attr->in_mdev, reg_c_preserve)) {
|
||||
@ -3451,7 +3450,8 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
|
||||
action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
|
||||
MLX5_FLOW_CONTEXT_ACTION_COUNT;
|
||||
attr->dest_chain = act->chain_index;
|
||||
break;
|
||||
case FLOW_ACTION_CT:
|
||||
@ -3484,17 +3484,11 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
|
||||
|
||||
attr->action = action;
|
||||
|
||||
if (attr->dest_chain) {
|
||||
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
|
||||
NL_SET_ERR_MSG(extack, "Mirroring goto chain rules isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||
if (attr->dest_chain && parse_attr->mirred_ifindex[0]) {
|
||||
NL_SET_ERR_MSG(extack, "Mirroring goto chain rules isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
|
||||
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||
|
||||
if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@ -3914,6 +3908,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (netif_is_macvlan(out_dev))
|
||||
out_dev = macvlan_dev_real_dev(out_dev);
|
||||
|
||||
err = verify_uplink_forwarding(priv, flow, out_dev, extack);
|
||||
if (err)
|
||||
return err;
|
||||
@ -3998,7 +3995,8 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
|
||||
action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
|
||||
MLX5_FLOW_CONTEXT_ACTION_COUNT;
|
||||
attr->dest_chain = act->chain_index;
|
||||
break;
|
||||
case FLOW_ACTION_CT:
|
||||
@ -4068,30 +4066,17 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (attr->dest_chain) {
|
||||
if (decap) {
|
||||
/* It can be supported if we'll create a mapping for
|
||||
* the tunnel device only (without tunnel), and set
|
||||
* this tunnel id with this decap flow.
|
||||
*
|
||||
* On restore (miss), we'll just set this saved tunnel
|
||||
* device.
|
||||
*/
|
||||
if (attr->dest_chain && decap) {
|
||||
/* It can be supported if we'll create a mapping for
|
||||
* the tunnel device only (without tunnel), and set
|
||||
* this tunnel id with this decap flow.
|
||||
*
|
||||
* On restore (miss), we'll just set this saved tunnel
|
||||
* device.
|
||||
*/
|
||||
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Decap with goto isn't supported");
|
||||
netdev_warn(priv->netdev,
|
||||
"Decap with goto isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||
}
|
||||
|
||||
if (!(attr->action &
|
||||
(MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Rule must have at least one forward/drop action");
|
||||
NL_SET_ERR_MSG(extack, "Decap with goto isn't supported");
|
||||
netdev_warn(priv->netdev, "Decap with goto isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@ -5006,9 +4991,7 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
|
||||
MLX5_FLOW_NAMESPACE_FDB,
|
||||
uplink_priv->post_act);
|
||||
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
uplink_priv->tc_psample = mlx5e_tc_sample_init(esw, uplink_priv->post_act);
|
||||
#endif
|
||||
|
||||
mapping_id = mlx5_query_nic_system_image_guid(esw->dev);
|
||||
|
||||
@ -5052,9 +5035,7 @@ err_ht_init:
|
||||
err_enc_opts_mapping:
|
||||
mapping_destroy(uplink_priv->tunnel_mapping);
|
||||
err_tun_mapping:
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
|
||||
#endif
|
||||
mlx5_tc_ct_clean(uplink_priv->ct_priv);
|
||||
netdev_warn(priv->netdev,
|
||||
"Failed to initialize tc (eswitch), err: %d", err);
|
||||
@ -5074,9 +5055,7 @@ void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht)
|
||||
mapping_destroy(uplink_priv->tunnel_enc_opts_mapping);
|
||||
mapping_destroy(uplink_priv->tunnel_mapping);
|
||||
|
||||
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
|
||||
mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
|
||||
#endif
|
||||
mlx5_tc_ct_clean(uplink_priv->ct_priv);
|
||||
mlx5e_tc_post_act_destroy(uplink_priv->post_act);
|
||||
}
|
||||
|
@ -1791,7 +1791,7 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
misc->source_eswitch_owner_vhca_id = 0;
|
||||
misc->source_eswitch_owner_vhca_id = 0;
|
||||
} else {
|
||||
caps = &dmn->info.caps;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user