#define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_TO (MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE / 2 - 1)
 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_FROM \
        (MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_TO + 1)
-#define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO (MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE - 1)
+#define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO (MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE - 2)
+#define MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_FROM \
+       (MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO + 1)
+#define MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_TO (MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE - 1)
 
 #define MLX5_ESW_BRIDGE_SKIP_TABLE_SIZE 0
 
        struct mlx5_flow_table *egress_ft;
        struct mlx5_flow_group *egress_vlan_fg;
        struct mlx5_flow_group *egress_mac_fg;
+       struct mlx5_flow_group *egress_miss_fg;
+       struct mlx5_pkt_reformat *egress_miss_pkt_reformat;
+       struct mlx5_flow_handle *egress_miss_handle;
        unsigned long ageing_time;
        u32 flags;
 };
        return fg;
 }
 
+static struct mlx5_flow_group *
+mlx5_esw_bridge_egress_miss_fg_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *egress_ft)
+{
+       int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+       struct mlx5_flow_group *fg;
+       u32 *in, *match;
+
+       in = kvzalloc(inlen, GFP_KERNEL);
+       if (!in)
+               return ERR_PTR(-ENOMEM);
+
+       MLX5_SET(create_flow_group_in, in, match_criteria_enable, MLX5_MATCH_MISC_PARAMETERS_2);
+       match = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
+
+       MLX5_SET(fte_match_param, match, misc_parameters_2.metadata_reg_c_1, ESW_TUN_MASK);
+
+       MLX5_SET(create_flow_group_in, in, start_flow_index,
+                MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_FROM);
+       MLX5_SET(create_flow_group_in, in, end_flow_index,
+                MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_TO);
+
+       fg = mlx5_create_flow_group(egress_ft, in);
+       if (IS_ERR(fg))
+               esw_warn(esw->dev,
+                        "Failed to create bridge egress table miss flow group (err=%ld)\n",
+                        PTR_ERR(fg));
+       kvfree(in);
+       return fg;
+}
+
 static int
 mlx5_esw_bridge_ingress_table_init(struct mlx5_esw_bridge_offloads *br_offloads)
 {
        br_offloads->ingress_ft = NULL;
 }
 
+static struct mlx5_flow_handle *
+mlx5_esw_bridge_egress_miss_flow_create(struct mlx5_flow_table *egress_ft,
+                                       struct mlx5_flow_table *skip_ft,
+                                       struct mlx5_pkt_reformat *pkt_reformat);
+
 static int
 mlx5_esw_bridge_egress_table_init(struct mlx5_esw_bridge_offloads *br_offloads,
                                  struct mlx5_esw_bridge *bridge)
 {
+       struct mlx5_flow_group *miss_fg = NULL, *mac_fg, *vlan_fg;
+       struct mlx5_pkt_reformat *miss_pkt_reformat = NULL;
+       struct mlx5_flow_handle *miss_handle = NULL;
        struct mlx5_eswitch *esw = br_offloads->esw;
-       struct mlx5_flow_group *mac_fg, *vlan_fg;
        struct mlx5_flow_table *egress_ft;
        int err;
 
                goto err_mac_fg;
        }
 
+       if (mlx5_esw_bridge_pkt_reformat_vlan_pop_supported(esw)) {
+               miss_fg = mlx5_esw_bridge_egress_miss_fg_create(esw, egress_ft);
+               if (IS_ERR(miss_fg)) {
+                       esw_warn(esw->dev, "Failed to create miss flow group (err=%ld)\n",
+                                PTR_ERR(miss_fg));
+                       miss_fg = NULL;
+                       goto skip_miss_flow;
+               }
+
+               miss_pkt_reformat = mlx5_esw_bridge_pkt_reformat_vlan_pop_create(esw);
+               if (IS_ERR(miss_pkt_reformat)) {
+                       esw_warn(esw->dev,
+                                "Failed to alloc packet reformat REMOVE_HEADER (err=%ld)\n",
+                                PTR_ERR(miss_pkt_reformat));
+                       miss_pkt_reformat = NULL;
+                       mlx5_destroy_flow_group(miss_fg);
+                       miss_fg = NULL;
+                       goto skip_miss_flow;
+               }
+
+               miss_handle = mlx5_esw_bridge_egress_miss_flow_create(egress_ft,
+                                                                     br_offloads->skip_ft,
+                                                                     miss_pkt_reformat);
+               if (IS_ERR(miss_handle)) {
+                       esw_warn(esw->dev, "Failed to create miss flow (err=%ld)\n",
+                                PTR_ERR(miss_handle));
+                       miss_handle = NULL;
+                       mlx5_packet_reformat_dealloc(esw->dev, miss_pkt_reformat);
+                       miss_pkt_reformat = NULL;
+                       mlx5_destroy_flow_group(miss_fg);
+                       miss_fg = NULL;
+                       goto skip_miss_flow;
+               }
+       }
+skip_miss_flow:
+
        bridge->egress_ft = egress_ft;
        bridge->egress_vlan_fg = vlan_fg;
        bridge->egress_mac_fg = mac_fg;
+       bridge->egress_miss_fg = miss_fg;
+       bridge->egress_miss_pkt_reformat = miss_pkt_reformat;
+       bridge->egress_miss_handle = miss_handle;
        return 0;
 
 err_mac_fg:
 static void
 mlx5_esw_bridge_egress_table_cleanup(struct mlx5_esw_bridge *bridge)
 {
+       if (bridge->egress_miss_handle)
+               mlx5_del_flow_rules(bridge->egress_miss_handle);
+       if (bridge->egress_miss_pkt_reformat)
+               mlx5_packet_reformat_dealloc(bridge->br_offloads->esw->dev,
+                                            bridge->egress_miss_pkt_reformat);
+       if (bridge->egress_miss_fg)
+               mlx5_destroy_flow_group(bridge->egress_miss_fg);
        mlx5_destroy_flow_group(bridge->egress_mac_fg);
        mlx5_destroy_flow_group(bridge->egress_vlan_fg);
        mlx5_destroy_flow_table(bridge->egress_ft);
        return handle;
 }
 
+static struct mlx5_flow_handle *
+mlx5_esw_bridge_egress_miss_flow_create(struct mlx5_flow_table *egress_ft,
+                                       struct mlx5_flow_table *skip_ft,
+                                       struct mlx5_pkt_reformat *pkt_reformat)
+{
+       struct mlx5_flow_destination dest = {
+               .type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE,
+               .ft = skip_ft,
+       };
+       struct mlx5_flow_act flow_act = {
+               .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
+               MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT,
+               .flags = FLOW_ACT_NO_APPEND,
+               .pkt_reformat = pkt_reformat,
+       };
+       struct mlx5_flow_spec *rule_spec;
+       struct mlx5_flow_handle *handle;
+
+       rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL);
+       if (!rule_spec)
+               return ERR_PTR(-ENOMEM);
+
+       rule_spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2;
+
+       MLX5_SET(fte_match_param, rule_spec->match_criteria,
+                misc_parameters_2.metadata_reg_c_1, ESW_TUN_MASK);
+       MLX5_SET(fte_match_param, rule_spec->match_value, misc_parameters_2.metadata_reg_c_1,
+                ESW_TUN_BRIDGE_INGRESS_PUSH_VLAN_MARK);
+
+       handle = mlx5_add_flow_rules(egress_ft, rule_spec, &flow_act, &dest, 1);
+
+       kvfree(rule_spec);
+       return handle;
+}
+
 static struct mlx5_esw_bridge *mlx5_esw_bridge_create(int ifindex,
                                                      struct mlx5_esw_bridge_offloads *br_offloads)
 {