OSDN Git Service

RDMA/core: Fix incorrect print format specifier
[uclinux-h8/linux.git] / drivers / infiniband / core / iwpm_msg.c
1 /*
2  * Copyright (c) 2014 Intel Corporation. All rights reserved.
3  * Copyright (c) 2014 Chelsio, Inc. All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33
34 #include "iwpm_util.h"
35
36 static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser";
37 u16 iwpm_ulib_version = IWPM_UABI_VERSION_MIN;
38 static int iwpm_user_pid = IWPM_PID_UNDEFINED;
39 static atomic_t echo_nlmsg_seq;
40
41 /**
42  * iwpm_valid_pid - Check if the userspace iwarp port mapper pid is valid
43  *
44  * Returns true if the pid is greater than zero, otherwise returns false
45  */
46 int iwpm_valid_pid(void)
47 {
48         return iwpm_user_pid > 0;
49 }
50
51 /**
52  * iwpm_register_pid - Send a netlink query to userspace
53  *                     to get the iwarp port mapper pid
54  * @pm_msg: Contains driver info to send to the userspace port mapper
55  * @nl_client: The index of the netlink client
56  *
57  * nlmsg attributes:
58  *      [IWPM_NLA_REG_PID_SEQ]
59  *      [IWPM_NLA_REG_IF_NAME]
60  *      [IWPM_NLA_REG_IBDEV_NAME]
61  *      [IWPM_NLA_REG_ULIB_NAME]
62  */
63 int 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         /* fill in the pid request message */
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(&init_net, skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
116         if (ret) {
117                 skb = NULL; /* skb is freed in the netlink send-op handling */
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;
125 pid_query_error:
126         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
127         dev_kfree_skb(skb);
128         if (nlmsg_request)
129                 iwpm_free_nlmsg_request(&nlmsg_request->kref);
130         return ret;
131 }
132
133 /**
134  * iwpm_add_mapping - Send a netlink add mapping request to
135  *                    the userspace port mapper
136  * @pm_msg: Contains the local ip/tcp address info to send
137  * @nl_client: The index of the netlink client
138  *
139  * nlmsg attributes:
140  *      [IWPM_NLA_MANAGE_MAPPING_SEQ]
141  *      [IWPM_NLA_MANAGE_ADDR]
142  *      [IWPM_NLA_MANAGE_FLAGS]
143  *
144  * If the request is successful, the pm_msg stores
145  * the port mapper response (mapped address info)
146  */
147 int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
148 {
149         struct sk_buff *skb = NULL;
150         struct iwpm_nlmsg_request *nlmsg_request = NULL;
151         struct nlmsghdr *nlh;
152         u32 msg_seq;
153         const char *err_str = "";
154         int ret = -EINVAL;
155
156         if (!iwpm_valid_client(nl_client)) {
157                 err_str = "Invalid port mapper client";
158                 goto add_mapping_error;
159         }
160         if (!iwpm_valid_pid())
161                 return 0;
162         if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
163                 err_str = "Unregistered port mapper client";
164                 goto add_mapping_error;
165         }
166         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
167         if (!skb) {
168                 err_str = "Unable to create a nlmsg";
169                 goto add_mapping_error;
170         }
171         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
172         nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
173         if (!nlmsg_request) {
174                 err_str = "Unable to allocate netlink request";
175                 goto add_mapping_error;
176         }
177         msg_seq = atomic_read(&echo_nlmsg_seq);
178         /* fill in the add mapping message */
179         err_str = "Unable to put attribute of the nlmsg";
180         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
181                                 IWPM_NLA_MANAGE_MAPPING_SEQ);
182         if (ret)
183                 goto add_mapping_error;
184         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
185                                 &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR);
186         if (ret)
187                 goto add_mapping_error;
188
189         /* If flags are required and we're not V4, then return a quiet error */
190         if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
191                 ret = -EINVAL;
192                 goto add_mapping_error_nowarn;
193         }
194         if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
195                 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
196                                 IWPM_NLA_MANAGE_FLAGS);
197                 if (ret)
198                         goto add_mapping_error;
199         }
200
201         nlmsg_end(skb, nlh);
202         nlmsg_request->req_buffer = pm_msg;
203
204         ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
205         if (ret) {
206                 skb = NULL; /* skb is freed in the netlink send-op handling */
207                 iwpm_user_pid = IWPM_PID_UNDEFINED;
208                 err_str = "Unable to send a nlmsg";
209                 goto add_mapping_error;
210         }
211         ret = iwpm_wait_complete_req(nlmsg_request);
212         return ret;
213 add_mapping_error:
214         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
215 add_mapping_error_nowarn:
216         dev_kfree_skb(skb);
217         if (nlmsg_request)
218                 iwpm_free_nlmsg_request(&nlmsg_request->kref);
219         return ret;
220 }
221
222 /**
223  * iwpm_add_and_query_mapping - Process the port mapper response to
224  *                              iwpm_add_and_query_mapping request
225  * @pm_msg: Contains the local ip/tcp address info to send
226  * @nl_client: The index of the netlink client
227  *
228  * nlmsg attributes:
229  *      [IWPM_NLA_QUERY_MAPPING_SEQ]
230  *      [IWPM_NLA_QUERY_LOCAL_ADDR]
231  *      [IWPM_NLA_QUERY_REMOTE_ADDR]
232  *      [IWPM_NLA_QUERY_FLAGS]
233  */
234 int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
235 {
236         struct sk_buff *skb = NULL;
237         struct iwpm_nlmsg_request *nlmsg_request = NULL;
238         struct nlmsghdr *nlh;
239         u32 msg_seq;
240         const char *err_str = "";
241         int ret = -EINVAL;
242
243         if (!iwpm_valid_client(nl_client)) {
244                 err_str = "Invalid port mapper client";
245                 goto query_mapping_error;
246         }
247         if (!iwpm_valid_pid())
248                 return 0;
249         if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
250                 err_str = "Unregistered port mapper client";
251                 goto query_mapping_error;
252         }
253         ret = -ENOMEM;
254         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client);
255         if (!skb) {
256                 err_str = "Unable to create a nlmsg";
257                 goto query_mapping_error;
258         }
259         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
260         nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq,
261                                 nl_client, GFP_KERNEL);
262         if (!nlmsg_request) {
263                 err_str = "Unable to allocate netlink request";
264                 goto query_mapping_error;
265         }
266         msg_seq = atomic_read(&echo_nlmsg_seq);
267
268         /* fill in the query message */
269         err_str = "Unable to put attribute of the nlmsg";
270         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
271                                 IWPM_NLA_QUERY_MAPPING_SEQ);
272         if (ret)
273                 goto query_mapping_error;
274         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
275                                 &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR);
276         if (ret)
277                 goto query_mapping_error;
278         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
279                                 &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR);
280         if (ret)
281                 goto query_mapping_error;
282
283         /* If flags are required and we're not V4, then return a quite error */
284         if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
285                 ret = -EINVAL;
286                 goto query_mapping_error_nowarn;
287         }
288         if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
289                 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
290                                 IWPM_NLA_QUERY_FLAGS);
291                 if (ret)
292                         goto query_mapping_error;
293         }
294
295         nlmsg_end(skb, nlh);
296         nlmsg_request->req_buffer = pm_msg;
297
298         ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
299         if (ret) {
300                 skb = NULL; /* skb is freed in the netlink send-op handling */
301                 err_str = "Unable to send a nlmsg";
302                 goto query_mapping_error;
303         }
304         ret = iwpm_wait_complete_req(nlmsg_request);
305         return ret;
306 query_mapping_error:
307         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
308 query_mapping_error_nowarn:
309         dev_kfree_skb(skb);
310         if (nlmsg_request)
311                 iwpm_free_nlmsg_request(&nlmsg_request->kref);
312         return ret;
313 }
314
315 /**
316  * iwpm_remove_mapping - Send a netlink remove mapping request
317  *                       to the userspace port mapper
318  *
319  * @local_addr: Local ip/tcp address to remove
320  * @nl_client: The index of the netlink client
321  *
322  * nlmsg attributes:
323  *      [IWPM_NLA_MANAGE_MAPPING_SEQ]
324  *      [IWPM_NLA_MANAGE_ADDR]
325  */
326 int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
327 {
328         struct sk_buff *skb = NULL;
329         struct nlmsghdr *nlh;
330         u32 msg_seq;
331         const char *err_str = "";
332         int ret = -EINVAL;
333
334         if (!iwpm_valid_client(nl_client)) {
335                 err_str = "Invalid port mapper client";
336                 goto remove_mapping_error;
337         }
338         if (!iwpm_valid_pid())
339                 return 0;
340         if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
341                 err_str = "Unregistered port mapper client";
342                 goto remove_mapping_error;
343         }
344         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
345         if (!skb) {
346                 ret = -ENOMEM;
347                 err_str = "Unable to create a nlmsg";
348                 goto remove_mapping_error;
349         }
350         msg_seq = atomic_read(&echo_nlmsg_seq);
351         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
352         err_str = "Unable to put attribute of the nlmsg";
353         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
354                                 IWPM_NLA_MANAGE_MAPPING_SEQ);
355         if (ret)
356                 goto remove_mapping_error;
357         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
358                                 local_addr, IWPM_NLA_MANAGE_ADDR);
359         if (ret)
360                 goto remove_mapping_error;
361
362         nlmsg_end(skb, nlh);
363
364         ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
365         if (ret) {
366                 skb = NULL; /* skb is freed in the netlink send-op handling */
367                 iwpm_user_pid = IWPM_PID_UNDEFINED;
368                 err_str = "Unable to send a nlmsg";
369                 goto remove_mapping_error;
370         }
371         iwpm_print_sockaddr(local_addr,
372                         "remove_mapping: Local sockaddr:");
373         return 0;
374 remove_mapping_error:
375         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
376         if (skb)
377                 dev_kfree_skb_any(skb);
378         return ret;
379 }
380
381 /* netlink attribute policy for the received response to register pid request */
382 static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = {
383         [IWPM_NLA_RREG_PID_SEQ]     = { .type = NLA_U32 },
384         [IWPM_NLA_RREG_IBDEV_NAME]  = { .type = NLA_STRING,
385                                         .len = IWPM_DEVNAME_SIZE - 1 },
386         [IWPM_NLA_RREG_ULIB_NAME]   = { .type = NLA_STRING,
387                                         .len = IWPM_ULIBNAME_SIZE - 1 },
388         [IWPM_NLA_RREG_ULIB_VER]    = { .type = NLA_U16 },
389         [IWPM_NLA_RREG_PID_ERR]     = { .type = NLA_U16 }
390 };
391
392 /**
393  * iwpm_register_pid_cb - Process the port mapper response to
394  *                        iwpm_register_pid query
395  * @skb: The socket buffer
396  * @cb: Contains the received message (payload and netlink header)
397  *
398  * If successful, the function receives the userspace port mapper pid
399  * which is used in future communication with the port mapper
400  */
401 int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
402 {
403         struct iwpm_nlmsg_request *nlmsg_request = NULL;
404         struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX];
405         struct iwpm_dev_data *pm_msg;
406         char *dev_name, *iwpm_name;
407         u32 msg_seq;
408         u8 nl_client;
409         u16 iwpm_version;
410         const char *msg_type = "Register Pid response";
411
412         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX,
413                                 resp_reg_policy, nltb, msg_type))
414                 return -EINVAL;
415
416         msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]);
417         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
418         if (!nlmsg_request) {
419                 pr_info("%s: Could not find a matching request (seq = %u)\n",
420                                  __func__, msg_seq);
421                 return -EINVAL;
422         }
423         pm_msg = nlmsg_request->req_buffer;
424         nl_client = nlmsg_request->nl_client;
425         dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]);
426         iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]);
427         iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]);
428
429         /* check device name, ulib name and version */
430         if (strcmp(pm_msg->dev_name, dev_name) ||
431                         strcmp(iwpm_ulib_name, iwpm_name) ||
432                         iwpm_version < IWPM_UABI_VERSION_MIN) {
433
434                 pr_info("%s: Incorrect info (dev = %s name = %s version = %u)\n",
435                                 __func__, dev_name, iwpm_name, iwpm_version);
436                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
437                 goto register_pid_response_exit;
438         }
439         iwpm_user_pid = cb->nlh->nlmsg_pid;
440         iwpm_ulib_version = iwpm_version;
441         if (iwpm_ulib_version < IWPM_UABI_VERSION)
442                 pr_warn_once("%s: Down level iwpmd/pid %d.  Continuing...",
443                         __func__, iwpm_user_pid);
444         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
445         pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
446                         __func__, iwpm_user_pid);
447         if (iwpm_valid_client(nl_client))
448                 iwpm_set_registration(nl_client, IWPM_REG_VALID);
449 register_pid_response_exit:
450         nlmsg_request->request_done = 1;
451         /* always for found nlmsg_request */
452         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
453         barrier();
454         up(&nlmsg_request->sem);
455         return 0;
456 }
457
458 /* netlink attribute policy for the received response to add mapping request */
459 static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = {
460         [IWPM_NLA_RMANAGE_MAPPING_SEQ]     = { .type = NLA_U32 },
461         [IWPM_NLA_RMANAGE_ADDR]            = {
462                                 .len = sizeof(struct sockaddr_storage) },
463         [IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR] = {
464                                 .len = sizeof(struct sockaddr_storage) },
465         [IWPM_NLA_RMANAGE_MAPPING_ERR]     = { .type = NLA_U16 }
466 };
467
468 /**
469  * iwpm_add_mapping_cb - Process the port mapper response to
470  *                       iwpm_add_mapping request
471  * @skb: The socket buffer
472  * @cb: Contains the received message (payload and netlink header)
473  */
474 int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb)
475 {
476         struct iwpm_sa_data *pm_msg;
477         struct iwpm_nlmsg_request *nlmsg_request = NULL;
478         struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX];
479         struct sockaddr_storage *local_sockaddr;
480         struct sockaddr_storage *mapped_sockaddr;
481         const char *msg_type;
482         u32 msg_seq;
483
484         msg_type = "Add Mapping response";
485         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX,
486                                 resp_add_policy, nltb, msg_type))
487                 return -EINVAL;
488
489         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
490
491         msg_seq = nla_get_u32(nltb[IWPM_NLA_RMANAGE_MAPPING_SEQ]);
492         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
493         if (!nlmsg_request) {
494                 pr_info("%s: Could not find a matching request (seq = %u)\n",
495                                  __func__, msg_seq);
496                 return -EINVAL;
497         }
498         pm_msg = nlmsg_request->req_buffer;
499         local_sockaddr = (struct sockaddr_storage *)
500                         nla_data(nltb[IWPM_NLA_RMANAGE_ADDR]);
501         mapped_sockaddr = (struct sockaddr_storage *)
502                         nla_data(nltb[IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR]);
503
504         if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) {
505                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
506                 goto add_mapping_response_exit;
507         }
508         if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) {
509                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
510                                 __func__);
511                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
512                 goto add_mapping_response_exit;
513         }
514         memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr,
515                         sizeof(*mapped_sockaddr));
516         iwpm_print_sockaddr(&pm_msg->loc_addr,
517                         "add_mapping: Local sockaddr:");
518         iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
519                         "add_mapping: Mapped local sockaddr:");
520
521 add_mapping_response_exit:
522         nlmsg_request->request_done = 1;
523         /* always for found request */
524         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
525         barrier();
526         up(&nlmsg_request->sem);
527         return 0;
528 }
529
530 /* netlink attribute policy for the response to add and query mapping request
531  * and response with remote address info
532  */
533 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = {
534         [IWPM_NLA_RQUERY_MAPPING_SEQ]     = { .type = NLA_U32 },
535         [IWPM_NLA_RQUERY_LOCAL_ADDR]      = {
536                                 .len = sizeof(struct sockaddr_storage) },
537         [IWPM_NLA_RQUERY_REMOTE_ADDR]     = {
538                                 .len = sizeof(struct sockaddr_storage) },
539         [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = {
540                                 .len = sizeof(struct sockaddr_storage) },
541         [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = {
542                                 .len = sizeof(struct sockaddr_storage) },
543         [IWPM_NLA_RQUERY_MAPPING_ERR]     = { .type = NLA_U16 }
544 };
545
546 /**
547  * iwpm_add_and_query_mapping_cb - Process the port mapper response to
548  *                                 iwpm_add_and_query_mapping request
549  * @skb: The socket buffer
550  * @cb: Contains the received message (payload and netlink header)
551  */
552 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
553                                 struct netlink_callback *cb)
554 {
555         struct iwpm_sa_data *pm_msg;
556         struct iwpm_nlmsg_request *nlmsg_request = NULL;
557         struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
558         struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
559         struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
560         const char *msg_type;
561         u32 msg_seq;
562         u16 err_code;
563
564         msg_type = "Query Mapping response";
565         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
566                                 resp_query_policy, nltb, msg_type))
567                 return -EINVAL;
568         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
569
570         msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]);
571         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
572         if (!nlmsg_request) {
573                 pr_info("%s: Could not find a matching request (seq = %u)\n",
574                                  __func__, msg_seq);
575                 return -EINVAL;
576         }
577         pm_msg = nlmsg_request->req_buffer;
578         local_sockaddr = (struct sockaddr_storage *)
579                         nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
580         remote_sockaddr = (struct sockaddr_storage *)
581                         nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
582         mapped_loc_sockaddr = (struct sockaddr_storage *)
583                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
584         mapped_rem_sockaddr = (struct sockaddr_storage *)
585                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
586
587         err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]);
588         if (err_code == IWPM_REMOTE_QUERY_REJECT) {
589                 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
590                         __func__, cb->nlh->nlmsg_pid, msg_seq);
591                 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT;
592         }
593         if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) ||
594                 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) {
595                 pr_info("%s: Incorrect local sockaddr\n", __func__);
596                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
597                 goto query_mapping_response_exit;
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                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
604                 goto query_mapping_response_exit;
605         }
606         memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr,
607                         sizeof(*mapped_loc_sockaddr));
608         memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr,
609                         sizeof(*mapped_rem_sockaddr));
610
611         iwpm_print_sockaddr(&pm_msg->loc_addr,
612                         "query_mapping: Local sockaddr:");
613         iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
614                         "query_mapping: Mapped local sockaddr:");
615         iwpm_print_sockaddr(&pm_msg->rem_addr,
616                         "query_mapping: Remote sockaddr:");
617         iwpm_print_sockaddr(&pm_msg->mapped_rem_addr,
618                         "query_mapping: Mapped remote sockaddr:");
619 query_mapping_response_exit:
620         nlmsg_request->request_done = 1;
621         /* always for found request */
622         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
623         barrier();
624         up(&nlmsg_request->sem);
625         return 0;
626 }
627
628 /**
629  * iwpm_remote_info_cb - Process remote connecting peer address info, which
630  *                       the port mapper has received from the connecting peer
631  * @skb: The socket buffer
632  * @cb: Contains the received message (payload and netlink header)
633  *
634  * Stores the IPv4/IPv6 address info in a hash table
635  */
636 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
637 {
638         struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
639         struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
640         struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
641         struct iwpm_remote_info *rem_info;
642         const char *msg_type;
643         u8 nl_client;
644         int ret = -EINVAL;
645
646         msg_type = "Remote Mapping info";
647         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
648                                 resp_query_policy, nltb, msg_type))
649                 return ret;
650
651         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
652         if (!iwpm_valid_client(nl_client)) {
653                 pr_info("%s: Invalid port mapper client = %u\n",
654                                 __func__, nl_client);
655                 return ret;
656         }
657         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
658
659         local_sockaddr = (struct sockaddr_storage *)
660                         nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
661         remote_sockaddr = (struct sockaddr_storage *)
662                         nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
663         mapped_loc_sockaddr = (struct sockaddr_storage *)
664                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
665         mapped_rem_sockaddr = (struct sockaddr_storage *)
666                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
667
668         if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
669                 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
670                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
671                                 __func__);
672                 return ret;
673         }
674         rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
675         if (!rem_info) {
676                 ret = -ENOMEM;
677                 return ret;
678         }
679         memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr,
680                sizeof(struct sockaddr_storage));
681         memcpy(&rem_info->remote_sockaddr, remote_sockaddr,
682                sizeof(struct sockaddr_storage));
683         memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr,
684                sizeof(struct sockaddr_storage));
685         rem_info->nl_client = nl_client;
686
687         iwpm_add_remote_info(rem_info);
688
689         iwpm_print_sockaddr(local_sockaddr,
690                         "remote_info: Local sockaddr:");
691         iwpm_print_sockaddr(mapped_loc_sockaddr,
692                         "remote_info: Mapped local sockaddr:");
693         iwpm_print_sockaddr(remote_sockaddr,
694                         "remote_info: Remote sockaddr:");
695         iwpm_print_sockaddr(mapped_rem_sockaddr,
696                         "remote_info: Mapped remote sockaddr:");
697         return ret;
698 }
699
700 /* netlink attribute policy for the received request for mapping info */
701 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
702         [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING,
703                                         .len = IWPM_ULIBNAME_SIZE - 1 },
704         [IWPM_NLA_MAPINFO_ULIB_VER]  = { .type = NLA_U16 }
705 };
706
707 /**
708  * iwpm_mapping_info_cb - Process a notification that the userspace
709  *                        port mapper daemon is started
710  * @skb: The socket buffer
711  * @cb: Contains the received message (payload and netlink header)
712  *
713  * Using the received port mapper pid, send all the local mapping
714  * info records to the userspace port mapper
715  */
716 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
717 {
718         struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
719         const char *msg_type = "Mapping Info response";
720         u8 nl_client;
721         char *iwpm_name;
722         u16 iwpm_version;
723         int ret = -EINVAL;
724
725         if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX,
726                                 resp_mapinfo_policy, nltb, msg_type)) {
727                 pr_info("%s: Unable to parse nlmsg\n", __func__);
728                 return ret;
729         }
730         iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]);
731         iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]);
732         if (strcmp(iwpm_ulib_name, iwpm_name) ||
733                         iwpm_version < IWPM_UABI_VERSION_MIN) {
734                 pr_info("%s: Invalid port mapper name = %s version = %u\n",
735                                 __func__, iwpm_name, iwpm_version);
736                 return ret;
737         }
738         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
739         if (!iwpm_valid_client(nl_client)) {
740                 pr_info("%s: Invalid port mapper client = %u\n",
741                                 __func__, nl_client);
742                 return ret;
743         }
744         iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
745         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
746         iwpm_user_pid = cb->nlh->nlmsg_pid;
747
748         if (iwpm_ulib_version < IWPM_UABI_VERSION)
749                 pr_warn_once("%s: Down level iwpmd/pid %d.  Continuing...",
750                         __func__, iwpm_user_pid);
751
752         if (!iwpm_mapinfo_available())
753                 return 0;
754         pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
755                  __func__, iwpm_user_pid);
756         ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
757         return ret;
758 }
759
760 /* netlink attribute policy for the received mapping info ack */
761 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
762         [IWPM_NLA_MAPINFO_SEQ]    =   { .type = NLA_U32 },
763         [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 },
764         [IWPM_NLA_MAPINFO_ACK_NUM] =  { .type = NLA_U32 }
765 };
766
767 /**
768  * iwpm_ack_mapping_info_cb - Process the port mapper ack for
769  *                            the provided local mapping info records
770  * @skb: The socket buffer
771  * @cb: Contains the received message (payload and netlink header)
772  */
773 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
774 {
775         struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX];
776         u32 mapinfo_send, mapinfo_ack;
777         const char *msg_type = "Mapping Info Ack";
778
779         if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX,
780                                 ack_mapinfo_policy, nltb, msg_type))
781                 return -EINVAL;
782         mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]);
783         mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]);
784         if (mapinfo_ack != mapinfo_send)
785                 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
786                         __func__, mapinfo_send, mapinfo_ack);
787         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
788         return 0;
789 }
790
791 /* netlink attribute policy for the received port mapper error message */
792 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
793         [IWPM_NLA_ERR_SEQ]        = { .type = NLA_U32 },
794         [IWPM_NLA_ERR_CODE]       = { .type = NLA_U16 },
795 };
796
797 /**
798  * iwpm_mapping_error_cb - Process port mapper notification for error
799  *
800  * @skb: The socket buffer
801  * @cb: Contains the received message (payload and netlink header)
802  */
803 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
804 {
805         struct iwpm_nlmsg_request *nlmsg_request = NULL;
806         int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
807         struct nlattr *nltb[IWPM_NLA_ERR_MAX];
808         u32 msg_seq;
809         u16 err_code;
810         const char *msg_type = "Mapping Error Msg";
811
812         if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX,
813                                 map_error_policy, nltb, msg_type))
814                 return -EINVAL;
815
816         msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]);
817         err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]);
818         pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
819                                 __func__, msg_seq, err_code, nl_client);
820         /* look for nlmsg_request */
821         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
822         if (!nlmsg_request) {
823                 /* not all errors have associated requests */
824                 pr_debug("Could not find matching req (seq = %u)\n", msg_seq);
825                 return 0;
826         }
827         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
828         nlmsg_request->err_code = err_code;
829         nlmsg_request->request_done = 1;
830         /* always for found request */
831         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
832         barrier();
833         up(&nlmsg_request->sem);
834         return 0;
835 }
836
837 /* netlink attribute policy for the received hello request */
838 static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = {
839         [IWPM_NLA_HELLO_ABI_VERSION]     = { .type = NLA_U16 }
840 };
841
842 /**
843  * iwpm_hello_cb - Process a hello message from iwpmd
844  *
845  * @skb: The socket buffer
846  * @cb: Contains the received message (payload and netlink header)
847  *
848  * Using the received port mapper pid, send the kernel's abi_version
849  * after adjusting it to support the iwpmd version.
850  */
851 int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb)
852 {
853         struct nlattr *nltb[IWPM_NLA_HELLO_MAX];
854         const char *msg_type = "Hello request";
855         u8 nl_client;
856         u16 abi_version;
857         int ret = -EINVAL;
858
859         if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb,
860                              msg_type)) {
861                 pr_info("%s: Unable to parse nlmsg\n", __func__);
862                 return ret;
863         }
864         abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]);
865         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
866         if (!iwpm_valid_client(nl_client)) {
867                 pr_info("%s: Invalid port mapper client = %u\n",
868                                 __func__, nl_client);
869                 return ret;
870         }
871         iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
872         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
873         iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version);
874         pr_debug("Using ABI version %u\n", iwpm_ulib_version);
875         iwpm_user_pid = cb->nlh->nlmsg_pid;
876         ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version);
877         return ret;
878 }