Commit 8765de69 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents acde891c 05000bbb
...@@ -220,8 +220,6 @@ struct mlx5e_umr_wqe { ...@@ -220,8 +220,6 @@ struct mlx5e_umr_wqe {
struct mlx5_mtt inline_mtts[0]; struct mlx5_mtt inline_mtts[0];
}; };
extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];
enum mlx5e_priv_flag { enum mlx5e_priv_flag {
MLX5E_PFLAG_RX_CQE_BASED_MODER, MLX5E_PFLAG_RX_CQE_BASED_MODER,
MLX5E_PFLAG_TX_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) ...@@ -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); void mlx5e_init_l2_addr(struct mlx5e_priv *priv);
int mlx5e_self_test_num(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, void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
u64 *buf); u64 *buf);
void mlx5e_set_rx_mode_work(struct work_struct *work); void mlx5e_set_rx_mode_work(struct work_struct *work);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <net/dst_metadata.h> #include <net/dst_metadata.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_macvlan.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
...@@ -409,6 +410,13 @@ static void mlx5e_rep_indr_block_unbind(void *cb_priv) ...@@ -409,6 +410,13 @@ static void mlx5e_rep_indr_block_unbind(void *cb_priv)
static LIST_HEAD(mlx5e_block_cb_list); 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 static int
mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch, mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch,
struct mlx5e_rep_priv *rpriv, struct mlx5e_rep_priv *rpriv,
...@@ -422,8 +430,14 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch, ...@@ -422,8 +430,14 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch,
struct flow_block_cb *block_cb; struct flow_block_cb *block_cb;
if (!mlx5e_tc_tun_device_to_offload(priv, netdev) && if (!mlx5e_tc_tun_device_to_offload(priv, netdev) &&
!(is_vlan_dev(netdev) && vlan_dev_real_dev(netdev) == rpriv->netdev)) !(is_vlan_dev(netdev) && vlan_dev_real_dev(netdev) == rpriv->netdev)) {
return -EOPNOTSUPP; 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) if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -647,9 +661,7 @@ static void mlx5e_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *sk ...@@ -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"); "Failed to restore tunnel info for sampled packet\n");
return; return;
} }
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
mlx5e_tc_sample_skb(skb, mapped_obj); mlx5e_tc_sample_skb(skb, mapped_obj);
#endif /* CONFIG_MLX5_TC_SAMPLE */
mlx5_rep_tc_post_napi_receive(tc_priv); mlx5_rep_tc_post_napi_receive(tc_priv);
} }
......
...@@ -391,7 +391,7 @@ int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss, ...@@ -391,7 +391,7 @@ int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
return 0; 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; int err;
...@@ -399,6 +399,7 @@ static void mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_r ...@@ -399,6 +399,7 @@ static void mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_r
if (err) if (err)
mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to channels: err = %d\n", mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to channels: err = %d\n",
mlx5e_rqt_get_rqtn(&rss->rqt), err); mlx5e_rqt_get_rqtn(&rss->rqt), err);
return err;
} }
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns) 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, ...@@ -490,6 +491,14 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
{ {
bool changed_indir = false; bool changed_indir = false;
bool changed_hash = 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) { if (hfunc && *hfunc != rss->hash.hfunc) {
switch (*hfunc) { switch (*hfunc) {
...@@ -497,7 +506,8 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir, ...@@ -497,7 +506,8 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
case ETH_RSS_HASH_TOP: case ETH_RSS_HASH_TOP:
break; break;
default: default:
return -EINVAL; err = -EINVAL;
goto out;
} }
changed_hash = true; changed_hash = true;
changed_indir = true; changed_indir = true;
...@@ -520,13 +530,20 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir, ...@@ -520,13 +530,20 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
rss->indir.table[i] = indir[i]; rss->indir.table[i] = indir[i];
} }
if (changed_indir && rss->enabled) if (changed_indir && rss->enabled) {
mlx5e_rss_apply(rss, rqns, num_rqns); err = mlx5e_rss_apply(rss, rqns, num_rqns);
if (err) {
*rss = *old_rss;
goto out;
}
}
if (changed_hash) if (changed_hash)
mlx5e_rss_update_tirs(rss); 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) struct mlx5e_rss_params_hash mlx5e_rss_get_hash(struct mlx5e_rss *rss)
......
...@@ -19,6 +19,8 @@ struct mlx5e_sample_attr { ...@@ -19,6 +19,8 @@ struct mlx5e_sample_attr {
struct mlx5e_sample_flow *sample_flow; 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); void mlx5e_tc_sample_skb(struct sk_buff *skb, struct mlx5_mapped_obj *mapped_obj);
struct mlx5_flow_handle * struct mlx5_flow_handle *
...@@ -38,4 +40,29 @@ mlx5e_tc_sample_init(struct mlx5_eswitch *esw, struct mlx5e_post_act *post_act); ...@@ -38,4 +40,29 @@ mlx5e_tc_sample_init(struct mlx5_eswitch *esw, struct mlx5e_post_act *post_act);
void void
mlx5e_tc_sample_cleanup(struct mlx5e_tc_psample *tc_psample); 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__ */ #endif /* __MLX5_EN_TC_SAMPLE_H__ */
...@@ -267,9 +267,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data) ...@@ -267,9 +267,7 @@ void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
break; break;
case ETH_SS_TEST: case ETH_SS_TEST:
for (i = 0; i < mlx5e_self_test_num(priv); i++) mlx5e_self_test_fill_strings(priv, data);
strcpy(data + i * ETH_GSTRING_LEN,
mlx5e_self_tests[i]);
break; break;
case ETH_SS_STATS: case ETH_SS_STATS:
......
...@@ -35,30 +35,7 @@ ...@@ -35,30 +35,7 @@
#include <net/udp.h> #include <net/udp.h>
#include "en.h" #include "en.h"
#include "en/port.h" #include "en/port.h"
#include "eswitch.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);
}
static int mlx5e_test_health_info(struct mlx5e_priv *priv) static int mlx5e_test_health_info(struct mlx5e_priv *priv)
{ {
...@@ -265,6 +242,14 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv, ...@@ -265,6 +242,14 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
mlx5e_refresh_tirs(priv, false, false); 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)) #define MLX5E_LB_VERIFY_TIMEOUT (msecs_to_jiffies(200))
static int mlx5e_test_loopback(struct mlx5e_priv *priv) static int mlx5e_test_loopback(struct mlx5e_priv *priv)
{ {
...@@ -313,37 +298,47 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv) ...@@ -313,37 +298,47 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv)
} }
#endif #endif
static int (*mlx5e_st_func[MLX5E_ST_NUM])(struct mlx5e_priv *) = { typedef int (*mlx5e_st_func)(struct mlx5e_priv *);
mlx5e_test_link_state,
mlx5e_test_link_speed, struct mlx5e_st {
mlx5e_test_health_info, 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 #ifdef CONFIG_INET
mlx5e_test_loopback, { "Loopback Test", mlx5e_test_loopback, mlx5e_cond_loopback },
#endif #endif
}; };
#define MLX5E_ST_NUM ARRAY_SIZE(mlx5e_sts)
void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest, void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
u64 *buf) u64 *buf)
{ {
struct mlx5e_priv *priv = netdev_priv(ndev); struct mlx5e_priv *priv = netdev_priv(ndev);
int i; int i, count = 0;
memset(buf, 0, sizeof(u64) * MLX5E_ST_NUM);
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
netdev_info(ndev, "Self test begin..\n"); netdev_info(ndev, "Self test begin..\n");
for (i = 0; i < MLX5E_ST_NUM; i++) { for (i = 0; i < MLX5E_ST_NUM; i++) {
netdev_info(ndev, "\t[%d] %s start..\n", struct mlx5e_st st = mlx5e_sts[i];
i, mlx5e_self_tests[i]);
buf[i] = mlx5e_st_func[i](priv); if (st.cond_func && st.cond_func(priv))
netdev_info(ndev, "\t[%d] %s end: result(%lld)\n", continue;
i, mlx5e_self_tests[i], buf[i]); 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); mutex_unlock(&priv->state_lock);
for (i = 0; i < MLX5E_ST_NUM; i++) { for (i = 0; i < count; i++) {
if (buf[i]) { if (buf[i]) {
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
break; break;
...@@ -352,3 +347,24 @@ void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest, ...@@ -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", netdev_info(ndev, "Self test out: status flags(0x%x)\n",
etest->flags); 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 @@ ...@@ -39,6 +39,7 @@
#include <linux/rhashtable.h> #include <linux/rhashtable.h>
#include <linux/refcount.h> #include <linux/refcount.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/if_macvlan.h>
#include <net/tc_act/tc_pedit.h> #include <net/tc_act/tc_pedit.h>
#include <net/tc_act/tc_csum.h> #include <net/tc_act/tc_csum.h>
#include <net/psample.h> #include <net/psample.h>
...@@ -246,7 +247,6 @@ get_ct_priv(struct mlx5e_priv *priv) ...@@ -246,7 +247,6 @@ get_ct_priv(struct mlx5e_priv *priv)
return priv->fs.tc.ct; return priv->fs.tc.ct;
} }
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
static struct mlx5e_tc_psample * static struct mlx5e_tc_psample *
get_sample_priv(struct mlx5e_priv *priv) get_sample_priv(struct mlx5e_priv *priv)
{ {
...@@ -263,7 +263,6 @@ get_sample_priv(struct mlx5e_priv *priv) ...@@ -263,7 +263,6 @@ get_sample_priv(struct mlx5e_priv *priv)
return NULL; return NULL;
} }
#endif
struct mlx5_flow_handle * struct mlx5_flow_handle *
mlx5_tc_rule_insert(struct mlx5e_priv *priv, mlx5_tc_rule_insert(struct mlx5e_priv *priv,
...@@ -1146,11 +1145,9 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw, ...@@ -1146,11 +1145,9 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
rule = mlx5_tc_ct_flow_offload(get_ct_priv(flow->priv), rule = mlx5_tc_ct_flow_offload(get_ct_priv(flow->priv),
flow, spec, attr, flow, spec, attr,
mod_hdr_acts); mod_hdr_acts);
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
} else if (flow_flag_test(flow, SAMPLE)) { } else if (flow_flag_test(flow, SAMPLE)) {
rule = mlx5e_tc_sample_offload(get_sample_priv(flow->priv), spec, attr, rule = mlx5e_tc_sample_offload(get_sample_priv(flow->priv), spec, attr,
mlx5e_tc_get_flow_tun_id(flow)); mlx5e_tc_get_flow_tun_id(flow));
#endif
} else { } else {
rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr); rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
} }
...@@ -1186,12 +1183,10 @@ void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw, ...@@ -1186,12 +1183,10 @@ void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
return; return;
} }
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
if (flow_flag_test(flow, SAMPLE)) { if (flow_flag_test(flow, SAMPLE)) {
mlx5e_tc_sample_unoffload(get_sample_priv(flow->priv), flow->rule[0], attr); mlx5e_tc_sample_unoffload(get_sample_priv(flow->priv), flow->rule[0], attr);
return; return;
} }
#endif
if (attr->esw_attr->split_count) if (attr->esw_attr->split_count)
mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr); 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, ...@@ -1688,8 +1683,8 @@ enc_opts_is_dont_care_or_full_match(struct mlx5e_priv *priv,
if (opt->opt_class != htons(U16_MAX) || if (opt->opt_class != htons(U16_MAX) ||
opt->type != U8_MAX) { opt->type != U8_MAX) {
NL_SET_ERR_MSG(extack, NL_SET_ERR_MSG_MOD(extack,
"Partial match of tunnel options in chain > 0 isn't supported"); "Partial match of tunnel options in chain > 0 isn't supported");
netdev_warn(priv->netdev, netdev_warn(priv->netdev,
"Partial match of tunnel options in chain > 0 isn't supported"); "Partial match of tunnel options in chain > 0 isn't supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -1905,8 +1900,8 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, ...@@ -1905,8 +1900,8 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
if ((needs_mapping || sets_mapping) && if ((needs_mapping || sets_mapping) &&
!mlx5_eswitch_reg_c1_loopback_enabled(esw)) { !mlx5_eswitch_reg_c1_loopback_enabled(esw)) {
NL_SET_ERR_MSG(extack, NL_SET_ERR_MSG_MOD(extack,
"Chains on tunnel devices isn't supported without register loopback support"); "Chains on tunnel devices isn't supported without register loopback support");
netdev_warn(priv->netdev, netdev_warn(priv->netdev,
"Chains on tunnel devices isn't supported without register loopback support"); "Chains on tunnel devices isn't supported without register loopback support");
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -2910,8 +2905,7 @@ parse_pedit_to_modify_hdr(struct mlx5e_priv *priv, ...@@ -2910,8 +2905,7 @@ parse_pedit_to_modify_hdr(struct mlx5e_priv *priv,
} }
static int static int
parse_pedit_to_reformat(struct mlx5e_priv *priv, parse_pedit_to_reformat(const struct flow_action_entry *act,
const struct flow_action_entry *act,
struct mlx5e_tc_flow_parse_attr *parse_attr, struct mlx5e_tc_flow_parse_attr *parse_attr,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
...@@ -2943,7 +2937,7 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv, ...@@ -2943,7 +2937,7 @@ static int parse_tc_pedit_action(struct mlx5e_priv *priv,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
if (flow && flow_flag_test(flow, L3_TO_L2_DECAP)) 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, return parse_pedit_to_modify_hdr(priv, act, namespace,
parse_attr, hdrs, extack); parse_attr, hdrs, extack);
...@@ -3025,10 +3019,10 @@ struct ipv6_hoplimit_word { ...@@ -3025,10 +3019,10 @@ struct ipv6_hoplimit_word {
__u8 hop_limit; __u8 hop_limit;
}; };
static int is_action_keys_supported(const struct flow_action_entry *act, static bool
bool ct_flow, bool *modify_ip_header, is_action_keys_supported(const struct flow_action_entry *act, bool ct_flow,
bool *modify_tuple, bool *modify_ip_header, bool *modify_tuple,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
u32 mask, offset; u32 mask, offset;
u8 htype; u8 htype;
...@@ -3056,7 +3050,7 @@ static int is_action_keys_supported(const struct flow_action_entry *act, ...@@ -3056,7 +3050,7 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
if (ct_flow && *modify_tuple) { if (ct_flow && *modify_tuple) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"can't offload re-write of ipv4 address with action ct"); "can't offload re-write of ipv4 address with action ct");
return -EOPNOTSUPP; return false;
} }
} else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) { } else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) {
struct ipv6_hoplimit_word *hoplimit_word = struct ipv6_hoplimit_word *hoplimit_word =
...@@ -3074,7 +3068,7 @@ static int is_action_keys_supported(const struct flow_action_entry *act, ...@@ -3074,7 +3068,7 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
if (ct_flow && *modify_tuple) { if (ct_flow && *modify_tuple) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"can't offload re-write of ipv6 address with action ct"); "can't offload re-write of ipv6 address with action ct");
return -EOPNOTSUPP; return false;
} }
} else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP || } else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP ||
htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP) { htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP) {
...@@ -3082,11 +3076,11 @@ static int is_action_keys_supported(const struct flow_action_entry *act, ...@@ -3082,11 +3076,11 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
if (ct_flow) { if (ct_flow) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"can't offload re-write of transport header ports with action ct"); "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, 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, ...@@ -3133,7 +3127,7 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv,
void *headers_v; void *headers_v;
u16 ethertype; u16 ethertype;
u8 ip_proto; u8 ip_proto;
int i, err; int i;
headers_c = get_match_headers_criteria(actions, spec); headers_c = get_match_headers_criteria(actions, spec);
headers_v = get_match_headers_value(actions, spec); headers_v = get_match_headers_value(actions, spec);
...@@ -3151,11 +3145,10 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv, ...@@ -3151,11 +3145,10 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv,
act->id != FLOW_ACTION_ADD) act->id != FLOW_ACTION_ADD)
continue; continue;
err = is_action_keys_supported(act, ct_flow, if (!is_action_keys_supported(act, ct_flow,
&modify_ip_header, &modify_ip_header,
&modify_tuple, extack); &modify_tuple, extack))
if (err) return false;
return err;
} }
if (!modify_tuple_supported(modify_tuple, ct_clear, ct_flow, extack, if (!modify_tuple_supported(modify_tuple, ct_clear, ct_flow, extack,
...@@ -3190,6 +3183,12 @@ static bool actions_match_supported(struct mlx5e_priv *priv, ...@@ -3190,6 +3183,12 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
ct_flow = flow_flag_test(flow, CT) && !ct_clear; ct_flow = flow_flag_test(flow, CT) && !ct_clear;
actions = flow->attr->action; 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 (mlx5e_is_eswitch_flow(flow)) {
if (flow->attr->esw_attr->split_count && ct_flow && if (flow->attr->esw_attr->split_count && ct_flow &&
!MLX5_CAP_GEN(flow->attr->esw_attr->in_mdev, reg_c_preserve)) { !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, ...@@ -3451,7 +3450,8 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
if (err) if (err)
return 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; attr->dest_chain = act->chain_index;
break; break;
case FLOW_ACTION_CT: case FLOW_ACTION_CT:
...@@ -3484,17 +3484,11 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, ...@@ -3484,17 +3484,11 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
attr->action = action; attr->action = action;
if (attr->dest_chain) { if (attr->dest_chain && parse_attr->mirred_ifindex[0]) {
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { NL_SET_ERR_MSG(extack, "Mirroring goto chain rules isn't supported");
NL_SET_ERR_MSG(extack, "Mirroring goto chain rules isn't supported"); return -EOPNOTSUPP;
return -EOPNOTSUPP;
}
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
} }
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)) if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -3914,6 +3908,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ...@@ -3914,6 +3908,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
return err; 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); err = verify_uplink_forwarding(priv, flow, out_dev, extack);
if (err) if (err)
return err; return err;
...@@ -3998,7 +3995,8 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ...@@ -3998,7 +3995,8 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
if (err) if (err)
return 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; attr->dest_chain = act->chain_index;
break; break;
case FLOW_ACTION_CT: case FLOW_ACTION_CT:
...@@ -4068,30 +4066,17 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ...@@ -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)) if (!actions_match_supported(priv, flow_action, parse_attr, flow, extack))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (attr->dest_chain) { if (attr->dest_chain && decap) {
if (decap) { /* It can be supported if we'll create a mapping for
/* It can be supported if we'll create a mapping for * the tunnel device only (without tunnel), and set
* the tunnel device only (without tunnel), and set * this tunnel id with this decap flow.
* this tunnel id with this decap flow. *
* * On restore (miss), we'll just set this saved tunnel
* On restore (miss), we'll just set this saved tunnel * device.
* 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 & NL_SET_ERR_MSG(extack, "Decap with goto isn't supported");
(MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) { netdev_warn(priv->netdev, "Decap with goto isn't supported");
NL_SET_ERR_MSG_MOD(extack,
"Rule must have at least one forward/drop action");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -5006,9 +4991,7 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht) ...@@ -5006,9 +4991,7 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
MLX5_FLOW_NAMESPACE_FDB, MLX5_FLOW_NAMESPACE_FDB,
uplink_priv->post_act); uplink_priv->post_act);
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
uplink_priv->tc_psample = mlx5e_tc_sample_init(esw, uplink_priv->post_act); uplink_priv->tc_psample = mlx5e_tc_sample_init(esw, uplink_priv->post_act);
#endif
mapping_id = mlx5_query_nic_system_image_guid(esw->dev); mapping_id = mlx5_query_nic_system_image_guid(esw->dev);
...@@ -5052,9 +5035,7 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht) ...@@ -5052,9 +5035,7 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
err_enc_opts_mapping: err_enc_opts_mapping:
mapping_destroy(uplink_priv->tunnel_mapping); mapping_destroy(uplink_priv->tunnel_mapping);
err_tun_mapping: err_tun_mapping:
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
mlx5e_tc_sample_cleanup(uplink_priv->tc_psample); mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
#endif
mlx5_tc_ct_clean(uplink_priv->ct_priv); mlx5_tc_ct_clean(uplink_priv->ct_priv);
netdev_warn(priv->netdev, netdev_warn(priv->netdev,
"Failed to initialize tc (eswitch), err: %d", err); "Failed to initialize tc (eswitch), err: %d", err);
...@@ -5074,9 +5055,7 @@ void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht) ...@@ -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_enc_opts_mapping);
mapping_destroy(uplink_priv->tunnel_mapping); mapping_destroy(uplink_priv->tunnel_mapping);
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
mlx5e_tc_sample_cleanup(uplink_priv->tc_psample); mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
#endif
mlx5_tc_ct_clean(uplink_priv->ct_priv); mlx5_tc_ct_clean(uplink_priv->ct_priv);
mlx5e_tc_post_act_destroy(uplink_priv->post_act); 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, ...@@ -1791,7 +1791,7 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
else else
return -EINVAL; return -EINVAL;
misc->source_eswitch_owner_vhca_id = 0; misc->source_eswitch_owner_vhca_id = 0;
} else { } else {
caps = &dmn->info.caps; caps = &dmn->info.caps;
} }
......
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