1 /* 2 * Copyright (c) 2017, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 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 63 static 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 80 PRINT_MASKED_VALP(smac, u8 *, p, "%pM"); 81 PRINT_MASKED_VALP(dmac, u8 *, p, "%pM"); 82 PRINT_MASKED_VAL(ethertype, p, "%04x"); 83 84 if (ethertype.m == 0xffff) { 85 if (ethertype.v == ETH_P_IP) { 86 #define MASK_VAL_L2_BE(type, name, fld) \ 87 MASK_VAL_BE(type, fte_match_set_lyr_2_4, name, mask, value, fld) 88 MASK_VAL_L2_BE(u32, src_ipv4, 89 src_ipv4_src_ipv6.ipv4_layout.ipv4); 90 MASK_VAL_L2_BE(u32, dst_ipv4, 91 dst_ipv4_dst_ipv6.ipv4_layout.ipv4); 92 93 PRINT_MASKED_VALP(src_ipv4, typeof(&src_ipv4.v), p, 94 "%pI4"); 95 PRINT_MASKED_VALP(dst_ipv4, typeof(&dst_ipv4.v), p, 96 "%pI4"); 97 } else if (ethertype.v == ETH_P_IPV6) { 98 static const struct in6_addr full_ones = { 99 .in6_u.u6_addr32 = {__constant_htonl(0xffffffff), 100 __constant_htonl(0xffffffff), 101 __constant_htonl(0xffffffff), 102 __constant_htonl(0xffffffff)}, 103 }; 104 DECLARE_MASK_VAL(struct in6_addr, src_ipv6); 105 DECLARE_MASK_VAL(struct in6_addr, dst_ipv6); 106 107 memcpy(src_ipv6.m.in6_u.u6_addr8, 108 MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask, 109 src_ipv4_src_ipv6.ipv6_layout.ipv6), 110 sizeof(src_ipv6.m)); 111 memcpy(dst_ipv6.m.in6_u.u6_addr8, 112 MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask, 113 dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 114 sizeof(dst_ipv6.m)); 115 memcpy(src_ipv6.v.in6_u.u6_addr8, 116 MLX5_ADDR_OF(fte_match_set_lyr_2_4, value, 117 src_ipv4_src_ipv6.ipv6_layout.ipv6), 118 sizeof(src_ipv6.v)); 119 memcpy(dst_ipv6.v.in6_u.u6_addr8, 120 MLX5_ADDR_OF(fte_match_set_lyr_2_4, value, 121 dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 122 sizeof(dst_ipv6.v)); 123 124 if (!memcmp(&src_ipv6.m, &full_ones, sizeof(full_ones))) 125 trace_seq_printf(p, "src_ipv6=%pI6 ", 126 &src_ipv6.v); 127 if (!memcmp(&dst_ipv6.m, &full_ones, sizeof(full_ones))) 128 trace_seq_printf(p, "dst_ipv6=%pI6 ", 129 &dst_ipv6.v); 130 } 131 } 132 133 #define PRINT_MASKED_VAL_L2(type, name, fld, p, format) {\ 134 MASK_VAL_L2(type, name, fld); \ 135 PRINT_MASKED_VAL(name, p, format); \ 136 } 137 138 PRINT_MASKED_VAL_L2(u8, ip_protocol, ip_protocol, p, "%02x"); 139 PRINT_MASKED_VAL_L2(u16, tcp_flags, tcp_flags, p, "%x"); 140 PRINT_MASKED_VAL_L2(u16, tcp_sport, tcp_sport, p, "%u"); 141 PRINT_MASKED_VAL_L2(u16, tcp_dport, tcp_dport, p, "%u"); 142 PRINT_MASKED_VAL_L2(u16, udp_sport, udp_sport, p, "%u"); 143 PRINT_MASKED_VAL_L2(u16, udp_dport, udp_dport, p, "%u"); 144 PRINT_MASKED_VAL_L2(u16, first_vid, first_vid, p, "%04x"); 145 PRINT_MASKED_VAL_L2(u8, first_prio, first_prio, p, "%x"); 146 PRINT_MASKED_VAL_L2(u8, first_cfi, first_cfi, p, "%d"); 147 PRINT_MASKED_VAL_L2(u8, ip_dscp, ip_dscp, p, "%02x"); 148 PRINT_MASKED_VAL_L2(u8, ip_ecn, ip_ecn, p, "%x"); 149 PRINT_MASKED_VAL_L2(u8, cvlan_tag, cvlan_tag, p, "%d"); 150 PRINT_MASKED_VAL_L2(u8, svlan_tag, svlan_tag, p, "%d"); 151 PRINT_MASKED_VAL_L2(u8, frag, frag, p, "%d"); 152 } 153 154 static void print_misc_parameters_hdrs(struct trace_seq *p, 155 const u32 *mask, const u32 *value) 156 { 157 #define MASK_VAL_MISC(type, name, fld) \ 158 MASK_VAL(type, fte_match_set_misc, name, mask, value, fld) 159 #define PRINT_MASKED_VAL_MISC(type, name, fld, p, format) {\ 160 MASK_VAL_MISC(type, name, fld); \ 161 PRINT_MASKED_VAL(name, p, format); \ 162 } 163 DECLARE_MASK_VAL(u64, gre_key) = { 164 .m = MLX5_GET(fte_match_set_misc, mask, gre_key.nvgre.hi) << 8 | 165 MLX5_GET(fte_match_set_misc, mask, gre_key.nvgre.lo), 166 .v = MLX5_GET(fte_match_set_misc, value, gre_key.nvgre.hi) << 8 | 167 MLX5_GET(fte_match_set_misc, value, gre_key.nvgre.lo)}; 168 169 PRINT_MASKED_VAL(gre_key, p, "%llu"); 170 PRINT_MASKED_VAL_MISC(u32, source_sqn, source_sqn, p, "%u"); 171 PRINT_MASKED_VAL_MISC(u16, source_port, source_port, p, "%u"); 172 PRINT_MASKED_VAL_MISC(u8, outer_second_prio, outer_second_prio, 173 p, "%u"); 174 PRINT_MASKED_VAL_MISC(u8, outer_second_cfi, outer_second_cfi, p, "%u"); 175 PRINT_MASKED_VAL_MISC(u16, outer_second_vid, outer_second_vid, p, "%u"); 176 PRINT_MASKED_VAL_MISC(u8, inner_second_prio, inner_second_prio, 177 p, "%u"); 178 PRINT_MASKED_VAL_MISC(u8, inner_second_cfi, inner_second_cfi, p, "%u"); 179 PRINT_MASKED_VAL_MISC(u16, inner_second_vid, inner_second_vid, p, "%u"); 180 181 PRINT_MASKED_VAL_MISC(u8, outer_second_cvlan_tag, 182 outer_second_cvlan_tag, p, "%u"); 183 PRINT_MASKED_VAL_MISC(u8, inner_second_cvlan_tag, 184 inner_second_cvlan_tag, p, "%u"); 185 PRINT_MASKED_VAL_MISC(u8, outer_second_svlan_tag, 186 outer_second_svlan_tag, p, "%u"); 187 PRINT_MASKED_VAL_MISC(u8, inner_second_svlan_tag, 188 inner_second_svlan_tag, p, "%u"); 189 190 PRINT_MASKED_VAL_MISC(u8, gre_protocol, gre_protocol, p, "%u"); 191 192 PRINT_MASKED_VAL_MISC(u32, vxlan_vni, vxlan_vni, p, "%u"); 193 PRINT_MASKED_VAL_MISC(u32, outer_ipv6_flow_label, outer_ipv6_flow_label, 194 p, "%x"); 195 PRINT_MASKED_VAL_MISC(u32, inner_ipv6_flow_label, inner_ipv6_flow_label, 196 p, "%x"); 197 } 198 199 const char *parse_fs_hdrs(struct trace_seq *p, 200 u8 match_criteria_enable, 201 const u32 *mask_outer, 202 const u32 *mask_misc, 203 const u32 *mask_inner, 204 const u32 *value_outer, 205 const u32 *value_misc, 206 const u32 *value_inner) 207 { 208 const char *ret = trace_seq_buffer_ptr(p); 209 210 if (match_criteria_enable & 211 1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_OUTER_HEADERS) { 212 trace_seq_printf(p, "[outer] "); 213 print_lyr_2_4_hdrs(p, mask_outer, value_outer); 214 } 215 216 if (match_criteria_enable & 217 1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS) { 218 trace_seq_printf(p, "[misc] "); 219 print_misc_parameters_hdrs(p, mask_misc, value_misc); 220 } 221 if (match_criteria_enable & 222 1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_INNER_HEADERS) { 223 trace_seq_printf(p, "[inner] "); 224 print_lyr_2_4_hdrs(p, mask_inner, value_inner); 225 } 226 trace_seq_putc(p, 0); 227 return ret; 228 } 229 230 const char *parse_fs_dst(struct trace_seq *p, 231 const struct mlx5_flow_destination *dst, 232 u32 counter_id) 233 { 234 const char *ret = trace_seq_buffer_ptr(p); 235 236 switch (dst->type) { 237 case MLX5_FLOW_DESTINATION_TYPE_VPORT: 238 trace_seq_printf(p, "vport=%u\n", dst->vport.num); 239 break; 240 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: 241 trace_seq_printf(p, "ft=%p\n", dst->ft); 242 break; 243 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM: 244 trace_seq_printf(p, "ft_num=%u\n", dst->ft_num); 245 break; 246 case MLX5_FLOW_DESTINATION_TYPE_TIR: 247 trace_seq_printf(p, "tir=%u\n", dst->tir_num); 248 break; 249 case MLX5_FLOW_DESTINATION_TYPE_COUNTER: 250 trace_seq_printf(p, "counter_id=%u\n", counter_id); 251 break; 252 case MLX5_FLOW_DESTINATION_TYPE_PORT: 253 trace_seq_printf(p, "port\n"); 254 break; 255 } 256 257 trace_seq_putc(p, 0); 258 return ret; 259 } 260 261 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_add_ft); 262 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_ft); 263 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_add_fg); 264 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_fg); 265 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_set_fte); 266 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_fte); 267 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_add_rule); 268 EXPORT_TRACEPOINT_SYMBOL(mlx5_fs_del_rule); 269 270