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 nf_flowtable *nf_ft;
29 	u32 ct_labels_id;
30 	u32 act_miss_mapping;
31 	u64 act_miss_cookie;
32 	struct mlx5_ct_ft *ft;
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 			const struct flow_action_entry *act,
117 			struct netlink_ext_ack *extack);
118 
119 int
120 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *attr);
121 
122 void
123 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
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 		struct mlx5e_post_act *post_act)
137 {
138 	return NULL;
139 }
140 
141 static inline void
142 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
143 {
144 }
145 
146 static inline void
147 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr) {}
148 
149 static inline int
150 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
151 		     struct mlx5_flow_spec *spec,
152 		     struct flow_cls_offload *f,
153 		     struct mlx5_ct_attr *ct_attr,
154 		     struct netlink_ext_ack *extack)
155 {
156 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
157 
158 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
159 		return 0;
160 
161 	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
162 	return -EOPNOTSUPP;
163 }
164 
165 static inline int
166 mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
167 {
168 	return 0;
169 }
170 
171 static inline int
172 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
173 			struct mlx5_flow_attr *attr,
174 			const struct flow_action_entry *act,
175 			struct netlink_ext_ack *extack)
176 {
177 	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
178 	return -EOPNOTSUPP;
179 }
180 
181 static inline int
182 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
183 			struct mlx5_flow_attr *attr)
184 {
185 	return -EOPNOTSUPP;
186 }
187 
188 static inline void
189 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
190 		       struct mlx5_flow_attr *attr)
191 {
192 }
193 
194 static inline bool
195 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
196 			 struct sk_buff *skb, u8 zone_restore_id)
197 {
198 	if (!zone_restore_id)
199 		return true;
200 
201 	return false;
202 }
203 
204 #endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
205 #endif /* __MLX5_EN_TC_CT_H__ */
206