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 u16 iwpm_ulib_version
= IWPM_UABI_VERSION_MIN
;
38 static int iwpm_user_pid
= IWPM_PID_UNDEFINED
;
39 static atomic_t echo_nlmsg_seq
;
42 * iwpm_valid_pid - Check if the userspace iwarp port mapper pid is valid
44 * Returns true if the pid is greater than zero, otherwise returns false
46 int iwpm_valid_pid(void)
48 return iwpm_user_pid
> 0;
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
58 * [IWPM_NLA_REG_PID_SEQ]
59 * [IWPM_NLA_REG_IF_NAME]
60 * [IWPM_NLA_REG_IBDEV_NAME]
61 * [IWPM_NLA_REG_ULIB_NAME]
63 int iwpm_register_pid(struct iwpm_dev_data
*pm_msg
, u8 nl_client
)
65 struct sk_buff
*skb
= NULL
;
66 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
69 const char *err_str
= "";
72 if (iwpm_check_registration(nl_client
, IWPM_REG_VALID
) ||
73 iwpm_user_pid
== IWPM_PID_UNAVAILABLE
)
75 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID
, &nlh
, nl_client
);
77 err_str
= "Unable to create a nlmsg";
80 nlh
->nlmsg_seq
= iwpm_get_nlmsg_seq();
81 nlmsg_request
= iwpm_get_nlmsg_request(nlh
->nlmsg_seq
, nl_client
, GFP_KERNEL
);
83 err_str
= "Unable to allocate netlink request";
86 msg_seq
= atomic_read(&echo_nlmsg_seq
);
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
);
93 ret
= ibnl_put_attr(skb
, nlh
, IFNAMSIZ
,
94 pm_msg
->if_name
, IWPM_NLA_REG_IF_NAME
);
97 ret
= ibnl_put_attr(skb
, nlh
, IWPM_DEVNAME_SIZE
,
98 pm_msg
->dev_name
, IWPM_NLA_REG_IBDEV_NAME
);
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
);
104 goto pid_query_error
;
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
);
111 ret
= rdma_nl_multicast(&init_net
, skb
, RDMA_NL_GROUP_IWPM
, GFP_KERNEL
);
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
;
118 nlmsg_request
->req_buffer
= pm_msg
;
119 ret
= iwpm_wait_complete_req(nlmsg_request
);
122 pr_info("%s: %s (client = %u)\n", __func__
, err_str
, nl_client
);
125 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
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
136 * [IWPM_NLA_MANAGE_MAPPING_SEQ]
137 * [IWPM_NLA_MANAGE_ADDR]
138 * [IWPM_NLA_MANAGE_FLAGS]
140 * If the request is successful, the pm_msg stores
141 * the port mapper response (mapped address info)
143 int iwpm_add_mapping(struct iwpm_sa_data
*pm_msg
, u8 nl_client
)
145 struct sk_buff
*skb
= NULL
;
146 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
147 struct nlmsghdr
*nlh
;
149 const char *err_str
= "";
152 if (!iwpm_valid_pid())
154 if (!iwpm_check_registration(nl_client
, IWPM_REG_VALID
)) {
155 err_str
= "Unregistered port mapper client";
156 goto add_mapping_error
;
158 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING
, &nlh
, nl_client
);
160 err_str
= "Unable to create a nlmsg";
161 goto add_mapping_error
;
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
;
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
);
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
);
179 goto add_mapping_error
;
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
) {
184 goto add_mapping_error_nowarn
;
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
);
190 goto add_mapping_error
;
194 nlmsg_request
->req_buffer
= pm_msg
;
196 ret
= rdma_nl_unicast_wait(&init_net
, skb
, iwpm_user_pid
);
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
;
203 ret
= iwpm_wait_complete_req(nlmsg_request
);
206 pr_info("%s: %s (client = %u)\n", __func__
, err_str
, nl_client
);
207 add_mapping_error_nowarn
:
210 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
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
221 * [IWPM_NLA_QUERY_MAPPING_SEQ]
222 * [IWPM_NLA_QUERY_LOCAL_ADDR]
223 * [IWPM_NLA_QUERY_REMOTE_ADDR]
224 * [IWPM_NLA_QUERY_FLAGS]
226 int iwpm_add_and_query_mapping(struct iwpm_sa_data
*pm_msg
, u8 nl_client
)
228 struct sk_buff
*skb
= NULL
;
229 struct iwpm_nlmsg_request
*nlmsg_request
= NULL
;
230 struct nlmsghdr
*nlh
;
232 const char *err_str
= "";
235 if (!iwpm_valid_pid())
237 if (!iwpm_check_registration(nl_client
, IWPM_REG_VALID
)) {
238 err_str
= "Unregistered port mapper client";
239 goto query_mapping_error
;
242 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING
, &nlh
, nl_client
);
244 err_str
= "Unable to create a nlmsg";
245 goto query_mapping_error
;
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
;
254 msg_seq
= atomic_read(&echo_nlmsg_seq
);
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
);
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
);
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
);
269 goto query_mapping_error
;
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
) {
274 goto query_mapping_error_nowarn
;
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
);
280 goto query_mapping_error
;
284 nlmsg_request
->req_buffer
= pm_msg
;
286 ret
= rdma_nl_unicast_wait(&init_net
, skb
, iwpm_user_pid
);
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
;
292 ret
= iwpm_wait_complete_req(nlmsg_request
);
295 pr_info("%s: %s (client = %u)\n", __func__
, err_str
, nl_client
);
296 query_mapping_error_nowarn
:
299 iwpm_free_nlmsg_request(&nlmsg_request
->kref
);
304 * iwpm_remove_mapping - Send a netlink remove mapping request
305 * to the userspace port mapper
307 * @local_addr: Local ip/tcp address to remove
308 * @nl_client: The index of the netlink client
311 * [IWPM_NLA_MANAGE_MAPPING_SEQ]
312 * [IWPM_NLA_MANAGE_ADDR]
314 int iwpm_remove_mapping(struct sockaddr_storage
*local_addr
, u8 nl_client
)
316 struct sk_buff
*skb
= NULL
;
317 struct nlmsghdr
*nlh
;
319 const char *err_str
= "";
322 if (!iwpm_valid_pid())
324 if (iwpm_check_registration(nl_client
, IWPM_REG_UNDEF
)) {
325 err_str
= "Unregistered port mapper client";
326 goto remove_mapping_error
;
328 skb
= iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING
, &nlh
, nl_client
);
331 err_str
= "Unable to create a nlmsg";
332 goto remove_mapping_error
;
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
);
340 goto remove_mapping_error
;
341 ret
= ibnl_put_attr(skb
, nlh
, sizeof(struct sockaddr_storage
),
342 local_addr
, IWPM_NLA_MANAGE_ADDR
);
344 goto remove_mapping_error
;
348 ret
= rdma_nl_unicast_wait(&init_net
, skb
, iwpm_user_pid
);
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
;
355 iwpm_print_sockaddr(local_addr
,
356 "remove_mapping: Local sockaddr:");
358 remove_mapping_error
:
359 pr_info("%s: %s (client = %u)\n", __func__
, err_str
, nl_client
);
361 dev_kfree_skb_any(skb
);
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
}
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)
382 * If successful, the function receives the userspace port mapper pid
383 * which is used in future communication with the port mapper
385 int iwpm_register_pid_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
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
;
394 const char *msg_type
= "Register Pid response";
396 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RREG_PID_MAX
,
397 resp_reg_policy
, nltb
, msg_type
))
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",
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
]);
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
) {
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
;
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
);
437 up(&nlmsg_request
->sem
);
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
}
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)
457 int iwpm_add_mapping_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
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
;
467 msg_type
= "Add Mapping response";
468 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RMANAGE_MAPPING_MAX
,
469 resp_add_policy
, nltb
, msg_type
))
472 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
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",
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
]);
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
;
491 if (mapped_sockaddr
->ss_family
!= local_sockaddr
->ss_family
) {
492 pr_info("%s: Sockaddr family doesn't match the requested one\n",
494 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
495 goto add_mapping_response_exit
;
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:");
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
);
509 up(&nlmsg_request
->sem
);
513 /* netlink attribute policy for the response to add and query mapping request
514 * and response with remote address info
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
}
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)
535 int iwpm_add_and_query_mapping_cb(struct sk_buff
*skb
,
536 struct netlink_callback
*cb
)
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
;
547 msg_type
= "Query Mapping response";
548 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RQUERY_MAPPING_MAX
,
549 resp_query_policy
, nltb
, msg_type
))
551 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
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",
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
]);
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
;
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
;
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",
586 nlmsg_request
->err_code
= IWPM_USER_LIB_INFO_ERR
;
587 goto query_mapping_response_exit
;
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
));
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
);
607 up(&nlmsg_request
->sem
);
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)
617 * Stores the IPv4/IPv6 address info in a hash table
619 int iwpm_remote_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
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
;
629 msg_type
= "Remote Mapping info";
630 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_RQUERY_MAPPING_MAX
,
631 resp_query_policy
, nltb
, msg_type
))
634 nl_client
= RDMA_NL_GET_CLIENT(cb
->nlh
->nlmsg_type
);
635 atomic_set(&echo_nlmsg_seq
, cb
->nlh
->nlmsg_seq
);
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
]);
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",
652 rem_info
= kzalloc(sizeof(struct iwpm_remote_info
), GFP_ATOMIC
);
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
;
665 iwpm_add_remote_info(rem_info
);
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:");
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
}
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)
691 * Using the received port mapper pid, send all the local mapping
692 * info records to the userspace port mapper
694 int iwpm_mapping_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
696 struct nlattr
*nltb
[IWPM_NLA_MAPINFO_REQ_MAX
];
697 const char *msg_type
= "Mapping Info response";
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__
);
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
);
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
;
721 if (iwpm_ulib_version
< IWPM_UABI_VERSION
)
722 pr_warn_once("%s: Down level iwpmd/pid %d. Continuing...",
723 __func__
, iwpm_user_pid
);
725 if (!iwpm_mapinfo_available())
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
);
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
}
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)
746 int iwpm_ack_mapping_info_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
748 struct nlattr
*nltb
[IWPM_NLA_MAPINFO_NUM_MAX
];
749 u32 mapinfo_send
, mapinfo_ack
;
750 const char *msg_type
= "Mapping Info Ack";
752 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_MAPINFO_NUM_MAX
,
753 ack_mapinfo_policy
, nltb
, msg_type
))
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
);
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
},
771 * iwpm_mapping_error_cb - Process port mapper notification for error
773 * @skb: The socket buffer
774 * @cb: Contains the received message (payload and netlink header)
776 int iwpm_mapping_error_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
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
];
783 const char *msg_type
= "Mapping Error Msg";
785 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_ERR_MAX
,
786 map_error_policy
, nltb
, msg_type
))
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
);
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
);
806 up(&nlmsg_request
->sem
);
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
}
816 * iwpm_hello_cb - Process a hello message from iwpmd
818 * @skb: The socket buffer
819 * @cb: Contains the received message (payload and netlink header)
821 * Using the received port mapper pid, send the kernel's abi_version
822 * after adjusting it to support the iwpmd version.
824 int iwpm_hello_cb(struct sk_buff
*skb
, struct netlink_callback
*cb
)
826 struct nlattr
*nltb
[IWPM_NLA_HELLO_MAX
];
827 const char *msg_type
= "Hello request";
832 if (iwpm_parse_nlmsg(cb
, IWPM_NLA_HELLO_MAX
, hello_policy
, nltb
,
834 pr_info("%s: Unable to parse nlmsg\n", __func__
);
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
);