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(&init_net, 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 = %u)\n", __func__, err_str, nl_client); 127 dev_kfree_skb(skb); 128 if (nlmsg_request) 129 iwpm_free_nlmsg_request(&nlmsg_request->kref); 130 return ret; 131 } 132 133 /** 134 * iwpm_add_mapping - Send a netlink add mapping request to 135 * the userspace port mapper 136 * @pm_msg: Contains the local ip/tcp address info to send 137 * @nl_client: The index of the netlink client 138 * 139 * nlmsg attributes: 140 * [IWPM_NLA_MANAGE_MAPPING_SEQ] 141 * [IWPM_NLA_MANAGE_ADDR] 142 * [IWPM_NLA_MANAGE_FLAGS] 143 * 144 * If the request is successful, the pm_msg stores 145 * the port mapper response (mapped address info) 146 */ 147 int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) 148 { 149 struct sk_buff *skb = NULL; 150 struct iwpm_nlmsg_request *nlmsg_request = NULL; 151 struct nlmsghdr *nlh; 152 u32 msg_seq; 153 const char *err_str = ""; 154 int ret = -EINVAL; 155 156 if (!iwpm_valid_client(nl_client)) { 157 err_str = "Invalid port mapper client"; 158 goto add_mapping_error; 159 } 160 if (!iwpm_valid_pid()) 161 return 0; 162 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { 163 err_str = "Unregistered port mapper client"; 164 goto add_mapping_error; 165 } 166 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client); 167 if (!skb) { 168 err_str = "Unable to create a nlmsg"; 169 goto add_mapping_error; 170 } 171 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 172 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL); 173 if (!nlmsg_request) { 174 err_str = "Unable to allocate netlink request"; 175 goto add_mapping_error; 176 } 177 msg_seq = atomic_read(&echo_nlmsg_seq); 178 /* fill in the add mapping message */ 179 err_str = "Unable to put attribute of the nlmsg"; 180 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, 181 IWPM_NLA_MANAGE_MAPPING_SEQ); 182 if (ret) 183 goto add_mapping_error; 184 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 185 &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR); 186 if (ret) 187 goto add_mapping_error; 188 189 /* If flags are required and we're not V4, then return a quiet error */ 190 if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) { 191 ret = -EINVAL; 192 goto add_mapping_error_nowarn; 193 } 194 if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) { 195 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags, 196 IWPM_NLA_MANAGE_FLAGS); 197 if (ret) 198 goto add_mapping_error; 199 } 200 201 nlmsg_end(skb, nlh); 202 nlmsg_request->req_buffer = pm_msg; 203 204 ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid); 205 if (ret) { 206 skb = NULL; /* skb is freed in the netlink send-op handling */ 207 iwpm_user_pid = IWPM_PID_UNDEFINED; 208 err_str = "Unable to send a nlmsg"; 209 goto add_mapping_error; 210 } 211 ret = iwpm_wait_complete_req(nlmsg_request); 212 return ret; 213 add_mapping_error: 214 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client); 215 add_mapping_error_nowarn: 216 dev_kfree_skb(skb); 217 if (nlmsg_request) 218 iwpm_free_nlmsg_request(&nlmsg_request->kref); 219 return ret; 220 } 221 222 /** 223 * iwpm_add_and_query_mapping - Process the port mapper response to 224 * iwpm_add_and_query_mapping request 225 * @pm_msg: Contains the local ip/tcp address info to send 226 * @nl_client: The index of the netlink client 227 * 228 * nlmsg attributes: 229 * [IWPM_NLA_QUERY_MAPPING_SEQ] 230 * [IWPM_NLA_QUERY_LOCAL_ADDR] 231 * [IWPM_NLA_QUERY_REMOTE_ADDR] 232 * [IWPM_NLA_QUERY_FLAGS] 233 */ 234 int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) 235 { 236 struct sk_buff *skb = NULL; 237 struct iwpm_nlmsg_request *nlmsg_request = NULL; 238 struct nlmsghdr *nlh; 239 u32 msg_seq; 240 const char *err_str = ""; 241 int ret = -EINVAL; 242 243 if (!iwpm_valid_client(nl_client)) { 244 err_str = "Invalid port mapper client"; 245 goto query_mapping_error; 246 } 247 if (!iwpm_valid_pid()) 248 return 0; 249 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { 250 err_str = "Unregistered port mapper client"; 251 goto query_mapping_error; 252 } 253 ret = -ENOMEM; 254 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client); 255 if (!skb) { 256 err_str = "Unable to create a nlmsg"; 257 goto query_mapping_error; 258 } 259 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 260 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, 261 nl_client, GFP_KERNEL); 262 if (!nlmsg_request) { 263 err_str = "Unable to allocate netlink request"; 264 goto query_mapping_error; 265 } 266 msg_seq = atomic_read(&echo_nlmsg_seq); 267 268 /* fill in the query message */ 269 err_str = "Unable to put attribute of the nlmsg"; 270 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, 271 IWPM_NLA_QUERY_MAPPING_SEQ); 272 if (ret) 273 goto query_mapping_error; 274 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 275 &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR); 276 if (ret) 277 goto query_mapping_error; 278 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 279 &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR); 280 if (ret) 281 goto query_mapping_error; 282 283 /* If flags are required and we're not V4, then return a quite error */ 284 if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) { 285 ret = -EINVAL; 286 goto query_mapping_error_nowarn; 287 } 288 if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) { 289 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags, 290 IWPM_NLA_QUERY_FLAGS); 291 if (ret) 292 goto query_mapping_error; 293 } 294 295 nlmsg_end(skb, nlh); 296 nlmsg_request->req_buffer = pm_msg; 297 298 ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid); 299 if (ret) { 300 skb = NULL; /* skb is freed in the netlink send-op handling */ 301 err_str = "Unable to send a nlmsg"; 302 goto query_mapping_error; 303 } 304 ret = iwpm_wait_complete_req(nlmsg_request); 305 return ret; 306 query_mapping_error: 307 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client); 308 query_mapping_error_nowarn: 309 dev_kfree_skb(skb); 310 if (nlmsg_request) 311 iwpm_free_nlmsg_request(&nlmsg_request->kref); 312 return ret; 313 } 314 315 /** 316 * iwpm_remove_mapping - Send a netlink remove mapping request 317 * to the userspace port mapper 318 * 319 * @local_addr: Local ip/tcp address to remove 320 * @nl_client: The index of the netlink client 321 * 322 * nlmsg attributes: 323 * [IWPM_NLA_MANAGE_MAPPING_SEQ] 324 * [IWPM_NLA_MANAGE_ADDR] 325 */ 326 int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) 327 { 328 struct sk_buff *skb = NULL; 329 struct nlmsghdr *nlh; 330 u32 msg_seq; 331 const char *err_str = ""; 332 int ret = -EINVAL; 333 334 if (!iwpm_valid_client(nl_client)) { 335 err_str = "Invalid port mapper client"; 336 goto remove_mapping_error; 337 } 338 if (!iwpm_valid_pid()) 339 return 0; 340 if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) { 341 err_str = "Unregistered port mapper client"; 342 goto remove_mapping_error; 343 } 344 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client); 345 if (!skb) { 346 ret = -ENOMEM; 347 err_str = "Unable to create a nlmsg"; 348 goto remove_mapping_error; 349 } 350 msg_seq = atomic_read(&echo_nlmsg_seq); 351 nlh->nlmsg_seq = iwpm_get_nlmsg_seq(); 352 err_str = "Unable to put attribute of the nlmsg"; 353 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, 354 IWPM_NLA_MANAGE_MAPPING_SEQ); 355 if (ret) 356 goto remove_mapping_error; 357 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage), 358 local_addr, IWPM_NLA_MANAGE_ADDR); 359 if (ret) 360 goto remove_mapping_error; 361 362 nlmsg_end(skb, nlh); 363 364 ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid); 365 if (ret) { 366 skb = NULL; /* skb is freed in the netlink send-op handling */ 367 iwpm_user_pid = IWPM_PID_UNDEFINED; 368 err_str = "Unable to send a nlmsg"; 369 goto remove_mapping_error; 370 } 371 iwpm_print_sockaddr(local_addr, 372 "remove_mapping: Local sockaddr:"); 373 return 0; 374 remove_mapping_error: 375 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client); 376 if (skb) 377 dev_kfree_skb_any(skb); 378 return ret; 379 } 380 381 /* netlink attribute policy for the received response to register pid request */ 382 static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = { 383 [IWPM_NLA_RREG_PID_SEQ] = { .type = NLA_U32 }, 384 [IWPM_NLA_RREG_IBDEV_NAME] = { .type = NLA_STRING, 385 .len = IWPM_DEVNAME_SIZE - 1 }, 386 [IWPM_NLA_RREG_ULIB_NAME] = { .type = NLA_STRING, 387 .len = IWPM_ULIBNAME_SIZE - 1 }, 388 [IWPM_NLA_RREG_ULIB_VER] = { .type = NLA_U16 }, 389 [IWPM_NLA_RREG_PID_ERR] = { .type = NLA_U16 } 390 }; 391 392 /** 393 * iwpm_register_pid_cb - Process the port mapper response to 394 * iwpm_register_pid query 395 * @skb: The socket buffer 396 * @cb: Contains the received message (payload and netlink header) 397 * 398 * If successful, the function receives the userspace port mapper pid 399 * which is used in future communication with the port mapper 400 */ 401 int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) 402 { 403 struct iwpm_nlmsg_request *nlmsg_request = NULL; 404 struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX]; 405 struct iwpm_dev_data *pm_msg; 406 char *dev_name, *iwpm_name; 407 u32 msg_seq; 408 u8 nl_client; 409 u16 iwpm_version; 410 const char *msg_type = "Register Pid response"; 411 412 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX, 413 resp_reg_policy, nltb, msg_type)) 414 return -EINVAL; 415 416 msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]); 417 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 418 if (!nlmsg_request) { 419 pr_info("%s: Could not find a matching request (seq = %u)\n", 420 __func__, msg_seq); 421 return -EINVAL; 422 } 423 pm_msg = nlmsg_request->req_buffer; 424 nl_client = nlmsg_request->nl_client; 425 dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]); 426 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]); 427 iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]); 428 429 /* check device name, ulib name and version */ 430 if (strcmp(pm_msg->dev_name, dev_name) || 431 strcmp(iwpm_ulib_name, iwpm_name) || 432 iwpm_version < IWPM_UABI_VERSION_MIN) { 433 434 pr_info("%s: Incorrect info (dev = %s name = %s version = %u)\n", 435 __func__, dev_name, iwpm_name, iwpm_version); 436 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 437 goto register_pid_response_exit; 438 } 439 iwpm_user_pid = cb->nlh->nlmsg_pid; 440 iwpm_ulib_version = iwpm_version; 441 if (iwpm_ulib_version < IWPM_UABI_VERSION) 442 pr_warn_once("%s: Down level iwpmd/pid %d. Continuing...", 443 __func__, iwpm_user_pid); 444 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 445 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", 446 __func__, iwpm_user_pid); 447 if (iwpm_valid_client(nl_client)) 448 iwpm_set_registration(nl_client, IWPM_REG_VALID); 449 register_pid_response_exit: 450 nlmsg_request->request_done = 1; 451 /* always for found nlmsg_request */ 452 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 453 barrier(); 454 up(&nlmsg_request->sem); 455 return 0; 456 } 457 458 /* netlink attribute policy for the received response to add mapping request */ 459 static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = { 460 [IWPM_NLA_RMANAGE_MAPPING_SEQ] = { .type = NLA_U32 }, 461 [IWPM_NLA_RMANAGE_ADDR] = { 462 .len = sizeof(struct sockaddr_storage) }, 463 [IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR] = { 464 .len = sizeof(struct sockaddr_storage) }, 465 [IWPM_NLA_RMANAGE_MAPPING_ERR] = { .type = NLA_U16 } 466 }; 467 468 /** 469 * iwpm_add_mapping_cb - Process the port mapper response to 470 * iwpm_add_mapping request 471 * @skb: The socket buffer 472 * @cb: Contains the received message (payload and netlink header) 473 */ 474 int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) 475 { 476 struct iwpm_sa_data *pm_msg; 477 struct iwpm_nlmsg_request *nlmsg_request = NULL; 478 struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX]; 479 struct sockaddr_storage *local_sockaddr; 480 struct sockaddr_storage *mapped_sockaddr; 481 const char *msg_type; 482 u32 msg_seq; 483 484 msg_type = "Add Mapping response"; 485 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX, 486 resp_add_policy, nltb, msg_type)) 487 return -EINVAL; 488 489 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 490 491 msg_seq = nla_get_u32(nltb[IWPM_NLA_RMANAGE_MAPPING_SEQ]); 492 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 493 if (!nlmsg_request) { 494 pr_info("%s: Could not find a matching request (seq = %u)\n", 495 __func__, msg_seq); 496 return -EINVAL; 497 } 498 pm_msg = nlmsg_request->req_buffer; 499 local_sockaddr = (struct sockaddr_storage *) 500 nla_data(nltb[IWPM_NLA_RMANAGE_ADDR]); 501 mapped_sockaddr = (struct sockaddr_storage *) 502 nla_data(nltb[IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR]); 503 504 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) { 505 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 506 goto add_mapping_response_exit; 507 } 508 if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) { 509 pr_info("%s: Sockaddr family doesn't match the requested one\n", 510 __func__); 511 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 512 goto add_mapping_response_exit; 513 } 514 memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr, 515 sizeof(*mapped_sockaddr)); 516 iwpm_print_sockaddr(&pm_msg->loc_addr, 517 "add_mapping: Local sockaddr:"); 518 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, 519 "add_mapping: Mapped local sockaddr:"); 520 521 add_mapping_response_exit: 522 nlmsg_request->request_done = 1; 523 /* always for found request */ 524 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 525 barrier(); 526 up(&nlmsg_request->sem); 527 return 0; 528 } 529 530 /* netlink attribute policy for the response to add and query mapping request 531 * and response with remote address info 532 */ 533 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { 534 [IWPM_NLA_RQUERY_MAPPING_SEQ] = { .type = NLA_U32 }, 535 [IWPM_NLA_RQUERY_LOCAL_ADDR] = { 536 .len = sizeof(struct sockaddr_storage) }, 537 [IWPM_NLA_RQUERY_REMOTE_ADDR] = { 538 .len = sizeof(struct sockaddr_storage) }, 539 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = { 540 .len = sizeof(struct sockaddr_storage) }, 541 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = { 542 .len = sizeof(struct sockaddr_storage) }, 543 [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 } 544 }; 545 546 /** 547 * iwpm_add_and_query_mapping_cb - Process the port mapper response to 548 * iwpm_add_and_query_mapping request 549 * @skb: The socket buffer 550 * @cb: Contains the received message (payload and netlink header) 551 */ 552 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, 553 struct netlink_callback *cb) 554 { 555 struct iwpm_sa_data *pm_msg; 556 struct iwpm_nlmsg_request *nlmsg_request = NULL; 557 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 558 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 559 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 560 const char *msg_type; 561 u32 msg_seq; 562 u16 err_code; 563 564 msg_type = "Query Mapping response"; 565 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 566 resp_query_policy, nltb, msg_type)) 567 return -EINVAL; 568 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 569 570 msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]); 571 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 572 if (!nlmsg_request) { 573 pr_info("%s: Could not find a matching request (seq = %u)\n", 574 __func__, msg_seq); 575 return -EINVAL; 576 } 577 pm_msg = nlmsg_request->req_buffer; 578 local_sockaddr = (struct sockaddr_storage *) 579 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]); 580 remote_sockaddr = (struct sockaddr_storage *) 581 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]); 582 mapped_loc_sockaddr = (struct sockaddr_storage *) 583 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 584 mapped_rem_sockaddr = (struct sockaddr_storage *) 585 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 586 587 err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]); 588 if (err_code == IWPM_REMOTE_QUERY_REJECT) { 589 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n", 590 __func__, cb->nlh->nlmsg_pid, msg_seq); 591 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT; 592 } 593 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) || 594 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) { 595 pr_info("%s: Incorrect local sockaddr\n", __func__); 596 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 597 goto query_mapping_response_exit; 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 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 604 goto query_mapping_response_exit; 605 } 606 memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr, 607 sizeof(*mapped_loc_sockaddr)); 608 memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr, 609 sizeof(*mapped_rem_sockaddr)); 610 611 iwpm_print_sockaddr(&pm_msg->loc_addr, 612 "query_mapping: Local sockaddr:"); 613 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, 614 "query_mapping: Mapped local sockaddr:"); 615 iwpm_print_sockaddr(&pm_msg->rem_addr, 616 "query_mapping: Remote sockaddr:"); 617 iwpm_print_sockaddr(&pm_msg->mapped_rem_addr, 618 "query_mapping: Mapped remote sockaddr:"); 619 query_mapping_response_exit: 620 nlmsg_request->request_done = 1; 621 /* always for found request */ 622 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 623 barrier(); 624 up(&nlmsg_request->sem); 625 return 0; 626 } 627 628 /** 629 * iwpm_remote_info_cb - Process remote connecting peer address info, which 630 * the port mapper has received from the connecting peer 631 * @skb: The socket buffer 632 * @cb: Contains the received message (payload and netlink header) 633 * 634 * Stores the IPv4/IPv6 address info in a hash table 635 */ 636 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 637 { 638 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 639 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 640 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 641 struct iwpm_remote_info *rem_info; 642 const char *msg_type; 643 u8 nl_client; 644 int ret = -EINVAL; 645 646 msg_type = "Remote Mapping info"; 647 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 648 resp_query_policy, nltb, msg_type)) 649 return ret; 650 651 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 652 if (!iwpm_valid_client(nl_client)) { 653 pr_info("%s: Invalid port mapper client = %u\n", 654 __func__, nl_client); 655 return ret; 656 } 657 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 658 659 local_sockaddr = (struct sockaddr_storage *) 660 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]); 661 remote_sockaddr = (struct sockaddr_storage *) 662 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]); 663 mapped_loc_sockaddr = (struct sockaddr_storage *) 664 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 665 mapped_rem_sockaddr = (struct sockaddr_storage *) 666 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 667 668 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || 669 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { 670 pr_info("%s: Sockaddr family doesn't match the requested one\n", 671 __func__); 672 return ret; 673 } 674 rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); 675 if (!rem_info) { 676 ret = -ENOMEM; 677 return ret; 678 } 679 memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr, 680 sizeof(struct sockaddr_storage)); 681 memcpy(&rem_info->remote_sockaddr, remote_sockaddr, 682 sizeof(struct sockaddr_storage)); 683 memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr, 684 sizeof(struct sockaddr_storage)); 685 rem_info->nl_client = nl_client; 686 687 iwpm_add_remote_info(rem_info); 688 689 iwpm_print_sockaddr(local_sockaddr, 690 "remote_info: Local sockaddr:"); 691 iwpm_print_sockaddr(mapped_loc_sockaddr, 692 "remote_info: Mapped local sockaddr:"); 693 iwpm_print_sockaddr(remote_sockaddr, 694 "remote_info: Remote sockaddr:"); 695 iwpm_print_sockaddr(mapped_rem_sockaddr, 696 "remote_info: Mapped remote sockaddr:"); 697 return ret; 698 } 699 700 /* netlink attribute policy for the received request for mapping info */ 701 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { 702 [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, 703 .len = IWPM_ULIBNAME_SIZE - 1 }, 704 [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 } 705 }; 706 707 /** 708 * iwpm_mapping_info_cb - Process a notification that the userspace 709 * port mapper daemon is started 710 * @skb: The socket buffer 711 * @cb: Contains the received message (payload and netlink header) 712 * 713 * Using the received port mapper pid, send all the local mapping 714 * info records to the userspace port mapper 715 */ 716 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 717 { 718 struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; 719 const char *msg_type = "Mapping Info response"; 720 u8 nl_client; 721 char *iwpm_name; 722 u16 iwpm_version; 723 int ret = -EINVAL; 724 725 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX, 726 resp_mapinfo_policy, nltb, msg_type)) { 727 pr_info("%s: Unable to parse nlmsg\n", __func__); 728 return ret; 729 } 730 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]); 731 iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]); 732 if (strcmp(iwpm_ulib_name, iwpm_name) || 733 iwpm_version < IWPM_UABI_VERSION_MIN) { 734 pr_info("%s: Invalid port mapper name = %s version = %u\n", 735 __func__, iwpm_name, iwpm_version); 736 return ret; 737 } 738 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 739 if (!iwpm_valid_client(nl_client)) { 740 pr_info("%s: Invalid port mapper client = %u\n", 741 __func__, nl_client); 742 return ret; 743 } 744 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); 745 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 746 iwpm_user_pid = cb->nlh->nlmsg_pid; 747 748 if (iwpm_ulib_version < IWPM_UABI_VERSION) 749 pr_warn_once("%s: Down level iwpmd/pid %d. Continuing...", 750 __func__, iwpm_user_pid); 751 752 if (!iwpm_mapinfo_available()) 753 return 0; 754 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", 755 __func__, iwpm_user_pid); 756 ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid); 757 return ret; 758 } 759 760 /* netlink attribute policy for the received mapping info ack */ 761 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = { 762 [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 }, 763 [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 }, 764 [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 } 765 }; 766 767 /** 768 * iwpm_ack_mapping_info_cb - Process the port mapper ack for 769 * the provided local mapping info records 770 * @skb: The socket buffer 771 * @cb: Contains the received message (payload and netlink header) 772 */ 773 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 774 { 775 struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX]; 776 u32 mapinfo_send, mapinfo_ack; 777 const char *msg_type = "Mapping Info Ack"; 778 779 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX, 780 ack_mapinfo_policy, nltb, msg_type)) 781 return -EINVAL; 782 mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]); 783 mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]); 784 if (mapinfo_ack != mapinfo_send) 785 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n", 786 __func__, mapinfo_send, mapinfo_ack); 787 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 788 return 0; 789 } 790 791 /* netlink attribute policy for the received port mapper error message */ 792 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = { 793 [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 }, 794 [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 }, 795 }; 796 797 /** 798 * iwpm_mapping_error_cb - Process port mapper notification for error 799 * 800 * @skb: The socket buffer 801 * @cb: Contains the received message (payload and netlink header) 802 */ 803 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) 804 { 805 struct iwpm_nlmsg_request *nlmsg_request = NULL; 806 int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 807 struct nlattr *nltb[IWPM_NLA_ERR_MAX]; 808 u32 msg_seq; 809 u16 err_code; 810 const char *msg_type = "Mapping Error Msg"; 811 812 if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX, 813 map_error_policy, nltb, msg_type)) 814 return -EINVAL; 815 816 msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]); 817 err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]); 818 pr_info("%s: Received msg seq = %u err code = %u client = %d\n", 819 __func__, msg_seq, err_code, nl_client); 820 /* look for nlmsg_request */ 821 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 822 if (!nlmsg_request) { 823 /* not all errors have associated requests */ 824 pr_debug("Could not find matching req (seq = %u)\n", msg_seq); 825 return 0; 826 } 827 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 828 nlmsg_request->err_code = err_code; 829 nlmsg_request->request_done = 1; 830 /* always for found request */ 831 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 832 barrier(); 833 up(&nlmsg_request->sem); 834 return 0; 835 } 836 837 /* netlink attribute policy for the received hello request */ 838 static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = { 839 [IWPM_NLA_HELLO_ABI_VERSION] = { .type = NLA_U16 } 840 }; 841 842 /** 843 * iwpm_hello_cb - Process a hello message from iwpmd 844 * 845 * @skb: The socket buffer 846 * @cb: Contains the received message (payload and netlink header) 847 * 848 * Using the received port mapper pid, send the kernel's abi_version 849 * after adjusting it to support the iwpmd version. 850 */ 851 int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb) 852 { 853 struct nlattr *nltb[IWPM_NLA_HELLO_MAX]; 854 const char *msg_type = "Hello request"; 855 u8 nl_client; 856 u16 abi_version; 857 int ret = -EINVAL; 858 859 if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb, 860 msg_type)) { 861 pr_info("%s: Unable to parse nlmsg\n", __func__); 862 return ret; 863 } 864 abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]); 865 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 866 if (!iwpm_valid_client(nl_client)) { 867 pr_info("%s: Invalid port mapper client = %u\n", 868 __func__, nl_client); 869 return ret; 870 } 871 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); 872 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 873 iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version); 874 pr_debug("Using ABI version %u\n", iwpm_ulib_version); 875 iwpm_user_pid = cb->nlh->nlmsg_pid; 876 ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version); 877 return ret; 878 } 879