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