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 };
32 
33 #define zone_to_reg_ct {\
34 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
35 	.moffset = 0,\
36 	.mlen = 16,\
37 	.soffset = MLX5_BYTE_OFF(fte_match_param,\
38 				 misc_parameters_2.metadata_reg_c_2),\
39 }
40 
41 #define ctstate_to_reg_ct {\
42 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\
43 	.moffset = 16,\
44 	.mlen = 16,\
45 	.soffset = MLX5_BYTE_OFF(fte_match_param,\
46 				 misc_parameters_2.metadata_reg_c_2),\
47 }
48 
49 #define mark_to_reg_ct {\
50 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_3,\
51 	.moffset = 0,\
52 	.mlen = 32,\
53 	.soffset = MLX5_BYTE_OFF(fte_match_param,\
54 				 misc_parameters_2.metadata_reg_c_3),\
55 }
56 
57 #define labels_to_reg_ct {\
58 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_4,\
59 	.moffset = 0,\
60 	.mlen = 32,\
61 	.soffset = MLX5_BYTE_OFF(fte_match_param,\
62 				 misc_parameters_2.metadata_reg_c_4),\
63 }
64 
65 #define fteid_to_reg_ct {\
66 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_5,\
67 	.moffset = 0,\
68 	.mlen = 32,\
69 	.soffset = MLX5_BYTE_OFF(fte_match_param,\
70 				 misc_parameters_2.metadata_reg_c_5),\
71 }
72 
73 #define zone_restore_to_reg_ct {\
74 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\
75 	.moffset = 0,\
76 	.mlen = ESW_ZONE_ID_BITS,\
77 	.soffset = MLX5_BYTE_OFF(fte_match_param,\
78 				 misc_parameters_2.metadata_reg_c_1),\
79 }
80 
81 #define nic_zone_restore_to_reg_ct {\
82 	.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_B,\
83 	.moffset = 16,\
84 	.mlen = ESW_ZONE_ID_BITS,\
85 }
86 
87 #define REG_MAPPING_MLEN(reg) (mlx5e_tc_attr_to_reg_mappings[reg].mlen)
88 #define REG_MAPPING_MOFFSET(reg) (mlx5e_tc_attr_to_reg_mappings[reg].moffset)
89 
90 #if IS_ENABLED(CONFIG_MLX5_TC_CT)
91 
92 struct mlx5_tc_ct_priv *
93 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
94 		struct mod_hdr_tbl *mod_hdr,
95 		enum mlx5_flow_namespace_type ns_type);
96 void
97 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv);
98 
99 void
100 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr);
101 
102 int
103 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
104 		     struct mlx5_flow_spec *spec,
105 		     struct flow_cls_offload *f,
106 		     struct mlx5_ct_attr *ct_attr,
107 		     struct netlink_ext_ack *extack);
108 int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec);
109 int
110 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
111 			struct mlx5_flow_attr *attr,
112 			const struct flow_action_entry *act,
113 			struct netlink_ext_ack *extack);
114 
115 struct mlx5_flow_handle *
116 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
117 			struct mlx5e_tc_flow *flow,
118 			struct mlx5_flow_spec *spec,
119 			struct mlx5_flow_attr *attr,
120 			struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
121 void
122 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
123 		       struct mlx5e_tc_flow *flow,
124 		       struct mlx5_flow_attr *attr);
125 
126 bool
127 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
128 			 struct sk_buff *skb, u8 zone_restore_id);
129 
130 #else /* CONFIG_MLX5_TC_CT */
131 
132 static inline struct mlx5_tc_ct_priv *
133 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
134 		struct mod_hdr_tbl *mod_hdr,
135 		enum mlx5_flow_namespace_type ns_type)
136 {
137 	return NULL;
138 }
139 
140 static inline void
141 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
142 {
143 }
144 
145 static inline void
146 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr) {}
147 
148 static inline int
149 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
150 		     struct mlx5_flow_spec *spec,
151 		     struct flow_cls_offload *f,
152 		     struct mlx5_ct_attr *ct_attr,
153 		     struct netlink_ext_ack *extack)
154 {
155 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
156 
157 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
158 		return 0;
159 
160 	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
161 	return -EOPNOTSUPP;
162 }
163 
164 static inline int
165 mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
166 {
167 	return 0;
168 }
169 
170 static inline int
171 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
172 			struct mlx5_flow_attr *attr,
173 			const struct flow_action_entry *act,
174 			struct netlink_ext_ack *extack)
175 {
176 	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
177 	return -EOPNOTSUPP;
178 }
179 
180 static inline struct mlx5_flow_handle *
181 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
182 			struct mlx5e_tc_flow *flow,
183 			struct mlx5_flow_spec *spec,
184 			struct mlx5_flow_attr *attr,
185 			struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
186 {
187 	return ERR_PTR(-EOPNOTSUPP);
188 }
189 
190 static inline void
191 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
192 		       struct mlx5e_tc_flow *flow,
193 		       struct mlx5_flow_attr *attr)
194 {
195 }
196 
197 static inline bool
198 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
199 			 struct sk_buff *skb, u8 zone_restore_id)
200 {
201 	if (!zone_restore_id)
202 		return true;
203 
204 	return false;
205 }
206 
207 #endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
208 #endif /* __MLX5_EN_TC_CT_H__ */
209