1 | // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB |
2 | // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
3 | |
4 | #include "act.h" |
5 | #include "en/tc/post_act.h" |
6 | #include "en/tc_priv.h" |
7 | #include "mlx5_core.h" |
8 | |
9 | static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = { |
10 | [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept, |
11 | [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop, |
12 | [FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap, |
13 | [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto, |
14 | [FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_redirect, |
15 | [FLOW_ACTION_MIRRED] = &mlx5e_tc_act_mirred, |
16 | [FLOW_ACTION_REDIRECT_INGRESS] = &mlx5e_tc_act_redirect_ingress, |
17 | [FLOW_ACTION_VLAN_PUSH] = &mlx5e_tc_act_vlan, |
18 | [FLOW_ACTION_VLAN_POP] = &mlx5e_tc_act_vlan, |
19 | [FLOW_ACTION_VLAN_MANGLE] = &mlx5e_tc_act_vlan_mangle, |
20 | [FLOW_ACTION_TUNNEL_ENCAP] = &mlx5e_tc_act_tun_encap, |
21 | [FLOW_ACTION_TUNNEL_DECAP] = &mlx5e_tc_act_tun_decap, |
22 | [FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit, |
23 | [FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit, |
24 | [FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum, |
25 | [FLOW_ACTION_PTYPE] = &mlx5e_tc_act_ptype, |
26 | [FLOW_ACTION_SAMPLE] = &mlx5e_tc_act_sample, |
27 | [FLOW_ACTION_POLICE] = &mlx5e_tc_act_police, |
28 | [FLOW_ACTION_CT] = &mlx5e_tc_act_ct, |
29 | [FLOW_ACTION_MPLS_PUSH] = &mlx5e_tc_act_mpls_push, |
30 | [FLOW_ACTION_MPLS_POP] = &mlx5e_tc_act_mpls_pop, |
31 | [FLOW_ACTION_VLAN_PUSH_ETH] = &mlx5e_tc_act_vlan, |
32 | [FLOW_ACTION_VLAN_POP_ETH] = &mlx5e_tc_act_vlan, |
33 | }; |
34 | |
35 | static struct mlx5e_tc_act *tc_acts_nic[NUM_FLOW_ACTIONS] = { |
36 | [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept, |
37 | [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop, |
38 | [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto, |
39 | [FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred_nic, |
40 | [FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit, |
41 | [FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit, |
42 | [FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum, |
43 | [FLOW_ACTION_MARK] = &mlx5e_tc_act_mark, |
44 | [FLOW_ACTION_CT] = &mlx5e_tc_act_ct, |
45 | }; |
46 | |
47 | /** |
48 | * mlx5e_tc_act_get() - Get an action parser for an action id. |
49 | * @act_id: Flow action id. |
50 | * @ns_type: flow namespace type. |
51 | */ |
52 | struct mlx5e_tc_act * |
53 | mlx5e_tc_act_get(enum flow_action_id act_id, |
54 | enum mlx5_flow_namespace_type ns_type) |
55 | { |
56 | struct mlx5e_tc_act **tc_acts; |
57 | |
58 | tc_acts = ns_type == MLX5_FLOW_NAMESPACE_FDB ? tc_acts_fdb : tc_acts_nic; |
59 | |
60 | return tc_acts[act_id]; |
61 | } |
62 | |
63 | /** |
64 | * mlx5e_tc_act_init_parse_state() - Init a new parse_state. |
65 | * @parse_state: Parsing state. |
66 | * @flow: mlx5e tc flow being handled. |
67 | * @flow_action: flow action to parse. |
68 | * @extack: to set an error msg. |
69 | * |
70 | * The same parse_state should be passed to action parsers |
71 | * for tracking the current parsing state. |
72 | */ |
73 | void |
74 | mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state, |
75 | struct mlx5e_tc_flow *flow, |
76 | struct flow_action *flow_action, |
77 | struct netlink_ext_ack *extack) |
78 | { |
79 | memset(parse_state, 0, sizeof(*parse_state)); |
80 | parse_state->flow = flow; |
81 | parse_state->extack = extack; |
82 | parse_state->flow_action = flow_action; |
83 | } |
84 | |
85 | int |
86 | mlx5e_tc_act_post_parse(struct mlx5e_tc_act_parse_state *parse_state, |
87 | struct flow_action *flow_action, int from, int to, |
88 | struct mlx5_flow_attr *attr, |
89 | enum mlx5_flow_namespace_type ns_type) |
90 | { |
91 | struct flow_action_entry *act; |
92 | struct mlx5e_tc_act *tc_act; |
93 | struct mlx5e_priv *priv; |
94 | int err = 0, i; |
95 | |
96 | priv = parse_state->flow->priv; |
97 | |
98 | flow_action_for_each(i, act, flow_action) { |
99 | if (i < from) |
100 | continue; |
101 | else if (i > to) |
102 | break; |
103 | |
104 | tc_act = mlx5e_tc_act_get(act_id: act->id, ns_type); |
105 | if (!tc_act || !tc_act->post_parse) |
106 | continue; |
107 | |
108 | err = tc_act->post_parse(parse_state, priv, attr); |
109 | if (err) |
110 | goto out; |
111 | } |
112 | |
113 | out: |
114 | return err; |
115 | } |
116 | |
117 | int |
118 | mlx5e_tc_act_set_next_post_act(struct mlx5e_tc_flow *flow, |
119 | struct mlx5_flow_attr *attr, |
120 | struct mlx5_flow_attr *next_attr) |
121 | { |
122 | struct mlx5_core_dev *mdev = flow->priv->mdev; |
123 | struct mlx5e_tc_mod_hdr_acts *mod_acts; |
124 | int err; |
125 | |
126 | mod_acts = &attr->parse_attr->mod_hdr_acts; |
127 | |
128 | /* Set handle on current post act rule to next post act rule. */ |
129 | err = mlx5e_tc_post_act_set_handle(dev: mdev, handle: next_attr->post_act_handle, acts: mod_acts); |
130 | if (err) { |
131 | mlx5_core_warn(mdev, "Failed setting post action handle" ); |
132 | return err; |
133 | } |
134 | |
135 | attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | |
136 | MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; |
137 | |
138 | return 0; |
139 | } |
140 | |