Message ID | 1579691703-56363-1-git-send-email-xiangxia.m.yue@gmail.com |
---|---|
State | Changes Requested |
Delegated to: | David Miller |
Headers | show |
Series | [v3] net/mlx5e: Don't allow forwarding between uplink | expand |
Wed, Jan 22, 2020 at 12:15:03PM CET, xiangxia.m.yue@gmail.com wrote: >From: Tonghao Zhang <xiangxia.m.yue@gmail.com> > >We can install forwarding packets rule between uplink >in switchdev mode, as show below. But the hardware does >not do that as expected (mlnx_perf -i $PF1, we can't get >the counter of the PF1). By the way, if we add the uplink >PF0, PF1 to Open vSwitch and enable hw-offload, the rules >can be offloaded but not work fine too. This patch add a >check and if so return -EOPNOTSUPP. > >$ tc filter add dev $PF0 protocol all parent ffff: prio 1 handle 1 \ > flower skip_sw action mirred egress redirect dev $PF1 > >$ tc -d -s filter show dev $PF0 ingress > skip_sw > in_hw in_hw_count 1 > action order 1: mirred (Egress Redirect to device enp130s0f1) stolen > ... > Sent hardware 408954 bytes 4173 pkt > ... > >Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> >--- > drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 5 +++++ > drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 1 + > drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 19 +++++++++++++++++++ > 3 files changed, 25 insertions(+) > >diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >index f175cb2..ac2a035 100644 >--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >@@ -1434,6 +1434,11 @@ static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev) > .ndo_set_features = mlx5e_set_features, > }; > >+bool mlx5e_eswitch_uplink_rep(struct net_device *netdev) >+{ >+ return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep; >+} >+ > bool mlx5e_eswitch_rep(struct net_device *netdev) > { > if (netdev->netdev_ops == &mlx5e_netdev_ops_rep || >diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >index 31f83c8..5211819 100644 >--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >@@ -199,6 +199,7 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, > void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); > > bool mlx5e_eswitch_rep(struct net_device *netdev); >+bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); > > #else /* CONFIG_MLX5_ESWITCH */ > static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } >diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >index db614bd..35f68e4 100644 >--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >@@ -3361,6 +3361,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, > struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; > struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); > struct net_device *uplink_upper; >+ struct mlx5e_rep_priv *rep_priv; > > if (is_duplicated_output_device(priv->netdev, > out_dev, >@@ -3396,6 +3397,24 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, > return err; > } > >+ /* Don't allow forwarding between uplink. >+ * >+ * Input vport was stored esw_attr->in_rep. >+ * In LAG case, *priv* is the private data of >+ * uplink which may be not the input vport. >+ */ >+ rep_priv = mlx5e_rep_to_rep_priv(attr->in_rep); >+ if (mlx5e_eswitch_uplink_rep(rep_priv->netdev) && >+ mlx5e_eswitch_uplink_rep(out_dev)) { >+ NL_SET_ERR_MSG_MOD(extack, >+ "devices are both uplink, " Never break error messages. >+ "can't offload forwarding"); >+ pr_err("devices %s %s are both uplink, " Here as well. >+ "can't offload forwarding\n", >+ priv->netdev->name, out_dev->name); >+ return -EOPNOTSUPP; >+ } >+ > if (!mlx5e_is_valid_eswitch_fwd_dev(priv, out_dev)) { > NL_SET_ERR_MSG_MOD(extack, > "devices are not on same switch HW, can't offload forwarding"); >-- >1.8.3.1 >
On 2020-01-22 3:33 PM, Jiri Pirko wrote: > Wed, Jan 22, 2020 at 12:15:03PM CET, xiangxia.m.yue@gmail.com wrote: >> From: Tonghao Zhang <xiangxia.m.yue@gmail.com> >> >> We can install forwarding packets rule between uplink >> in switchdev mode, as show below. But the hardware does >> not do that as expected (mlnx_perf -i $PF1, we can't get >> the counter of the PF1). By the way, if we add the uplink >> PF0, PF1 to Open vSwitch and enable hw-offload, the rules >> can be offloaded but not work fine too. This patch add a >> check and if so return -EOPNOTSUPP. >> >> $ tc filter add dev $PF0 protocol all parent ffff: prio 1 handle 1 \ >> flower skip_sw action mirred egress redirect dev $PF1 >> >> $ tc -d -s filter show dev $PF0 ingress >> skip_sw >> in_hw in_hw_count 1 >> action order 1: mirred (Egress Redirect to device enp130s0f1) stolen >> ... >> Sent hardware 408954 bytes 4173 pkt >> ... >> >> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> >> --- >> drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 5 +++++ >> drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 1 + >> drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 19 +++++++++++++++++++ >> 3 files changed, 25 insertions(+) >> >> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >> index f175cb2..ac2a035 100644 >> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >> @@ -1434,6 +1434,11 @@ static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev) >> .ndo_set_features = mlx5e_set_features, >> }; >> >> +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev) >> +{ >> + return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep; >> +} >> + >> bool mlx5e_eswitch_rep(struct net_device *netdev) >> { >> if (netdev->netdev_ops == &mlx5e_netdev_ops_rep || >> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >> index 31f83c8..5211819 100644 >> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >> @@ -199,6 +199,7 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, >> void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); >> >> bool mlx5e_eswitch_rep(struct net_device *netdev); >> +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); >> >> #else /* CONFIG_MLX5_ESWITCH */ >> static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } >> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >> index db614bd..35f68e4 100644 >> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >> @@ -3361,6 +3361,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, >> struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; >> struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); >> struct net_device *uplink_upper; >> + struct mlx5e_rep_priv *rep_priv; >> >> if (is_duplicated_output_device(priv->netdev, >> out_dev, >> @@ -3396,6 +3397,24 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, >> return err; >> } >> >> + /* Don't allow forwarding between uplink. >> + * >> + * Input vport was stored esw_attr->in_rep. >> + * In LAG case, *priv* is the private data of >> + * uplink which may be not the input vport. >> + */ >> + rep_priv = mlx5e_rep_to_rep_priv(attr->in_rep); >> + if (mlx5e_eswitch_uplink_rep(rep_priv->netdev) && >> + mlx5e_eswitch_uplink_rep(out_dev)) { >> + NL_SET_ERR_MSG_MOD(extack, >> + "devices are both uplink, " > > Never break error messages. > > >> + "can't offload forwarding"); >> + pr_err("devices %s %s are both uplink, " > > Here as well. > > >> + "can't offload forwarding\n", >> + priv->netdev->name, out_dev->name); >> + return -EOPNOTSUPP; >> + } >> + >> if (!mlx5e_is_valid_eswitch_fwd_dev(priv, out_dev)) { >> NL_SET_ERR_MSG_MOD(extack, >> "devices are not on same switch HW, can't offload forwarding"); >> -- >> 1.8.3.1 >> beside what Jiri commented, the rest looks fine to me.
On 2020-01-29 1:42 PM, Roi Dayan wrote: > > > On 2020-01-22 3:33 PM, Jiri Pirko wrote: >> Wed, Jan 22, 2020 at 12:15:03PM CET, xiangxia.m.yue@gmail.com wrote: >>> From: Tonghao Zhang <xiangxia.m.yue@gmail.com> >>> >>> We can install forwarding packets rule between uplink >>> in switchdev mode, as show below. But the hardware does >>> not do that as expected (mlnx_perf -i $PF1, we can't get >>> the counter of the PF1). By the way, if we add the uplink >>> PF0, PF1 to Open vSwitch and enable hw-offload, the rules >>> can be offloaded but not work fine too. This patch add a >>> check and if so return -EOPNOTSUPP. >>> >>> $ tc filter add dev $PF0 protocol all parent ffff: prio 1 handle 1 \ >>> flower skip_sw action mirred egress redirect dev $PF1 >>> >>> $ tc -d -s filter show dev $PF0 ingress >>> skip_sw >>> in_hw in_hw_count 1 >>> action order 1: mirred (Egress Redirect to device enp130s0f1) stolen >>> ... >>> Sent hardware 408954 bytes 4173 pkt >>> ... >>> >>> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> >>> --- >>> drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 5 +++++ >>> drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 1 + >>> drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 19 +++++++++++++++++++ >>> 3 files changed, 25 insertions(+) >>> >>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >>> index f175cb2..ac2a035 100644 >>> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c >>> @@ -1434,6 +1434,11 @@ static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev) >>> .ndo_set_features = mlx5e_set_features, >>> }; >>> >>> +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev) >>> +{ >>> + return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep; >>> +} >>> + >>> bool mlx5e_eswitch_rep(struct net_device *netdev) >>> { >>> if (netdev->netdev_ops == &mlx5e_netdev_ops_rep || >>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >>> index 31f83c8..5211819 100644 >>> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h >>> @@ -199,6 +199,7 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, >>> void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); >>> >>> bool mlx5e_eswitch_rep(struct net_device *netdev); >>> +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); >>> >>> #else /* CONFIG_MLX5_ESWITCH */ >>> static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } >>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >>> index db614bd..35f68e4 100644 >>> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c >>> @@ -3361,6 +3361,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, >>> struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; >>> struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); >>> struct net_device *uplink_upper; >>> + struct mlx5e_rep_priv *rep_priv; >>> >>> if (is_duplicated_output_device(priv->netdev, >>> out_dev, >>> @@ -3396,6 +3397,24 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, >>> return err; >>> } >>> >>> + /* Don't allow forwarding between uplink. >>> + * >>> + * Input vport was stored esw_attr->in_rep. >>> + * In LAG case, *priv* is the private data of >>> + * uplink which may be not the input vport. >>> + */ >>> + rep_priv = mlx5e_rep_to_rep_priv(attr->in_rep); >>> + if (mlx5e_eswitch_uplink_rep(rep_priv->netdev) && >>> + mlx5e_eswitch_uplink_rep(out_dev)) { >>> + NL_SET_ERR_MSG_MOD(extack, >>> + "devices are both uplink, " >> >> Never break error messages. >> >> >>> + "can't offload forwarding"); >>> + pr_err("devices %s %s are both uplink, " >> >> Here as well. >> >> >>> + "can't offload forwarding\n", >>> + priv->netdev->name, out_dev->name); >>> + return -EOPNOTSUPP; >>> + } >>> + >>> if (!mlx5e_is_valid_eswitch_fwd_dev(priv, out_dev)) { >>> NL_SET_ERR_MSG_MOD(extack, >>> "devices are not on same switch HW, can't offload forwarding"); >>> -- >>> 1.8.3.1 >>> > > beside what Jiri commented, the rest looks fine to me. > Hi Zhang, Are you going to send v4? Thanks, Roi
On Mon, Feb 10, 2020 at 4:15 PM Roi Dayan <roid@mellanox.com> wrote: > > > > On 2020-01-29 1:42 PM, Roi Dayan wrote: > > > > > > On 2020-01-22 3:33 PM, Jiri Pirko wrote: > >> Wed, Jan 22, 2020 at 12:15:03PM CET, xiangxia.m.yue@gmail.com wrote: > >>> From: Tonghao Zhang <xiangxia.m.yue@gmail.com> > >>> > >>> We can install forwarding packets rule between uplink > >>> in switchdev mode, as show below. But the hardware does > >>> not do that as expected (mlnx_perf -i $PF1, we can't get > >>> the counter of the PF1). By the way, if we add the uplink > >>> PF0, PF1 to Open vSwitch and enable hw-offload, the rules > >>> can be offloaded but not work fine too. This patch add a > >>> check and if so return -EOPNOTSUPP. > >>> > >>> $ tc filter add dev $PF0 protocol all parent ffff: prio 1 handle 1 \ > >>> flower skip_sw action mirred egress redirect dev $PF1 > >>> > >>> $ tc -d -s filter show dev $PF0 ingress > >>> skip_sw > >>> in_hw in_hw_count 1 > >>> action order 1: mirred (Egress Redirect to device enp130s0f1) stolen > >>> ... > >>> Sent hardware 408954 bytes 4173 pkt > >>> ... > >>> > >>> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> > >>> --- > >>> drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 5 +++++ > >>> drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 1 + > >>> drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 19 +++++++++++++++++++ > >>> 3 files changed, 25 insertions(+) > >>> > >>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c > >>> index f175cb2..ac2a035 100644 > >>> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c > >>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c > >>> @@ -1434,6 +1434,11 @@ static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev) > >>> .ndo_set_features = mlx5e_set_features, > >>> }; > >>> > >>> +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev) > >>> +{ > >>> + return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep; > >>> +} > >>> + > >>> bool mlx5e_eswitch_rep(struct net_device *netdev) > >>> { > >>> if (netdev->netdev_ops == &mlx5e_netdev_ops_rep || > >>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h > >>> index 31f83c8..5211819 100644 > >>> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h > >>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h > >>> @@ -199,6 +199,7 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, > >>> void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); > >>> > >>> bool mlx5e_eswitch_rep(struct net_device *netdev); > >>> +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); > >>> > >>> #else /* CONFIG_MLX5_ESWITCH */ > >>> static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } > >>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c > >>> index db614bd..35f68e4 100644 > >>> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c > >>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c > >>> @@ -3361,6 +3361,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, > >>> struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; > >>> struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); > >>> struct net_device *uplink_upper; > >>> + struct mlx5e_rep_priv *rep_priv; > >>> > >>> if (is_duplicated_output_device(priv->netdev, > >>> out_dev, > >>> @@ -3396,6 +3397,24 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, > >>> return err; > >>> } > >>> > >>> + /* Don't allow forwarding between uplink. > >>> + * > >>> + * Input vport was stored esw_attr->in_rep. > >>> + * In LAG case, *priv* is the private data of > >>> + * uplink which may be not the input vport. > >>> + */ > >>> + rep_priv = mlx5e_rep_to_rep_priv(attr->in_rep); > >>> + if (mlx5e_eswitch_uplink_rep(rep_priv->netdev) && > >>> + mlx5e_eswitch_uplink_rep(out_dev)) { > >>> + NL_SET_ERR_MSG_MOD(extack, > >>> + "devices are both uplink, " > >> > >> Never break error messages. > >> > >> > >>> + "can't offload forwarding"); > >>> + pr_err("devices %s %s are both uplink, " > >> > >> Here as well. > >> > >> > >>> + "can't offload forwarding\n", > >>> + priv->netdev->name, out_dev->name); > >>> + return -EOPNOTSUPP; > >>> + } > >>> + > >>> if (!mlx5e_is_valid_eswitch_fwd_dev(priv, out_dev)) { > >>> NL_SET_ERR_MSG_MOD(extack, > >>> "devices are not on same switch HW, can't offload forwarding"); > >>> -- > >>> 1.8.3.1 > >>> > > > > beside what Jiri commented, the rest looks fine to me. > > > > Hi Zhang, > > Are you going to send v4? Hi, I am so sorry, reply too later. Holiday ends. v4 is sent. > Thanks, > Roi
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index f175cb2..ac2a035 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -1434,6 +1434,11 @@ static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev) .ndo_set_features = mlx5e_set_features, }; +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev) +{ + return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep; +} + bool mlx5e_eswitch_rep(struct net_device *netdev) { if (netdev->netdev_ops == &mlx5e_netdev_ops_rep || diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h index 31f83c8..5211819 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h @@ -199,6 +199,7 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv, void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv); bool mlx5e_eswitch_rep(struct net_device *netdev); +bool mlx5e_eswitch_uplink_rep(struct net_device *netdev); #else /* CONFIG_MLX5_ESWITCH */ static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index db614bd..35f68e4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -3361,6 +3361,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH); struct net_device *uplink_upper; + struct mlx5e_rep_priv *rep_priv; if (is_duplicated_output_device(priv->netdev, out_dev, @@ -3396,6 +3397,24 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, return err; } + /* Don't allow forwarding between uplink. + * + * Input vport was stored esw_attr->in_rep. + * In LAG case, *priv* is the private data of + * uplink which may be not the input vport. + */ + rep_priv = mlx5e_rep_to_rep_priv(attr->in_rep); + if (mlx5e_eswitch_uplink_rep(rep_priv->netdev) && + mlx5e_eswitch_uplink_rep(out_dev)) { + NL_SET_ERR_MSG_MOD(extack, + "devices are both uplink, " + "can't offload forwarding"); + pr_err("devices %s %s are both uplink, " + "can't offload forwarding\n", + priv->netdev->name, out_dev->name); + return -EOPNOTSUPP; + } + if (!mlx5e_is_valid_eswitch_fwd_dev(priv, out_dev)) { NL_SET_ERR_MSG_MOD(extack, "devices are not on same switch HW, can't offload forwarding");