1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2018 Mellanox Technologies. */
3
4 #ifndef __MLX5_EN_TC_CT_H__
5 #define __MLX5_EN_TC_CT_H__
6
7 #include <net/pkt_cls.h>
8 #include <linux/mlx5/fs.h>
9 #include <net/tc_act/tc_ct.h>
10
11 #include "en.h"
12
13 struct mlx5_flow_attr;
14 struct mlx5e_tc_mod_hdr_acts;
15 struct mlx5_rep_uplink_priv;
16 struct mlx5e_tc_flow;
17 struct mlx5e_priv;
18
19 struct mlx5_fs_chains;
20 struct mlx5_tc_ct_priv;
21 struct mlx5_ct_flow;
22
23 struct nf_flowtable;
24
25 struct mlx5_ct_attr {
26 u16 zone;
27 u16 ct_action;
28 struct mlx5_ct_flow *ct_flow;
29 struct nf_flowtable *nf_ft;
30 u32 ct_labels_id;
31 u32 act_miss_mapping;
32 u64 act_miss_cookie;
33 };
34
35 #define zone_to_reg_ct {\
36 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
37 .moffset = 0,\
38 .mlen = 16,\
39 .soffset = MLX5_BYTE_OFF(fte_match_param,\
40 misc_parameters_2.metadata_reg_c_2),\
41 }
42
43 #define ctstate_to_reg_ct {\
44 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
45 .moffset = 16,\
46 .mlen = 16,\
47 .soffset = MLX5_BYTE_OFF(fte_match_param,\
48 misc_parameters_2.metadata_reg_c_2),\
49 }
50
51 #define mark_to_reg_ct {\
52 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_3,\
53 .moffset = 0,\
54 .mlen = 32,\
55 .soffset = MLX5_BYTE_OFF(fte_match_param,\
56 misc_parameters_2.metadata_reg_c_3),\
57 }
58
59 #define labels_to_reg_ct {\
60 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_4,\
61 .moffset = 0,\
62 .mlen = 32,\
63 .soffset = MLX5_BYTE_OFF(fte_match_param,\
64 misc_parameters_2.metadata_reg_c_4),\
65 }
66
67 /* 8 LSB of metadata C5 are reserved for packet color */
68 #define fteid_to_reg_ct {\
69 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_5,\
70 .moffset = 8,\
71 .mlen = 24,\
72 .soffset = MLX5_BYTE_OFF(fte_match_param,\
73 misc_parameters_2.metadata_reg_c_5),\
74 }
75
76 #define zone_restore_to_reg_ct {\
77 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\
78 .moffset = 0,\
79 .mlen = ESW_ZONE_ID_BITS,\
80 .soffset = MLX5_BYTE_OFF(fte_match_param,\
81 misc_parameters_2.metadata_reg_c_1),\
82 }
83
84 #define nic_zone_restore_to_reg_ct {\
85 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_B,\
86 .moffset = 16,\
87 .mlen = ESW_ZONE_ID_BITS,\
88 }
89
90 #define MLX5_CT_ZONE_BITS MLX5_REG_MAPPING_MBITS(ZONE_TO_REG)
91 #define MLX5_CT_ZONE_MASK MLX5_REG_MAPPING_MASK(ZONE_TO_REG)
92
93 #if IS_ENABLED(CONFIG_MLX5_TC_CT)
94
95 struct mlx5_tc_ct_priv *
96 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
97 struct mod_hdr_tbl *mod_hdr,
98 enum mlx5_flow_namespace_type ns_type,
99 struct mlx5e_post_act *post_act);
100 void
101 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv);
102
103 void
104 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr);
105
106 int
107 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
108 struct mlx5_flow_spec *spec,
109 struct flow_cls_offload *f,
110 struct mlx5_ct_attr *ct_attr,
111 struct netlink_ext_ack *extack);
112 int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec);
113 int
114 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
115 struct mlx5_flow_attr *attr,
116 struct mlx5e_tc_mod_hdr_acts *mod_acts,
117 const struct flow_action_entry *act,
118 struct netlink_ext_ack *extack);
119
120 struct mlx5_flow_handle *
121 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
122 struct mlx5_flow_spec *spec,
123 struct mlx5_flow_attr *attr,
124 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
125 void
126 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
127 struct mlx5_flow_attr *attr);
128
129 bool
130 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
131 struct sk_buff *skb, u8 zone_restore_id);
132
133 int
134 mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
135 struct mlx5e_tc_mod_hdr_acts *mod_acts);
136
137 #else /* CONFIG_MLX5_TC_CT */
138
139 static inline struct mlx5_tc_ct_priv *
mlx5_tc_ct_init(struct mlx5e_priv * priv,struct mlx5_fs_chains * chains,struct mod_hdr_tbl * mod_hdr,enum mlx5_flow_namespace_type ns_type,struct mlx5e_post_act * post_act)140 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
141 struct mod_hdr_tbl *mod_hdr,
142 enum mlx5_flow_namespace_type ns_type,
143 struct mlx5e_post_act *post_act)
144 {
145 return NULL;
146 }
147
148 static inline void
mlx5_tc_ct_clean(struct mlx5_tc_ct_priv * ct_priv)149 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
150 {
151 }
152
153 static inline void
mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv * priv,struct mlx5_ct_attr * ct_attr)154 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr) {}
155
156 static inline int
mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv * priv,struct mlx5_flow_spec * spec,struct flow_cls_offload * f,struct mlx5_ct_attr * ct_attr,struct netlink_ext_ack * extack)157 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
158 struct mlx5_flow_spec *spec,
159 struct flow_cls_offload *f,
160 struct mlx5_ct_attr *ct_attr,
161 struct netlink_ext_ack *extack)
162 {
163 struct flow_rule *rule = flow_cls_offload_flow_rule(f);
164
165 if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
166 return 0;
167
168 NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
169 return -EOPNOTSUPP;
170 }
171
172 static inline int
mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec * spec)173 mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
174 {
175 return 0;
176 }
177
178 static inline int
mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv * priv,struct mlx5e_tc_mod_hdr_acts * mod_acts)179 mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
180 struct mlx5e_tc_mod_hdr_acts *mod_acts)
181 {
182 return -EOPNOTSUPP;
183 }
184
185 static inline int
mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv * priv,struct mlx5_flow_attr * attr,struct mlx5e_tc_mod_hdr_acts * mod_acts,const struct flow_action_entry * act,struct netlink_ext_ack * extack)186 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
187 struct mlx5_flow_attr *attr,
188 struct mlx5e_tc_mod_hdr_acts *mod_acts,
189 const struct flow_action_entry *act,
190 struct netlink_ext_ack *extack)
191 {
192 NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
193 return -EOPNOTSUPP;
194 }
195
196 static inline struct mlx5_flow_handle *
mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv * priv,struct mlx5_flow_spec * spec,struct mlx5_flow_attr * attr,struct mlx5e_tc_mod_hdr_acts * mod_hdr_acts)197 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
198 struct mlx5_flow_spec *spec,
199 struct mlx5_flow_attr *attr,
200 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
201 {
202 return ERR_PTR(-EOPNOTSUPP);
203 }
204
205 static inline void
mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv * priv,struct mlx5_flow_attr * attr)206 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
207 struct mlx5_flow_attr *attr)
208 {
209 }
210
211 static inline bool
mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv * ct_priv,struct sk_buff * skb,u8 zone_restore_id)212 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
213 struct sk_buff *skb, u8 zone_restore_id)
214 {
215 if (!zone_restore_id)
216 return true;
217
218 return false;
219 }
220
221 #endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
222 #endif /* __MLX5_EN_TC_CT_H__ */
223