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