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