2 * Copyright (c) 2014 Intel Corporation. All rights reserved.
3 * Copyright (c) 2014 Chelsio, Inc. All rights reserved.
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:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
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.
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
34 #include "iwpm_util.h"
36 static const char iwpm_ulib_name
[IWPM_ULIBNAME_SIZE
] = "iWarpPortMapperUser";
37 static int iwpm_ulib_version
= 3;
38 static int iwpm_user_pid
= IWPM_PID_UNDEFINED
;
39 static atomic_t echo_nlmsg_seq
;
41 int iwpm_valid_pid(void)
43 return iwpm_user_pid
> 0;
45 EXPORT_SYMBOL(iwpm_valid_pid
);
48 * iwpm_register_pid - Send a netlink query to user space
49 * for the iwarp port mapper pid
52 * [IWPM_NLA_REG_PID_SEQ]
53 * [IWPM_NLA_REG_IF_NAME]
54 * [IWPM_NLA_REG_IBDEV_NAME]
55 * [IWPM_NLA_REG_ULIB_NAME]
57 int iwpm_register_pid(struct iwpm_dev_data
*pm_msg
, u8 nl_client
)
59 struct sk_buff
*skb
= NULL
;
60 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
63 const char *err_str
= "";
66 if (!iwpm_valid_client(nl_client
)) {
67 err_str
= "Invalid port mapper client";
70 if (iwpm_registered_client(nl_client
))
72 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID
, &nlh
, nl_client
);
74 err_str
= "Unable to create a nlmsg";
77 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
78 nlmsg_request
= iwpm_get_nlmsg_request(nlh
->nlmsg_seq
, nl_client
, GFP_KERNEL
);
80 err_str
= "Unable to allocate netlink request";
83 msg_seq
= atomic_read(&echo_nlmsg_seq
);
85 /* fill in the pid request message */
86 err_str
= "Unable to put attribute of the nlmsg";
87 ret
= ibnl_put_attr(skb
, nlh
, sizeof(u32
), &msg_seq
, IWPM_NLA_REG_PID_SEQ
);
90 ret
= ibnl_put_attr(skb
, nlh
, IWPM_IFNAME_SIZE
,
91 pm_msg
->if_name
, IWPM_NLA_REG_IF_NAME
);
94 ret
= ibnl_put_attr(skb
, nlh
, IWPM_DEVNAME_SIZE
,
95 pm_msg
->dev_name
, IWPM_NLA_REG_IBDEV_NAME
);
98 ret
= ibnl_put_attr(skb
, nlh
, IWPM_ULIBNAME_SIZE
,
99 (char *)iwpm_ulib_name
, IWPM_NLA_REG_ULIB_NAME
);
101 goto pid_query_error
;
103 pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
104 __func__
, pm_msg
->dev_name
, pm_msg
->if_name
, iwpm_ulib_name
);
106 ret
= ibnl_multicast(skb
, nlh
, RDMA_NL_GROUP_IWPM
, GFP_KERNEL
);
108 skb
= NULL
; /* skb is freed in the netlink send-op handling */
109 iwpm_set_registered(nl_client
, 1);
110 iwpm_user_pid
= IWPM_PID_UNAVAILABLE
;
111 err_str
= "Unable to send a nlmsg";
112 goto pid_query_error
;
114 nlmsg_request
->req_buffer
= pm_msg
;
115 ret
= iwpm_wait_complete_req(nlmsg_request
);
118 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
122 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
125 EXPORT_SYMBOL(iwpm_register_pid
);
128 * iwpm_add_mapping - Send a netlink add mapping message
131 * [IWPM_NLA_MANAGE_MAPPING_SEQ]
132 * [IWPM_NLA_MANAGE_ADDR]
134 int iwpm_add_mapping(struct iwpm_sa_data
*pm_msg
, u8 nl_client
)
136 struct sk_buff
*skb
= NULL
;
137 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
138 struct nlmsghdr
*nlh
;
140 const char *err_str
= "";
143 if (!iwpm_valid_client(nl_client
)) {
144 err_str
= "Invalid port mapper client";
145 goto add_mapping_error
;
147 if (!iwpm_registered_client(nl_client
)) {
148 err_str
= "Unregistered port mapper client";
149 goto add_mapping_error
;
151 if (!iwpm_valid_pid())
153 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING
, &nlh
, nl_client
);
155 err_str
= "Unable to create a nlmsg";
156 goto add_mapping_error
;
158 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
159 nlmsg_request
= iwpm_get_nlmsg_request(nlh
->nlmsg_seq
, nl_client
, GFP_KERNEL
);
160 if (!nlmsg_request
) {
161 err_str
= "Unable to allocate netlink request";
162 goto add_mapping_error
;
164 msg_seq
= atomic_read(&echo_nlmsg_seq
);
165 /* fill in the add mapping message */
166 err_str
= "Unable to put attribute of the nlmsg";
167 ret
= ibnl_put_attr(skb
, nlh
, sizeof(u32
), &msg_seq
,
168 IWPM_NLA_MANAGE_MAPPING_SEQ
);
170 goto add_mapping_error
;
171 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
172 &pm_msg
->loc_addr
, IWPM_NLA_MANAGE_ADDR
);
174 goto add_mapping_error
;
175 nlmsg_request
->req_buffer
= pm_msg
;
177 ret
= ibnl_unicast(skb
, nlh
, iwpm_user_pid
);
179 skb
= NULL
; /* skb is freed in the netlink send-op handling */
180 iwpm_user_pid
= IWPM_PID_UNDEFINED
;
181 err_str
= "Unable to send a nlmsg";
182 goto add_mapping_error
;
184 ret
= iwpm_wait_complete_req(nlmsg_request
);
187 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
191 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
194 EXPORT_SYMBOL(iwpm_add_mapping
);
197 * iwpm_add_and_query_mapping - Send a netlink add and query
198 * mapping message to the port mapper
200 * [IWPM_NLA_QUERY_MAPPING_SEQ]
201 * [IWPM_NLA_QUERY_LOCAL_ADDR]
202 * [IWPM_NLA_QUERY_REMOTE_ADDR]
204 int iwpm_add_and_query_mapping(struct iwpm_sa_data
*pm_msg
, u8 nl_client
)
206 struct sk_buff
*skb
= NULL
;
207 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
208 struct nlmsghdr
*nlh
;
210 const char *err_str
= "";
213 if (!iwpm_valid_client(nl_client
)) {
214 err_str
= "Invalid port mapper client";
215 goto query_mapping_error
;
217 if (!iwpm_registered_client(nl_client
)) {
218 err_str
= "Unregistered port mapper client";
219 goto query_mapping_error
;
221 if (!iwpm_valid_pid())
224 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING
, &nlh
, nl_client
);
226 err_str
= "Unable to create a nlmsg";
227 goto query_mapping_error
;
229 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
230 nlmsg_request
= iwpm_get_nlmsg_request(nlh
->nlmsg_seq
,
231 nl_client
, GFP_KERNEL
);
232 if (!nlmsg_request
) {
233 err_str
= "Unable to allocate netlink request";
234 goto query_mapping_error
;
236 msg_seq
= atomic_read(&echo_nlmsg_seq
);
238 /* fill in the query message */
239 err_str
= "Unable to put attribute of the nlmsg";
240 ret
= ibnl_put_attr(skb
, nlh
, sizeof(u32
), &msg_seq
,
241 IWPM_NLA_QUERY_MAPPING_SEQ
);
243 goto query_mapping_error
;
244 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
245 &pm_msg
->loc_addr
, IWPM_NLA_QUERY_LOCAL_ADDR
);
247 goto query_mapping_error
;
248 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
249 &pm_msg
->rem_addr
, IWPM_NLA_QUERY_REMOTE_ADDR
);
251 goto query_mapping_error
;
252 nlmsg_request
->req_buffer
= pm_msg
;
254 ret
= ibnl_unicast(skb
, nlh
, iwpm_user_pid
);
256 skb
= NULL
; /* skb is freed in the netlink send-op handling */
257 err_str
= "Unable to send a nlmsg";
258 goto query_mapping_error
;
260 ret
= iwpm_wait_complete_req(nlmsg_request
);
263 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
267 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
270 EXPORT_SYMBOL(iwpm_add_and_query_mapping
);
273 * iwpm_remove_mapping - Send a netlink remove mapping message
276 * [IWPM_NLA_MANAGE_MAPPING_SEQ]
277 * [IWPM_NLA_MANAGE_ADDR]
279 int iwpm_remove_mapping(struct sockaddr_storage
*local_addr
, u8 nl_client
)
281 struct sk_buff
*skb
= NULL
;
282 struct nlmsghdr
*nlh
;
284 const char *err_str
= "";
287 if (!iwpm_valid_client(nl_client
)) {
288 err_str
= "Invalid port mapper client";
289 goto remove_mapping_error
;
291 if (!iwpm_registered_client(nl_client
)) {
292 err_str
= "Unregistered port mapper client";
293 goto remove_mapping_error
;
295 if (!iwpm_valid_pid())
297 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING
, &nlh
, nl_client
);
300 err_str
= "Unable to create a nlmsg";
301 goto remove_mapping_error
;
303 msg_seq
= atomic_read(&echo_nlmsg_seq
);
304 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
305 err_str
= "Unable to put attribute of the nlmsg";
306 ret
= ibnl_put_attr(skb
, nlh
, sizeof(u32
), &msg_seq
,
307 IWPM_NLA_MANAGE_MAPPING_SEQ
);
309 goto remove_mapping_error
;
310 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
311 local_addr
, IWPM_NLA_MANAGE_ADDR
);
313 goto remove_mapping_error
;
315 ret
= ibnl_unicast(skb
, nlh
, iwpm_user_pid
);
317 skb
= NULL
; /* skb is freed in the netlink send-op handling */
318 iwpm_user_pid
= IWPM_PID_UNDEFINED
;
319 err_str
= "Unable to send a nlmsg";
320 goto remove_mapping_error
;
322 iwpm_print_sockaddr(local_addr
,
323 "remove_mapping: Local sockaddr:");
325 remove_mapping_error
:
326 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
328 dev_kfree_skb_any(skb
);
331 EXPORT_SYMBOL(iwpm_remove_mapping
);
333 /* netlink attribute policy for the received response to register pid request */
334 static const struct nla_policy resp_reg_policy
[IWPM_NLA_RREG_PID_MAX
] = {
335 [IWPM_NLA_RREG_PID_SEQ
] = { .type
= NLA_U32
},
336 [IWPM_NLA_RREG_IBDEV_NAME
] = { .type
= NLA_STRING
,
337 .len
= IWPM_DEVNAME_SIZE
- 1 },
338 [IWPM_NLA_RREG_ULIB_NAME
] = { .type
= NLA_STRING
,
339 .len
= IWPM_ULIBNAME_SIZE
- 1 },
340 [IWPM_NLA_RREG_ULIB_VER
] = { .type
= NLA_U16
},
341 [IWPM_NLA_RREG_PID_ERR
] = { .type
= NLA_U16
}
345 * iwpm_register_pid_cb - Process a port mapper response to
346 * iwpm_register_pid()
348 int iwpm_register_pid_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
350 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
351 struct nlattr
*nltb
[IWPM_NLA_RREG_PID_MAX
];
352 struct iwpm_dev_data
*pm_msg
;
353 char *dev_name
, *iwpm_name
;
357 const char *msg_type
= "Register Pid response";
359 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RREG_PID_MAX
,
360 resp_reg_policy
, nltb
, msg_type
))
363 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_RREG_PID_SEQ
]);
364 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
365 if (!nlmsg_request
) {
366 pr_info("%s: Could not find a matching request (seq = %u)\n",
370 pm_msg
= nlmsg_request
->req_buffer
;
371 nl_client
= nlmsg_request
->nl_client
;
372 dev_name
= (char *)nla_data(nltb
[IWPM_NLA_RREG_IBDEV_NAME
]);
373 iwpm_name
= (char *)nla_data(nltb
[IWPM_NLA_RREG_ULIB_NAME
]);
374 iwpm_version
= nla_get_u16(nltb
[IWPM_NLA_RREG_ULIB_VER
]);
376 /* check device name, ulib name and version */
377 if (strcmp(pm_msg
->dev_name
, dev_name
) ||
378 strcmp(iwpm_ulib_name
, iwpm_name
) ||
379 iwpm_version
!= iwpm_ulib_version
) {
381 pr_info("%s: Incorrect info (dev = %s name = %s version = %d)\n",
382 __func__
, dev_name
, iwpm_name
, iwpm_version
);
383 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
384 goto register_pid_response_exit
;
386 iwpm_user_pid
= cb
->nlh
->nlmsg_pid
;
387 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
388 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
389 __func__
, iwpm_user_pid
);
390 if (iwpm_valid_client(nl_client
))
391 iwpm_set_registered(nl_client
, 1);
392 register_pid_response_exit
:
393 nlmsg_request
->request_done
= 1;
394 /* always for found nlmsg_request */
395 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
397 wake_up(&nlmsg_request
->waitq
);
400 EXPORT_SYMBOL(iwpm_register_pid_cb
);
402 /* netlink attribute policy for the received response to add mapping request */
403 static const struct nla_policy resp_add_policy
[IWPM_NLA_RMANAGE_MAPPING_MAX
] = {
404 [IWPM_NLA_MANAGE_MAPPING_SEQ
] = { .type
= NLA_U32
},
405 [IWPM_NLA_MANAGE_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
406 [IWPM_NLA_MANAGE_MAPPED_LOC_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
407 [IWPM_NLA_RMANAGE_MAPPING_ERR
] = { .type
= NLA_U16
}
411 * iwpm_add_mapping_cb - Process a port mapper response to
414 int iwpm_add_mapping_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
416 struct iwpm_sa_data
*pm_msg
;
417 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
418 struct nlattr
*nltb
[IWPM_NLA_RMANAGE_MAPPING_MAX
];
419 struct sockaddr_storage
*local_sockaddr
;
420 struct sockaddr_storage
*mapped_sockaddr
;
421 const char *msg_type
;
424 msg_type
= "Add Mapping response";
425 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RMANAGE_MAPPING_MAX
,
426 resp_add_policy
, nltb
, msg_type
))
429 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
431 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_MANAGE_MAPPING_SEQ
]);
432 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
433 if (!nlmsg_request
) {
434 pr_info("%s: Could not find a matching request (seq = %u)\n",
438 pm_msg
= nlmsg_request
->req_buffer
;
439 local_sockaddr
= (struct sockaddr_storage
*)
440 nla_data(nltb
[IWPM_NLA_MANAGE_ADDR
]);
441 mapped_sockaddr
= (struct sockaddr_storage
*)
442 nla_data(nltb
[IWPM_NLA_MANAGE_MAPPED_LOC_ADDR
]);
444 if (iwpm_compare_sockaddr(local_sockaddr
, &pm_msg
->loc_addr
)) {
445 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
446 goto add_mapping_response_exit
;
448 if (mapped_sockaddr
->ss_family
!= local_sockaddr
->ss_family
) {
449 pr_info("%s: Sockaddr family doesn't match the requested one\n",
451 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
452 goto add_mapping_response_exit
;
454 memcpy(&pm_msg
->mapped_loc_addr
, mapped_sockaddr
,
455 sizeof(*mapped_sockaddr
));
456 iwpm_print_sockaddr(&pm_msg
->loc_addr
,
457 "add_mapping: Local sockaddr:");
458 iwpm_print_sockaddr(&pm_msg
->mapped_loc_addr
,
459 "add_mapping: Mapped local sockaddr:");
461 add_mapping_response_exit
:
462 nlmsg_request
->request_done
= 1;
463 /* always for found request */
464 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
466 wake_up(&nlmsg_request
->waitq
);
469 EXPORT_SYMBOL(iwpm_add_mapping_cb
);
471 /* netlink attribute policy for the response to add and query mapping request
472 * and response with remote address info */
473 static const struct nla_policy resp_query_policy
[IWPM_NLA_RQUERY_MAPPING_MAX
] = {
474 [IWPM_NLA_QUERY_MAPPING_SEQ
] = { .type
= NLA_U32
},
475 [IWPM_NLA_QUERY_LOCAL_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
476 [IWPM_NLA_QUERY_REMOTE_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
477 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
478 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
479 [IWPM_NLA_RQUERY_MAPPING_ERR
] = { .type
= NLA_U16
}
483 * iwpm_add_and_query_mapping_cb - Process a port mapper response to
484 * iwpm_add_and_query_mapping()
486 int iwpm_add_and_query_mapping_cb(struct sk_buff
*skb
,
487 struct netlink_callback
*cb
)
489 struct iwpm_sa_data
*pm_msg
;
490 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
491 struct nlattr
*nltb
[IWPM_NLA_RQUERY_MAPPING_MAX
];
492 struct sockaddr_storage
*local_sockaddr
, *remote_sockaddr
;
493 struct sockaddr_storage
*mapped_loc_sockaddr
, *mapped_rem_sockaddr
;
494 const char *msg_type
;
498 msg_type
= "Query Mapping response";
499 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RQUERY_MAPPING_MAX
,
500 resp_query_policy
, nltb
, msg_type
))
502 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
504 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_QUERY_MAPPING_SEQ
]);
505 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
506 if (!nlmsg_request
) {
507 pr_info("%s: Could not find a matching request (seq = %u)\n",
511 pm_msg
= nlmsg_request
->req_buffer
;
512 local_sockaddr
= (struct sockaddr_storage
*)
513 nla_data(nltb
[IWPM_NLA_QUERY_LOCAL_ADDR
]);
514 remote_sockaddr
= (struct sockaddr_storage
*)
515 nla_data(nltb
[IWPM_NLA_QUERY_REMOTE_ADDR
]);
516 mapped_loc_sockaddr
= (struct sockaddr_storage
*)
517 nla_data(nltb
[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR
]);
518 mapped_rem_sockaddr
= (struct sockaddr_storage
*)
519 nla_data(nltb
[IWPM_NLA_RQUERY_MAPPED_REM_ADDR
]);
521 err_code
= nla_get_u16(nltb
[IWPM_NLA_RQUERY_MAPPING_ERR
]);
522 if (err_code
== IWPM_REMOTE_QUERY_REJECT
) {
523 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
524 __func__
, cb
->nlh
->nlmsg_pid
, msg_seq
);
525 nlmsg_request
->err_code
= IWPM_REMOTE_QUERY_REJECT
;
527 if (iwpm_compare_sockaddr(local_sockaddr
, &pm_msg
->loc_addr
) ||
528 iwpm_compare_sockaddr(remote_sockaddr
, &pm_msg
->rem_addr
)) {
529 pr_info("%s: Incorrect local sockaddr\n", __func__
);
530 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
531 goto query_mapping_response_exit
;
533 if (mapped_loc_sockaddr
->ss_family
!= local_sockaddr
->ss_family
||
534 mapped_rem_sockaddr
->ss_family
!= remote_sockaddr
->ss_family
) {
535 pr_info("%s: Sockaddr family doesn't match the requested one\n",
537 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
538 goto query_mapping_response_exit
;
540 memcpy(&pm_msg
->mapped_loc_addr
, mapped_loc_sockaddr
,
541 sizeof(*mapped_loc_sockaddr
));
542 memcpy(&pm_msg
->mapped_rem_addr
, mapped_rem_sockaddr
,
543 sizeof(*mapped_rem_sockaddr
));
545 iwpm_print_sockaddr(&pm_msg
->loc_addr
,
546 "query_mapping: Local sockaddr:");
547 iwpm_print_sockaddr(&pm_msg
->mapped_loc_addr
,
548 "query_mapping: Mapped local sockaddr:");
549 iwpm_print_sockaddr(&pm_msg
->rem_addr
,
550 "query_mapping: Remote sockaddr:");
551 iwpm_print_sockaddr(&pm_msg
->mapped_rem_addr
,
552 "query_mapping: Mapped remote sockaddr:");
553 query_mapping_response_exit
:
554 nlmsg_request
->request_done
= 1;
555 /* always for found request */
556 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
558 wake_up(&nlmsg_request
->waitq
);
561 EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb
);
564 * iwpm_remote_info_cb - Process a port mapper message, containing
565 * the remote connecting peer address info
567 int iwpm_remote_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
569 struct nlattr
*nltb
[IWPM_NLA_RQUERY_MAPPING_MAX
];
570 struct sockaddr_storage
*local_sockaddr
, *remote_sockaddr
;
571 struct sockaddr_storage
*mapped_loc_sockaddr
, *mapped_rem_sockaddr
;
572 struct iwpm_remote_info
*rem_info
;
573 const char *msg_type
;
577 msg_type
= "Remote Mapping info";
578 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RQUERY_MAPPING_MAX
,
579 resp_query_policy
, nltb
, msg_type
))
582 nl_client
= RDMA_NL_GET_CLIENT(cb
->nlh
->nlmsg_type
);
583 if (!iwpm_valid_client(nl_client
)) {
584 pr_info("%s: Invalid port mapper client = %d\n",
585 __func__
, nl_client
);
588 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
590 local_sockaddr
= (struct sockaddr_storage
*)
591 nla_data(nltb
[IWPM_NLA_QUERY_LOCAL_ADDR
]);
592 remote_sockaddr
= (struct sockaddr_storage
*)
593 nla_data(nltb
[IWPM_NLA_QUERY_REMOTE_ADDR
]);
594 mapped_loc_sockaddr
= (struct sockaddr_storage
*)
595 nla_data(nltb
[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR
]);
596 mapped_rem_sockaddr
= (struct sockaddr_storage
*)
597 nla_data(nltb
[IWPM_NLA_RQUERY_MAPPED_REM_ADDR
]);
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",
605 rem_info
= kzalloc(sizeof(struct iwpm_remote_info
), GFP_ATOMIC
);
607 pr_err("%s: Unable to allocate a remote info\n", __func__
);
611 memcpy(&rem_info
->mapped_loc_sockaddr
, mapped_loc_sockaddr
,
612 sizeof(struct sockaddr_storage
));
613 memcpy(&rem_info
->remote_sockaddr
, remote_sockaddr
,
614 sizeof(struct sockaddr_storage
));
615 memcpy(&rem_info
->mapped_rem_sockaddr
, mapped_rem_sockaddr
,
616 sizeof(struct sockaddr_storage
));
617 rem_info
->nl_client
= nl_client
;
619 iwpm_add_remote_info(rem_info
);
621 iwpm_print_sockaddr(local_sockaddr
,
622 "remote_info: Local sockaddr:");
623 iwpm_print_sockaddr(mapped_loc_sockaddr
,
624 "remote_info: Mapped local sockaddr:");
625 iwpm_print_sockaddr(remote_sockaddr
,
626 "remote_info: Remote sockaddr:");
627 iwpm_print_sockaddr(mapped_rem_sockaddr
,
628 "remote_info: Mapped remote sockaddr:");
631 EXPORT_SYMBOL(iwpm_remote_info_cb
);
633 /* netlink attribute policy for the received request for mapping info */
634 static const struct nla_policy resp_mapinfo_policy
[IWPM_NLA_MAPINFO_REQ_MAX
] = {
635 [IWPM_NLA_MAPINFO_ULIB_NAME
] = { .type
= NLA_STRING
,
636 .len
= IWPM_ULIBNAME_SIZE
- 1 },
637 [IWPM_NLA_MAPINFO_ULIB_VER
] = { .type
= NLA_U16
}
641 * iwpm_mapping_info_cb - Process a port mapper request for mapping info
643 int iwpm_mapping_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
645 struct nlattr
*nltb
[IWPM_NLA_MAPINFO_REQ_MAX
];
646 const char *msg_type
= "Mapping Info response";
653 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_MAPINFO_REQ_MAX
,
654 resp_mapinfo_policy
, nltb
, msg_type
)) {
655 pr_info("%s: Unable to parse nlmsg\n", __func__
);
658 iwpm_name
= (char *)nla_data(nltb
[IWPM_NLA_MAPINFO_ULIB_NAME
]);
659 iwpm_version
= nla_get_u16(nltb
[IWPM_NLA_MAPINFO_ULIB_VER
]);
660 if (strcmp(iwpm_ulib_name
, iwpm_name
) ||
661 iwpm_version
!= iwpm_ulib_version
) {
662 pr_info("%s: Invalid port mapper name = %s version = %d\n",
663 __func__
, iwpm_name
, iwpm_version
);
666 nl_client
= RDMA_NL_GET_CLIENT(cb
->nlh
->nlmsg_type
);
667 if (!iwpm_valid_client(nl_client
)) {
668 pr_info("%s: Invalid port mapper client = %d\n",
669 __func__
, nl_client
);
672 iwpm_set_registered(nl_client
, 0);
673 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
674 if (!iwpm_mapinfo_available())
676 iwpm_pid
= cb
->nlh
->nlmsg_pid
;
677 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
679 ret
= iwpm_send_mapinfo(nl_client
, iwpm_pid
);
682 EXPORT_SYMBOL(iwpm_mapping_info_cb
);
684 /* netlink attribute policy for the received mapping info ack */
685 static const struct nla_policy ack_mapinfo_policy
[IWPM_NLA_MAPINFO_NUM_MAX
] = {
686 [IWPM_NLA_MAPINFO_SEQ
] = { .type
= NLA_U32
},
687 [IWPM_NLA_MAPINFO_SEND_NUM
] = { .type
= NLA_U32
},
688 [IWPM_NLA_MAPINFO_ACK_NUM
] = { .type
= NLA_U32
}
692 * iwpm_ack_mapping_info_cb - Process a port mapper ack for
693 * the provided mapping info records
695 int iwpm_ack_mapping_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
697 struct nlattr
*nltb
[IWPM_NLA_MAPINFO_NUM_MAX
];
698 u32 mapinfo_send
, mapinfo_ack
;
699 const char *msg_type
= "Mapping Info Ack";
701 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_MAPINFO_NUM_MAX
,
702 ack_mapinfo_policy
, nltb
, msg_type
))
704 mapinfo_send
= nla_get_u32(nltb
[IWPM_NLA_MAPINFO_SEND_NUM
]);
705 mapinfo_ack
= nla_get_u32(nltb
[IWPM_NLA_MAPINFO_ACK_NUM
]);
706 if (mapinfo_ack
!= mapinfo_send
)
707 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
708 __func__
, mapinfo_send
, mapinfo_ack
);
709 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
712 EXPORT_SYMBOL(iwpm_ack_mapping_info_cb
);
714 /* netlink attribute policy for the received port mapper error message */
715 static const struct nla_policy map_error_policy
[IWPM_NLA_ERR_MAX
] = {
716 [IWPM_NLA_ERR_SEQ
] = { .type
= NLA_U32
},
717 [IWPM_NLA_ERR_CODE
] = { .type
= NLA_U16
},
721 * iwpm_mapping_error_cb - Process a port mapper error message
723 int iwpm_mapping_error_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
725 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
726 int nl_client
= RDMA_NL_GET_CLIENT(cb
->nlh
->nlmsg_type
);
727 struct nlattr
*nltb
[IWPM_NLA_ERR_MAX
];
730 const char *msg_type
= "Mapping Error Msg";
732 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_ERR_MAX
,
733 map_error_policy
, nltb
, msg_type
))
736 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_ERR_SEQ
]);
737 err_code
= nla_get_u16(nltb
[IWPM_NLA_ERR_CODE
]);
738 pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
739 __func__
, msg_seq
, err_code
, nl_client
);
740 /* look for nlmsg_request */
741 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
742 if (!nlmsg_request
) {
743 /* not all errors have associated requests */
744 pr_debug("Could not find matching req (seq = %u)\n", msg_seq
);
747 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
748 nlmsg_request
->err_code
= err_code
;
749 nlmsg_request
->request_done
= 1;
750 /* always for found request */
751 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
753 wake_up(&nlmsg_request
->waitq
);
756 EXPORT_SYMBOL(iwpm_mapping_error_cb
);