1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#define CREATE_TRACE_POINTS
34
35#include "fs_tracepoint.h"
36#include <linux/stringify.h>
37
38#define DECLARE_MASK_VAL(type, name) struct {type m; type v; } name
39#define MASK_VAL(type, spec, name, mask, val, fld) \
40 DECLARE_MASK_VAL(type, name) = \
41 {.m = MLX5_GET(spec, mask, fld),\
42 .v = MLX5_GET(spec, val, fld)}
43#define MASK_VAL_BE(type, spec, name, mask, val, fld) \
44 DECLARE_MASK_VAL(type, name) = \
45 {.m = MLX5_GET_BE(type, spec, mask, fld),\
46 .v = MLX5_GET_BE(type, spec, val, fld)}
47#define GET_MASKED_VAL(name) (name.m & name.v)
48
49#define GET_MASK_VAL(name, type, mask, val, fld) \
50 (name.m = MLX5_GET(type, mask, fld), \
51 name.v = MLX5_GET(type, val, fld), \
52 name.m & name.v)
53#define PRINT_MASKED_VAL(name, p, format) { \
54 if (name.m) \
55 trace_seq_printf(p, __stringify(name) "=" format " ", name.v); \
56 }
57#define PRINT_MASKED_VALP(name, cast, p, format) { \
58 if (name.m) \
59 trace_seq_printf(p, __stringify(name) "=" format " ", \
60 (cast)&name.v);\
61 }
62
63static void print_lyr_2_4_hdrs(struct trace_seq *p,
64 const u32 *mask, const u32 *value)
65{
66#define MASK_VAL_L2(type, name, fld) \
67 MASK_VAL(type, fte_match_set_lyr_2_4, name, mask, value, fld)
68 DECLARE_MASK_VAL(u64, smac) = {
69 .m = MLX5_GET(fte_match_set_lyr_2_4, mask, smac_47_16) << 16 |
70 MLX5_GET(fte_match_set_lyr_2_4, mask, smac_15_0),
71 .v = MLX5_GET(fte_match_set_lyr_2_4, value, smac_47_16) << 16 |
72 MLX5_GET(fte_match_set_lyr_2_4, value, smac_15_0)};
73 DECLARE_MASK_VAL(u64, dmac) = {
74 .m = MLX5_GET(fte_match_set_lyr_2_4, mask, dmac_47_16) << 16 |
75 MLX5_GET(fte_match_set_lyr_2_4, mask, dmac_15_0),
76 .v = MLX5_GET(fte_match_set_lyr_2_4, value, dmac_47_16) << 16 |
77 MLX5_GET(fte_match_set_lyr_2_4, value, dmac_15_0)};
78 MASK_VAL_L2(u16, ethertype, ethertype);
79 MASK_VAL_L2(u8, ip_version, ip_version);
80
81 PRINT_MASKED_VALP(smac, u8 *, p, "%pM");
82 PRINT_MASKED_VALP(dmac, u8 *, p, "%pM");
83 PRINT_MASKED_VAL(ethertype, p, "%04x");
84
85 if ((ethertype.m == 0xffff && ethertype.v == ETH_P_IP) ||
86 (ip_version.m == 0xf && ip_version.v == 4)) {
87#define MASK_VAL_L2_BE(type, name, fld) \
88 MASK_VAL_BE(type, fte_match_set_lyr_2_4, name, mask, value, fld)
89 MASK_VAL_L2_BE(u32, src_ipv4,
90 src_ipv4_src_ipv6.ipv4_layout.ipv4);
91 MASK_VAL_L2_BE(u32, dst_ipv4,
92 dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
93
94 PRINT_MASKED_VALP(src_ipv4, typeof(&src_ipv4.v), p,
95 "%pI4");
96 PRINT_MASKED_VALP(dst_ipv4, typeof(&dst_ipv4.v), p,
97 "%pI4");
98 } else if ((ethertype.m == 0xffff && ethertype.v == ETH_P_IPV6) ||
99 (ip_version.m == 0xf && ip_version.v == 6)) {
100 static const struct in6_addr full_ones = {
101 .in6_u.u6_addr32 = {__constant_htonl(0xffffffff),
102 __constant_htonl(0xffffffff),
103 __constant_htonl(0xffffffff),
104 __constant_htonl(0xffffffff)},
105 };
106 DECLARE_MASK_VAL(struct in6_addr, src_ipv6);
107 DECLARE_MASK_VAL(struct in6_addr, dst_ipv6);
108
109 memcpy(src_ipv6.m.in6_u.u6_addr8,
110 MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
111 src_ipv4_src_ipv6.ipv6_layout.ipv6),
112 sizeof(src_ipv6.m));
113 memcpy(dst_ipv6.m.in6_u.u6_addr8,
114 MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
115 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
116 sizeof(dst_ipv6.m));
117 memcpy(src_ipv6.v.in6_u.u6_addr8,
118 MLX5_ADDR_OF(fte_match_set_lyr_2_4, value,
119 src_ipv4_src_ipv6.ipv6_layout.ipv6),
120 sizeof(src_ipv6.v));
121 memcpy(dst_ipv6.v.in6_u.u6_addr8,
122 MLX5_ADDR_OF(fte_match_set_lyr_2_4, value,
123 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
124 sizeof(dst_ipv6.v));
125
126 if (!memcmp(&src_ipv6.m, &full_ones, sizeof(full_ones)))
127 trace_seq_printf(p, "src_ipv6=%pI6 ",
128 &src_ipv6.v);
129 if (!memcmp(&dst_ipv6.m, &full_ones, sizeof(full_ones)))
130 trace_seq_printf(p, "dst_ipv6=%pI6 ",
131 &dst_ipv6.v);
132 }
133
134#define PRINT_MASKED_VAL_L2(type, name, fld, p, format) {\
135 MASK_VAL_L2(type, name, fld); \
136 PRINT_MASKED_VAL(name, p, format); \
137}
138
139 PRINT_MASKED_VAL_L2(u8, ip_protocol, ip_protocol, p, "%02x");
140 PRINT_MASKED_VAL_L2(u16, tcp_flags, tcp_flags, p, "%x");
141 PRINT_MASKED_VAL_L2(u16, tcp_sport, tcp_sport, p, "%u");
142 PRINT_MASKED_VAL_L2(u16, tcp_dport, tcp_dport, p, "%u");
143 PRINT_MASKED_VAL_L2(u16, udp_sport, udp_sport, p, "%u");
144 PRINT_MASKED_VAL_L2(u16, udp_dport, udp_dport, p, "%u");
145 PRINT_MASKED_VAL_L2(u16, first_vid, first_vid, p, "%04x");
146 PRINT_MASKED_VAL_L2(u8, first_prio, first_prio, p, "%x");
147 PRINT_MASKED_VAL_L2(u8, first_cfi, first_cfi, p, "%d");
148 PRINT_MASKED_VAL_L2(u8, ip_dscp, ip_dscp, p, "%02x");
149 PRINT_MASKED_VAL_L2(u8, ip_ecn, ip_ecn, p, "%x");
150 PRINT_MASKED_VAL_L2(u8, cvlan_tag, cvlan_tag, p, "%d");
151 PRINT_MASKED_VAL_L2(u8, svlan_tag, svlan_tag, p, "%d");
152 PRINT_MASKED_VAL_L2(u8, frag, frag, p, "%d");
153}
154
155static void print_misc_parameters_hdrs(struct trace_seq *p,
156 const u32 *mask, const u32 *value)
157{
158#define MASK_VAL_MISC(type, name, fld) \
159 MASK_VAL(type, fte_match_set_misc, name, mask, value, fld)
160#define PRINT_MASKED_VAL_MISC(type, name, fld, p, format) {\
161 MASK_VAL_MISC(type, name, fld); \
162 PRINT_MASKED_VAL(name, p, format); \
163}
164 DECLARE_MASK_VAL(u64, gre_key) = {
165 .m = MLX5_GET(fte_match_set_misc, mask, gre_key.nvgre.hi) << 8 |
166 MLX5_GET(fte_match_set_misc, mask, gre_key.nvgre.lo),
167 .v = MLX5_GET(fte_match_set_misc, value, gre_key.nvgre.hi) << 8 |
168 MLX5_GET(fte_match_set_misc, value, gre_key.nvgre.lo)};
169
170 PRINT_MASKED_VAL(gre_key, p, "%llu");
171 PRINT_MASKED_VAL_MISC(u32, source_sqn, source_sqn, p, "%u");
172 PRINT_MASKED_VAL_MISC(u16, source_port, source_port, p, "%u");
173 PRINT_MASKED_VAL_MISC(u8, outer_second_prio, outer_second_prio,
174 p, "%u");
175 PRINT_MASKED_VAL_MISC(u8, outer_second_cfi, outer_second_cfi, p, "%u");
176 PRINT_MASKED_VAL_MISC(u16, outer_second_vid, outer_second_vid, p, "%u");
177 PRINT_MASKED_VAL_MISC(u8, inner_second_prio, inner_second_prio,
178 p, "%u");
179 PRINT_MASKED_VAL_MISC(u8, inner_second_cfi, inner_second_cfi, p, "%u");
180 PRINT_MASKED_VAL_MISC(u16, inner_second_vid, inner_second_vid, p, "%u");
181
182 PRINT_MASKED_VAL_MISC(u8, outer_second_cvlan_tag,
183 outer_second_cvlan_tag, p, "%u");
184 PRINT_MASKED_VAL_MISC(u8, inner_second_cvlan_tag,
185 inner_second_cvlan_tag, p, "%u");
186 PRINT_MASKED_VAL_MISC(u8, outer_second_svlan_tag,
187 outer_second_svlan_tag, p, "%u");
188 PRINT_MASKED_VAL_MISC(u8, inner_second_svlan_tag,
189 inner_second_svlan_tag, p, "%u");
190
191 PRINT_MASKED_VAL_MISC(u8, gre_protocol, gre_protocol, p, "%u");
192
193 PRINT_MASKED_VAL_MISC(u32, vxlan_vni, vxlan_vni, p, "%u");
194 PRINT_MASKED_VAL_MISC(u32, outer_ipv6_flow_label, outer_ipv6_flow_label,
195 p, "%x");
196 PRINT_MASKED_VAL_MISC(u32, inner_ipv6_flow_label, inner_ipv6_flow_label,
197 p, "%x");
198}
199
200const char *parse_fs_hdrs(struct trace_seq *p,
201 u8 match_criteria_enable,
202 const u32 *mask_outer,
203 const u32 *mask_misc,
204 const u32 *mask_inner,
205 const u32 *value_outer,
206 const u32 *value_misc,
207 const u32 *value_inner)
208{
209 const char *ret = trace_seq_buffer_ptr(p);
210
211 if (match_criteria_enable &
212 1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_OUTER_HEADERS) {
213 trace_seq_printf(p, "[outer] ");
214 print_lyr_2_4_hdrs(p, mask_outer, value_outer);
215 }
216
217 if (match_criteria_enable &
218 1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS) {
219 trace_seq_printf(p, "[misc] ");
220 print_misc_parameters_hdrs(p, mask_misc, value_misc);
221 }
222 if (match_criteria_enable &
223 1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_INNER_HEADERS) {
224 trace_seq_printf(p, "[inner] ");
225 print_lyr_2_4_hdrs(p, mask_inner, value_inner);
226 }
227 trace_seq_putc(p, 0);
228 return ret;
229}
230
231const char *parse_fs_dst(struct trace_seq *p,
232 const struct mlx5_flow_destination *dst,
233 u32 counter_id)
234{
235 const char *ret = trace_seq_buffer_ptr(p);
236
237 switch (dst->type) {
238 case MLX5_FLOW_DESTINATION_TYPE_VPORT:
239 trace_seq_printf(p, "vport=%u\n", dst->vport.num);
240 break;
241 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
242 trace_seq_printf(p, "ft=%p\n", dst->ft);
243 break;
244 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM:
245 trace_seq_printf(p, "ft_num=%u\n", dst->ft_num);
246 break;
247 case MLX5_FLOW_DESTINATION_TYPE_TIR:
248 trace_seq_printf(p, "tir=%u\n", dst->tir_num);
249 break;
250 case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER:
251 trace_seq_printf(p, "sampler_id=%u\n", dst->sampler_id);
252 break;
253 case MLX5_FLOW_DESTINATION_TYPE_COUNTER:
254 trace_seq_printf(p, "counter_id=%u\n", counter_id);
255 break;
256 case MLX5_FLOW_DESTINATION_TYPE_PORT:
257 trace_seq_printf(p, "port\n");
258 break;
259 }
260
261 trace_seq_putc(p, 0);
262 return ret;
263}
264
265EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_add_ft);
266EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_ft);
267EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_add_fg);
268EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_fg);
269EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_set_fte);
270EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_fte);
271EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_add_rule);
272EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_rule);
273
274