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;
47 * iwpm_register_pid - Send a netlink query to user space
48 * for the iwarp port mapper pid
51 * [IWPM_NLA_REG_PID_SEQ]
52 * [IWPM_NLA_REG_IF_NAME]
53 * [IWPM_NLA_REG_IBDEV_NAME]
54 * [IWPM_NLA_REG_ULIB_NAME]
56 int iwpm_register_pid(struct iwpm_dev_data
*pm_msg
, u8 nl_client
)
58 struct sk_buff
*skb
= NULL
;
59 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
62 const char *err_str
= "";
65 if (!iwpm_valid_client(nl_client
)) {
66 err_str
= "Invalid port mapper client";
69 if (iwpm_check_registration(nl_client
, IWPM_REG_VALID
) ||
70 iwpm_user_pid
== IWPM_PID_UNAVAILABLE
)
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
, IFNAMSIZ
,
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
;
105 pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
106 __func__
, pm_msg
->dev_name
, pm_msg
->if_name
, iwpm_ulib_name
);
108 ret
= rdma_nl_multicast(skb
, RDMA_NL_GROUP_IWPM
, GFP_KERNEL
);
110 skb
= NULL
; /* skb is freed in the netlink send-op handling */
111 iwpm_user_pid
= IWPM_PID_UNAVAILABLE
;
112 err_str
= "Unable to send a nlmsg";
113 goto pid_query_error
;
115 nlmsg_request
->req_buffer
= pm_msg
;
116 ret
= iwpm_wait_complete_req(nlmsg_request
);
119 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
123 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
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_valid_pid())
149 if (!iwpm_check_registration(nl_client
, IWPM_REG_VALID
)) {
150 err_str
= "Unregistered port mapper client";
151 goto add_mapping_error
;
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
;
177 nlmsg_request
->req_buffer
= pm_msg
;
179 ret
= rdma_nl_unicast_wait(skb
, iwpm_user_pid
);
181 skb
= NULL
; /* skb is freed in the netlink send-op handling */
182 iwpm_user_pid
= IWPM_PID_UNDEFINED
;
183 err_str
= "Unable to send a nlmsg";
184 goto add_mapping_error
;
186 ret
= iwpm_wait_complete_req(nlmsg_request
);
189 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
193 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
198 * iwpm_add_and_query_mapping - Send a netlink add and query
199 * mapping message to the port mapper
201 * [IWPM_NLA_QUERY_MAPPING_SEQ]
202 * [IWPM_NLA_QUERY_LOCAL_ADDR]
203 * [IWPM_NLA_QUERY_REMOTE_ADDR]
205 int iwpm_add_and_query_mapping(struct iwpm_sa_data
*pm_msg
, u8 nl_client
)
207 struct sk_buff
*skb
= NULL
;
208 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
209 struct nlmsghdr
*nlh
;
211 const char *err_str
= "";
214 if (!iwpm_valid_client(nl_client
)) {
215 err_str
= "Invalid port mapper client";
216 goto query_mapping_error
;
218 if (!iwpm_valid_pid())
220 if (!iwpm_check_registration(nl_client
, IWPM_REG_VALID
)) {
221 err_str
= "Unregistered port mapper client";
222 goto query_mapping_error
;
225 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING
, &nlh
, nl_client
);
227 err_str
= "Unable to create a nlmsg";
228 goto query_mapping_error
;
230 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
231 nlmsg_request
= iwpm_get_nlmsg_request(nlh
->nlmsg_seq
,
232 nl_client
, GFP_KERNEL
);
233 if (!nlmsg_request
) {
234 err_str
= "Unable to allocate netlink request";
235 goto query_mapping_error
;
237 msg_seq
= atomic_read(&echo_nlmsg_seq
);
239 /* fill in the query message */
240 err_str
= "Unable to put attribute of the nlmsg";
241 ret
= ibnl_put_attr(skb
, nlh
, sizeof(u32
), &msg_seq
,
242 IWPM_NLA_QUERY_MAPPING_SEQ
);
244 goto query_mapping_error
;
245 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
246 &pm_msg
->loc_addr
, IWPM_NLA_QUERY_LOCAL_ADDR
);
248 goto query_mapping_error
;
249 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
250 &pm_msg
->rem_addr
, IWPM_NLA_QUERY_REMOTE_ADDR
);
252 goto query_mapping_error
;
255 nlmsg_request
->req_buffer
= pm_msg
;
257 ret
= rdma_nl_unicast_wait(skb
, iwpm_user_pid
);
259 skb
= NULL
; /* skb is freed in the netlink send-op handling */
260 err_str
= "Unable to send a nlmsg";
261 goto query_mapping_error
;
263 ret
= iwpm_wait_complete_req(nlmsg_request
);
266 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
270 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
275 * iwpm_remove_mapping - Send a netlink remove mapping message
278 * [IWPM_NLA_MANAGE_MAPPING_SEQ]
279 * [IWPM_NLA_MANAGE_ADDR]
281 int iwpm_remove_mapping(struct sockaddr_storage
*local_addr
, u8 nl_client
)
283 struct sk_buff
*skb
= NULL
;
284 struct nlmsghdr
*nlh
;
286 const char *err_str
= "";
289 if (!iwpm_valid_client(nl_client
)) {
290 err_str
= "Invalid port mapper client";
291 goto remove_mapping_error
;
293 if (!iwpm_valid_pid())
295 if (iwpm_check_registration(nl_client
, IWPM_REG_UNDEF
)) {
296 err_str
= "Unregistered port mapper client";
297 goto remove_mapping_error
;
299 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING
, &nlh
, nl_client
);
302 err_str
= "Unable to create a nlmsg";
303 goto remove_mapping_error
;
305 msg_seq
= atomic_read(&echo_nlmsg_seq
);
306 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
307 err_str
= "Unable to put attribute of the nlmsg";
308 ret
= ibnl_put_attr(skb
, nlh
, sizeof(u32
), &msg_seq
,
309 IWPM_NLA_MANAGE_MAPPING_SEQ
);
311 goto remove_mapping_error
;
312 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
313 local_addr
, IWPM_NLA_MANAGE_ADDR
);
315 goto remove_mapping_error
;
319 ret
= rdma_nl_unicast_wait(skb
, iwpm_user_pid
);
321 skb
= NULL
; /* skb is freed in the netlink send-op handling */
322 iwpm_user_pid
= IWPM_PID_UNDEFINED
;
323 err_str
= "Unable to send a nlmsg";
324 goto remove_mapping_error
;
326 iwpm_print_sockaddr(local_addr
,
327 "remove_mapping: Local sockaddr:");
329 remove_mapping_error
:
330 pr_info("%s: %s (client = %d)\n", __func__
, err_str
, nl_client
);
332 dev_kfree_skb_any(skb
);
336 /* netlink attribute policy for the received response to register pid request */
337 static const struct nla_policy resp_reg_policy
[IWPM_NLA_RREG_PID_MAX
] = {
338 [IWPM_NLA_RREG_PID_SEQ
] = { .type
= NLA_U32
},
339 [IWPM_NLA_RREG_IBDEV_NAME
] = { .type
= NLA_STRING
,
340 .len
= IWPM_DEVNAME_SIZE
- 1 },
341 [IWPM_NLA_RREG_ULIB_NAME
] = { .type
= NLA_STRING
,
342 .len
= IWPM_ULIBNAME_SIZE
- 1 },
343 [IWPM_NLA_RREG_ULIB_VER
] = { .type
= NLA_U16
},
344 [IWPM_NLA_RREG_PID_ERR
] = { .type
= NLA_U16
}
348 * iwpm_register_pid_cb - Process a port mapper response to
349 * iwpm_register_pid()
351 int iwpm_register_pid_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
353 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
354 struct nlattr
*nltb
[IWPM_NLA_RREG_PID_MAX
];
355 struct iwpm_dev_data
*pm_msg
;
356 char *dev_name
, *iwpm_name
;
360 const char *msg_type
= "Register Pid response";
362 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RREG_PID_MAX
,
363 resp_reg_policy
, nltb
, msg_type
))
366 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_RREG_PID_SEQ
]);
367 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
368 if (!nlmsg_request
) {
369 pr_info("%s: Could not find a matching request (seq = %u)\n",
373 pm_msg
= nlmsg_request
->req_buffer
;
374 nl_client
= nlmsg_request
->nl_client
;
375 dev_name
= (char *)nla_data(nltb
[IWPM_NLA_RREG_IBDEV_NAME
]);
376 iwpm_name
= (char *)nla_data(nltb
[IWPM_NLA_RREG_ULIB_NAME
]);
377 iwpm_version
= nla_get_u16(nltb
[IWPM_NLA_RREG_ULIB_VER
]);
379 /* check device name, ulib name and version */
380 if (strcmp(pm_msg
->dev_name
, dev_name
) ||
381 strcmp(iwpm_ulib_name
, iwpm_name
) ||
382 iwpm_version
!= iwpm_ulib_version
) {
384 pr_info("%s: Incorrect info (dev = %s name = %s version = %d)\n",
385 __func__
, dev_name
, iwpm_name
, iwpm_version
);
386 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
387 goto register_pid_response_exit
;
389 iwpm_user_pid
= cb
->nlh
->nlmsg_pid
;
390 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
391 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
392 __func__
, iwpm_user_pid
);
393 if (iwpm_valid_client(nl_client
))
394 iwpm_set_registration(nl_client
, IWPM_REG_VALID
);
395 register_pid_response_exit
:
396 nlmsg_request
->request_done
= 1;
397 /* always for found nlmsg_request */
398 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
400 up(&nlmsg_request
->sem
);
404 /* netlink attribute policy for the received response to add mapping request */
405 static const struct nla_policy resp_add_policy
[IWPM_NLA_RMANAGE_MAPPING_MAX
] = {
406 [IWPM_NLA_MANAGE_MAPPING_SEQ
] = { .type
= NLA_U32
},
407 [IWPM_NLA_MANAGE_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
408 [IWPM_NLA_MANAGE_MAPPED_LOC_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
409 [IWPM_NLA_RMANAGE_MAPPING_ERR
] = { .type
= NLA_U16
}
413 * iwpm_add_mapping_cb - Process a port mapper response to
416 int iwpm_add_mapping_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
418 struct iwpm_sa_data
*pm_msg
;
419 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
420 struct nlattr
*nltb
[IWPM_NLA_RMANAGE_MAPPING_MAX
];
421 struct sockaddr_storage
*local_sockaddr
;
422 struct sockaddr_storage
*mapped_sockaddr
;
423 const char *msg_type
;
426 msg_type
= "Add Mapping response";
427 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RMANAGE_MAPPING_MAX
,
428 resp_add_policy
, nltb
, msg_type
))
431 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
433 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_MANAGE_MAPPING_SEQ
]);
434 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
435 if (!nlmsg_request
) {
436 pr_info("%s: Could not find a matching request (seq = %u)\n",
440 pm_msg
= nlmsg_request
->req_buffer
;
441 local_sockaddr
= (struct sockaddr_storage
*)
442 nla_data(nltb
[IWPM_NLA_MANAGE_ADDR
]);
443 mapped_sockaddr
= (struct sockaddr_storage
*)
444 nla_data(nltb
[IWPM_NLA_MANAGE_MAPPED_LOC_ADDR
]);
446 if (iwpm_compare_sockaddr(local_sockaddr
, &pm_msg
->loc_addr
)) {
447 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
448 goto add_mapping_response_exit
;
450 if (mapped_sockaddr
->ss_family
!= local_sockaddr
->ss_family
) {
451 pr_info("%s: Sockaddr family doesn't match the requested one\n",
453 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
454 goto add_mapping_response_exit
;
456 memcpy(&pm_msg
->mapped_loc_addr
, mapped_sockaddr
,
457 sizeof(*mapped_sockaddr
));
458 iwpm_print_sockaddr(&pm_msg
->loc_addr
,
459 "add_mapping: Local sockaddr:");
460 iwpm_print_sockaddr(&pm_msg
->mapped_loc_addr
,
461 "add_mapping: Mapped local sockaddr:");
463 add_mapping_response_exit
:
464 nlmsg_request
->request_done
= 1;
465 /* always for found request */
466 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
468 up(&nlmsg_request
->sem
);
472 /* netlink attribute policy for the response to add and query mapping request
473 * and response with remote address info */
474 static const struct nla_policy resp_query_policy
[IWPM_NLA_RQUERY_MAPPING_MAX
] = {
475 [IWPM_NLA_QUERY_MAPPING_SEQ
] = { .type
= NLA_U32
},
476 [IWPM_NLA_QUERY_LOCAL_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
477 [IWPM_NLA_QUERY_REMOTE_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
478 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
479 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR
] = { .len
= sizeof(struct sockaddr_storage
) },
480 [IWPM_NLA_RQUERY_MAPPING_ERR
] = { .type
= NLA_U16
}
484 * iwpm_add_and_query_mapping_cb - Process a port mapper response to
485 * iwpm_add_and_query_mapping()
487 int iwpm_add_and_query_mapping_cb(struct sk_buff
*skb
,
488 struct netlink_callback
*cb
)
490 struct iwpm_sa_data
*pm_msg
;
491 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
492 struct nlattr
*nltb
[IWPM_NLA_RQUERY_MAPPING_MAX
];
493 struct sockaddr_storage
*local_sockaddr
, *remote_sockaddr
;
494 struct sockaddr_storage
*mapped_loc_sockaddr
, *mapped_rem_sockaddr
;
495 const char *msg_type
;
499 msg_type
= "Query Mapping response";
500 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RQUERY_MAPPING_MAX
,
501 resp_query_policy
, nltb
, msg_type
))
503 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
505 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_QUERY_MAPPING_SEQ
]);
506 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
507 if (!nlmsg_request
) {
508 pr_info("%s: Could not find a matching request (seq = %u)\n",
512 pm_msg
= nlmsg_request
->req_buffer
;
513 local_sockaddr
= (struct sockaddr_storage
*)
514 nla_data(nltb
[IWPM_NLA_QUERY_LOCAL_ADDR
]);
515 remote_sockaddr
= (struct sockaddr_storage
*)
516 nla_data(nltb
[IWPM_NLA_QUERY_REMOTE_ADDR
]);
517 mapped_loc_sockaddr
= (struct sockaddr_storage
*)
518 nla_data(nltb
[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR
]);
519 mapped_rem_sockaddr
= (struct sockaddr_storage
*)
520 nla_data(nltb
[IWPM_NLA_RQUERY_MAPPED_REM_ADDR
]);
522 err_code
= nla_get_u16(nltb
[IWPM_NLA_RQUERY_MAPPING_ERR
]);
523 if (err_code
== IWPM_REMOTE_QUERY_REJECT
) {
524 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
525 __func__
, cb
->nlh
->nlmsg_pid
, msg_seq
);
526 nlmsg_request
->err_code
= IWPM_REMOTE_QUERY_REJECT
;
528 if (iwpm_compare_sockaddr(local_sockaddr
, &pm_msg
->loc_addr
) ||
529 iwpm_compare_sockaddr(remote_sockaddr
, &pm_msg
->rem_addr
)) {
530 pr_info("%s: Incorrect local sockaddr\n", __func__
);
531 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
532 goto query_mapping_response_exit
;
534 if (mapped_loc_sockaddr
->ss_family
!= local_sockaddr
->ss_family
||
535 mapped_rem_sockaddr
->ss_family
!= remote_sockaddr
->ss_family
) {
536 pr_info("%s: Sockaddr family doesn't match the requested one\n",
538 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
539 goto query_mapping_response_exit
;
541 memcpy(&pm_msg
->mapped_loc_addr
, mapped_loc_sockaddr
,
542 sizeof(*mapped_loc_sockaddr
));
543 memcpy(&pm_msg
->mapped_rem_addr
, mapped_rem_sockaddr
,
544 sizeof(*mapped_rem_sockaddr
));
546 iwpm_print_sockaddr(&pm_msg
->loc_addr
,
547 "query_mapping: Local sockaddr:");
548 iwpm_print_sockaddr(&pm_msg
->mapped_loc_addr
,
549 "query_mapping: Mapped local sockaddr:");
550 iwpm_print_sockaddr(&pm_msg
->rem_addr
,
551 "query_mapping: Remote sockaddr:");
552 iwpm_print_sockaddr(&pm_msg
->mapped_rem_addr
,
553 "query_mapping: Mapped remote sockaddr:");
554 query_mapping_response_exit
:
555 nlmsg_request
->request_done
= 1;
556 /* always for found request */
557 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
559 up(&nlmsg_request
->sem
);
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
);
610 memcpy(&rem_info
->mapped_loc_sockaddr
, mapped_loc_sockaddr
,
611 sizeof(struct sockaddr_storage
));
612 memcpy(&rem_info
->remote_sockaddr
, remote_sockaddr
,
613 sizeof(struct sockaddr_storage
));
614 memcpy(&rem_info
->mapped_rem_sockaddr
, mapped_rem_sockaddr
,
615 sizeof(struct sockaddr_storage
));
616 rem_info
->nl_client
= nl_client
;
618 iwpm_add_remote_info(rem_info
);
620 iwpm_print_sockaddr(local_sockaddr
,
621 "remote_info: Local sockaddr:");
622 iwpm_print_sockaddr(mapped_loc_sockaddr
,
623 "remote_info: Mapped local sockaddr:");
624 iwpm_print_sockaddr(remote_sockaddr
,
625 "remote_info: Remote sockaddr:");
626 iwpm_print_sockaddr(mapped_rem_sockaddr
,
627 "remote_info: Mapped remote sockaddr:");
631 /* netlink attribute policy for the received request for mapping info */
632 static const struct nla_policy resp_mapinfo_policy
[IWPM_NLA_MAPINFO_REQ_MAX
] = {
633 [IWPM_NLA_MAPINFO_ULIB_NAME
] = { .type
= NLA_STRING
,
634 .len
= IWPM_ULIBNAME_SIZE
- 1 },
635 [IWPM_NLA_MAPINFO_ULIB_VER
] = { .type
= NLA_U16
}
639 * iwpm_mapping_info_cb - Process a port mapper request for mapping info
641 int iwpm_mapping_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
643 struct nlattr
*nltb
[IWPM_NLA_MAPINFO_REQ_MAX
];
644 const char *msg_type
= "Mapping Info response";
650 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_MAPINFO_REQ_MAX
,
651 resp_mapinfo_policy
, nltb
, msg_type
)) {
652 pr_info("%s: Unable to parse nlmsg\n", __func__
);
655 iwpm_name
= (char *)nla_data(nltb
[IWPM_NLA_MAPINFO_ULIB_NAME
]);
656 iwpm_version
= nla_get_u16(nltb
[IWPM_NLA_MAPINFO_ULIB_VER
]);
657 if (strcmp(iwpm_ulib_name
, iwpm_name
) ||
658 iwpm_version
!= iwpm_ulib_version
) {
659 pr_info("%s: Invalid port mapper name = %s version = %d\n",
660 __func__
, iwpm_name
, iwpm_version
);
663 nl_client
= RDMA_NL_GET_CLIENT(cb
->nlh
->nlmsg_type
);
664 if (!iwpm_valid_client(nl_client
)) {
665 pr_info("%s: Invalid port mapper client = %d\n",
666 __func__
, nl_client
);
669 iwpm_set_registration(nl_client
, IWPM_REG_INCOMPL
);
670 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
671 iwpm_user_pid
= cb
->nlh
->nlmsg_pid
;
672 if (!iwpm_mapinfo_available())
674 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
675 __func__
, iwpm_user_pid
);
676 ret
= iwpm_send_mapinfo(nl_client
, iwpm_user_pid
);
680 /* netlink attribute policy for the received mapping info ack */
681 static const struct nla_policy ack_mapinfo_policy
[IWPM_NLA_MAPINFO_NUM_MAX
] = {
682 [IWPM_NLA_MAPINFO_SEQ
] = { .type
= NLA_U32
},
683 [IWPM_NLA_MAPINFO_SEND_NUM
] = { .type
= NLA_U32
},
684 [IWPM_NLA_MAPINFO_ACK_NUM
] = { .type
= NLA_U32
}
688 * iwpm_ack_mapping_info_cb - Process a port mapper ack for
689 * the provided mapping info records
691 int iwpm_ack_mapping_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
693 struct nlattr
*nltb
[IWPM_NLA_MAPINFO_NUM_MAX
];
694 u32 mapinfo_send
, mapinfo_ack
;
695 const char *msg_type
= "Mapping Info Ack";
697 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_MAPINFO_NUM_MAX
,
698 ack_mapinfo_policy
, nltb
, msg_type
))
700 mapinfo_send
= nla_get_u32(nltb
[IWPM_NLA_MAPINFO_SEND_NUM
]);
701 mapinfo_ack
= nla_get_u32(nltb
[IWPM_NLA_MAPINFO_ACK_NUM
]);
702 if (mapinfo_ack
!= mapinfo_send
)
703 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
704 __func__
, mapinfo_send
, mapinfo_ack
);
705 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
709 /* netlink attribute policy for the received port mapper error message */
710 static const struct nla_policy map_error_policy
[IWPM_NLA_ERR_MAX
] = {
711 [IWPM_NLA_ERR_SEQ
] = { .type
= NLA_U32
},
712 [IWPM_NLA_ERR_CODE
] = { .type
= NLA_U16
},
716 * iwpm_mapping_error_cb - Process a port mapper error message
718 int iwpm_mapping_error_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
720 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
721 int nl_client
= RDMA_NL_GET_CLIENT(cb
->nlh
->nlmsg_type
);
722 struct nlattr
*nltb
[IWPM_NLA_ERR_MAX
];
725 const char *msg_type
= "Mapping Error Msg";
727 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_ERR_MAX
,
728 map_error_policy
, nltb
, msg_type
))
731 msg_seq
= nla_get_u32(nltb
[IWPM_NLA_ERR_SEQ
]);
732 err_code
= nla_get_u16(nltb
[IWPM_NLA_ERR_CODE
]);
733 pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
734 __func__
, msg_seq
, err_code
, nl_client
);
735 /* look for nlmsg_request */
736 nlmsg_request
= iwpm_find_nlmsg_request(msg_seq
);
737 if (!nlmsg_request
) {
738 /* not all errors have associated requests */
739 pr_debug("Could not find matching req (seq = %u)\n", msg_seq
);
742 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
743 nlmsg_request
->err_code
= err_code
;
744 nlmsg_request
->request_done
= 1;
745 /* always for found request */
746 kref_put(&nlmsg_request
->kref
, iwpm_free_nlmsg_request
);
748 up(&nlmsg_request
->sem
);