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
34#include "iwpm_util.h"
35
36static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser";
37u16 iwpm_ulib_version = IWPM_UABI_VERSION_MIN;
38static int iwpm_user_pid = IWPM_PID_UNDEFINED;
39static atomic_t echo_nlmsg_seq;
40
41
42
43
44
45
46int iwpm_valid_pid(void)
47{
48 return iwpm_user_pid > 0;
49}
50
51
52
53
54
55
56
57
58
59
60
61
62
63int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
64{
65 struct sk_buff *skb = NULL;
66 struct iwpm_nlmsg_request *nlmsg_request = NULL;
67 struct nlmsghdr *nlh;
68 u32 msg_seq;
69 const char *err_str = "";
70 int ret = -EINVAL;
71
72 if (!iwpm_valid_client(nl_client)) {
73 err_str = "Invalid port mapper client";
74 goto pid_query_error;
75 }
76 if (iwpm_check_registration(nl_client, IWPM_REG_VALID) ||
77 iwpm_user_pid == IWPM_PID_UNAVAILABLE)
78 return 0;
79 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client);
80 if (!skb) {
81 err_str = "Unable to create a nlmsg";
82 goto pid_query_error;
83 }
84 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
85 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
86 if (!nlmsg_request) {
87 err_str = "Unable to allocate netlink request";
88 goto pid_query_error;
89 }
90 msg_seq = atomic_read(&echo_nlmsg_seq);
91
92
93 err_str = "Unable to put attribute of the nlmsg";
94 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_REG_PID_SEQ);
95 if (ret)
96 goto pid_query_error;
97 ret = ibnl_put_attr(skb, nlh, IFNAMSIZ,
98 pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
99 if (ret)
100 goto pid_query_error;
101 ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
102 pm_msg->dev_name, IWPM_NLA_REG_IBDEV_NAME);
103 if (ret)
104 goto pid_query_error;
105 ret = ibnl_put_attr(skb, nlh, IWPM_ULIBNAME_SIZE,
106 (char *)iwpm_ulib_name, IWPM_NLA_REG_ULIB_NAME);
107 if (ret)
108 goto pid_query_error;
109
110 nlmsg_end(skb, nlh);
111
112 pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
113 __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);
114
115 ret = rdma_nl_multicast(skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
116 if (ret) {
117 skb = NULL;
118 iwpm_user_pid = IWPM_PID_UNAVAILABLE;
119 err_str = "Unable to send a nlmsg";
120 goto pid_query_error;
121 }
122 nlmsg_request->req_buffer = pm_msg;
123 ret = iwpm_wait_complete_req(nlmsg_request);
124 return ret;
125pid_query_error:
126 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
127 if (skb)
128 dev_kfree_skb(skb);
129 if (nlmsg_request)
130 iwpm_free_nlmsg_request(&nlmsg_request->kref);
131 return ret;
132}
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
149{
150 struct sk_buff *skb = NULL;
151 struct iwpm_nlmsg_request *nlmsg_request = NULL;
152 struct nlmsghdr *nlh;
153 u32 msg_seq;
154 const char *err_str = "";
155 int ret = -EINVAL;
156
157 if (!iwpm_valid_client(nl_client)) {
158 err_str = "Invalid port mapper client";
159 goto add_mapping_error;
160 }
161 if (!iwpm_valid_pid())
162 return 0;
163 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
164 err_str = "Unregistered port mapper client";
165 goto add_mapping_error;
166 }
167 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
168 if (!skb) {
169 err_str = "Unable to create a nlmsg";
170 goto add_mapping_error;
171 }
172 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
173 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
174 if (!nlmsg_request) {
175 err_str = "Unable to allocate netlink request";
176 goto add_mapping_error;
177 }
178 msg_seq = atomic_read(&echo_nlmsg_seq);
179
180 err_str = "Unable to put attribute of the nlmsg";
181 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
182 IWPM_NLA_MANAGE_MAPPING_SEQ);
183 if (ret)
184 goto add_mapping_error;
185 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
186 &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR);
187 if (ret)
188 goto add_mapping_error;
189
190
191 if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
192 ret = -EINVAL;
193 goto add_mapping_error_nowarn;
194 }
195 if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
196 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
197 IWPM_NLA_MANAGE_FLAGS);
198 if (ret)
199 goto add_mapping_error;
200 }
201
202 nlmsg_end(skb, nlh);
203 nlmsg_request->req_buffer = pm_msg;
204
205 ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
206 if (ret) {
207 skb = NULL;
208 iwpm_user_pid = IWPM_PID_UNDEFINED;
209 err_str = "Unable to send a nlmsg";
210 goto add_mapping_error;
211 }
212 ret = iwpm_wait_complete_req(nlmsg_request);
213 return ret;
214add_mapping_error:
215 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
216add_mapping_error_nowarn:
217 if (skb)
218 dev_kfree_skb(skb);
219 if (nlmsg_request)
220 iwpm_free_nlmsg_request(&nlmsg_request->kref);
221 return ret;
222}
223
224
225
226
227
228
229
230
231
232
233
234
235
236int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
237{
238 struct sk_buff *skb = NULL;
239 struct iwpm_nlmsg_request *nlmsg_request = NULL;
240 struct nlmsghdr *nlh;
241 u32 msg_seq;
242 const char *err_str = "";
243 int ret = -EINVAL;
244
245 if (!iwpm_valid_client(nl_client)) {
246 err_str = "Invalid port mapper client";
247 goto query_mapping_error;
248 }
249 if (!iwpm_valid_pid())
250 return 0;
251 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
252 err_str = "Unregistered port mapper client";
253 goto query_mapping_error;
254 }
255 ret = -ENOMEM;
256 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client);
257 if (!skb) {
258 err_str = "Unable to create a nlmsg";
259 goto query_mapping_error;
260 }
261 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
262 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq,
263 nl_client, GFP_KERNEL);
264 if (!nlmsg_request) {
265 err_str = "Unable to allocate netlink request";
266 goto query_mapping_error;
267 }
268 msg_seq = atomic_read(&echo_nlmsg_seq);
269
270
271 err_str = "Unable to put attribute of the nlmsg";
272 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
273 IWPM_NLA_QUERY_MAPPING_SEQ);
274 if (ret)
275 goto query_mapping_error;
276 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
277 &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR);
278 if (ret)
279 goto query_mapping_error;
280 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
281 &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR);
282 if (ret)
283 goto query_mapping_error;
284
285
286 if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
287 ret = -EINVAL;
288 goto query_mapping_error_nowarn;
289 }
290 if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
291 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
292 IWPM_NLA_QUERY_FLAGS);
293 if (ret)
294 goto query_mapping_error;
295 }
296
297 nlmsg_end(skb, nlh);
298 nlmsg_request->req_buffer = pm_msg;
299
300 ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
301 if (ret) {
302 skb = NULL;
303 err_str = "Unable to send a nlmsg";
304 goto query_mapping_error;
305 }
306 ret = iwpm_wait_complete_req(nlmsg_request);
307 return ret;
308query_mapping_error:
309 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
310query_mapping_error_nowarn:
311 if (skb)
312 dev_kfree_skb(skb);
313 if (nlmsg_request)
314 iwpm_free_nlmsg_request(&nlmsg_request->kref);
315 return ret;
316}
317
318
319
320
321
322
323
324
325
326
327
328
329int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
330{
331 struct sk_buff *skb = NULL;
332 struct nlmsghdr *nlh;
333 u32 msg_seq;
334 const char *err_str = "";
335 int ret = -EINVAL;
336
337 if (!iwpm_valid_client(nl_client)) {
338 err_str = "Invalid port mapper client";
339 goto remove_mapping_error;
340 }
341 if (!iwpm_valid_pid())
342 return 0;
343 if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
344 err_str = "Unregistered port mapper client";
345 goto remove_mapping_error;
346 }
347 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
348 if (!skb) {
349 ret = -ENOMEM;
350 err_str = "Unable to create a nlmsg";
351 goto remove_mapping_error;
352 }
353 msg_seq = atomic_read(&echo_nlmsg_seq);
354 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
355 err_str = "Unable to put attribute of the nlmsg";
356 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
357 IWPM_NLA_MANAGE_MAPPING_SEQ);
358 if (ret)
359 goto remove_mapping_error;
360 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
361 local_addr, IWPM_NLA_MANAGE_ADDR);
362 if (ret)
363 goto remove_mapping_error;
364
365 nlmsg_end(skb, nlh);
366
367 ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
368 if (ret) {
369 skb = NULL;
370 iwpm_user_pid = IWPM_PID_UNDEFINED;
371 err_str = "Unable to send a nlmsg";
372 goto remove_mapping_error;
373 }
374 iwpm_print_sockaddr(local_addr,
375 "remove_mapping: Local sockaddr:");
376 return 0;
377remove_mapping_error:
378 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
379 if (skb)
380 dev_kfree_skb_any(skb);
381 return ret;
382}
383
384
385static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = {
386 [IWPM_NLA_RREG_PID_SEQ] = { .type = NLA_U32 },
387 [IWPM_NLA_RREG_IBDEV_NAME] = { .type = NLA_STRING,
388 .len = IWPM_DEVNAME_SIZE - 1 },
389 [IWPM_NLA_RREG_ULIB_NAME] = { .type = NLA_STRING,
390 .len = IWPM_ULIBNAME_SIZE - 1 },
391 [IWPM_NLA_RREG_ULIB_VER] = { .type = NLA_U16 },
392 [IWPM_NLA_RREG_PID_ERR] = { .type = NLA_U16 }
393};
394
395
396
397
398
399
400
401
402
403
404int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
405{
406 struct iwpm_nlmsg_request *nlmsg_request = NULL;
407 struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX];
408 struct iwpm_dev_data *pm_msg;
409 char *dev_name, *iwpm_name;
410 u32 msg_seq;
411 u8 nl_client;
412 u16 iwpm_version;
413 const char *msg_type = "Register Pid response";
414
415 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX,
416 resp_reg_policy, nltb, msg_type))
417 return -EINVAL;
418
419 msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]);
420 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
421 if (!nlmsg_request) {
422 pr_info("%s: Could not find a matching request (seq = %u)\n",
423 __func__, msg_seq);
424 return -EINVAL;
425 }
426 pm_msg = nlmsg_request->req_buffer;
427 nl_client = nlmsg_request->nl_client;
428 dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]);
429 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]);
430 iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]);
431
432
433 if (strcmp(pm_msg->dev_name, dev_name) ||
434 strcmp(iwpm_ulib_name, iwpm_name) ||
435 iwpm_version < IWPM_UABI_VERSION_MIN) {
436
437 pr_info("%s: Incorrect info (dev = %s name = %s version = %d)\n",
438 __func__, dev_name, iwpm_name, iwpm_version);
439 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
440 goto register_pid_response_exit;
441 }
442 iwpm_user_pid = cb->nlh->nlmsg_pid;
443 iwpm_ulib_version = iwpm_version;
444 if (iwpm_ulib_version < IWPM_UABI_VERSION)
445 pr_warn_once("%s: Down level iwpmd/pid %u. Continuing...",
446 __func__, iwpm_user_pid);
447 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
448 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
449 __func__, iwpm_user_pid);
450 if (iwpm_valid_client(nl_client))
451 iwpm_set_registration(nl_client, IWPM_REG_VALID);
452register_pid_response_exit:
453 nlmsg_request->request_done = 1;
454
455 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
456 barrier();
457 up(&nlmsg_request->sem);
458 return 0;
459}
460
461
462static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = {
463 [IWPM_NLA_RMANAGE_MAPPING_SEQ] = { .type = NLA_U32 },
464 [IWPM_NLA_RMANAGE_ADDR] = {
465 .len = sizeof(struct sockaddr_storage) },
466 [IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR] = {
467 .len = sizeof(struct sockaddr_storage) },
468 [IWPM_NLA_RMANAGE_MAPPING_ERR] = { .type = NLA_U16 }
469};
470
471
472
473
474
475
476
477int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb)
478{
479 struct iwpm_sa_data *pm_msg;
480 struct iwpm_nlmsg_request *nlmsg_request = NULL;
481 struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX];
482 struct sockaddr_storage *local_sockaddr;
483 struct sockaddr_storage *mapped_sockaddr;
484 const char *msg_type;
485 u32 msg_seq;
486
487 msg_type = "Add Mapping response";
488 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX,
489 resp_add_policy, nltb, msg_type))
490 return -EINVAL;
491
492 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
493
494 msg_seq = nla_get_u32(nltb[IWPM_NLA_RMANAGE_MAPPING_SEQ]);
495 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
496 if (!nlmsg_request) {
497 pr_info("%s: Could not find a matching request (seq = %u)\n",
498 __func__, msg_seq);
499 return -EINVAL;
500 }
501 pm_msg = nlmsg_request->req_buffer;
502 local_sockaddr = (struct sockaddr_storage *)
503 nla_data(nltb[IWPM_NLA_RMANAGE_ADDR]);
504 mapped_sockaddr = (struct sockaddr_storage *)
505 nla_data(nltb[IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR]);
506
507 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) {
508 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
509 goto add_mapping_response_exit;
510 }
511 if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) {
512 pr_info("%s: Sockaddr family doesn't match the requested one\n",
513 __func__);
514 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
515 goto add_mapping_response_exit;
516 }
517 memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr,
518 sizeof(*mapped_sockaddr));
519 iwpm_print_sockaddr(&pm_msg->loc_addr,
520 "add_mapping: Local sockaddr:");
521 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
522 "add_mapping: Mapped local sockaddr:");
523
524add_mapping_response_exit:
525 nlmsg_request->request_done = 1;
526
527 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
528 barrier();
529 up(&nlmsg_request->sem);
530 return 0;
531}
532
533
534
535static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = {
536 [IWPM_NLA_RQUERY_MAPPING_SEQ] = { .type = NLA_U32 },
537 [IWPM_NLA_RQUERY_LOCAL_ADDR] = {
538 .len = sizeof(struct sockaddr_storage) },
539 [IWPM_NLA_RQUERY_REMOTE_ADDR] = {
540 .len = sizeof(struct sockaddr_storage) },
541 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = {
542 .len = sizeof(struct sockaddr_storage) },
543 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = {
544 .len = sizeof(struct sockaddr_storage) },
545 [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 }
546};
547
548
549
550
551
552
553
554int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
555 struct netlink_callback *cb)
556{
557 struct iwpm_sa_data *pm_msg;
558 struct iwpm_nlmsg_request *nlmsg_request = NULL;
559 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
560 struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
561 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
562 const char *msg_type;
563 u32 msg_seq;
564 u16 err_code;
565
566 msg_type = "Query Mapping response";
567 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
568 resp_query_policy, nltb, msg_type))
569 return -EINVAL;
570 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
571
572 msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]);
573 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
574 if (!nlmsg_request) {
575 pr_info("%s: Could not find a matching request (seq = %u)\n",
576 __func__, msg_seq);
577 return -EINVAL;
578 }
579 pm_msg = nlmsg_request->req_buffer;
580 local_sockaddr = (struct sockaddr_storage *)
581 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
582 remote_sockaddr = (struct sockaddr_storage *)
583 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
584 mapped_loc_sockaddr = (struct sockaddr_storage *)
585 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
586 mapped_rem_sockaddr = (struct sockaddr_storage *)
587 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
588
589 err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]);
590 if (err_code == IWPM_REMOTE_QUERY_REJECT) {
591 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
592 __func__, cb->nlh->nlmsg_pid, msg_seq);
593 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT;
594 }
595 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) ||
596 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) {
597 pr_info("%s: Incorrect local sockaddr\n", __func__);
598 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
599 goto query_mapping_response_exit;
600 }
601 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
602 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
603 pr_info("%s: Sockaddr family doesn't match the requested one\n",
604 __func__);
605 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
606 goto query_mapping_response_exit;
607 }
608 memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr,
609 sizeof(*mapped_loc_sockaddr));
610 memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr,
611 sizeof(*mapped_rem_sockaddr));
612
613 iwpm_print_sockaddr(&pm_msg->loc_addr,
614 "query_mapping: Local sockaddr:");
615 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
616 "query_mapping: Mapped local sockaddr:");
617 iwpm_print_sockaddr(&pm_msg->rem_addr,
618 "query_mapping: Remote sockaddr:");
619 iwpm_print_sockaddr(&pm_msg->mapped_rem_addr,
620 "query_mapping: Mapped remote sockaddr:");
621query_mapping_response_exit:
622 nlmsg_request->request_done = 1;
623
624 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
625 barrier();
626 up(&nlmsg_request->sem);
627 return 0;
628}
629
630
631
632
633
634
635
636
637
638int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
639{
640 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
641 struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
642 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
643 struct iwpm_remote_info *rem_info;
644 const char *msg_type;
645 u8 nl_client;
646 int ret = -EINVAL;
647
648 msg_type = "Remote Mapping info";
649 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
650 resp_query_policy, nltb, msg_type))
651 return ret;
652
653 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
654 if (!iwpm_valid_client(nl_client)) {
655 pr_info("%s: Invalid port mapper client = %d\n",
656 __func__, nl_client);
657 return ret;
658 }
659 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
660
661 local_sockaddr = (struct sockaddr_storage *)
662 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
663 remote_sockaddr = (struct sockaddr_storage *)
664 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
665 mapped_loc_sockaddr = (struct sockaddr_storage *)
666 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
667 mapped_rem_sockaddr = (struct sockaddr_storage *)
668 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
669
670 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
671 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
672 pr_info("%s: Sockaddr family doesn't match the requested one\n",
673 __func__);
674 return ret;
675 }
676 rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
677 if (!rem_info) {
678 ret = -ENOMEM;
679 return ret;
680 }
681 memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr,
682 sizeof(struct sockaddr_storage));
683 memcpy(&rem_info->remote_sockaddr, remote_sockaddr,
684 sizeof(struct sockaddr_storage));
685 memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr,
686 sizeof(struct sockaddr_storage));
687 rem_info->nl_client = nl_client;
688
689 iwpm_add_remote_info(rem_info);
690
691 iwpm_print_sockaddr(local_sockaddr,
692 "remote_info: Local sockaddr:");
693 iwpm_print_sockaddr(mapped_loc_sockaddr,
694 "remote_info: Mapped local sockaddr:");
695 iwpm_print_sockaddr(remote_sockaddr,
696 "remote_info: Remote sockaddr:");
697 iwpm_print_sockaddr(mapped_rem_sockaddr,
698 "remote_info: Mapped remote sockaddr:");
699 return ret;
700}
701
702
703static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
704 [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING,
705 .len = IWPM_ULIBNAME_SIZE - 1 },
706 [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 }
707};
708
709
710
711
712
713
714
715
716
717
718int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
719{
720 struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
721 const char *msg_type = "Mapping Info response";
722 u8 nl_client;
723 char *iwpm_name;
724 u16 iwpm_version;
725 int ret = -EINVAL;
726
727 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX,
728 resp_mapinfo_policy, nltb, msg_type)) {
729 pr_info("%s: Unable to parse nlmsg\n", __func__);
730 return ret;
731 }
732 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]);
733 iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]);
734 if (strcmp(iwpm_ulib_name, iwpm_name) ||
735 iwpm_version < IWPM_UABI_VERSION_MIN) {
736 pr_info("%s: Invalid port mapper name = %s version = %d\n",
737 __func__, iwpm_name, iwpm_version);
738 return ret;
739 }
740 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
741 if (!iwpm_valid_client(nl_client)) {
742 pr_info("%s: Invalid port mapper client = %d\n",
743 __func__, nl_client);
744 return ret;
745 }
746 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
747 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
748 iwpm_user_pid = cb->nlh->nlmsg_pid;
749
750 if (iwpm_ulib_version < IWPM_UABI_VERSION)
751 pr_warn_once("%s: Down level iwpmd/pid %u. Continuing...",
752 __func__, iwpm_user_pid);
753
754 if (!iwpm_mapinfo_available())
755 return 0;
756 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
757 __func__, iwpm_user_pid);
758 ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
759 return ret;
760}
761
762
763static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
764 [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 },
765 [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 },
766 [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 }
767};
768
769
770
771
772
773
774
775int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
776{
777 struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX];
778 u32 mapinfo_send, mapinfo_ack;
779 const char *msg_type = "Mapping Info Ack";
780
781 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX,
782 ack_mapinfo_policy, nltb, msg_type))
783 return -EINVAL;
784 mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]);
785 mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]);
786 if (mapinfo_ack != mapinfo_send)
787 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
788 __func__, mapinfo_send, mapinfo_ack);
789 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
790 return 0;
791}
792
793
794static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
795 [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 },
796 [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 },
797};
798
799
800
801
802
803
804
805int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
806{
807 struct iwpm_nlmsg_request *nlmsg_request = NULL;
808 int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
809 struct nlattr *nltb[IWPM_NLA_ERR_MAX];
810 u32 msg_seq;
811 u16 err_code;
812 const char *msg_type = "Mapping Error Msg";
813
814 if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX,
815 map_error_policy, nltb, msg_type))
816 return -EINVAL;
817
818 msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]);
819 err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]);
820 pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
821 __func__, msg_seq, err_code, nl_client);
822
823 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
824 if (!nlmsg_request) {
825
826 pr_debug("Could not find matching req (seq = %u)\n", msg_seq);
827 return 0;
828 }
829 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
830 nlmsg_request->err_code = err_code;
831 nlmsg_request->request_done = 1;
832
833 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
834 barrier();
835 up(&nlmsg_request->sem);
836 return 0;
837}
838
839
840static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = {
841 [IWPM_NLA_HELLO_ABI_VERSION] = { .type = NLA_U16 }
842};
843
844
845
846
847
848
849
850
851
852
853int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb)
854{
855 struct nlattr *nltb[IWPM_NLA_HELLO_MAX];
856 const char *msg_type = "Hello request";
857 u8 nl_client;
858 u16 abi_version;
859 int ret = -EINVAL;
860
861 if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb,
862 msg_type)) {
863 pr_info("%s: Unable to parse nlmsg\n", __func__);
864 return ret;
865 }
866 abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]);
867 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
868 if (!iwpm_valid_client(nl_client)) {
869 pr_info("%s: Invalid port mapper client = %d\n",
870 __func__, nl_client);
871 return ret;
872 }
873 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
874 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
875 iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version);
876 pr_debug("Using ABI version %u\n", iwpm_ulib_version);
877 iwpm_user_pid = cb->nlh->nlmsg_pid;
878 ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version);
879 return ret;
880}
881