aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorTatyana Nikolova <Tatyana.E.Nikolova@intel.com>2015-04-21 16:28:10 -0400
committerDoug Ledford <dledford@redhat.com>2015-05-05 09:18:01 -0400
commit6eec177461751f0fe191cf9977cde692b9481d0a (patch)
tree0e4eebf1d276bab4714bae1b846b6016f246ad6a /drivers/infiniband
parent4a75a86c8d04390f268d7237cc49fe9a8e36efe7 (diff)
RDMA/core: Enable the iWarp Port Mapper to provide the actual address of the connecting peer to its clients
Add functionality to enable the port mapper on the passive side to provide to its clients the actual (non-mapped) ip/tcp address information of the connecting peer 1) Adding remote_info_cb() to process the address info of the connecting peer The address info is provided by the user space port mapper service when the connection is initiated by the peer 2) Adding a hash list to store the remote address info 3) Adding functionality to add/remove the remote address info After the info has been provided to the port mapper client, it is removed from the hash list Signed-off-by: Tatyana Nikolova <tatyana.e.nikolova@intel.com> Reviewed-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/iwpm_msg.c73
-rw-r--r--drivers/infiniband/core/iwpm_util.c208
-rw-r--r--drivers/infiniband/core/iwpm_util.h15
3 files changed, 262 insertions, 34 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}
469EXPORT_SYMBOL(iwpm_add_mapping_cb); 469EXPORT_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 */
472static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { 473static 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}
560EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); 561EXPORT_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 */
567int 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}
631EXPORT_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 */
563static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { 634static 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,
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c
index 69e9f84c1605..a626795bf9c7 100644
--- a/drivers/infiniband/core/iwpm_util.c
+++ b/drivers/infiniband/core/iwpm_util.c
@@ -33,8 +33,10 @@
33 33
34#include "iwpm_util.h" 34#include "iwpm_util.h"
35 35
36#define IWPM_HASH_BUCKET_SIZE 512 36#define IWPM_MAPINFO_HASH_SIZE 512
37#define IWPM_HASH_BUCKET_MASK (IWPM_HASH_BUCKET_SIZE - 1) 37#define IWPM_MAPINFO_HASH_MASK (IWPM_MAPINFO_HASH_SIZE - 1)
38#define IWPM_REMINFO_HASH_SIZE 64
39#define IWPM_REMINFO_HASH_MASK (IWPM_REMINFO_HASH_SIZE - 1)
38 40
39static LIST_HEAD(iwpm_nlmsg_req_list); 41static LIST_HEAD(iwpm_nlmsg_req_list);
40static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock); 42static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock);
@@ -42,31 +44,49 @@ static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock);
42static struct hlist_head *iwpm_hash_bucket; 44static struct hlist_head *iwpm_hash_bucket;
43static DEFINE_SPINLOCK(iwpm_mapinfo_lock); 45static DEFINE_SPINLOCK(iwpm_mapinfo_lock);
44 46
47static struct hlist_head *iwpm_reminfo_bucket;
48static DEFINE_SPINLOCK(iwpm_reminfo_lock);
49
45static DEFINE_MUTEX(iwpm_admin_lock); 50static DEFINE_MUTEX(iwpm_admin_lock);
46static struct iwpm_admin_data iwpm_admin; 51static struct iwpm_admin_data iwpm_admin;
47 52
48int iwpm_init(u8 nl_client) 53int iwpm_init(u8 nl_client)
49{ 54{
55 int ret = 0;
50 if (iwpm_valid_client(nl_client)) 56 if (iwpm_valid_client(nl_client))
51 return -EINVAL; 57 return -EINVAL;
52 mutex_lock(&iwpm_admin_lock); 58 mutex_lock(&iwpm_admin_lock);
53 if (atomic_read(&iwpm_admin.refcount) == 0) { 59 if (atomic_read(&iwpm_admin.refcount) == 0) {
54 iwpm_hash_bucket = kzalloc(IWPM_HASH_BUCKET_SIZE * 60 iwpm_hash_bucket = kzalloc(IWPM_MAPINFO_HASH_SIZE *
55 sizeof(struct hlist_head), GFP_KERNEL); 61 sizeof(struct hlist_head), GFP_KERNEL);
56 if (!iwpm_hash_bucket) { 62 if (!iwpm_hash_bucket) {
57 mutex_unlock(&iwpm_admin_lock); 63 ret = -ENOMEM;
58 pr_err("%s Unable to create mapinfo hash table\n", __func__); 64 pr_err("%s Unable to create mapinfo hash table\n", __func__);
59 return -ENOMEM; 65 goto init_exit;
66 }
67 iwpm_reminfo_bucket = kzalloc(IWPM_REMINFO_HASH_SIZE *
68 sizeof(struct hlist_head), GFP_KERNEL);
69 if (!iwpm_reminfo_bucket) {
70 kfree(iwpm_hash_bucket);
71 ret = -ENOMEM;
72 pr_err("%s Unable to create reminfo hash table\n", __func__);
73 goto init_exit;
60 } 74 }
61 } 75 }
62 atomic_inc(&iwpm_admin.refcount); 76 atomic_inc(&iwpm_admin.refcount);
77init_exit:
63 mutex_unlock(&iwpm_admin_lock); 78 mutex_unlock(&iwpm_admin_lock);
64 iwpm_set_valid(nl_client, 1); 79 if (!ret) {
65 return 0; 80 iwpm_set_valid(nl_client, 1);
81 pr_debug("%s: Mapinfo and reminfo tables are created\n",
82 __func__);
83 }
84 return ret;
66} 85}
67EXPORT_SYMBOL(iwpm_init); 86EXPORT_SYMBOL(iwpm_init);
68 87
69static void free_hash_bucket(void); 88static void free_hash_bucket(void);
89static void free_reminfo_bucket(void);
70 90
71int iwpm_exit(u8 nl_client) 91int iwpm_exit(u8 nl_client)
72{ 92{
@@ -81,7 +101,8 @@ int iwpm_exit(u8 nl_client)
81 } 101 }
82 if (atomic_dec_and_test(&iwpm_admin.refcount)) { 102 if (atomic_dec_and_test(&iwpm_admin.refcount)) {
83 free_hash_bucket(); 103 free_hash_bucket();
84 pr_debug("%s: Mapinfo hash table is destroyed\n", __func__); 104 free_reminfo_bucket();
105 pr_debug("%s: Resources are destroyed\n", __func__);
85 } 106 }
86 mutex_unlock(&iwpm_admin_lock); 107 mutex_unlock(&iwpm_admin_lock);
87 iwpm_set_valid(nl_client, 0); 108 iwpm_set_valid(nl_client, 0);
@@ -89,7 +110,7 @@ int iwpm_exit(u8 nl_client)
89} 110}
90EXPORT_SYMBOL(iwpm_exit); 111EXPORT_SYMBOL(iwpm_exit);
91 112
92static struct hlist_head *get_hash_bucket_head(struct sockaddr_storage *, 113static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage *,
93 struct sockaddr_storage *); 114 struct sockaddr_storage *);
94 115
95int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, 116int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr,
@@ -99,9 +120,10 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr,
99 struct hlist_head *hash_bucket_head; 120 struct hlist_head *hash_bucket_head;
100 struct iwpm_mapping_info *map_info; 121 struct iwpm_mapping_info *map_info;
101 unsigned long flags; 122 unsigned long flags;
123 int ret = -EINVAL;
102 124
103 if (!iwpm_valid_client(nl_client)) 125 if (!iwpm_valid_client(nl_client))
104 return -EINVAL; 126 return ret;
105 map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL); 127 map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL);
106 if (!map_info) { 128 if (!map_info) {
107 pr_err("%s: Unable to allocate a mapping info\n", __func__); 129 pr_err("%s: Unable to allocate a mapping info\n", __func__);
@@ -115,13 +137,16 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr,
115 137
116 spin_lock_irqsave(&iwpm_mapinfo_lock, flags); 138 spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
117 if (iwpm_hash_bucket) { 139 if (iwpm_hash_bucket) {
118 hash_bucket_head = get_hash_bucket_head( 140 hash_bucket_head = get_mapinfo_hash_bucket(
119 &map_info->local_sockaddr, 141 &map_info->local_sockaddr,
120 &map_info->mapped_sockaddr); 142 &map_info->mapped_sockaddr);
121 hlist_add_head(&map_info->hlist_node, hash_bucket_head); 143 if (hash_bucket_head) {
144 hlist_add_head(&map_info->hlist_node, hash_bucket_head);
145 ret = 0;
146 }
122 } 147 }
123 spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); 148 spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
124 return 0; 149 return ret;
125} 150}
126EXPORT_SYMBOL(iwpm_create_mapinfo); 151EXPORT_SYMBOL(iwpm_create_mapinfo);
127 152
@@ -136,9 +161,12 @@ int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr,
136 161
137 spin_lock_irqsave(&iwpm_mapinfo_lock, flags); 162 spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
138 if (iwpm_hash_bucket) { 163 if (iwpm_hash_bucket) {
139 hash_bucket_head = get_hash_bucket_head( 164 hash_bucket_head = get_mapinfo_hash_bucket(
140 local_sockaddr, 165 local_sockaddr,
141 mapped_local_addr); 166 mapped_local_addr);
167 if (!hash_bucket_head)
168 goto remove_mapinfo_exit;
169
142 hlist_for_each_entry_safe(map_info, tmp_hlist_node, 170 hlist_for_each_entry_safe(map_info, tmp_hlist_node,
143 hash_bucket_head, hlist_node) { 171 hash_bucket_head, hlist_node) {
144 172
@@ -152,6 +180,7 @@ int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr,
152 } 180 }
153 } 181 }
154 } 182 }
183remove_mapinfo_exit:
155 spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); 184 spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
156 return ret; 185 return ret;
157} 186}
@@ -166,7 +195,7 @@ static void free_hash_bucket(void)
166 195
167 /* remove all the mapinfo data from the list */ 196 /* remove all the mapinfo data from the list */
168 spin_lock_irqsave(&iwpm_mapinfo_lock, flags); 197 spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
169 for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { 198 for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
170 hlist_for_each_entry_safe(map_info, tmp_hlist_node, 199 hlist_for_each_entry_safe(map_info, tmp_hlist_node,
171 &iwpm_hash_bucket[i], hlist_node) { 200 &iwpm_hash_bucket[i], hlist_node) {
172 201
@@ -180,6 +209,96 @@ static void free_hash_bucket(void)
180 spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); 209 spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
181} 210}
182 211
212static void free_reminfo_bucket(void)
213{
214 struct hlist_node *tmp_hlist_node;
215 struct iwpm_remote_info *rem_info;
216 unsigned long flags;
217 int i;
218
219 /* remove all the remote info from the list */
220 spin_lock_irqsave(&iwpm_reminfo_lock, flags);
221 for (i = 0; i < IWPM_REMINFO_HASH_SIZE; i++) {
222 hlist_for_each_entry_safe(rem_info, tmp_hlist_node,
223 &iwpm_reminfo_bucket[i], hlist_node) {
224
225 hlist_del_init(&rem_info->hlist_node);
226 kfree(rem_info);
227 }
228 }
229 /* free the hash list */
230 kfree(iwpm_reminfo_bucket);
231 iwpm_reminfo_bucket = NULL;
232 spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
233}
234
235static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage *,
236 struct sockaddr_storage *);
237
238void iwpm_add_remote_info(struct iwpm_remote_info *rem_info)
239{
240 struct hlist_head *hash_bucket_head;
241 unsigned long flags;
242
243 spin_lock_irqsave(&iwpm_reminfo_lock, flags);
244 if (iwpm_reminfo_bucket) {
245 hash_bucket_head = get_reminfo_hash_bucket(
246 &rem_info->mapped_loc_sockaddr,
247 &rem_info->mapped_rem_sockaddr);
248 if (hash_bucket_head)
249 hlist_add_head(&rem_info->hlist_node, hash_bucket_head);
250 }
251 spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
252}
253
254int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr,
255 struct sockaddr_storage *mapped_rem_addr,
256 struct sockaddr_storage *remote_addr,
257 u8 nl_client)
258{
259 struct hlist_node *tmp_hlist_node;
260 struct hlist_head *hash_bucket_head;
261 struct iwpm_remote_info *rem_info = NULL;
262 unsigned long flags;
263 int ret = -EINVAL;
264
265 if (!iwpm_valid_client(nl_client)) {
266 pr_info("%s: Invalid client = %d\n", __func__, nl_client);
267 return ret;
268 }
269 spin_lock_irqsave(&iwpm_reminfo_lock, flags);
270 if (iwpm_reminfo_bucket) {
271 hash_bucket_head = get_reminfo_hash_bucket(
272 mapped_loc_addr,
273 mapped_rem_addr);
274 if (!hash_bucket_head)
275 goto get_remote_info_exit;
276 hlist_for_each_entry_safe(rem_info, tmp_hlist_node,
277 hash_bucket_head, hlist_node) {
278
279 if (!iwpm_compare_sockaddr(&rem_info->mapped_loc_sockaddr,
280 mapped_loc_addr) &&
281 !iwpm_compare_sockaddr(&rem_info->mapped_rem_sockaddr,
282 mapped_rem_addr)) {
283
284 memcpy(remote_addr, &rem_info->remote_sockaddr,
285 sizeof(struct sockaddr_storage));
286 iwpm_print_sockaddr(remote_addr,
287 "get_remote_info: Remote sockaddr:");
288
289 hlist_del_init(&rem_info->hlist_node);
290 kfree(rem_info);
291 ret = 0;
292 break;
293 }
294 }
295 }
296get_remote_info_exit:
297 spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
298 return ret;
299}
300EXPORT_SYMBOL(iwpm_get_remote_info);
301
183struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, 302struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
184 u8 nl_client, gfp_t gfp) 303 u8 nl_client, gfp_t gfp)
185{ 304{
@@ -409,31 +528,54 @@ static u32 iwpm_ipv4_jhash(struct sockaddr_in *ipv4_sockaddr)
409 return hash; 528 return hash;
410} 529}
411 530
412static struct hlist_head *get_hash_bucket_head(struct sockaddr_storage 531static int get_hash_bucket(struct sockaddr_storage *a_sockaddr,
413 *local_sockaddr, 532 struct sockaddr_storage *b_sockaddr, u32 *hash)
414 struct sockaddr_storage
415 *mapped_sockaddr)
416{ 533{
417 u32 local_hash, mapped_hash, hash; 534 u32 a_hash, b_hash;
418 535
419 if (local_sockaddr->ss_family == AF_INET) { 536 if (a_sockaddr->ss_family == AF_INET) {
420 local_hash = iwpm_ipv4_jhash((struct sockaddr_in *) local_sockaddr); 537 a_hash = iwpm_ipv4_jhash((struct sockaddr_in *) a_sockaddr);
421 mapped_hash = iwpm_ipv4_jhash((struct sockaddr_in *) mapped_sockaddr); 538 b_hash = iwpm_ipv4_jhash((struct sockaddr_in *) b_sockaddr);
422 539
423 } else if (local_sockaddr->ss_family == AF_INET6) { 540 } else if (a_sockaddr->ss_family == AF_INET6) {
424 local_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) local_sockaddr); 541 a_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) a_sockaddr);
425 mapped_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) mapped_sockaddr); 542 b_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) b_sockaddr);
426 } else { 543 } else {
427 pr_err("%s: Invalid sockaddr family\n", __func__); 544 pr_err("%s: Invalid sockaddr family\n", __func__);
428 return NULL; 545 return -EINVAL;
429 } 546 }
430 547
431 if (local_hash == mapped_hash) /* if port mapper isn't available */ 548 if (a_hash == b_hash) /* if port mapper isn't available */
432 hash = local_hash; 549 *hash = a_hash;
433 else 550 else
434 hash = jhash_2words(local_hash, mapped_hash, 0); 551 *hash = jhash_2words(a_hash, b_hash, 0);
552 return 0;
553}
554
555static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage
556 *local_sockaddr, struct sockaddr_storage
557 *mapped_sockaddr)
558{
559 u32 hash;
560 int ret;
435 561
436 return &iwpm_hash_bucket[hash & IWPM_HASH_BUCKET_MASK]; 562 ret = get_hash_bucket(local_sockaddr, mapped_sockaddr, &hash);
563 if (ret)
564 return NULL;
565 return &iwpm_hash_bucket[hash & IWPM_MAPINFO_HASH_MASK];
566}
567
568static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage
569 *mapped_loc_sockaddr, struct sockaddr_storage
570 *mapped_rem_sockaddr)
571{
572 u32 hash;
573 int ret;
574
575 ret = get_hash_bucket(mapped_loc_sockaddr, mapped_rem_sockaddr, &hash);
576 if (ret)
577 return NULL;
578 return &iwpm_reminfo_bucket[hash & IWPM_REMINFO_HASH_MASK];
437} 579}
438 580
439static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid) 581static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid)
@@ -512,7 +654,7 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid)
512 } 654 }
513 skb_num++; 655 skb_num++;
514 spin_lock_irqsave(&iwpm_mapinfo_lock, flags); 656 spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
515 for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { 657 for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
516 hlist_for_each_entry(map_info, &iwpm_hash_bucket[i], 658 hlist_for_each_entry(map_info, &iwpm_hash_bucket[i],
517 hlist_node) { 659 hlist_node) {
518 if (map_info->nl_client != nl_client) 660 if (map_info->nl_client != nl_client)
@@ -595,7 +737,7 @@ int iwpm_mapinfo_available(void)
595 737
596 spin_lock_irqsave(&iwpm_mapinfo_lock, flags); 738 spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
597 if (iwpm_hash_bucket) { 739 if (iwpm_hash_bucket) {
598 for (i = 0; i < IWPM_HASH_BUCKET_SIZE; i++) { 740 for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
599 if (!hlist_empty(&iwpm_hash_bucket[i])) { 741 if (!hlist_empty(&iwpm_hash_bucket[i])) {
600 full_bucket = 1; 742 full_bucket = 1;
601 break; 743 break;
diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h
index 9777c869a140..ee2d9ff095be 100644
--- a/drivers/infiniband/core/iwpm_util.h
+++ b/drivers/infiniband/core/iwpm_util.h
@@ -76,6 +76,14 @@ struct iwpm_mapping_info {
76 u8 nl_client; 76 u8 nl_client;
77}; 77};
78 78
79struct iwpm_remote_info {
80 struct hlist_node hlist_node;
81 struct sockaddr_storage remote_sockaddr;
82 struct sockaddr_storage mapped_loc_sockaddr;
83 struct sockaddr_storage mapped_rem_sockaddr;
84 u8 nl_client;
85};
86
79struct iwpm_admin_data { 87struct iwpm_admin_data {
80 atomic_t refcount; 88 atomic_t refcount;
81 atomic_t nlmsg_seq; 89 atomic_t nlmsg_seq;
@@ -128,6 +136,13 @@ int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request);
128int iwpm_get_nlmsg_seq(void); 136int iwpm_get_nlmsg_seq(void);
129 137
130/** 138/**
139 * iwpm_add_reminfo - Add remote address info of the connecting peer
140 * to the remote info hash table
141 * @reminfo: The remote info to be added
142 */
143void iwpm_add_remote_info(struct iwpm_remote_info *reminfo);
144
145/**
131 * iwpm_valid_client - Check if the port mapper client is valid 146 * iwpm_valid_client - Check if the port mapper client is valid
132 * @nl_client: The index of the netlink client 147 * @nl_client: The index of the netlink client
133 * 148 *