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