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