]>
Commit | Line | Data |
---|---|---|
438fac3a LR |
1 | // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB |
2 | /* | |
3 | * res-cmid.c RDMA tool | |
4 | * Authors: Leon Romanovsky <leonro@mellanox.com> | |
5 | */ | |
6 | ||
7 | #include "res.h" | |
8 | #include <inttypes.h> | |
9 | ||
10 | static void print_qp_type(struct rd *rd, uint32_t val) | |
11 | { | |
b0a688a5 IK |
12 | print_color_string(PRINT_ANY, COLOR_NONE, "qp-type", "qp-type %s ", |
13 | qp_types_to_str(val)); | |
438fac3a LR |
14 | } |
15 | ||
16 | static const char *cm_id_state_to_str(uint8_t idx) | |
17 | { | |
18 | static const char *const cm_id_states_str[] = { | |
19 | "IDLE", "ADDR_QUERY", "ADDR_RESOLVED", | |
20 | "ROUTE_QUERY", "ROUTE_RESOLVED", "CONNECT", | |
21 | "DISCONNECT", "ADDR_BOUND", "LISTEN", | |
22 | "DEVICE_REMOVAL", "DESTROYING" | |
23 | }; | |
24 | ||
25 | if (idx < ARRAY_SIZE(cm_id_states_str)) | |
26 | return cm_id_states_str[idx]; | |
27 | return "UNKNOWN"; | |
28 | } | |
29 | ||
30 | static const char *cm_id_ps_to_str(uint32_t ps) | |
31 | { | |
32 | switch (ps) { | |
33 | case RDMA_PS_IPOIB: | |
34 | return "IPoIB"; | |
35 | case RDMA_PS_IB: | |
36 | return "IPoIB"; | |
37 | case RDMA_PS_TCP: | |
38 | return "TCP"; | |
39 | case RDMA_PS_UDP: | |
40 | return "UDP"; | |
41 | default: | |
42 | return "---"; | |
43 | } | |
44 | } | |
45 | ||
46 | static void print_cm_id_state(struct rd *rd, uint8_t state) | |
47 | { | |
b0a688a5 IK |
48 | print_color_string(PRINT_ANY, COLOR_NONE, "state", "state %s ", |
49 | cm_id_state_to_str(state)); | |
438fac3a LR |
50 | } |
51 | ||
52 | static void print_ps(struct rd *rd, uint32_t ps) | |
53 | { | |
b0a688a5 IK |
54 | print_color_string(PRINT_ANY, COLOR_NONE, "ps", "ps %s ", |
55 | cm_id_ps_to_str(ps)); | |
438fac3a LR |
56 | } |
57 | ||
58 | static void print_ipaddr(struct rd *rd, const char *key, char *addrstr, | |
59 | uint16_t port) | |
60 | { | |
b0a688a5 IK |
61 | int name_size = INET6_ADDRSTRLEN + strlen(":65535"); |
62 | char json_name[name_size]; | |
438fac3a | 63 | |
b0a688a5 IK |
64 | snprintf(json_name, name_size, "%s:%u", addrstr, port); |
65 | print_color_string(PRINT_ANY, COLOR_NONE, key, key, json_name); | |
66 | print_color_string(PRINT_FP, COLOR_NONE, NULL, " %s:", addrstr); | |
67 | print_color_uint(PRINT_FP, COLOR_NONE, NULL, "%u ", port); | |
438fac3a LR |
68 | } |
69 | ||
70 | static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port) | |
71 | { | |
72 | struct __kernel_sockaddr_storage *addr; | |
73 | ||
74 | addr = (struct __kernel_sockaddr_storage *)mnl_attr_get_payload( | |
75 | nla_line); | |
76 | switch (addr->ss_family) { | |
77 | case AF_INET: { | |
78 | struct sockaddr_in *sin = (struct sockaddr_in *)addr; | |
79 | ||
80 | if (!inet_ntop(AF_INET, (const void *)&sin->sin_addr, addr_str, | |
81 | INET6_ADDRSTRLEN)) | |
82 | return -EINVAL; | |
83 | *port = ntohs(sin->sin_port); | |
84 | break; | |
85 | } | |
86 | case AF_INET6: { | |
87 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; | |
88 | ||
89 | if (!inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, | |
90 | addr_str, INET6_ADDRSTRLEN)) | |
91 | return -EINVAL; | |
92 | *port = ntohs(sin6->sin6_port); | |
93 | break; | |
94 | } | |
95 | default: | |
96 | return -EINVAL; | |
97 | } | |
98 | return 0; | |
99 | } | |
7d06b31f | 100 | static int res_cm_id_line(struct rd *rd, const char *name, int idx, |
5a823593 | 101 | struct nlattr **nla_line) |
7d06b31f | 102 | { |
7d06b31f LR |
103 | char src_addr_str[INET6_ADDRSTRLEN]; |
104 | char dst_addr_str[INET6_ADDRSTRLEN]; | |
105 | uint16_t src_port, dst_port; | |
106 | uint32_t port = 0, pid = 0; | |
107 | uint8_t type = 0, state; | |
108 | uint32_t lqpn = 0, ps; | |
109 | uint32_t cm_idn = 0; | |
110 | char *comm = NULL; | |
7d06b31f LR |
111 | |
112 | if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] || | |
f9313484 | 113 | !nla_line[RDMA_NLDEV_ATTR_RES_PS]) |
7d06b31f | 114 | return MNL_CB_ERROR; |
7d06b31f LR |
115 | |
116 | if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) | |
117 | port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]); | |
118 | ||
119 | if (port && port != rd->port_idx) | |
120 | goto out; | |
121 | ||
78728b7e | 122 | if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) |
7d06b31f | 123 | lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); |
78728b7e LR |
124 | |
125 | if (rd_is_filtered_attr(rd, "lqpn", lqpn, | |
126 | nla_line[RDMA_NLDEV_ATTR_RES_LQPN])) | |
127 | goto out; | |
128 | ||
129 | if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) | |
7d06b31f | 130 | type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]); |
78728b7e LR |
131 | if (rd_is_string_filtered_attr(rd, "qp-type", qp_types_to_str(type), |
132 | nla_line[RDMA_NLDEV_ATTR_RES_TYPE])) | |
133 | goto out; | |
7d06b31f LR |
134 | |
135 | ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]); | |
78728b7e LR |
136 | if (rd_is_string_filtered_attr(rd, "ps", cm_id_ps_to_str(ps), |
137 | nla_line[RDMA_NLDEV_ATTR_RES_PS])) | |
7d06b31f LR |
138 | goto out; |
139 | ||
140 | state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]); | |
78728b7e LR |
141 | if (rd_is_string_filtered_attr(rd, "state", cm_id_state_to_str(state), |
142 | nla_line[RDMA_NLDEV_ATTR_RES_STATE])) | |
7d06b31f LR |
143 | goto out; |
144 | ||
78728b7e | 145 | if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) |
7d06b31f LR |
146 | if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR], |
147 | src_addr_str, &src_port)) | |
148 | goto out; | |
78728b7e LR |
149 | if (rd_is_string_filtered_attr(rd, "src-addr", src_addr_str, |
150 | nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])) | |
151 | goto out; | |
152 | if (rd_is_filtered_attr(rd, "src-port", src_port, | |
153 | nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])) | |
154 | goto out; | |
7d06b31f | 155 | |
78728b7e | 156 | if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) |
7d06b31f LR |
157 | if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR], |
158 | dst_addr_str, &dst_port)) | |
159 | goto out; | |
78728b7e LR |
160 | if (rd_is_string_filtered_attr(rd, "dst-addr", dst_addr_str, |
161 | nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])) | |
162 | goto out; | |
163 | if (rd_is_filtered_attr(rd, "dst-port", dst_port, | |
164 | nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])) | |
165 | goto out; | |
7d06b31f LR |
166 | |
167 | if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { | |
168 | pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]); | |
169 | comm = get_task_name(pid); | |
170 | } | |
171 | ||
78728b7e LR |
172 | if (rd_is_filtered_attr(rd, "pid", pid, |
173 | nla_line[RDMA_NLDEV_ATTR_RES_PID])) | |
7d06b31f LR |
174 | goto out; |
175 | ||
176 | if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]) | |
177 | cm_idn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]); | |
78728b7e LR |
178 | if (rd_is_filtered_attr(rd, "cm-idn", cm_idn, |
179 | nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])) | |
7d06b31f LR |
180 | goto out; |
181 | ||
182 | if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) { | |
183 | /* discard const from mnl_attr_get_str */ | |
184 | comm = (char *)mnl_attr_get_str( | |
185 | nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); | |
186 | } | |
187 | ||
b0a688a5 | 188 | open_json_object(NULL); |
7d06b31f | 189 | print_link(rd, idx, name, port, nla_line); |
127ff956 LR |
190 | res_print_uint(rd, "cm-idn", cm_idn, |
191 | nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]); | |
192 | res_print_uint(rd, "lqpn", lqpn, nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); | |
7d06b31f LR |
193 | if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) |
194 | print_qp_type(rd, type); | |
195 | print_cm_id_state(rd, state); | |
196 | print_ps(rd, ps); | |
127ff956 | 197 | res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]); |
7d06b31f | 198 | print_comm(rd, comm, nla_line); |
7d06b31f LR |
199 | |
200 | if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) | |
201 | print_ipaddr(rd, "src-addr", src_addr_str, src_port); | |
202 | if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) | |
203 | print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port); | |
204 | ||
205 | print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]); | |
206 | newline(rd); | |
207 | ||
208 | out: if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) | |
209 | free(comm); | |
210 | return MNL_CB_OK; | |
211 | } | |
212 | ||
5a823593 LR |
213 | int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data) |
214 | { | |
215 | struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; | |
216 | struct rd *rd = data; | |
217 | const char *name; | |
218 | int idx; | |
219 | ||
220 | mnl_attr_parse(nlh, 0, rd_attr_cb, tb); | |
221 | if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME]) | |
222 | return MNL_CB_ERROR; | |
223 | ||
224 | name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); | |
225 | idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); | |
226 | ||
227 | return res_cm_id_line(rd, name, idx, tb); | |
228 | } | |
229 | ||
438fac3a LR |
230 | int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data) |
231 | { | |
232 | struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; | |
233 | struct nlattr *nla_table, *nla_entry; | |
234 | struct rd *rd = data; | |
7d06b31f | 235 | int ret = MNL_CB_OK; |
438fac3a LR |
236 | const char *name; |
237 | int idx; | |
238 | ||
239 | mnl_attr_parse(nlh, 0, rd_attr_cb, tb); | |
240 | if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] || | |
241 | !tb[RDMA_NLDEV_ATTR_RES_CM_ID]) | |
242 | return MNL_CB_ERROR; | |
243 | ||
244 | name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); | |
245 | idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); | |
246 | nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID]; | |
7d06b31f | 247 | |
438fac3a | 248 | mnl_attr_for_each_nested(nla_entry, nla_table) { |
5a823593 LR |
249 | struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; |
250 | ||
251 | ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); | |
252 | if (ret != MNL_CB_OK) | |
253 | break; | |
438fac3a | 254 | |
5a823593 | 255 | ret = res_cm_id_line(rd, name, idx, nla_line); |
7d06b31f LR |
256 | if (ret != MNL_CB_OK) |
257 | break; | |
438fac3a | 258 | } |
7d06b31f | 259 | return ret; |
438fac3a | 260 | } |