Mention branches and keyring.
[releases.git] / 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_check_registration(nl_client, IWPM_REG_VALID) ||
73                         iwpm_user_pid == IWPM_PID_UNAVAILABLE)
74                 return 0;
75         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client);
76         if (!skb) {
77                 err_str = "Unable to create a nlmsg";
78                 goto pid_query_error;
79         }
80         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
81         nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
82         if (!nlmsg_request) {
83                 err_str = "Unable to allocate netlink request";
84                 goto pid_query_error;
85         }
86         msg_seq = atomic_read(&echo_nlmsg_seq);
87
88         /* fill in the pid request message */
89         err_str = "Unable to put attribute of the nlmsg";
90         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_REG_PID_SEQ);
91         if (ret)
92                 goto pid_query_error;
93         ret = ibnl_put_attr(skb, nlh, IFNAMSIZ,
94                             pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
95         if (ret)
96                 goto pid_query_error;
97         ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
98                                 pm_msg->dev_name, IWPM_NLA_REG_IBDEV_NAME);
99         if (ret)
100                 goto pid_query_error;
101         ret = ibnl_put_attr(skb, nlh, IWPM_ULIBNAME_SIZE,
102                                 (char *)iwpm_ulib_name, IWPM_NLA_REG_ULIB_NAME);
103         if (ret)
104                 goto pid_query_error;
105
106         nlmsg_end(skb, nlh);
107
108         pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
109                 __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);
110
111         ret = rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
112         if (ret) {
113                 skb = NULL; /* skb is freed in the netlink send-op handling */
114                 iwpm_user_pid = IWPM_PID_UNAVAILABLE;
115                 err_str = "Unable to send a nlmsg";
116                 goto pid_query_error;
117         }
118         nlmsg_request->req_buffer = pm_msg;
119         ret = iwpm_wait_complete_req(nlmsg_request);
120         return ret;
121 pid_query_error:
122         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
123         dev_kfree_skb(skb);
124         if (nlmsg_request)
125                 iwpm_free_nlmsg_request(&nlmsg_request->kref);
126         return ret;
127 }
128
129 /**
130  * iwpm_add_mapping - Send a netlink add mapping request to
131  *                    the userspace port mapper
132  * @pm_msg: Contains the local ip/tcp address info to send
133  * @nl_client: The index of the netlink client
134  *
135  * nlmsg attributes:
136  *      [IWPM_NLA_MANAGE_MAPPING_SEQ]
137  *      [IWPM_NLA_MANAGE_ADDR]
138  *      [IWPM_NLA_MANAGE_FLAGS]
139  *
140  * If the request is successful, the pm_msg stores
141  * the port mapper response (mapped address info)
142  */
143 int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
144 {
145         struct sk_buff *skb = NULL;
146         struct iwpm_nlmsg_request *nlmsg_request = NULL;
147         struct nlmsghdr *nlh;
148         u32 msg_seq;
149         const char *err_str = "";
150         int ret = -EINVAL;
151
152         if (!iwpm_valid_pid())
153                 return 0;
154         if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
155                 err_str = "Unregistered port mapper client";
156                 goto add_mapping_error;
157         }
158         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
159         if (!skb) {
160                 err_str = "Unable to create a nlmsg";
161                 goto add_mapping_error;
162         }
163         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
164         nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
165         if (!nlmsg_request) {
166                 err_str = "Unable to allocate netlink request";
167                 goto add_mapping_error;
168         }
169         msg_seq = atomic_read(&echo_nlmsg_seq);
170         /* fill in the add mapping message */
171         err_str = "Unable to put attribute of the nlmsg";
172         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
173                                 IWPM_NLA_MANAGE_MAPPING_SEQ);
174         if (ret)
175                 goto add_mapping_error;
176         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
177                                 &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR);
178         if (ret)
179                 goto add_mapping_error;
180
181         /* If flags are required and we're not V4, then return a quiet error */
182         if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
183                 ret = -EINVAL;
184                 goto add_mapping_error_nowarn;
185         }
186         if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
187                 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
188                                 IWPM_NLA_MANAGE_FLAGS);
189                 if (ret)
190                         goto add_mapping_error;
191         }
192
193         nlmsg_end(skb, nlh);
194         nlmsg_request->req_buffer = pm_msg;
195
196         ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
197         if (ret) {
198                 skb = NULL; /* skb is freed in the netlink send-op handling */
199                 iwpm_user_pid = IWPM_PID_UNDEFINED;
200                 err_str = "Unable to send a nlmsg";
201                 goto add_mapping_error;
202         }
203         ret = iwpm_wait_complete_req(nlmsg_request);
204         return ret;
205 add_mapping_error:
206         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
207 add_mapping_error_nowarn:
208         dev_kfree_skb(skb);
209         if (nlmsg_request)
210                 iwpm_free_nlmsg_request(&nlmsg_request->kref);
211         return ret;
212 }
213
214 /**
215  * iwpm_add_and_query_mapping - Process the port mapper response to
216  *                              iwpm_add_and_query_mapping request
217  * @pm_msg: Contains the local ip/tcp address info to send
218  * @nl_client: The index of the netlink client
219  *
220  * nlmsg attributes:
221  *      [IWPM_NLA_QUERY_MAPPING_SEQ]
222  *      [IWPM_NLA_QUERY_LOCAL_ADDR]
223  *      [IWPM_NLA_QUERY_REMOTE_ADDR]
224  *      [IWPM_NLA_QUERY_FLAGS]
225  */
226 int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
227 {
228         struct sk_buff *skb = NULL;
229         struct iwpm_nlmsg_request *nlmsg_request = NULL;
230         struct nlmsghdr *nlh;
231         u32 msg_seq;
232         const char *err_str = "";
233         int ret = -EINVAL;
234
235         if (!iwpm_valid_pid())
236                 return 0;
237         if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
238                 err_str = "Unregistered port mapper client";
239                 goto query_mapping_error;
240         }
241         ret = -ENOMEM;
242         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client);
243         if (!skb) {
244                 err_str = "Unable to create a nlmsg";
245                 goto query_mapping_error;
246         }
247         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
248         nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq,
249                                 nl_client, GFP_KERNEL);
250         if (!nlmsg_request) {
251                 err_str = "Unable to allocate netlink request";
252                 goto query_mapping_error;
253         }
254         msg_seq = atomic_read(&echo_nlmsg_seq);
255
256         /* fill in the query message */
257         err_str = "Unable to put attribute of the nlmsg";
258         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
259                                 IWPM_NLA_QUERY_MAPPING_SEQ);
260         if (ret)
261                 goto query_mapping_error;
262         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
263                                 &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR);
264         if (ret)
265                 goto query_mapping_error;
266         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
267                                 &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR);
268         if (ret)
269                 goto query_mapping_error;
270
271         /* If flags are required and we're not V4, then return a quite error */
272         if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
273                 ret = -EINVAL;
274                 goto query_mapping_error_nowarn;
275         }
276         if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
277                 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
278                                 IWPM_NLA_QUERY_FLAGS);
279                 if (ret)
280                         goto query_mapping_error;
281         }
282
283         nlmsg_end(skb, nlh);
284         nlmsg_request->req_buffer = pm_msg;
285
286         ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
287         if (ret) {
288                 skb = NULL; /* skb is freed in the netlink send-op handling */
289                 err_str = "Unable to send a nlmsg";
290                 goto query_mapping_error;
291         }
292         ret = iwpm_wait_complete_req(nlmsg_request);
293         return ret;
294 query_mapping_error:
295         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
296 query_mapping_error_nowarn:
297         dev_kfree_skb(skb);
298         if (nlmsg_request)
299                 iwpm_free_nlmsg_request(&nlmsg_request->kref);
300         return ret;
301 }
302
303 /**
304  * iwpm_remove_mapping - Send a netlink remove mapping request
305  *                       to the userspace port mapper
306  *
307  * @local_addr: Local ip/tcp address to remove
308  * @nl_client: The index of the netlink client
309  *
310  * nlmsg attributes:
311  *      [IWPM_NLA_MANAGE_MAPPING_SEQ]
312  *      [IWPM_NLA_MANAGE_ADDR]
313  */
314 int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
315 {
316         struct sk_buff *skb = NULL;
317         struct nlmsghdr *nlh;
318         u32 msg_seq;
319         const char *err_str = "";
320         int ret = -EINVAL;
321
322         if (!iwpm_valid_pid())
323                 return 0;
324         if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
325                 err_str = "Unregistered port mapper client";
326                 goto remove_mapping_error;
327         }
328         skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
329         if (!skb) {
330                 ret = -ENOMEM;
331                 err_str = "Unable to create a nlmsg";
332                 goto remove_mapping_error;
333         }
334         msg_seq = atomic_read(&echo_nlmsg_seq);
335         nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
336         err_str = "Unable to put attribute of the nlmsg";
337         ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
338                                 IWPM_NLA_MANAGE_MAPPING_SEQ);
339         if (ret)
340                 goto remove_mapping_error;
341         ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
342                                 local_addr, IWPM_NLA_MANAGE_ADDR);
343         if (ret)
344                 goto remove_mapping_error;
345
346         nlmsg_end(skb, nlh);
347
348         ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
349         if (ret) {
350                 skb = NULL; /* skb is freed in the netlink send-op handling */
351                 iwpm_user_pid = IWPM_PID_UNDEFINED;
352                 err_str = "Unable to send a nlmsg";
353                 goto remove_mapping_error;
354         }
355         iwpm_print_sockaddr(local_addr,
356                         "remove_mapping: Local sockaddr:");
357         return 0;
358 remove_mapping_error:
359         pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
360         if (skb)
361                 dev_kfree_skb_any(skb);
362         return ret;
363 }
364
365 /* netlink attribute policy for the received response to register pid request */
366 static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = {
367         [IWPM_NLA_RREG_PID_SEQ]     = { .type = NLA_U32 },
368         [IWPM_NLA_RREG_IBDEV_NAME]  = { .type = NLA_STRING,
369                                         .len = IWPM_DEVNAME_SIZE - 1 },
370         [IWPM_NLA_RREG_ULIB_NAME]   = { .type = NLA_STRING,
371                                         .len = IWPM_ULIBNAME_SIZE - 1 },
372         [IWPM_NLA_RREG_ULIB_VER]    = { .type = NLA_U16 },
373         [IWPM_NLA_RREG_PID_ERR]     = { .type = NLA_U16 }
374 };
375
376 /**
377  * iwpm_register_pid_cb - Process the port mapper response to
378  *                        iwpm_register_pid query
379  * @skb: The socket buffer
380  * @cb: Contains the received message (payload and netlink header)
381  *
382  * If successful, the function receives the userspace port mapper pid
383  * which is used in future communication with the port mapper
384  */
385 int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
386 {
387         struct iwpm_nlmsg_request *nlmsg_request = NULL;
388         struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX];
389         struct iwpm_dev_data *pm_msg;
390         char *dev_name, *iwpm_name;
391         u32 msg_seq;
392         u8 nl_client;
393         u16 iwpm_version;
394         const char *msg_type = "Register Pid response";
395
396         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX,
397                                 resp_reg_policy, nltb, msg_type))
398                 return -EINVAL;
399
400         msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]);
401         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
402         if (!nlmsg_request) {
403                 pr_info("%s: Could not find a matching request (seq = %u)\n",
404                                  __func__, msg_seq);
405                 return -EINVAL;
406         }
407         pm_msg = nlmsg_request->req_buffer;
408         nl_client = nlmsg_request->nl_client;
409         dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]);
410         iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]);
411         iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]);
412
413         /* check device name, ulib name and version */
414         if (strcmp(pm_msg->dev_name, dev_name) ||
415                         strcmp(iwpm_ulib_name, iwpm_name) ||
416                         iwpm_version < IWPM_UABI_VERSION_MIN) {
417
418                 pr_info("%s: Incorrect info (dev = %s name = %s version = %u)\n",
419                                 __func__, dev_name, iwpm_name, iwpm_version);
420                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
421                 goto register_pid_response_exit;
422         }
423         iwpm_user_pid = cb->nlh->nlmsg_pid;
424         iwpm_ulib_version = iwpm_version;
425         if (iwpm_ulib_version < IWPM_UABI_VERSION)
426                 pr_warn_once("%s: Down level iwpmd/pid %d.  Continuing...",
427                         __func__, iwpm_user_pid);
428         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
429         pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
430                         __func__, iwpm_user_pid);
431         iwpm_set_registration(nl_client, IWPM_REG_VALID);
432 register_pid_response_exit:
433         nlmsg_request->request_done = 1;
434         /* always for found nlmsg_request */
435         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
436         barrier();
437         up(&nlmsg_request->sem);
438         return 0;
439 }
440
441 /* netlink attribute policy for the received response to add mapping request */
442 static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = {
443         [IWPM_NLA_RMANAGE_MAPPING_SEQ]     = { .type = NLA_U32 },
444         [IWPM_NLA_RMANAGE_ADDR]            = {
445                                 .len = sizeof(struct sockaddr_storage) },
446         [IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR] = {
447                                 .len = sizeof(struct sockaddr_storage) },
448         [IWPM_NLA_RMANAGE_MAPPING_ERR]     = { .type = NLA_U16 }
449 };
450
451 /**
452  * iwpm_add_mapping_cb - Process the port mapper response to
453  *                       iwpm_add_mapping request
454  * @skb: The socket buffer
455  * @cb: Contains the received message (payload and netlink header)
456  */
457 int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb)
458 {
459         struct iwpm_sa_data *pm_msg;
460         struct iwpm_nlmsg_request *nlmsg_request = NULL;
461         struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX];
462         struct sockaddr_storage *local_sockaddr;
463         struct sockaddr_storage *mapped_sockaddr;
464         const char *msg_type;
465         u32 msg_seq;
466
467         msg_type = "Add Mapping response";
468         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX,
469                                 resp_add_policy, nltb, msg_type))
470                 return -EINVAL;
471
472         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
473
474         msg_seq = nla_get_u32(nltb[IWPM_NLA_RMANAGE_MAPPING_SEQ]);
475         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
476         if (!nlmsg_request) {
477                 pr_info("%s: Could not find a matching request (seq = %u)\n",
478                                  __func__, msg_seq);
479                 return -EINVAL;
480         }
481         pm_msg = nlmsg_request->req_buffer;
482         local_sockaddr = (struct sockaddr_storage *)
483                         nla_data(nltb[IWPM_NLA_RMANAGE_ADDR]);
484         mapped_sockaddr = (struct sockaddr_storage *)
485                         nla_data(nltb[IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR]);
486
487         if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) {
488                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
489                 goto add_mapping_response_exit;
490         }
491         if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) {
492                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
493                                 __func__);
494                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
495                 goto add_mapping_response_exit;
496         }
497         memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr,
498                         sizeof(*mapped_sockaddr));
499         iwpm_print_sockaddr(&pm_msg->loc_addr,
500                         "add_mapping: Local sockaddr:");
501         iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
502                         "add_mapping: Mapped local sockaddr:");
503
504 add_mapping_response_exit:
505         nlmsg_request->request_done = 1;
506         /* always for found request */
507         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
508         barrier();
509         up(&nlmsg_request->sem);
510         return 0;
511 }
512
513 /* netlink attribute policy for the response to add and query mapping request
514  * and response with remote address info
515  */
516 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = {
517         [IWPM_NLA_RQUERY_MAPPING_SEQ]     = { .type = NLA_U32 },
518         [IWPM_NLA_RQUERY_LOCAL_ADDR]      = {
519                                 .len = sizeof(struct sockaddr_storage) },
520         [IWPM_NLA_RQUERY_REMOTE_ADDR]     = {
521                                 .len = sizeof(struct sockaddr_storage) },
522         [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = {
523                                 .len = sizeof(struct sockaddr_storage) },
524         [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = {
525                                 .len = sizeof(struct sockaddr_storage) },
526         [IWPM_NLA_RQUERY_MAPPING_ERR]     = { .type = NLA_U16 }
527 };
528
529 /**
530  * iwpm_add_and_query_mapping_cb - Process the port mapper response to
531  *                                 iwpm_add_and_query_mapping request
532  * @skb: The socket buffer
533  * @cb: Contains the received message (payload and netlink header)
534  */
535 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
536                                 struct netlink_callback *cb)
537 {
538         struct iwpm_sa_data *pm_msg;
539         struct iwpm_nlmsg_request *nlmsg_request = NULL;
540         struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
541         struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
542         struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
543         const char *msg_type;
544         u32 msg_seq;
545         u16 err_code;
546
547         msg_type = "Query Mapping response";
548         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
549                                 resp_query_policy, nltb, msg_type))
550                 return -EINVAL;
551         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
552
553         msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]);
554         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
555         if (!nlmsg_request) {
556                 pr_info("%s: Could not find a matching request (seq = %u)\n",
557                                  __func__, msg_seq);
558                 return -EINVAL;
559         }
560         pm_msg = nlmsg_request->req_buffer;
561         local_sockaddr = (struct sockaddr_storage *)
562                         nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
563         remote_sockaddr = (struct sockaddr_storage *)
564                         nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
565         mapped_loc_sockaddr = (struct sockaddr_storage *)
566                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
567         mapped_rem_sockaddr = (struct sockaddr_storage *)
568                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
569
570         err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]);
571         if (err_code == IWPM_REMOTE_QUERY_REJECT) {
572                 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
573                         __func__, cb->nlh->nlmsg_pid, msg_seq);
574                 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT;
575         }
576         if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) ||
577                 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) {
578                 pr_info("%s: Incorrect local sockaddr\n", __func__);
579                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
580                 goto query_mapping_response_exit;
581         }
582         if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
583                 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
584                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
585                                 __func__);
586                 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
587                 goto query_mapping_response_exit;
588         }
589         memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr,
590                         sizeof(*mapped_loc_sockaddr));
591         memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr,
592                         sizeof(*mapped_rem_sockaddr));
593
594         iwpm_print_sockaddr(&pm_msg->loc_addr,
595                         "query_mapping: Local sockaddr:");
596         iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
597                         "query_mapping: Mapped local sockaddr:");
598         iwpm_print_sockaddr(&pm_msg->rem_addr,
599                         "query_mapping: Remote sockaddr:");
600         iwpm_print_sockaddr(&pm_msg->mapped_rem_addr,
601                         "query_mapping: Mapped remote sockaddr:");
602 query_mapping_response_exit:
603         nlmsg_request->request_done = 1;
604         /* always for found request */
605         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
606         barrier();
607         up(&nlmsg_request->sem);
608         return 0;
609 }
610
611 /**
612  * iwpm_remote_info_cb - Process remote connecting peer address info, which
613  *                       the port mapper has received from the connecting peer
614  * @skb: The socket buffer
615  * @cb: Contains the received message (payload and netlink header)
616  *
617  * Stores the IPv4/IPv6 address info in a hash table
618  */
619 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
620 {
621         struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
622         struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
623         struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
624         struct iwpm_remote_info *rem_info;
625         const char *msg_type;
626         u8 nl_client;
627         int ret = -EINVAL;
628
629         msg_type = "Remote Mapping info";
630         if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
631                                 resp_query_policy, nltb, msg_type))
632                 return ret;
633
634         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
635         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
636
637         local_sockaddr = (struct sockaddr_storage *)
638                         nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
639         remote_sockaddr = (struct sockaddr_storage *)
640                         nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
641         mapped_loc_sockaddr = (struct sockaddr_storage *)
642                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
643         mapped_rem_sockaddr = (struct sockaddr_storage *)
644                         nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
645
646         if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
647                 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
648                 pr_info("%s: Sockaddr family doesn't match the requested one\n",
649                                 __func__);
650                 return ret;
651         }
652         rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
653         if (!rem_info) {
654                 ret = -ENOMEM;
655                 return ret;
656         }
657         memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr,
658                sizeof(struct sockaddr_storage));
659         memcpy(&rem_info->remote_sockaddr, remote_sockaddr,
660                sizeof(struct sockaddr_storage));
661         memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr,
662                sizeof(struct sockaddr_storage));
663         rem_info->nl_client = nl_client;
664
665         iwpm_add_remote_info(rem_info);
666
667         iwpm_print_sockaddr(local_sockaddr,
668                         "remote_info: Local sockaddr:");
669         iwpm_print_sockaddr(mapped_loc_sockaddr,
670                         "remote_info: Mapped local sockaddr:");
671         iwpm_print_sockaddr(remote_sockaddr,
672                         "remote_info: Remote sockaddr:");
673         iwpm_print_sockaddr(mapped_rem_sockaddr,
674                         "remote_info: Mapped remote sockaddr:");
675         return ret;
676 }
677
678 /* netlink attribute policy for the received request for mapping info */
679 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
680         [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING,
681                                         .len = IWPM_ULIBNAME_SIZE - 1 },
682         [IWPM_NLA_MAPINFO_ULIB_VER]  = { .type = NLA_U16 }
683 };
684
685 /**
686  * iwpm_mapping_info_cb - Process a notification that the userspace
687  *                        port mapper daemon is started
688  * @skb: The socket buffer
689  * @cb: Contains the received message (payload and netlink header)
690  *
691  * Using the received port mapper pid, send all the local mapping
692  * info records to the userspace port mapper
693  */
694 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
695 {
696         struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
697         const char *msg_type = "Mapping Info response";
698         u8 nl_client;
699         char *iwpm_name;
700         u16 iwpm_version;
701         int ret = -EINVAL;
702
703         if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX,
704                                 resp_mapinfo_policy, nltb, msg_type)) {
705                 pr_info("%s: Unable to parse nlmsg\n", __func__);
706                 return ret;
707         }
708         iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]);
709         iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]);
710         if (strcmp(iwpm_ulib_name, iwpm_name) ||
711                         iwpm_version < IWPM_UABI_VERSION_MIN) {
712                 pr_info("%s: Invalid port mapper name = %s version = %u\n",
713                                 __func__, iwpm_name, iwpm_version);
714                 return ret;
715         }
716         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
717         iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
718         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
719         iwpm_user_pid = cb->nlh->nlmsg_pid;
720
721         if (iwpm_ulib_version < IWPM_UABI_VERSION)
722                 pr_warn_once("%s: Down level iwpmd/pid %d.  Continuing...",
723                         __func__, iwpm_user_pid);
724
725         if (!iwpm_mapinfo_available())
726                 return 0;
727         pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
728                  __func__, iwpm_user_pid);
729         ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
730         return ret;
731 }
732
733 /* netlink attribute policy for the received mapping info ack */
734 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
735         [IWPM_NLA_MAPINFO_SEQ]    =   { .type = NLA_U32 },
736         [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 },
737         [IWPM_NLA_MAPINFO_ACK_NUM] =  { .type = NLA_U32 }
738 };
739
740 /**
741  * iwpm_ack_mapping_info_cb - Process the port mapper ack for
742  *                            the provided local mapping info records
743  * @skb: The socket buffer
744  * @cb: Contains the received message (payload and netlink header)
745  */
746 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
747 {
748         struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX];
749         u32 mapinfo_send, mapinfo_ack;
750         const char *msg_type = "Mapping Info Ack";
751
752         if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX,
753                                 ack_mapinfo_policy, nltb, msg_type))
754                 return -EINVAL;
755         mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]);
756         mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]);
757         if (mapinfo_ack != mapinfo_send)
758                 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
759                         __func__, mapinfo_send, mapinfo_ack);
760         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
761         return 0;
762 }
763
764 /* netlink attribute policy for the received port mapper error message */
765 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
766         [IWPM_NLA_ERR_SEQ]        = { .type = NLA_U32 },
767         [IWPM_NLA_ERR_CODE]       = { .type = NLA_U16 },
768 };
769
770 /**
771  * iwpm_mapping_error_cb - Process port mapper notification for error
772  *
773  * @skb: The socket buffer
774  * @cb: Contains the received message (payload and netlink header)
775  */
776 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
777 {
778         struct iwpm_nlmsg_request *nlmsg_request = NULL;
779         int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
780         struct nlattr *nltb[IWPM_NLA_ERR_MAX];
781         u32 msg_seq;
782         u16 err_code;
783         const char *msg_type = "Mapping Error Msg";
784
785         if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX,
786                                 map_error_policy, nltb, msg_type))
787                 return -EINVAL;
788
789         msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]);
790         err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]);
791         pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
792                                 __func__, msg_seq, err_code, nl_client);
793         /* look for nlmsg_request */
794         nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
795         if (!nlmsg_request) {
796                 /* not all errors have associated requests */
797                 pr_debug("Could not find matching req (seq = %u)\n", msg_seq);
798                 return 0;
799         }
800         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
801         nlmsg_request->err_code = err_code;
802         nlmsg_request->request_done = 1;
803         /* always for found request */
804         kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
805         barrier();
806         up(&nlmsg_request->sem);
807         return 0;
808 }
809
810 /* netlink attribute policy for the received hello request */
811 static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = {
812         [IWPM_NLA_HELLO_ABI_VERSION]     = { .type = NLA_U16 }
813 };
814
815 /**
816  * iwpm_hello_cb - Process a hello message from iwpmd
817  *
818  * @skb: The socket buffer
819  * @cb: Contains the received message (payload and netlink header)
820  *
821  * Using the received port mapper pid, send the kernel's abi_version
822  * after adjusting it to support the iwpmd version.
823  */
824 int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb)
825 {
826         struct nlattr *nltb[IWPM_NLA_HELLO_MAX];
827         const char *msg_type = "Hello request";
828         u8 nl_client;
829         u16 abi_version;
830         int ret = -EINVAL;
831
832         if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb,
833                              msg_type)) {
834                 pr_info("%s: Unable to parse nlmsg\n", __func__);
835                 return ret;
836         }
837         abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]);
838         nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
839         iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
840         atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
841         iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version);
842         pr_debug("Using ABI version %u\n", iwpm_ulib_version);
843         iwpm_user_pid = cb->nlh->nlmsg_pid;
844         ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version);
845         return ret;
846 }