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 /* 8 LSB of metadata C5 are reserved for packet color */
66 #define fteid_to_reg_ct {\
67 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_5,\
68 .moffset = 8,\
69 .mlen = 24,\
70 .soffset = MLX5_BYTE_OFF(fte_match_param,\
71 misc_parameters_2.metadata_reg_c_5),\
72 }
73
74 #define zone_restore_to_reg_ct {\
75 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\
76 .moffset = 0,\
77 .mlen = ESW_ZONE_ID_BITS,\
78 .soffset = MLX5_BYTE_OFF(fte_match_param,\
79 misc_parameters_2.metadata_reg_c_1),\
80 }
81
82 #define nic_zone_restore_to_reg_ct {\
83 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_B,\
84 .moffset = 16,\
85 .mlen = ESW_ZONE_ID_BITS,\
86 }
87
88 #define MLX5_CT_ZONE_BITS MLX5_REG_MAPPING_MBITS(ZONE_TO_REG)
89 #define MLX5_CT_ZONE_MASK MLX5_REG_MAPPING_MASK(ZONE_TO_REG)
90
91 #if IS_ENABLED(CONFIG_MLX5_TC_CT)
92
93 struct mlx5_tc_ct_priv *
94 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
95 struct mod_hdr_tbl *mod_hdr,
96 enum mlx5_flow_namespace_type ns_type,
97 struct mlx5e_post_act *post_act);
98 void
99 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv);
100
101 void
102 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr);
103
104 int
105 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
106 struct mlx5_flow_spec *spec,
107 struct flow_cls_offload *f,
108 struct mlx5_ct_attr *ct_attr,
109 struct netlink_ext_ack *extack);
110 int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec);
111 int
112 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
113 struct mlx5_flow_attr *attr,
114 struct mlx5e_tc_mod_hdr_acts *mod_acts,
115 const struct flow_action_entry *act,
116 struct netlink_ext_ack *extack);
117
118 struct mlx5_flow_handle *
119 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
120 struct mlx5_flow_spec *spec,
121 struct mlx5_flow_attr *attr,
122 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
123 void
124 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
125 struct mlx5_flow_attr *attr);
126
127 bool
128 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
129 struct sk_buff *skb, u8 zone_restore_id);
130
131 int
132 mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
133 struct mlx5e_tc_mod_hdr_acts *mod_acts);
134
135 #else /* CONFIG_MLX5_TC_CT */
136
137 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)138 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
139 struct mod_hdr_tbl *mod_hdr,
140 enum mlx5_flow_namespace_type ns_type,
141 struct mlx5e_post_act *post_act)
142 {
143 return NULL;
144 }
145
146 static inline void
mlx5_tc_ct_clean(struct mlx5_tc_ct_priv * ct_priv)147 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
148 {
149 }
150
151 static inline void
mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv * priv,struct mlx5_ct_attr * ct_attr)152 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr) {}
153
154 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)155 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
156 struct mlx5_flow_spec *spec,
157 struct flow_cls_offload *f,
158 struct mlx5_ct_attr *ct_attr,
159 struct netlink_ext_ack *extack)
160 {
161 struct flow_rule *rule = flow_cls_offload_flow_rule(f);
162
163 if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
164 return 0;
165
166 NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
167 return -EOPNOTSUPP;
168 }
169
170 static inline int
mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec * spec)171 mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
172 {
173 return 0;
174 }
175
176 static inline int
mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv * priv,struct mlx5e_tc_mod_hdr_acts * mod_acts)177 mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
178 struct mlx5e_tc_mod_hdr_acts *mod_acts)
179 {
180 return -EOPNOTSUPP;
181 }
182
183 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)184 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
185 struct mlx5_flow_attr *attr,
186 struct mlx5e_tc_mod_hdr_acts *mod_acts,
187 const struct flow_action_entry *act,
188 struct netlink_ext_ack *extack)
189 {
190 NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
191 return -EOPNOTSUPP;
192 }
193
194 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)195 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
196 struct mlx5_flow_spec *spec,
197 struct mlx5_flow_attr *attr,
198 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
199 {
200 return ERR_PTR(-EOPNOTSUPP);
201 }
202
203 static inline void
mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv * priv,struct mlx5_flow_attr * attr)204 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
205 struct mlx5_flow_attr *attr)
206 {
207 }
208
209 static inline bool
mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv * ct_priv,struct sk_buff * skb,u8 zone_restore_id)210 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv,
211 struct sk_buff *skb, u8 zone_restore_id)
212 {
213 if (!zone_restore_id)
214 return true;
215
216 return false;
217 }
218
219 #endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */
220 #endif /* __MLX5_EN_TC_CT_H__ */
221