Loading drivers/net/ethernet/mellanox/mlx5/core/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/act/trap.o \ en/tc/act/accept.o en/tc/act/mark.o en/tc/act/goto.o \ en/tc/act/tun.o en/tc/act/csum.o en/tc/act/pedit.o \ en/tc/act/vlan.o en/tc/act/vlan_mangle.o en/tc/act/vlan.o en/tc/act/vlan_mangle.o en/tc/act/mpls.o mlx5_core-$(CONFIG_MLX5_TC_CT) += en/tc_ct.o mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o Loading drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c +11 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,17 @@ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = { &mlx5e_tc_act_pedit, &mlx5e_tc_act_pedit, &mlx5e_tc_act_csum, NULL, /* FLOW_ACTION_MARK, */ NULL, /* FLOW_ACTION_PTYPE, */ NULL, /* FLOW_ACTION_PRIORITY, */ NULL, /* FLOW_ACTION_WAKE, */ NULL, /* FLOW_ACTION_QUEUE, */ NULL, /* FLOW_ACTION_SAMPLE, */ NULL, /* FLOW_ACTION_POLICE, */ NULL, /* FLOW_ACTION_CT, */ NULL, /* FLOW_ACTION_CT_METADATA, */ &mlx5e_tc_act_mpls_push, &mlx5e_tc_act_mpls_pop, }; /* Must be aligned with enum flow_action_id. */ Loading drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h +3 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ struct mlx5e_tc_act_parse_state { struct netlink_ext_ack *extack; bool encap; bool decap; bool mpls_push; const struct ip_tunnel_info *tun_info; struct pedit_headers_action hdrs[__PEDIT_CMD_MAX]; }; Loading @@ -44,6 +45,8 @@ extern struct mlx5e_tc_act mlx5e_tc_act_csum; extern struct mlx5e_tc_act mlx5e_tc_act_pedit; extern struct mlx5e_tc_act mlx5e_tc_act_vlan; extern struct mlx5e_tc_act mlx5e_tc_act_vlan_mangle; extern struct mlx5e_tc_act mlx5e_tc_act_mpls_push; extern struct mlx5e_tc_act mlx5e_tc_act_mpls_pop; struct mlx5e_tc_act * mlx5e_tc_act_get(enum flow_action_id act_id, Loading drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mpls.c 0 → 100644 +86 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include <net/bareudp.h> #include "act.h" #include "en/tc_priv.h" static bool tc_act_can_offload_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, int act_index) { struct netlink_ext_ack *extack = parse_state->extack; struct mlx5e_priv *priv = parse_state->flow->priv; if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, reformat_l2_to_l3_tunnel) || act->mpls_push.proto != htons(ETH_P_MPLS_UC)) { NL_SET_ERR_MSG_MOD(extack, "mpls push is supported only for mpls_uc protocol"); return false; } return true; } static int tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, struct mlx5e_priv *priv, struct mlx5_flow_attr *attr) { parse_state->mpls_push = true; return 0; } static bool tc_act_can_offload_mpls_pop(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, int act_index) { struct netlink_ext_ack *extack = parse_state->extack; struct mlx5e_tc_flow *flow = parse_state->flow; struct net_device *filter_dev; filter_dev = flow->attr->parse_attr->filter_dev; /* we only support mpls pop if it is the first action * and the filter net device is bareudp. Subsequent * actions can be pedit and the last can be mirred * egress redirect. */ if (act_index) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only as first action"); return false; } if (!netif_is_bareudp(filter_dev)) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only on bareudp devices"); return false; } return true; } static int tc_act_parse_mpls_pop(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, struct mlx5e_priv *priv, struct mlx5_flow_attr *attr) { attr->parse_attr->eth.h_proto = act->mpls_pop.proto; attr->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; flow_flag_set(parse_state->flow, L3_TO_L2_DECAP); return 0; } struct mlx5e_tc_act mlx5e_tc_act_mpls_push = { .can_offload = tc_act_can_offload_mpls_push, .parse_action = tc_act_parse_mpls_push, }; struct mlx5e_tc_act mlx5e_tc_act_mpls_pop = { .can_offload = tc_act_can_offload_mpls_pop, .parse_action = tc_act_parse_mpls_pop, }; drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +1 −33 Original line number Diff line number Diff line Loading @@ -3481,7 +3481,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct mlx5e_tc_act *tc_act; int err, i, if_count = 0; bool ptype_host = false; bool mpls_push = false; err = flow_action_supported(flow_action, extack); if (err) Loading @@ -3505,37 +3504,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ptype_host = true; break; case FLOW_ACTION_MPLS_PUSH: if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, reformat_l2_to_l3_tunnel) || act->mpls_push.proto != htons(ETH_P_MPLS_UC)) { NL_SET_ERR_MSG_MOD(extack, "mpls push is supported only for mpls_uc protocol"); return -EOPNOTSUPP; } mpls_push = true; break; case FLOW_ACTION_MPLS_POP: /* we only support mpls pop if it is the first action * and the filter net device is bareudp. Subsequent * actions can be pedit and the last can be mirred * egress redirect. */ if (i) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only as first action"); return -EOPNOTSUPP; } if (!netif_is_bareudp(parse_attr->filter_dev)) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only on bareudp devices"); return -EOPNOTSUPP; } parse_attr->eth.h_proto = act->mpls_pop.proto; attr->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; flow_flag_set(flow, L3_TO_L2_DECAP); break; case FLOW_ACTION_REDIRECT_INGRESS: { struct net_device *out_dev; Loading Loading @@ -3594,7 +3562,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, return -EINVAL; } if (mpls_push && !netif_is_bareudp(out_dev)) { if (parse_state->mpls_push && !netif_is_bareudp(out_dev)) { NL_SET_ERR_MSG_MOD(extack, "mpls is supported only through a bareudp device"); return -EOPNOTSUPP; Loading Loading
drivers/net/ethernet/mellanox/mlx5/core/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/act/trap.o \ en/tc/act/accept.o en/tc/act/mark.o en/tc/act/goto.o \ en/tc/act/tun.o en/tc/act/csum.o en/tc/act/pedit.o \ en/tc/act/vlan.o en/tc/act/vlan_mangle.o en/tc/act/vlan.o en/tc/act/vlan_mangle.o en/tc/act/mpls.o mlx5_core-$(CONFIG_MLX5_TC_CT) += en/tc_ct.o mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o Loading
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c +11 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,17 @@ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = { &mlx5e_tc_act_pedit, &mlx5e_tc_act_pedit, &mlx5e_tc_act_csum, NULL, /* FLOW_ACTION_MARK, */ NULL, /* FLOW_ACTION_PTYPE, */ NULL, /* FLOW_ACTION_PRIORITY, */ NULL, /* FLOW_ACTION_WAKE, */ NULL, /* FLOW_ACTION_QUEUE, */ NULL, /* FLOW_ACTION_SAMPLE, */ NULL, /* FLOW_ACTION_POLICE, */ NULL, /* FLOW_ACTION_CT, */ NULL, /* FLOW_ACTION_CT_METADATA, */ &mlx5e_tc_act_mpls_push, &mlx5e_tc_act_mpls_pop, }; /* Must be aligned with enum flow_action_id. */ Loading
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h +3 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ struct mlx5e_tc_act_parse_state { struct netlink_ext_ack *extack; bool encap; bool decap; bool mpls_push; const struct ip_tunnel_info *tun_info; struct pedit_headers_action hdrs[__PEDIT_CMD_MAX]; }; Loading @@ -44,6 +45,8 @@ extern struct mlx5e_tc_act mlx5e_tc_act_csum; extern struct mlx5e_tc_act mlx5e_tc_act_pedit; extern struct mlx5e_tc_act mlx5e_tc_act_vlan; extern struct mlx5e_tc_act mlx5e_tc_act_vlan_mangle; extern struct mlx5e_tc_act mlx5e_tc_act_mpls_push; extern struct mlx5e_tc_act mlx5e_tc_act_mpls_pop; struct mlx5e_tc_act * mlx5e_tc_act_get(enum flow_action_id act_id, Loading
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mpls.c 0 → 100644 +86 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include <net/bareudp.h> #include "act.h" #include "en/tc_priv.h" static bool tc_act_can_offload_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, int act_index) { struct netlink_ext_ack *extack = parse_state->extack; struct mlx5e_priv *priv = parse_state->flow->priv; if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, reformat_l2_to_l3_tunnel) || act->mpls_push.proto != htons(ETH_P_MPLS_UC)) { NL_SET_ERR_MSG_MOD(extack, "mpls push is supported only for mpls_uc protocol"); return false; } return true; } static int tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, struct mlx5e_priv *priv, struct mlx5_flow_attr *attr) { parse_state->mpls_push = true; return 0; } static bool tc_act_can_offload_mpls_pop(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, int act_index) { struct netlink_ext_ack *extack = parse_state->extack; struct mlx5e_tc_flow *flow = parse_state->flow; struct net_device *filter_dev; filter_dev = flow->attr->parse_attr->filter_dev; /* we only support mpls pop if it is the first action * and the filter net device is bareudp. Subsequent * actions can be pedit and the last can be mirred * egress redirect. */ if (act_index) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only as first action"); return false; } if (!netif_is_bareudp(filter_dev)) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only on bareudp devices"); return false; } return true; } static int tc_act_parse_mpls_pop(struct mlx5e_tc_act_parse_state *parse_state, const struct flow_action_entry *act, struct mlx5e_priv *priv, struct mlx5_flow_attr *attr) { attr->parse_attr->eth.h_proto = act->mpls_pop.proto; attr->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; flow_flag_set(parse_state->flow, L3_TO_L2_DECAP); return 0; } struct mlx5e_tc_act mlx5e_tc_act_mpls_push = { .can_offload = tc_act_can_offload_mpls_push, .parse_action = tc_act_parse_mpls_push, }; struct mlx5e_tc_act mlx5e_tc_act_mpls_pop = { .can_offload = tc_act_can_offload_mpls_pop, .parse_action = tc_act_parse_mpls_pop, };
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +1 −33 Original line number Diff line number Diff line Loading @@ -3481,7 +3481,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct mlx5e_tc_act *tc_act; int err, i, if_count = 0; bool ptype_host = false; bool mpls_push = false; err = flow_action_supported(flow_action, extack); if (err) Loading @@ -3505,37 +3504,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ptype_host = true; break; case FLOW_ACTION_MPLS_PUSH: if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, reformat_l2_to_l3_tunnel) || act->mpls_push.proto != htons(ETH_P_MPLS_UC)) { NL_SET_ERR_MSG_MOD(extack, "mpls push is supported only for mpls_uc protocol"); return -EOPNOTSUPP; } mpls_push = true; break; case FLOW_ACTION_MPLS_POP: /* we only support mpls pop if it is the first action * and the filter net device is bareudp. Subsequent * actions can be pedit and the last can be mirred * egress redirect. */ if (i) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only as first action"); return -EOPNOTSUPP; } if (!netif_is_bareudp(parse_attr->filter_dev)) { NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only on bareudp devices"); return -EOPNOTSUPP; } parse_attr->eth.h_proto = act->mpls_pop.proto; attr->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; flow_flag_set(flow, L3_TO_L2_DECAP); break; case FLOW_ACTION_REDIRECT_INGRESS: { struct net_device *out_dev; Loading Loading @@ -3594,7 +3562,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, return -EINVAL; } if (mpls_push && !netif_is_bareudp(out_dev)) { if (parse_state->mpls_push && !netif_is_bareudp(out_dev)) { NL_SET_ERR_MSG_MOD(extack, "mpls is supported only through a bareudp device"); return -EOPNOTSUPP; Loading