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 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 46 /* 47 * iwpm_register_pid - Send a netlink query to user space 48 * for the iwarp port mapper pid 49 * 50 * nlmsg attributes: 51 * [IWPM_NLA_REG_PID_SEQ] 52 * [IWPM_NLA_REG_IF_NAME] 53 * [IWPM_NLA_REG_IBDEV_NAME] 54 * [IWPM_NLA_REG_ULIB_NAME] 55 */ 56 int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) 57 { 58 struct sk_buff *skb = NULL; 59 struct iwpm_nlmsg_request *nlmsg_request = NULL; 60 struct nlmsghdr *nlh; 61 u32 msg_seq; 62 const char *err_str = ""; 63 int ret = -EINVAL; 64 65 if (!iwpm_valid_client(nl_client)) { 66 err_str = "Invalid port mapper client"; 67 goto pid_query_error; 68 } 69 if (iwpm_check_registration(nl_client, IWPM_REG_VALID) || 70 iwpm_user_pid == IWPM_PID_UNAVAILABLE) 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, IFNAMSIZ, 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 = rdma_nl_multicast(skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL); 107 if (ret) { 108 skb = NULL; /* skb is freed in the netlink send-op handling */ 109 iwpm_user_pid = IWPM_PID_UNAVAILABLE; 110 err_str = "Unable to send a nlmsg"; 111 goto pid_query_error; 112 } 113 nlmsg_request->req_buffer = pm_msg; 114 ret = iwpm_wait_complete_req(nlmsg_request); 115 return ret; 116 pid_query_error: 117 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 118 if (skb) 119 dev_kfree_skb(skb); 120 if (nlmsg_request) 121 iwpm_free_nlmsg_request(&nlmsg_request->kref); 122 return ret; 123 } 124 125 /* 126 * iwpm_add_mapping - Send a netlink add mapping message 127 * to the port mapper 128 * nlmsg attributes: 129 * [IWPM_NLA_MANAGE_MAPPING_SEQ] 130 * [IWPM_NLA_MANAGE_ADDR] 131 */ 132 int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) 133 { 134 struct sk_buff *skb = NULL; 135 struct iwpm_nlmsg_request *nlmsg_request = NULL; 136 struct nlmsghdr *nlh; 137 u32 msg_seq; 138 const char *err_str = ""; 139 int ret = -EINVAL; 140 141 if (!iwpm_valid_client(nl_client)) { 142 err_str = "Invalid port mapper client"; 143 goto add_mapping_error; 144 } 145 if (!iwpm_valid_pid()) 146 return 0; 147 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { 148 err_str = "Unregistered port mapper client"; 149 goto add_mapping_error; 150 } 151 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client); 152 if (!skb) { 153 err_str = "Unable to create a nlmsg"; 154 goto add_mapping_error; 155 } 156 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 157 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL); 158 if (!nlmsg_request) { 159 err_str = "Unable to allocate netlink request"; 160 goto add_mapping_error; 161 } 162 msg_seq = atomic_read(&echo_nlmsg_seq); 163 /* fill in the add mapping message */ 164 err_str = "Unable to put attribute of the nlmsg"; 165 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, 166 IWPM_NLA_MANAGE_MAPPING_SEQ); 167 if (ret) 168 goto add_mapping_error; 169 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 170 &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR); 171 if (ret) 172 goto add_mapping_error; 173 nlmsg_request->req_buffer = pm_msg; 174 175 ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); 176 if (ret) { 177 skb = NULL; /* skb is freed in the netlink send-op handling */ 178 iwpm_user_pid = IWPM_PID_UNDEFINED; 179 err_str = "Unable to send a nlmsg"; 180 goto add_mapping_error; 181 } 182 ret = iwpm_wait_complete_req(nlmsg_request); 183 return ret; 184 add_mapping_error: 185 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 186 if (skb) 187 dev_kfree_skb(skb); 188 if (nlmsg_request) 189 iwpm_free_nlmsg_request(&nlmsg_request->kref); 190 return ret; 191 } 192 193 /* 194 * iwpm_add_and_query_mapping - Send a netlink add and query 195 * mapping message to the port mapper 196 * nlmsg attributes: 197 * [IWPM_NLA_QUERY_MAPPING_SEQ] 198 * [IWPM_NLA_QUERY_LOCAL_ADDR] 199 * [IWPM_NLA_QUERY_REMOTE_ADDR] 200 */ 201 int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) 202 { 203 struct sk_buff *skb = NULL; 204 struct iwpm_nlmsg_request *nlmsg_request = NULL; 205 struct nlmsghdr *nlh; 206 u32 msg_seq; 207 const char *err_str = ""; 208 int ret = -EINVAL; 209 210 if (!iwpm_valid_client(nl_client)) { 211 err_str = "Invalid port mapper client"; 212 goto query_mapping_error; 213 } 214 if (!iwpm_valid_pid()) 215 return 0; 216 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { 217 err_str = "Unregistered port mapper client"; 218 goto query_mapping_error; 219 } 220 ret = -ENOMEM; 221 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client); 222 if (!skb) { 223 err_str = "Unable to create a nlmsg"; 224 goto query_mapping_error; 225 } 226 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 227 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, 228 nl_client, GFP_KERNEL); 229 if (!nlmsg_request) { 230 err_str = "Unable to allocate netlink request"; 231 goto query_mapping_error; 232 } 233 msg_seq = atomic_read(&echo_nlmsg_seq); 234 235 /* fill in the query message */ 236 err_str = "Unable to put attribute of the nlmsg"; 237 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, 238 IWPM_NLA_QUERY_MAPPING_SEQ); 239 if (ret) 240 goto query_mapping_error; 241 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 242 &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR); 243 if (ret) 244 goto query_mapping_error; 245 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 246 &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR); 247 if (ret) 248 goto query_mapping_error; 249 nlmsg_request->req_buffer = pm_msg; 250 251 ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); 252 if (ret) { 253 skb = NULL; /* skb is freed in the netlink send-op handling */ 254 err_str = "Unable to send a nlmsg"; 255 goto query_mapping_error; 256 } 257 ret = iwpm_wait_complete_req(nlmsg_request); 258 return ret; 259 query_mapping_error: 260 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 261 if (skb) 262 dev_kfree_skb(skb); 263 if (nlmsg_request) 264 iwpm_free_nlmsg_request(&nlmsg_request->kref); 265 return ret; 266 } 267 268 /* 269 * iwpm_remove_mapping - Send a netlink remove mapping message 270 * to the port mapper 271 * nlmsg attributes: 272 * [IWPM_NLA_MANAGE_MAPPING_SEQ] 273 * [IWPM_NLA_MANAGE_ADDR] 274 */ 275 int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) 276 { 277 struct sk_buff *skb = NULL; 278 struct nlmsghdr *nlh; 279 u32 msg_seq; 280 const char *err_str = ""; 281 int ret = -EINVAL; 282 283 if (!iwpm_valid_client(nl_client)) { 284 err_str = "Invalid port mapper client"; 285 goto remove_mapping_error; 286 } 287 if (!iwpm_valid_pid()) 288 return 0; 289 if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) { 290 err_str = "Unregistered port mapper client"; 291 goto remove_mapping_error; 292 } 293 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client); 294 if (!skb) { 295 ret = -ENOMEM; 296 err_str = "Unable to create a nlmsg"; 297 goto remove_mapping_error; 298 } 299 msg_seq = atomic_read(&echo_nlmsg_seq); 300 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 301 err_str = "Unable to put attribute of the nlmsg"; 302 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, 303 IWPM_NLA_MANAGE_MAPPING_SEQ); 304 if (ret) 305 goto remove_mapping_error; 306 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 307 local_addr, IWPM_NLA_MANAGE_ADDR); 308 if (ret) 309 goto remove_mapping_error; 310 311 ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); 312 if (ret) { 313 skb = NULL; /* skb is freed in the netlink send-op handling */ 314 iwpm_user_pid = IWPM_PID_UNDEFINED; 315 err_str = "Unable to send a nlmsg"; 316 goto remove_mapping_error; 317 } 318 iwpm_print_sockaddr(local_addr, 319 "remove_mapping: Local sockaddr:"); 320 return 0; 321 remove_mapping_error: 322 pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); 323 if (skb) 324 dev_kfree_skb_any(skb); 325 return ret; 326 } 327 328 /* netlink attribute policy for the received response to register pid request */ 329 static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = { 330 [IWPM_NLA_RREG_PID_SEQ] = { .type = NLA_U32 }, 331 [IWPM_NLA_RREG_IBDEV_NAME] = { .type = NLA_STRING, 332 .len = IWPM_DEVNAME_SIZE - 1 }, 333 [IWPM_NLA_RREG_ULIB_NAME] = { .type = NLA_STRING, 334 .len = IWPM_ULIBNAME_SIZE - 1 }, 335 [IWPM_NLA_RREG_ULIB_VER] = { .type = NLA_U16 }, 336 [IWPM_NLA_RREG_PID_ERR] = { .type = NLA_U16 } 337 }; 338 339 /* 340 * iwpm_register_pid_cb - Process a port mapper response to 341 * iwpm_register_pid() 342 */ 343 int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) 344 { 345 struct iwpm_nlmsg_request *nlmsg_request = NULL; 346 struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX]; 347 struct iwpm_dev_data *pm_msg; 348 char *dev_name, *iwpm_name; 349 u32 msg_seq; 350 u8 nl_client; 351 u16 iwpm_version; 352 const char *msg_type = "Register Pid response"; 353 354 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX, 355 resp_reg_policy, nltb, msg_type)) 356 return -EINVAL; 357 358 msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]); 359 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 360 if (!nlmsg_request) { 361 pr_info("%s: Could not find a matching request (seq = %u)\n", 362 __func__, msg_seq); 363 return -EINVAL; 364 } 365 pm_msg = nlmsg_request->req_buffer; 366 nl_client = nlmsg_request->nl_client; 367 dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]); 368 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]); 369 iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]); 370 371 /* check device name, ulib name and version */ 372 if (strcmp(pm_msg->dev_name, dev_name) || 373 strcmp(iwpm_ulib_name, iwpm_name) || 374 iwpm_version != iwpm_ulib_version) { 375 376 pr_info("%s: Incorrect info (dev = %s name = %s version = %d)\n", 377 __func__, dev_name, iwpm_name, iwpm_version); 378 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 379 goto register_pid_response_exit; 380 } 381 iwpm_user_pid = cb->nlh->nlmsg_pid; 382 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 383 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", 384 __func__, iwpm_user_pid); 385 if (iwpm_valid_client(nl_client)) 386 iwpm_set_registration(nl_client, IWPM_REG_VALID); 387 register_pid_response_exit: 388 nlmsg_request->request_done = 1; 389 /* always for found nlmsg_request */ 390 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 391 barrier(); 392 up(&nlmsg_request->sem); 393 return 0; 394 } 395 396 /* netlink attribute policy for the received response to add mapping request */ 397 static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = { 398 [IWPM_NLA_MANAGE_MAPPING_SEQ] = { .type = NLA_U32 }, 399 [IWPM_NLA_MANAGE_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 400 [IWPM_NLA_MANAGE_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 401 [IWPM_NLA_RMANAGE_MAPPING_ERR] = { .type = NLA_U16 } 402 }; 403 404 /* 405 * iwpm_add_mapping_cb - Process a port mapper response to 406 * iwpm_add_mapping() 407 */ 408 int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) 409 { 410 struct iwpm_sa_data *pm_msg; 411 struct iwpm_nlmsg_request *nlmsg_request = NULL; 412 struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX]; 413 struct sockaddr_storage *local_sockaddr; 414 struct sockaddr_storage *mapped_sockaddr; 415 const char *msg_type; 416 u32 msg_seq; 417 418 msg_type = "Add Mapping response"; 419 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX, 420 resp_add_policy, nltb, msg_type)) 421 return -EINVAL; 422 423 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 424 425 msg_seq = nla_get_u32(nltb[IWPM_NLA_MANAGE_MAPPING_SEQ]); 426 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 427 if (!nlmsg_request) { 428 pr_info("%s: Could not find a matching request (seq = %u)\n", 429 __func__, msg_seq); 430 return -EINVAL; 431 } 432 pm_msg = nlmsg_request->req_buffer; 433 local_sockaddr = (struct sockaddr_storage *) 434 nla_data(nltb[IWPM_NLA_MANAGE_ADDR]); 435 mapped_sockaddr = (struct sockaddr_storage *) 436 nla_data(nltb[IWPM_NLA_MANAGE_MAPPED_LOC_ADDR]); 437 438 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) { 439 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 440 goto add_mapping_response_exit; 441 } 442 if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) { 443 pr_info("%s: Sockaddr family doesn't match the requested one\n", 444 __func__); 445 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 446 goto add_mapping_response_exit; 447 } 448 memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr, 449 sizeof(*mapped_sockaddr)); 450 iwpm_print_sockaddr(&pm_msg->loc_addr, 451 "add_mapping: Local sockaddr:"); 452 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, 453 "add_mapping: Mapped local sockaddr:"); 454 455 add_mapping_response_exit: 456 nlmsg_request->request_done = 1; 457 /* always for found request */ 458 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 459 barrier(); 460 up(&nlmsg_request->sem); 461 return 0; 462 } 463 464 /* netlink attribute policy for the response to add and query mapping request 465 * and response with remote address info */ 466 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { 467 [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, 468 [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 469 [IWPM_NLA_QUERY_REMOTE_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 470 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 471 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = { .len = sizeof(struct sockaddr_storage) }, 472 [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 } 473 }; 474 475 /* 476 * iwpm_add_and_query_mapping_cb - Process a port mapper response to 477 * iwpm_add_and_query_mapping() 478 */ 479 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, 480 struct netlink_callback *cb) 481 { 482 struct iwpm_sa_data *pm_msg; 483 struct iwpm_nlmsg_request *nlmsg_request = NULL; 484 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 485 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 486 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 487 const char *msg_type; 488 u32 msg_seq; 489 u16 err_code; 490 491 msg_type = "Query Mapping response"; 492 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 493 resp_query_policy, nltb, msg_type)) 494 return -EINVAL; 495 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 496 497 msg_seq = nla_get_u32(nltb[IWPM_NLA_QUERY_MAPPING_SEQ]); 498 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 499 if (!nlmsg_request) { 500 pr_info("%s: Could not find a matching request (seq = %u)\n", 501 __func__, msg_seq); 502 return -EINVAL; 503 } 504 pm_msg = nlmsg_request->req_buffer; 505 local_sockaddr = (struct sockaddr_storage *) 506 nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); 507 remote_sockaddr = (struct sockaddr_storage *) 508 nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); 509 mapped_loc_sockaddr = (struct sockaddr_storage *) 510 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 511 mapped_rem_sockaddr = (struct sockaddr_storage *) 512 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 513 514 err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]); 515 if (err_code == IWPM_REMOTE_QUERY_REJECT) { 516 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n", 517 __func__, cb->nlh->nlmsg_pid, msg_seq); 518 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT; 519 } 520 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) || 521 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) { 522 pr_info("%s: Incorrect local sockaddr\n", __func__); 523 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 524 goto query_mapping_response_exit; 525 } 526 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || 527 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { 528 pr_info("%s: Sockaddr family doesn't match the requested one\n", 529 __func__); 530 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 531 goto query_mapping_response_exit; 532 } 533 memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr, 534 sizeof(*mapped_loc_sockaddr)); 535 memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr, 536 sizeof(*mapped_rem_sockaddr)); 537 538 iwpm_print_sockaddr(&pm_msg->loc_addr, 539 "query_mapping: Local sockaddr:"); 540 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, 541 "query_mapping: Mapped local sockaddr:"); 542 iwpm_print_sockaddr(&pm_msg->rem_addr, 543 "query_mapping: Remote sockaddr:"); 544 iwpm_print_sockaddr(&pm_msg->mapped_rem_addr, 545 "query_mapping: Mapped remote sockaddr:"); 546 query_mapping_response_exit: 547 nlmsg_request->request_done = 1; 548 /* always for found request */ 549 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 550 barrier(); 551 up(&nlmsg_request->sem); 552 return 0; 553 } 554 555 /* 556 * iwpm_remote_info_cb - Process a port mapper message, containing 557 * the remote connecting peer address info 558 */ 559 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 560 { 561 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 562 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 563 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 564 struct iwpm_remote_info *rem_info; 565 const char *msg_type; 566 u8 nl_client; 567 int ret = -EINVAL; 568 569 msg_type = "Remote Mapping info"; 570 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 571 resp_query_policy, nltb, msg_type)) 572 return ret; 573 574 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 575 if (!iwpm_valid_client(nl_client)) { 576 pr_info("%s: Invalid port mapper client = %d\n", 577 __func__, nl_client); 578 return ret; 579 } 580 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 581 582 local_sockaddr = (struct sockaddr_storage *) 583 nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); 584 remote_sockaddr = (struct sockaddr_storage *) 585 nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); 586 mapped_loc_sockaddr = (struct sockaddr_storage *) 587 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 588 mapped_rem_sockaddr = (struct sockaddr_storage *) 589 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 590 591 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || 592 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { 593 pr_info("%s: Sockaddr family doesn't match the requested one\n", 594 __func__); 595 return ret; 596 } 597 rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); 598 if (!rem_info) { 599 ret = -ENOMEM; 600 return ret; 601 } 602 memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr, 603 sizeof(struct sockaddr_storage)); 604 memcpy(&rem_info->remote_sockaddr, remote_sockaddr, 605 sizeof(struct sockaddr_storage)); 606 memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr, 607 sizeof(struct sockaddr_storage)); 608 rem_info->nl_client = nl_client; 609 610 iwpm_add_remote_info(rem_info); 611 612 iwpm_print_sockaddr(local_sockaddr, 613 "remote_info: Local sockaddr:"); 614 iwpm_print_sockaddr(mapped_loc_sockaddr, 615 "remote_info: Mapped local sockaddr:"); 616 iwpm_print_sockaddr(remote_sockaddr, 617 "remote_info: Remote sockaddr:"); 618 iwpm_print_sockaddr(mapped_rem_sockaddr, 619 "remote_info: Mapped remote sockaddr:"); 620 return ret; 621 } 622 623 /* netlink attribute policy for the received request for mapping info */ 624 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { 625 [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, 626 .len = IWPM_ULIBNAME_SIZE - 1 }, 627 [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 } 628 }; 629 630 /* 631 * iwpm_mapping_info_cb - Process a port mapper request for mapping info 632 */ 633 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 634 { 635 struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; 636 const char *msg_type = "Mapping Info response"; 637 u8 nl_client; 638 char *iwpm_name; 639 u16 iwpm_version; 640 int ret = -EINVAL; 641 642 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX, 643 resp_mapinfo_policy, nltb, msg_type)) { 644 pr_info("%s: Unable to parse nlmsg\n", __func__); 645 return ret; 646 } 647 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]); 648 iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]); 649 if (strcmp(iwpm_ulib_name, iwpm_name) || 650 iwpm_version != iwpm_ulib_version) { 651 pr_info("%s: Invalid port mapper name = %s version = %d\n", 652 __func__, iwpm_name, iwpm_version); 653 return ret; 654 } 655 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 656 if (!iwpm_valid_client(nl_client)) { 657 pr_info("%s: Invalid port mapper client = %d\n", 658 __func__, nl_client); 659 return ret; 660 } 661 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); 662 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 663 iwpm_user_pid = cb->nlh->nlmsg_pid; 664 if (!iwpm_mapinfo_available()) 665 return 0; 666 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", 667 __func__, iwpm_user_pid); 668 ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid); 669 return ret; 670 } 671 672 /* netlink attribute policy for the received mapping info ack */ 673 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = { 674 [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 }, 675 [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 }, 676 [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 } 677 }; 678 679 /* 680 * iwpm_ack_mapping_info_cb - Process a port mapper ack for 681 * the provided mapping info records 682 */ 683 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 684 { 685 struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX]; 686 u32 mapinfo_send, mapinfo_ack; 687 const char *msg_type = "Mapping Info Ack"; 688 689 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX, 690 ack_mapinfo_policy, nltb, msg_type)) 691 return -EINVAL; 692 mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]); 693 mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]); 694 if (mapinfo_ack != mapinfo_send) 695 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n", 696 __func__, mapinfo_send, mapinfo_ack); 697 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 698 return 0; 699 } 700 701 /* netlink attribute policy for the received port mapper error message */ 702 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = { 703 [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 }, 704 [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 }, 705 }; 706 707 /* 708 * iwpm_mapping_error_cb - Process a port mapper error message 709 */ 710 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) 711 { 712 struct iwpm_nlmsg_request *nlmsg_request = NULL; 713 int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 714 struct nlattr *nltb[IWPM_NLA_ERR_MAX]; 715 u32 msg_seq; 716 u16 err_code; 717 const char *msg_type = "Mapping Error Msg"; 718 719 if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX, 720 map_error_policy, nltb, msg_type)) 721 return -EINVAL; 722 723 msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]); 724 err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]); 725 pr_info("%s: Received msg seq = %u err code = %u client = %d\n", 726 __func__, msg_seq, err_code, nl_client); 727 /* look for nlmsg_request */ 728 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 729 if (!nlmsg_request) { 730 /* not all errors have associated requests */ 731 pr_debug("Could not find matching req (seq = %u)\n", msg_seq); 732 return 0; 733 } 734 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 735 nlmsg_request->err_code = err_code; 736 nlmsg_request->request_done = 1; 737 /* always for found request */ 738 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 739 barrier(); 740 up(&nlmsg_request->sem); 741 return 0; 742 } 743