Merge tag 'drm-next-2019-09-27' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.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 = %d)\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 = %d)\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 = %d)\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 = %d)\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:
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 = %d)\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 %u.  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:
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 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = {
533         [IWPM_NLA_RQUERY_MAPPING_SEQ]     = { .type = NLA_U32 },
534         [IWPM_NLA_RQUERY_LOCAL_ADDR]      = {
535                                 .len = sizeof(struct sockaddr_storage) },
536         [IWPM_NLA_RQUERY_REMOTE_ADDR]     = {
537                                 .len = sizeof(struct sockaddr_storage) },
538         [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = {
539                                 .len = sizeof(struct sockaddr_storage) },
540         [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = {
541                                 .len = sizeof(struct sockaddr_storage) },
542         [IWPM_NLA_RQUERY_MAPPING_ERR]     = { .type = NLA_U16 }
543 };
544
545 /**
546  * iwpm_add_and_query_mapping_cb - Process the port mapper response to
547  *                                 iwpm_add_and_query_mapping request
548  * @skb:
549  * @cb: Contains the received message (payload and netlink header)
550  */
551 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
552                                 struct netlink_callback *cb)
553 {
554         struct iwpm_sa_data *pm_msg;
555         struct iwpm_nlmsg_request *nlmsg_request = NULL;
556         struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
557         struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
558         struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
559         const char *msg_type;
560         u32 msg_seq;
561         u16 err_code;
562
563         msg_type = "Query Mapping response";
564         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
565                                 resp_query_policy, nltb, msg_type))
566                 return -EINVAL;
567         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
568
569         msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]);
570         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
571         if (!nlmsg_request) {
572                 pr_info("%s: Could not find a matching request (seq = %u)\n",
573                                  __func__, msg_seq);
574                 return -EINVAL;
575         }
576         pm_msg = nlmsg_request->req_buffer;
577         local_sockaddr = (struct sockaddr_storage *)
578                         nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
579         remote_sockaddr = (struct sockaddr_storage *)
580                         nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
581         mapped_loc_sockaddr = (struct sockaddr_storage *)
582                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
583         mapped_rem_sockaddr = (struct sockaddr_storage *)
584                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
585
586         err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]);
587         if (err_code == IWPM_REMOTE_QUERY_REJECT) {
588                 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
589                         __func__, cb->nlh->nlmsg_pid, msg_seq);
590                 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT;
591         }
592         if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) ||
593                 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) {
594                 pr_info("%s: Incorrect local sockaddr\n", __func__);
595                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
596                 goto query_mapping_response_exit;
597         }
598         if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
599                 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
600                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
601                                 __func__);
602                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
603                 goto query_mapping_response_exit;
604         }
605         memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr,
606                         sizeof(*mapped_loc_sockaddr));
607         memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr,
608                         sizeof(*mapped_rem_sockaddr));
609
610         iwpm_print_sockaddr(&pm_msg->loc_addr,
611                         "query_mapping: Local sockaddr:");
612         iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
613                         "query_mapping: Mapped local sockaddr:");
614         iwpm_print_sockaddr(&pm_msg->rem_addr,
615                         "query_mapping: Remote sockaddr:");
616         iwpm_print_sockaddr(&pm_msg->mapped_rem_addr,
617                         "query_mapping: Mapped remote sockaddr:");
618 query_mapping_response_exit:
619         nlmsg_request->request_done = 1;
620         /* always for found request */
621         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
622         barrier();
623         up(&nlmsg_request->sem);
624         return 0;
625 }
626
627 /**
628  * iwpm_remote_info_cb - Process remote connecting peer address info, which
629  *                       the port mapper has received from the connecting peer
630  * @skb:
631  * @cb: Contains the received message (payload and netlink header)
632  *
633  * Stores the IPv4/IPv6 address info in a hash table
634  */
635 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
636 {
637         struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
638         struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
639         struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
640         struct iwpm_remote_info *rem_info;
641         const char *msg_type;
642         u8 nl_client;
643         int ret = -EINVAL;
644
645         msg_type = "Remote Mapping info";
646         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
647                                 resp_query_policy, nltb, msg_type))
648                 return ret;
649
650         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
651         if (!iwpm_valid_client(nl_client)) {
652                 pr_info("%s: Invalid port mapper client = %d\n",
653                                 __func__, nl_client);
654                 return ret;
655         }
656         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
657
658         local_sockaddr = (struct sockaddr_storage *)
659                         nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
660         remote_sockaddr = (struct sockaddr_storage *)
661                         nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
662         mapped_loc_sockaddr = (struct sockaddr_storage *)
663                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
664         mapped_rem_sockaddr = (struct sockaddr_storage *)
665                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
666
667         if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
668                 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
669                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
670                                 __func__);
671                 return ret;
672         }
673         rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
674         if (!rem_info) {
675                 ret = -ENOMEM;
676                 return ret;
677         }
678         memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr,
679                sizeof(struct sockaddr_storage));
680         memcpy(&rem_info->remote_sockaddr, remote_sockaddr,
681                sizeof(struct sockaddr_storage));
682         memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr,
683                sizeof(struct sockaddr_storage));
684         rem_info->nl_client = nl_client;
685
686         iwpm_add_remote_info(rem_info);
687
688         iwpm_print_sockaddr(local_sockaddr,
689                         "remote_info: Local sockaddr:");
690         iwpm_print_sockaddr(mapped_loc_sockaddr,
691                         "remote_info: Mapped local sockaddr:");
692         iwpm_print_sockaddr(remote_sockaddr,
693                         "remote_info: Remote sockaddr:");
694         iwpm_print_sockaddr(mapped_rem_sockaddr,
695                         "remote_info: Mapped remote sockaddr:");
696         return ret;
697 }
698
699 /* netlink attribute policy for the received request for mapping info */
700 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
701         [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING,
702                                         .len = IWPM_ULIBNAME_SIZE - 1 },
703         [IWPM_NLA_MAPINFO_ULIB_VER]  = { .type = NLA_U16 }
704 };
705
706 /**
707  * iwpm_mapping_info_cb - Process a notification that the userspace
708  *                        port mapper daemon is started
709  * @skb:
710  * @cb: Contains the received message (payload and netlink header)
711  *
712  * Using the received port mapper pid, send all the local mapping
713  * info records to the userspace port mapper
714  */
715 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
716 {
717         struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
718         const char *msg_type = "Mapping Info response";
719         u8 nl_client;
720         char *iwpm_name;
721         u16 iwpm_version;
722         int ret = -EINVAL;
723
724         if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX,
725                                 resp_mapinfo_policy, nltb, msg_type)) {
726                 pr_info("%s: Unable to parse nlmsg\n", __func__);
727                 return ret;
728         }
729         iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]);
730         iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]);
731         if (strcmp(iwpm_ulib_name, iwpm_name) ||
732                         iwpm_version < IWPM_UABI_VERSION_MIN) {
733                 pr_info("%s: Invalid port mapper name = %s version = %d\n",
734                                 __func__, iwpm_name, iwpm_version);
735                 return ret;
736         }
737         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
738         if (!iwpm_valid_client(nl_client)) {
739                 pr_info("%s: Invalid port mapper client = %d\n",
740                                 __func__, nl_client);
741                 return ret;
742         }
743         iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
744         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
745         iwpm_user_pid = cb->nlh->nlmsg_pid;
746
747         if (iwpm_ulib_version < IWPM_UABI_VERSION)
748                 pr_warn_once("%s: Down level iwpmd/pid %u.  Continuing...",
749                         __func__, iwpm_user_pid);
750
751         if (!iwpm_mapinfo_available())
752                 return 0;
753         pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
754                  __func__, iwpm_user_pid);
755         ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
756         return ret;
757 }
758
759 /* netlink attribute policy for the received mapping info ack */
760 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
761         [IWPM_NLA_MAPINFO_SEQ]    =   { .type = NLA_U32 },
762         [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 },
763         [IWPM_NLA_MAPINFO_ACK_NUM] =  { .type = NLA_U32 }
764 };
765
766 /**
767  * iwpm_ack_mapping_info_cb - Process the port mapper ack for
768  *                            the provided local mapping info records
769  * @skb:
770  * @cb: Contains the received message (payload and netlink header)
771  */
772 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
773 {
774         struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX];
775         u32 mapinfo_send, mapinfo_ack;
776         const char *msg_type = "Mapping Info Ack";
777
778         if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX,
779                                 ack_mapinfo_policy, nltb, msg_type))
780                 return -EINVAL;
781         mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]);
782         mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]);
783         if (mapinfo_ack != mapinfo_send)
784                 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
785                         __func__, mapinfo_send, mapinfo_ack);
786         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
787         return 0;
788 }
789
790 /* netlink attribute policy for the received port mapper error message */
791 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
792         [IWPM_NLA_ERR_SEQ]        = { .type = NLA_U32 },
793         [IWPM_NLA_ERR_CODE]       = { .type = NLA_U16 },
794 };
795
796 /**
797  * iwpm_mapping_error_cb - Process port mapper notification for error
798  *
799  * @skb:
800  * @cb: Contains the received message (payload and netlink header)
801  */
802 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
803 {
804         struct iwpm_nlmsg_request *nlmsg_request = NULL;
805         int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
806         struct nlattr *nltb[IWPM_NLA_ERR_MAX];
807         u32 msg_seq;
808         u16 err_code;
809         const char *msg_type = "Mapping Error Msg";
810
811         if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX,
812                                 map_error_policy, nltb, msg_type))
813                 return -EINVAL;
814
815         msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]);
816         err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]);
817         pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
818                                 __func__, msg_seq, err_code, nl_client);
819         /* look for nlmsg_request */
820         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
821         if (!nlmsg_request) {
822                 /* not all errors have associated requests */
823                 pr_debug("Could not find matching req (seq = %u)\n", msg_seq);
824                 return 0;
825         }
826         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
827         nlmsg_request->err_code = err_code;
828         nlmsg_request->request_done = 1;
829         /* always for found request */
830         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
831         barrier();
832         up(&nlmsg_request->sem);
833         return 0;
834 }
835
836 /* netlink attribute policy for the received hello request */
837 static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = {
838         [IWPM_NLA_HELLO_ABI_VERSION]     = { .type = NLA_U16 }
839 };
840
841 /**
842  * iwpm_hello_cb - Process a hello message from iwpmd
843  *
844  * @skb:
845  * @cb: Contains the received message (payload and netlink header)
846  *
847  * Using the received port mapper pid, send the kernel's abi_version
848  * after adjusting it to support the iwpmd version.
849  */
850 int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb)
851 {
852         struct nlattr *nltb[IWPM_NLA_HELLO_MAX];
853         const char *msg_type = "Hello request";
854         u8 nl_client;
855         u16 abi_version;
856         int ret = -EINVAL;
857
858         if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb,
859                              msg_type)) {
860                 pr_info("%s: Unable to parse nlmsg\n", __func__);
861                 return ret;
862         }
863         abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]);
864         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
865         if (!iwpm_valid_client(nl_client)) {
866                 pr_info("%s: Invalid port mapper client = %d\n",
867                                 __func__, nl_client);
868                 return ret;
869         }
870         iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
871         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
872         iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version);
873         pr_debug("Using ABI version %u\n", iwpm_ulib_version);
874         iwpm_user_pid = cb->nlh->nlmsg_pid;
875         ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version);
876         return ret;
877 }