| .. | .. |
|---|
| 51 | 51 | static DEFINE_MUTEX(iwpm_admin_lock); |
|---|
| 52 | 52 | static struct iwpm_admin_data iwpm_admin; |
|---|
| 53 | 53 | |
|---|
| 54 | +/** |
|---|
| 55 | + * iwpm_init - Allocate resources for the iwarp port mapper |
|---|
| 56 | + * @nl_client: The index of the netlink client |
|---|
| 57 | + * |
|---|
| 58 | + * Should be called when network interface goes up. |
|---|
| 59 | + */ |
|---|
| 54 | 60 | int iwpm_init(u8 nl_client) |
|---|
| 55 | 61 | { |
|---|
| 56 | 62 | int ret = 0; |
|---|
| .. | .. |
|---|
| 87 | 93 | static void free_hash_bucket(void); |
|---|
| 88 | 94 | static void free_reminfo_bucket(void); |
|---|
| 89 | 95 | |
|---|
| 96 | +/** |
|---|
| 97 | + * iwpm_exit - Deallocate resources for the iwarp port mapper |
|---|
| 98 | + * @nl_client: The index of the netlink client |
|---|
| 99 | + * |
|---|
| 100 | + * Should be called when network interface goes down. |
|---|
| 101 | + */ |
|---|
| 90 | 102 | int iwpm_exit(u8 nl_client) |
|---|
| 91 | 103 | { |
|---|
| 92 | 104 | |
|---|
| .. | .. |
|---|
| 112 | 124 | static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage *, |
|---|
| 113 | 125 | struct sockaddr_storage *); |
|---|
| 114 | 126 | |
|---|
| 127 | +/** |
|---|
| 128 | + * iwpm_create_mapinfo - Store local and mapped IPv4/IPv6 address |
|---|
| 129 | + * info in a hash table |
|---|
| 130 | + * @local_addr: Local ip/tcp address |
|---|
| 131 | + * @mapped_addr: Mapped local ip/tcp address |
|---|
| 132 | + * @nl_client: The index of the netlink client |
|---|
| 133 | + * @map_flags: IWPM mapping flags |
|---|
| 134 | + */ |
|---|
| 115 | 135 | int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, |
|---|
| 116 | 136 | struct sockaddr_storage *mapped_sockaddr, |
|---|
| 117 | | - u8 nl_client) |
|---|
| 137 | + u8 nl_client, u32 map_flags) |
|---|
| 118 | 138 | { |
|---|
| 119 | 139 | struct hlist_head *hash_bucket_head = NULL; |
|---|
| 120 | 140 | struct iwpm_mapping_info *map_info; |
|---|
| .. | .. |
|---|
| 132 | 152 | memcpy(&map_info->mapped_sockaddr, mapped_sockaddr, |
|---|
| 133 | 153 | sizeof(struct sockaddr_storage)); |
|---|
| 134 | 154 | map_info->nl_client = nl_client; |
|---|
| 155 | + map_info->map_flags = map_flags; |
|---|
| 135 | 156 | |
|---|
| 136 | 157 | spin_lock_irqsave(&iwpm_mapinfo_lock, flags); |
|---|
| 137 | 158 | if (iwpm_hash_bucket) { |
|---|
| .. | .. |
|---|
| 150 | 171 | return ret; |
|---|
| 151 | 172 | } |
|---|
| 152 | 173 | |
|---|
| 174 | +/** |
|---|
| 175 | + * iwpm_remove_mapinfo - Remove local and mapped IPv4/IPv6 address |
|---|
| 176 | + * info from the hash table |
|---|
| 177 | + * @local_addr: Local ip/tcp address |
|---|
| 178 | + * @mapped_local_addr: Mapped local ip/tcp address |
|---|
| 179 | + * |
|---|
| 180 | + * Returns err code if mapping info is not found in the hash table, |
|---|
| 181 | + * otherwise returns 0 |
|---|
| 182 | + */ |
|---|
| 153 | 183 | int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr, |
|---|
| 154 | 184 | struct sockaddr_storage *mapped_local_addr) |
|---|
| 155 | 185 | { |
|---|
| .. | .. |
|---|
| 250 | 280 | spin_unlock_irqrestore(&iwpm_reminfo_lock, flags); |
|---|
| 251 | 281 | } |
|---|
| 252 | 282 | |
|---|
| 283 | +/** |
|---|
| 284 | + * iwpm_get_remote_info - Get the remote connecting peer address info |
|---|
| 285 | + * |
|---|
| 286 | + * @mapped_loc_addr: Mapped local address of the listening peer |
|---|
| 287 | + * @mapped_rem_addr: Mapped remote address of the connecting peer |
|---|
| 288 | + * @remote_addr: To store the remote address of the connecting peer |
|---|
| 289 | + * @nl_client: The index of the netlink client |
|---|
| 290 | + * |
|---|
| 291 | + * The remote address info is retrieved and provided to the client in |
|---|
| 292 | + * the remote_addr. After that it is removed from the hash table |
|---|
| 293 | + */ |
|---|
| 253 | 294 | int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, |
|---|
| 254 | 295 | struct sockaddr_storage *mapped_rem_addr, |
|---|
| 255 | 296 | struct sockaddr_storage *remote_addr, |
|---|
| .. | .. |
|---|
| 465 | 506 | int ret; |
|---|
| 466 | 507 | const char *err_str = ""; |
|---|
| 467 | 508 | |
|---|
| 468 | | - ret = nlmsg_validate(cb->nlh, nlh_len, policy_max - 1, nlmsg_policy, |
|---|
| 469 | | - NULL); |
|---|
| 509 | + ret = nlmsg_validate_deprecated(cb->nlh, nlh_len, policy_max - 1, |
|---|
| 510 | + nlmsg_policy, NULL); |
|---|
| 470 | 511 | if (ret) { |
|---|
| 471 | 512 | err_str = "Invalid attribute"; |
|---|
| 472 | 513 | goto parse_nlmsg_error; |
|---|
| 473 | 514 | } |
|---|
| 474 | | - ret = nlmsg_parse(cb->nlh, nlh_len, nltb, policy_max - 1, |
|---|
| 475 | | - nlmsg_policy, NULL); |
|---|
| 515 | + ret = nlmsg_parse_deprecated(cb->nlh, nlh_len, nltb, policy_max - 1, |
|---|
| 516 | + nlmsg_policy, NULL); |
|---|
| 476 | 517 | if (ret) { |
|---|
| 477 | 518 | err_str = "Unable to parse the nlmsg"; |
|---|
| 478 | 519 | goto parse_nlmsg_error; |
|---|
| .. | .. |
|---|
| 604 | 645 | |
|---|
| 605 | 646 | nlmsg_end(skb, nlh); |
|---|
| 606 | 647 | |
|---|
| 607 | | - ret = rdma_nl_unicast(skb, iwpm_pid); |
|---|
| 648 | + ret = rdma_nl_unicast(&init_net, skb, iwpm_pid); |
|---|
| 608 | 649 | if (ret) { |
|---|
| 609 | 650 | skb = NULL; |
|---|
| 610 | 651 | err_str = "Unable to send a nlmsg"; |
|---|
| .. | .. |
|---|
| 614 | 655 | return 0; |
|---|
| 615 | 656 | mapinfo_num_error: |
|---|
| 616 | 657 | pr_info("%s: %s\n", __func__, err_str); |
|---|
| 617 | | - if (skb) |
|---|
| 618 | | - dev_kfree_skb(skb); |
|---|
| 658 | + dev_kfree_skb(skb); |
|---|
| 619 | 659 | return ret; |
|---|
| 620 | 660 | } |
|---|
| 621 | 661 | |
|---|
| .. | .. |
|---|
| 633 | 673 | return -ENOMEM; |
|---|
| 634 | 674 | } |
|---|
| 635 | 675 | nlh->nlmsg_type = NLMSG_DONE; |
|---|
| 636 | | - ret = rdma_nl_unicast(skb, iwpm_pid); |
|---|
| 676 | + ret = rdma_nl_unicast(&init_net, skb, iwpm_pid); |
|---|
| 637 | 677 | if (ret) |
|---|
| 638 | 678 | pr_warn("%s Unable to send a nlmsg\n", __func__); |
|---|
| 639 | 679 | return ret; |
|---|
| .. | .. |
|---|
| 686 | 726 | if (ret) |
|---|
| 687 | 727 | goto send_mapping_info_unlock; |
|---|
| 688 | 728 | |
|---|
| 729 | + if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) { |
|---|
| 730 | + ret = ibnl_put_attr(skb, nlh, sizeof(u32), |
|---|
| 731 | + &map_info->map_flags, |
|---|
| 732 | + IWPM_NLA_MAPINFO_FLAGS); |
|---|
| 733 | + if (ret) |
|---|
| 734 | + goto send_mapping_info_unlock; |
|---|
| 735 | + } |
|---|
| 736 | + |
|---|
| 689 | 737 | nlmsg_end(skb, nlh); |
|---|
| 690 | 738 | |
|---|
| 691 | 739 | iwpm_print_sockaddr(&map_info->local_sockaddr, |
|---|
| .. | .. |
|---|
| 729 | 777 | send_mapping_info_exit: |
|---|
| 730 | 778 | if (ret) { |
|---|
| 731 | 779 | pr_warn("%s: %s (ret = %d)\n", __func__, err_str, ret); |
|---|
| 732 | | - if (skb) |
|---|
| 733 | | - dev_kfree_skb(skb); |
|---|
| 780 | + dev_kfree_skb(skb); |
|---|
| 734 | 781 | return ret; |
|---|
| 735 | 782 | } |
|---|
| 736 | 783 | send_nlmsg_done(skb, nl_client, iwpm_pid); |
|---|
| .. | .. |
|---|
| 754 | 801 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); |
|---|
| 755 | 802 | return full_bucket; |
|---|
| 756 | 803 | } |
|---|
| 804 | + |
|---|
| 805 | +int iwpm_send_hello(u8 nl_client, int iwpm_pid, u16 abi_version) |
|---|
| 806 | +{ |
|---|
| 807 | + struct sk_buff *skb = NULL; |
|---|
| 808 | + struct nlmsghdr *nlh; |
|---|
| 809 | + const char *err_str = ""; |
|---|
| 810 | + int ret = -EINVAL; |
|---|
| 811 | + |
|---|
| 812 | + skb = iwpm_create_nlmsg(RDMA_NL_IWPM_HELLO, &nlh, nl_client); |
|---|
| 813 | + if (!skb) { |
|---|
| 814 | + err_str = "Unable to create a nlmsg"; |
|---|
| 815 | + goto hello_num_error; |
|---|
| 816 | + } |
|---|
| 817 | + nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); |
|---|
| 818 | + err_str = "Unable to put attribute of abi_version into nlmsg"; |
|---|
| 819 | + ret = ibnl_put_attr(skb, nlh, sizeof(u16), &abi_version, |
|---|
| 820 | + IWPM_NLA_HELLO_ABI_VERSION); |
|---|
| 821 | + if (ret) |
|---|
| 822 | + goto hello_num_error; |
|---|
| 823 | + nlmsg_end(skb, nlh); |
|---|
| 824 | + |
|---|
| 825 | + ret = rdma_nl_unicast(&init_net, skb, iwpm_pid); |
|---|
| 826 | + if (ret) { |
|---|
| 827 | + skb = NULL; |
|---|
| 828 | + err_str = "Unable to send a nlmsg"; |
|---|
| 829 | + goto hello_num_error; |
|---|
| 830 | + } |
|---|
| 831 | + pr_debug("%s: Sent hello abi_version = %u\n", __func__, abi_version); |
|---|
| 832 | + return 0; |
|---|
| 833 | +hello_num_error: |
|---|
| 834 | + pr_info("%s: %s\n", __func__, err_str); |
|---|
| 835 | + dev_kfree_skb(skb); |
|---|
| 836 | + return ret; |
|---|
| 837 | +} |
|---|