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[] = "iWarpPortMapperUser"; 37 static int iwpm_ulib_version = 3; 38 static int iwpm_user_pid = IWPM_PID_UNDEFINED; 39 static atomic_t echo_nlmsg_seq; 40 41 int iwpm_valid_pid(void) 42 { 43 return iwpm_user_pid > 0; 44 } 45 EXPORT_SYMBOL(iwpm_valid_pid); 46 47 /* 48 * iwpm_register_pid - Send a netlink query to user space 49 * for the iwarp port mapper pid 50 * 51 * nlmsg attributes: 52 * [IWPM_NLA_REG_PID_SEQ] 53 * [IWPM_NLA_REG_IF_NAME] 54 * [IWPM_NLA_REG_IBDEV_NAME] 55 * [IWPM_NLA_REG_ULIB_NAME] 56 */ 57 int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) 58 { 59 struct sk_buff *skb = NULL; 60 struct iwpm_nlmsg_request *nlmsg_request = NULL; 61 struct nlmsghdr *nlh; 62 u32 msg_seq; 63 const char *err_str = ""; 64 int ret = -EINVAL; 65 66 if (!iwpm_valid_client(nl_client)) { 67 err_str = "Invalid port mapper client"; 68 goto pid_query_error; 69 } 70 if (iwpm_registered_client(nl_client)) 71 return 0; 72 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client); 73 if (!skb) { 74 err_str = "Unable to create a nlmsg"; 75 goto pid_query_error; 76 } 77 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 78 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL); 79 if (!nlmsg_request) { 80 err_str = "Unable to allocate netlink request"; 81 goto pid_query_error; 82 } 83 msg_seq = atomic_read(&echo_nlmsg_seq); 84 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); 88 if (ret) 89 goto pid_query_error; 90 ret = ibnl_put_attr(skb, nlh, IWPM_IFNAME_SIZE, 91 pm_msg->if_name, IWPM_NLA_REG_IF_NAME); 92 if (ret) 93 goto pid_query_error; 94 ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE, 95 pm_msg->dev_name, IWPM_NLA_REG_IBDEV_NAME); 96 if (ret) 97 goto pid_query_error; 98 ret = ibnl_put_attr(skb, nlh, IWPM_ULIBNAME_SIZE, 99 (char *)iwpm_ulib_name, IWPM_NLA_REG_ULIB_NAME); 100 if (ret) 101 goto pid_query_error; 102 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); 105 106 ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL); 107 if (ret) { 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; 113 } 114 nlmsg_request->req_buffer = pm_msg; 115 ret = iwpm_wait_complete_req(nlmsg_request); 116 return ret; 117 pid_query_error: 118 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 119 if (skb) 120 dev_kfree_skb(skb); 121 if (nlmsg_request) 122 iwpm_free_nlmsg_request(&nlmsg_request->kref); 123 return ret; 124 } 125 EXPORT_SYMBOL(iwpm_register_pid); 126 127 /* 128 * iwpm_add_mapping - Send a netlink add mapping message 129 * to the port mapper 130 * nlmsg attributes: 131 * [IWPM_NLA_MANAGE_MAPPING_SEQ] 132 * [IWPM_NLA_MANAGE_ADDR] 133 */ 134 int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) 135 { 136 struct sk_buff *skb = NULL; 137 struct iwpm_nlmsg_request *nlmsg_request = NULL; 138 struct nlmsghdr *nlh; 139 u32 msg_seq; 140 const char *err_str = ""; 141 int ret = -EINVAL; 142 143 if (!iwpm_valid_client(nl_client)) { 144 err_str = "Invalid port mapper client"; 145 goto add_mapping_error; 146 } 147 if (!iwpm_registered_client(nl_client)) { 148 err_str = "Unregistered port mapper client"; 149 goto add_mapping_error; 150 } 151 if (!iwpm_valid_pid()) 152 return 0; 153 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client); 154 if (!skb) { 155 err_str = "Unable to create a nlmsg"; 156 goto add_mapping_error; 157 } 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; 163 } 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); 169 if (ret) 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); 173 if (ret) 174 goto add_mapping_error; 175 nlmsg_request->req_buffer = pm_msg; 176 177 ret = ibnl_unicast(skb, nlh, iwpm_user_pid); 178 if (ret) { 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; 183 } 184 ret = iwpm_wait_complete_req(nlmsg_request); 185 return ret; 186 add_mapping_error: 187 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 188 if (skb) 189 dev_kfree_skb(skb); 190 if (nlmsg_request) 191 iwpm_free_nlmsg_request(&nlmsg_request->kref); 192 return ret; 193 } 194 EXPORT_SYMBOL(iwpm_add_mapping); 195 196 /* 197 * iwpm_add_and_query_mapping - Send a netlink add and query 198 * mapping message to the port mapper 199 * nlmsg attributes: 200 * [IWPM_NLA_QUERY_MAPPING_SEQ] 201 * [IWPM_NLA_QUERY_LOCAL_ADDR] 202 * [IWPM_NLA_QUERY_REMOTE_ADDR] 203 */ 204 int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) 205 { 206 struct sk_buff *skb = NULL; 207 struct iwpm_nlmsg_request *nlmsg_request = NULL; 208 struct nlmsghdr *nlh; 209 u32 msg_seq; 210 const char *err_str = ""; 211 int ret = -EINVAL; 212 213 if (!iwpm_valid_client(nl_client)) { 214 err_str = "Invalid port mapper client"; 215 goto query_mapping_error; 216 } 217 if (!iwpm_registered_client(nl_client)) { 218 err_str = "Unregistered port mapper client"; 219 goto query_mapping_error; 220 } 221 if (!iwpm_valid_pid()) 222 return 0; 223 ret = -ENOMEM; 224 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client); 225 if (!skb) { 226 err_str = "Unable to create a nlmsg"; 227 goto query_mapping_error; 228 } 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; 235 } 236 msg_seq = atomic_read(&echo_nlmsg_seq); 237 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); 242 if (ret) 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); 246 if (ret) 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); 250 if (ret) 251 goto query_mapping_error; 252 nlmsg_request->req_buffer = pm_msg; 253 254 ret = ibnl_unicast(skb, nlh, iwpm_user_pid); 255 if (ret) { 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; 259 } 260 ret = iwpm_wait_complete_req(nlmsg_request); 261 return ret; 262 query_mapping_error: 263 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 264 if (skb) 265 dev_kfree_skb(skb); 266 if (nlmsg_request) 267 iwpm_free_nlmsg_request(&nlmsg_request->kref); 268 return ret; 269 } 270 EXPORT_SYMBOL(iwpm_add_and_query_mapping); 271 272 /* 273 * iwpm_remove_mapping - Send a netlink remove mapping message 274 * to the port mapper 275 * nlmsg attributes: 276 * [IWPM_NLA_MANAGE_MAPPING_SEQ] 277 * [IWPM_NLA_MANAGE_ADDR] 278 */ 279 int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) 280 { 281 struct sk_buff *skb = NULL; 282 struct nlmsghdr *nlh; 283 u32 msg_seq; 284 const char *err_str = ""; 285 int ret = -EINVAL; 286 287 if (!iwpm_valid_client(nl_client)) { 288 err_str = "Invalid port mapper client"; 289 goto remove_mapping_error; 290 } 291 if (!iwpm_registered_client(nl_client)) { 292 err_str = "Unregistered port mapper client"; 293 goto remove_mapping_error; 294 } 295 if (!iwpm_valid_pid()) 296 return 0; 297 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client); 298 if (!skb) { 299 ret = -ENOMEM; 300 err_str = "Unable to create a nlmsg"; 301 goto remove_mapping_error; 302 } 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); 308 if (ret) 309 goto remove_mapping_error; 310 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 311 local_addr, IWPM_NLA_MANAGE_ADDR); 312 if (ret) 313 goto remove_mapping_error; 314 315 ret = ibnl_unicast(skb, nlh, iwpm_user_pid); 316 if (ret) { 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; 321 } 322 iwpm_print_sockaddr(local_addr, 323 "remove_mapping: Local sockaddr:"); 324 return 0; 325 remove_mapping_error: 326 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 327 if (skb) 328 dev_kfree_skb_any(skb); 329 return ret; 330 } 331 EXPORT_SYMBOL(iwpm_remove_mapping); 332 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 } 342 }; 343 344 /* 345 * iwpm_register_pid_cb - Process a port mapper response to 346 * iwpm_register_pid() 347 */ 348 int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) 349 { 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; 354 u32 msg_seq; 355 u8 nl_client; 356 u16 iwpm_version; 357 const char *msg_type = "Register Pid response"; 358 359 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX, 360 resp_reg_policy, nltb, msg_type)) 361 return -EINVAL; 362 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", 367 __func__, msg_seq); 368 return -EINVAL; 369 } 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]); 375 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) { 380 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; 385 } 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); 396 barrier(); 397 wake_up(&nlmsg_request->waitq); 398 return 0; 399 } 400 EXPORT_SYMBOL(iwpm_register_pid_cb); 401 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 } 408 }; 409 410 /* 411 * iwpm_add_mapping_cb - Process a port mapper response to 412 * iwpm_add_mapping() 413 */ 414 int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) 415 { 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; 422 u32 msg_seq; 423 424 msg_type = "Add Mapping response"; 425 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX, 426 resp_add_policy, nltb, msg_type)) 427 return -EINVAL; 428 429 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 430 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", 435 __func__, msg_seq); 436 return -EINVAL; 437 } 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]); 443 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; 447 } 448 if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) { 449 pr_info("%s: Sockaddr family doesn't match the requested one\n", 450 __func__); 451 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 452 goto add_mapping_response_exit; 453 } 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:"); 460 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); 465 barrier(); 466 wake_up(&nlmsg_request->waitq); 467 return 0; 468 } 469 EXPORT_SYMBOL(iwpm_add_mapping_cb); 470 471 /* netlink attribute policy for the response to add and query mapping request */ 472 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { 473 [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, 474 [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 475 [IWPM_NLA_QUERY_REMOTE_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 476 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 477 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 478 [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 } 479 }; 480 481 /* 482 * iwpm_add_and_query_mapping_cb - Process a port mapper response to 483 * iwpm_add_and_query_mapping() 484 */ 485 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, 486 struct netlink_callback *cb) 487 { 488 struct iwpm_sa_data *pm_msg; 489 struct iwpm_nlmsg_request *nlmsg_request = NULL; 490 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 491 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 492 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 493 const char *msg_type; 494 u32 msg_seq; 495 u16 err_code; 496 497 msg_type = "Query Mapping response"; 498 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 499 resp_query_policy, nltb, msg_type)) 500 return -EINVAL; 501 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 502 503 msg_seq = nla_get_u32(nltb[IWPM_NLA_QUERY_MAPPING_SEQ]); 504 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 505 if (!nlmsg_request) { 506 pr_info("%s: Could not find a matching request (seq = %u)\n", 507 __func__, msg_seq); 508 return -EINVAL; 509 } 510 pm_msg = nlmsg_request->req_buffer; 511 local_sockaddr = (struct sockaddr_storage *) 512 nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); 513 remote_sockaddr = (struct sockaddr_storage *) 514 nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); 515 mapped_loc_sockaddr = (struct sockaddr_storage *) 516 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 517 mapped_rem_sockaddr = (struct sockaddr_storage *) 518 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 519 520 err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]); 521 if (err_code == IWPM_REMOTE_QUERY_REJECT) { 522 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n", 523 __func__, cb->nlh->nlmsg_pid, msg_seq); 524 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT; 525 } 526 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) || 527 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) { 528 pr_info("%s: Incorrect local sockaddr\n", __func__); 529 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 530 goto query_mapping_response_exit; 531 } 532 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || 533 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { 534 pr_info("%s: Sockaddr family doesn't match the requested one\n", 535 __func__); 536 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 537 goto query_mapping_response_exit; 538 } 539 memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr, 540 sizeof(*mapped_loc_sockaddr)); 541 memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr, 542 sizeof(*mapped_rem_sockaddr)); 543 544 iwpm_print_sockaddr(&pm_msg->loc_addr, 545 "query_mapping: Local sockaddr:"); 546 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, 547 "query_mapping: Mapped local sockaddr:"); 548 iwpm_print_sockaddr(&pm_msg->rem_addr, 549 "query_mapping: Remote sockaddr:"); 550 iwpm_print_sockaddr(&pm_msg->mapped_rem_addr, 551 "query_mapping: Mapped remote sockaddr:"); 552 query_mapping_response_exit: 553 nlmsg_request->request_done = 1; 554 /* always for found request */ 555 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 556 barrier(); 557 wake_up(&nlmsg_request->waitq); 558 return 0; 559 } 560 EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb); 561 562 /* netlink attribute policy for the received request for mapping info */ 563 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { 564 [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, 565 .len = IWPM_ULIBNAME_SIZE - 1 }, 566 [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 } 567 }; 568 569 /* 570 * iwpm_mapping_info_cb - Process a port mapper request for mapping info 571 */ 572 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 573 { 574 struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; 575 const char *msg_type = "Mapping Info response"; 576 int iwpm_pid; 577 u8 nl_client; 578 char *iwpm_name; 579 u16 iwpm_version; 580 int ret = -EINVAL; 581 582 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX, 583 resp_mapinfo_policy, nltb, msg_type)) { 584 pr_info("%s: Unable to parse nlmsg\n", __func__); 585 return ret; 586 } 587 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]); 588 iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]); 589 if (strcmp(iwpm_ulib_name, iwpm_name) || 590 iwpm_version != iwpm_ulib_version) { 591 pr_info("%s: Invalid port mapper name = %s version = %d\n", 592 __func__, iwpm_name, iwpm_version); 593 return ret; 594 } 595 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 596 if (!iwpm_valid_client(nl_client)) { 597 pr_info("%s: Invalid port mapper client = %d\n", 598 __func__, nl_client); 599 return ret; 600 } 601 iwpm_set_registered(nl_client, 0); 602 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 603 if (!iwpm_mapinfo_available()) 604 return 0; 605 iwpm_pid = cb->nlh->nlmsg_pid; 606 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", 607 __func__, iwpm_pid); 608 ret = iwpm_send_mapinfo(nl_client, iwpm_pid); 609 return ret; 610 } 611 EXPORT_SYMBOL(iwpm_mapping_info_cb); 612 613 /* netlink attribute policy for the received mapping info ack */ 614 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = { 615 [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 }, 616 [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 }, 617 [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 } 618 }; 619 620 /* 621 * iwpm_ack_mapping_info_cb - Process a port mapper ack for 622 * the provided mapping info records 623 */ 624 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 625 { 626 struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX]; 627 u32 mapinfo_send, mapinfo_ack; 628 const char *msg_type = "Mapping Info Ack"; 629 630 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX, 631 ack_mapinfo_policy, nltb, msg_type)) 632 return -EINVAL; 633 mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]); 634 mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]); 635 if (mapinfo_ack != mapinfo_send) 636 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n", 637 __func__, mapinfo_send, mapinfo_ack); 638 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 639 return 0; 640 } 641 EXPORT_SYMBOL(iwpm_ack_mapping_info_cb); 642 643 /* netlink attribute policy for the received port mapper error message */ 644 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = { 645 [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 }, 646 [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 }, 647 }; 648 649 /* 650 * iwpm_mapping_error_cb - Process a port mapper error message 651 */ 652 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) 653 { 654 struct iwpm_nlmsg_request *nlmsg_request = NULL; 655 int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 656 struct nlattr *nltb[IWPM_NLA_ERR_MAX]; 657 u32 msg_seq; 658 u16 err_code; 659 const char *msg_type = "Mapping Error Msg"; 660 661 if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX, 662 map_error_policy, nltb, msg_type)) 663 return -EINVAL; 664 665 msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]); 666 err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]); 667 pr_info("%s: Received msg seq = %u err code = %u client = %d\n", 668 __func__, msg_seq, err_code, nl_client); 669 /* look for nlmsg_request */ 670 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 671 if (!nlmsg_request) { 672 /* not all errors have associated requests */ 673 pr_debug("Could not find matching req (seq = %u)\n", msg_seq); 674 return 0; 675 } 676 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 677 nlmsg_request->err_code = err_code; 678 nlmsg_request->request_done = 1; 679 /* always for found request */ 680 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 681 barrier(); 682 wake_up(&nlmsg_request->waitq); 683 return 0; 684 } 685 EXPORT_SYMBOL(iwpm_mapping_error_cb); 686