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 = %d)\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 = %d)\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 = %d)\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 = %d)\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: 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 = %d)\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 %u. 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: 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 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { 533 [IWPM_NLA_RQUERY_MAPPING_SEQ] = { .type = NLA_U32 }, 534 [IWPM_NLA_RQUERY_LOCAL_ADDR] = { 535 .len = sizeof(struct sockaddr_storage) }, 536 [IWPM_NLA_RQUERY_REMOTE_ADDR] = { 537 .len = sizeof(struct sockaddr_storage) }, 538 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = { 539 .len = sizeof(struct sockaddr_storage) }, 540 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = { 541 .len = sizeof(struct sockaddr_storage) }, 542 [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 } 543 }; 544 545 /** 546 * iwpm_add_and_query_mapping_cb - Process the port mapper response to 547 * iwpm_add_and_query_mapping request 548 * @skb: 549 * @cb: Contains the received message (payload and netlink header) 550 */ 551 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, 552 struct netlink_callback *cb) 553 { 554 struct iwpm_sa_data *pm_msg; 555 struct iwpm_nlmsg_request *nlmsg_request = NULL; 556 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 557 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 558 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 559 const char *msg_type; 560 u32 msg_seq; 561 u16 err_code; 562 563 msg_type = "Query Mapping response"; 564 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 565 resp_query_policy, nltb, msg_type)) 566 return -EINVAL; 567 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 568 569 msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]); 570 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 571 if (!nlmsg_request) { 572 pr_info("%s: Could not find a matching request (seq = %u)\n", 573 __func__, msg_seq); 574 return -EINVAL; 575 } 576 pm_msg = nlmsg_request->req_buffer; 577 local_sockaddr = (struct sockaddr_storage *) 578 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]); 579 remote_sockaddr = (struct sockaddr_storage *) 580 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]); 581 mapped_loc_sockaddr = (struct sockaddr_storage *) 582 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 583 mapped_rem_sockaddr = (struct sockaddr_storage *) 584 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 585 586 err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]); 587 if (err_code == IWPM_REMOTE_QUERY_REJECT) { 588 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n", 589 __func__, cb->nlh->nlmsg_pid, msg_seq); 590 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT; 591 } 592 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) || 593 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) { 594 pr_info("%s: Incorrect local sockaddr\n", __func__); 595 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 596 goto query_mapping_response_exit; 597 } 598 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || 599 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { 600 pr_info("%s: Sockaddr family doesn't match the requested one\n", 601 __func__); 602 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; 603 goto query_mapping_response_exit; 604 } 605 memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr, 606 sizeof(*mapped_loc_sockaddr)); 607 memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr, 608 sizeof(*mapped_rem_sockaddr)); 609 610 iwpm_print_sockaddr(&pm_msg->loc_addr, 611 "query_mapping: Local sockaddr:"); 612 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr, 613 "query_mapping: Mapped local sockaddr:"); 614 iwpm_print_sockaddr(&pm_msg->rem_addr, 615 "query_mapping: Remote sockaddr:"); 616 iwpm_print_sockaddr(&pm_msg->mapped_rem_addr, 617 "query_mapping: Mapped remote sockaddr:"); 618 query_mapping_response_exit: 619 nlmsg_request->request_done = 1; 620 /* always for found request */ 621 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 622 barrier(); 623 up(&nlmsg_request->sem); 624 return 0; 625 } 626 627 /** 628 * iwpm_remote_info_cb - Process remote connecting peer address info, which 629 * the port mapper has received from the connecting peer 630 * @skb: 631 * @cb: Contains the received message (payload and netlink header) 632 * 633 * Stores the IPv4/IPv6 address info in a hash table 634 */ 635 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 636 { 637 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX]; 638 struct sockaddr_storage *local_sockaddr, *remote_sockaddr; 639 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr; 640 struct iwpm_remote_info *rem_info; 641 const char *msg_type; 642 u8 nl_client; 643 int ret = -EINVAL; 644 645 msg_type = "Remote Mapping info"; 646 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX, 647 resp_query_policy, nltb, msg_type)) 648 return ret; 649 650 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 651 if (!iwpm_valid_client(nl_client)) { 652 pr_info("%s: Invalid port mapper client = %d\n", 653 __func__, nl_client); 654 return ret; 655 } 656 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 657 658 local_sockaddr = (struct sockaddr_storage *) 659 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]); 660 remote_sockaddr = (struct sockaddr_storage *) 661 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]); 662 mapped_loc_sockaddr = (struct sockaddr_storage *) 663 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); 664 mapped_rem_sockaddr = (struct sockaddr_storage *) 665 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]); 666 667 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family || 668 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) { 669 pr_info("%s: Sockaddr family doesn't match the requested one\n", 670 __func__); 671 return ret; 672 } 673 rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); 674 if (!rem_info) { 675 ret = -ENOMEM; 676 return ret; 677 } 678 memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr, 679 sizeof(struct sockaddr_storage)); 680 memcpy(&rem_info->remote_sockaddr, remote_sockaddr, 681 sizeof(struct sockaddr_storage)); 682 memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr, 683 sizeof(struct sockaddr_storage)); 684 rem_info->nl_client = nl_client; 685 686 iwpm_add_remote_info(rem_info); 687 688 iwpm_print_sockaddr(local_sockaddr, 689 "remote_info: Local sockaddr:"); 690 iwpm_print_sockaddr(mapped_loc_sockaddr, 691 "remote_info: Mapped local sockaddr:"); 692 iwpm_print_sockaddr(remote_sockaddr, 693 "remote_info: Remote sockaddr:"); 694 iwpm_print_sockaddr(mapped_rem_sockaddr, 695 "remote_info: Mapped remote sockaddr:"); 696 return ret; 697 } 698 699 /* netlink attribute policy for the received request for mapping info */ 700 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = { 701 [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING, 702 .len = IWPM_ULIBNAME_SIZE - 1 }, 703 [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 } 704 }; 705 706 /** 707 * iwpm_mapping_info_cb - Process a notification that the userspace 708 * port mapper daemon is started 709 * @skb: 710 * @cb: Contains the received message (payload and netlink header) 711 * 712 * Using the received port mapper pid, send all the local mapping 713 * info records to the userspace port mapper 714 */ 715 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 716 { 717 struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; 718 const char *msg_type = "Mapping Info response"; 719 u8 nl_client; 720 char *iwpm_name; 721 u16 iwpm_version; 722 int ret = -EINVAL; 723 724 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX, 725 resp_mapinfo_policy, nltb, msg_type)) { 726 pr_info("%s: Unable to parse nlmsg\n", __func__); 727 return ret; 728 } 729 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]); 730 iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]); 731 if (strcmp(iwpm_ulib_name, iwpm_name) || 732 iwpm_version < IWPM_UABI_VERSION_MIN) { 733 pr_info("%s: Invalid port mapper name = %s version = %d\n", 734 __func__, iwpm_name, iwpm_version); 735 return ret; 736 } 737 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 738 if (!iwpm_valid_client(nl_client)) { 739 pr_info("%s: Invalid port mapper client = %d\n", 740 __func__, nl_client); 741 return ret; 742 } 743 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); 744 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 745 iwpm_user_pid = cb->nlh->nlmsg_pid; 746 747 if (iwpm_ulib_version < IWPM_UABI_VERSION) 748 pr_warn_once("%s: Down level iwpmd/pid %u. Continuing...", 749 __func__, iwpm_user_pid); 750 751 if (!iwpm_mapinfo_available()) 752 return 0; 753 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", 754 __func__, iwpm_user_pid); 755 ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid); 756 return ret; 757 } 758 759 /* netlink attribute policy for the received mapping info ack */ 760 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = { 761 [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 }, 762 [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 }, 763 [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 } 764 }; 765 766 /** 767 * iwpm_ack_mapping_info_cb - Process the port mapper ack for 768 * the provided local mapping info records 769 * @skb: 770 * @cb: Contains the received message (payload and netlink header) 771 */ 772 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) 773 { 774 struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX]; 775 u32 mapinfo_send, mapinfo_ack; 776 const char *msg_type = "Mapping Info Ack"; 777 778 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX, 779 ack_mapinfo_policy, nltb, msg_type)) 780 return -EINVAL; 781 mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]); 782 mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]); 783 if (mapinfo_ack != mapinfo_send) 784 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n", 785 __func__, mapinfo_send, mapinfo_ack); 786 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 787 return 0; 788 } 789 790 /* netlink attribute policy for the received port mapper error message */ 791 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = { 792 [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 }, 793 [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 }, 794 }; 795 796 /** 797 * iwpm_mapping_error_cb - Process port mapper notification for error 798 * 799 * @skb: 800 * @cb: Contains the received message (payload and netlink header) 801 */ 802 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) 803 { 804 struct iwpm_nlmsg_request *nlmsg_request = NULL; 805 int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 806 struct nlattr *nltb[IWPM_NLA_ERR_MAX]; 807 u32 msg_seq; 808 u16 err_code; 809 const char *msg_type = "Mapping Error Msg"; 810 811 if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX, 812 map_error_policy, nltb, msg_type)) 813 return -EINVAL; 814 815 msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]); 816 err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]); 817 pr_info("%s: Received msg seq = %u err code = %u client = %d\n", 818 __func__, msg_seq, err_code, nl_client); 819 /* look for nlmsg_request */ 820 nlmsg_request = iwpm_find_nlmsg_request(msg_seq); 821 if (!nlmsg_request) { 822 /* not all errors have associated requests */ 823 pr_debug("Could not find matching req (seq = %u)\n", msg_seq); 824 return 0; 825 } 826 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 827 nlmsg_request->err_code = err_code; 828 nlmsg_request->request_done = 1; 829 /* always for found request */ 830 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request); 831 barrier(); 832 up(&nlmsg_request->sem); 833 return 0; 834 } 835 836 /* netlink attribute policy for the received hello request */ 837 static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = { 838 [IWPM_NLA_HELLO_ABI_VERSION] = { .type = NLA_U16 } 839 }; 840 841 /** 842 * iwpm_hello_cb - Process a hello message from iwpmd 843 * 844 * @skb: 845 * @cb: Contains the received message (payload and netlink header) 846 * 847 * Using the received port mapper pid, send the kernel's abi_version 848 * after adjusting it to support the iwpmd version. 849 */ 850 int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb) 851 { 852 struct nlattr *nltb[IWPM_NLA_HELLO_MAX]; 853 const char *msg_type = "Hello request"; 854 u8 nl_client; 855 u16 abi_version; 856 int ret = -EINVAL; 857 858 if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb, 859 msg_type)) { 860 pr_info("%s: Unable to parse nlmsg\n", __func__); 861 return ret; 862 } 863 abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]); 864 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); 865 if (!iwpm_valid_client(nl_client)) { 866 pr_info("%s: Invalid port mapper client = %d\n", 867 __func__, nl_client); 868 return ret; 869 } 870 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); 871 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); 872 iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version); 873 pr_debug("Using ABI version %u\n", iwpm_ulib_version); 874 iwpm_user_pid = cb->nlh->nlmsg_pid; 875 ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version); 876 return ret; 877 } 878