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