diff options
Diffstat (limited to 'drivers/infiniband/core/iwpm_msg.c')
| -rw-r--r-- | drivers/infiniband/core/iwpm_msg.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index b85ddbc979e0..ab081702566f 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c | |||
| @@ -468,7 +468,8 @@ add_mapping_response_exit: | |||
| 468 | } | 468 | } |
| 469 | EXPORT_SYMBOL(iwpm_add_mapping_cb); | 469 | EXPORT_SYMBOL(iwpm_add_mapping_cb); |
| 470 | 470 | ||
| 471 | /* netlink attribute policy for the response to add and query mapping request */ | 471 | /* netlink attribute policy for the response to add and query mapping request |
| 472 | * and response with remote address info */ | ||
| 472 | static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { | 473 | static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { |
| 473 | [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, | 474 | [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, |
| 474 | [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, | 475 | [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
| @@ -559,6 +560,76 @@ query_mapping_response_exit: | |||
| 559 | } | 560 | } |
| 560 | EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); | 561 | EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); |
| 561 | 562 | ||
| 563 | /* | ||
| 564 | * iwpm_remote_info_cb - Process a port mapper message, containing | ||
| 565 | * the remote connecting peer address info | ||
| 566 | */ | ||
| 567 | int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) | ||
| 568 | { | ||
| 569 | struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; | ||
| 570 | struct sockaddr_storage *local_sockaddr, *remote_sockaddr; | ||
| 571 | struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; | ||
| 572 | struct iwpm_remote_info *rem_info; | ||
| 573 | const char *msg_type; | ||
| 574 | u8 nl_client; | ||
| 575 | int ret = -EINVAL; | ||
| 576 | |||
| 577 | msg_type = "Remote Mapping info"; | ||
| 578 | if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, | ||
| 579 | resp_query_policy, nltb, msg_type)) | ||
| 580 | return ret; | ||
| 581 | |||
| 582 | nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); | ||
| 583 | if (!iwpm_valid_client(nl_client)) { | ||
| 584 | pr_info("%s: Invalid port mapper client = %d\n", | ||
| 585 | __func__, nl_client); | ||
| 586 | return ret; | ||
| 587 | } | ||
| 588 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); | ||
| 589 | |||
| 590 | local_sockaddr = (struct sockaddr_storage *) | ||
| 591 | nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); | ||
| 592 | remote_sockaddr = (struct sockaddr_storage *) | ||
| 593 | nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); | ||
| 594 | mapped_loc_sockaddr = (struct sockaddr_storage *) | ||
| 595 | nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); | ||
| 596 | mapped_rem_sockaddr = (struct sockaddr_storage *) | ||
| 597 | nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); | ||
| 598 | |||
| 599 | if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || | ||
| 600 | mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { | ||
| 601 | pr_info("%s: Sockaddr family doesn't match the requested one\n", | ||
| 602 | __func__); | ||
| 603 | return ret; | ||
| 604 | } | ||
| 605 | rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); | ||
| 606 | if (!rem_info) { | ||
| 607 | pr_err("%s: Unable to allocate a remote info\n", __func__); | ||
| 608 | ret = -ENOMEM; | ||
| 609 | return ret; | ||
| 610 | } | ||
| 611 | memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr, | ||
| 612 | sizeof(struct sockaddr_storage)); | ||
| 613 | memcpy(&rem_info->remote_sockaddr, remote_sockaddr, | ||
| 614 | sizeof(struct sockaddr_storage)); | ||
| 615 | memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr, | ||
| 616 | sizeof(struct sockaddr_storage)); | ||
| 617 | rem_info->nl_client = nl_client; | ||
| 618 | |||
| 619 | iwpm_add_remote_info(rem_info); | ||
| 620 | |||
| 621 | iwpm_print_sockaddr(local_sockaddr, | ||
| 622 | "remote_info: Local sockaddr:"); | ||
| 623 | iwpm_print_sockaddr(mapped_loc_sockaddr, | ||
| 624 | "remote_info: Mapped local sockaddr:"); | ||
| 625 | iwpm_print_sockaddr(remote_sockaddr, | ||
| 626 | "remote_info: Remote sockaddr:"); | ||
| 627 | iwpm_print_sockaddr(mapped_rem_sockaddr, | ||
| 628 | "remote_info: Mapped remote sockaddr:"); | ||
| 629 | return ret; | ||
| 630 | } | ||
| 631 | EXPORT_SYMBOL(iwpm_remote_info_cb); | ||
| 632 | |||
| 562 | /* netlink attribute policy for the received request for mapping info */ | 633 | /* netlink attribute policy for the received request for mapping info */ |
| 563 | static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { | 634 | static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { |
| 564 | [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, | 635 | [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, |
