From: Eli Britstein <el...@mellanox.com>

Upon redirection to an uplink VLAN device, emulate vlan push actions
according to the VLAN properties of the VLAN device and redirect to
the uplink.

Signed-off-by: Eli Britstein <el...@mellanox.com>
Reviewed-by: Roi Dayan <r...@mellanox.com>
Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_tc.c   | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 1304cb07e319..3689ee72b8e2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2582,6 +2582,32 @@ static int parse_tc_vlan_action(struct mlx5e_priv *priv,
        return 0;
 }
 
+static int add_vlan_push_action(struct mlx5e_priv *priv,
+                               struct mlx5_esw_flow_attr *attr,
+                               struct net_device **out_dev,
+                               u32 *action)
+{
+       struct net_device *vlan_dev = *out_dev;
+       struct flow_action_entry vlan_act = {
+               .id = FLOW_ACTION_VLAN_PUSH,
+               .vlan.vid = vlan_dev_vlan_id(vlan_dev),
+               .vlan.proto = vlan_dev_vlan_proto(vlan_dev),
+               .vlan.prio = 0,
+       };
+       int err;
+
+       err = parse_tc_vlan_action(priv, &vlan_act, attr, action);
+       if (err)
+               return err;
+
+       *out_dev = dev_get_by_index_rcu(dev_net(vlan_dev),
+                                       dev_get_iflink(vlan_dev));
+       if (is_vlan_dev(*out_dev))
+               err = add_vlan_push_action(priv, attr, out_dev, action);
+
+       return err;
+}
+
 static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                struct flow_action *flow_action,
                                struct mlx5e_tc_flow *flow,
@@ -2662,6 +2688,14 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                                    uplink_upper == out_dev)
                                        out_dev = uplink_dev;
 
+                               if (is_vlan_dev(out_dev)) {
+                                       err = add_vlan_push_action(priv, attr,
+                                                                  &out_dev,
+                                                                  &action);
+                                       if (err)
+                                               return err;
+                               }
+
                                if (!mlx5e_eswitch_rep(out_dev))
                                        return -EOPNOTSUPP;
 
-- 
2.20.1

Reply via email to