| .. | .. |
|---|
| 34 | 34 | #include "iwpm_util.h" |
|---|
| 35 | 35 | |
|---|
| 36 | 36 | static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser"; |
|---|
| 37 | | -static int iwpm_ulib_version = 3; |
|---|
| 37 | +u16 iwpm_ulib_version = IWPM_UABI_VERSION_MIN; |
|---|
| 38 | 38 | static int iwpm_user_pid = IWPM_PID_UNDEFINED; |
|---|
| 39 | 39 | static atomic_t echo_nlmsg_seq; |
|---|
| 40 | 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 | + */ |
|---|
| 41 | 46 | int iwpm_valid_pid(void) |
|---|
| 42 | 47 | { |
|---|
| 43 | 48 | return iwpm_user_pid > 0; |
|---|
| 44 | 49 | } |
|---|
| 45 | 50 | |
|---|
| 46 | | -/* |
|---|
| 47 | | - * iwpm_register_pid - Send a netlink query to user space |
|---|
| 48 | | - * for the iwarp port mapper pid |
|---|
| 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 |
|---|
| 49 | 56 | * |
|---|
| 50 | 57 | * nlmsg attributes: |
|---|
| 51 | 58 | * [IWPM_NLA_REG_PID_SEQ] |
|---|
| .. | .. |
|---|
| 105 | 112 | pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n", |
|---|
| 106 | 113 | __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name); |
|---|
| 107 | 114 | |
|---|
| 108 | | - ret = rdma_nl_multicast(skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL); |
|---|
| 115 | + ret = rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL); |
|---|
| 109 | 116 | if (ret) { |
|---|
| 110 | 117 | skb = NULL; /* skb is freed in the netlink send-op handling */ |
|---|
| 111 | 118 | iwpm_user_pid = IWPM_PID_UNAVAILABLE; |
|---|
| .. | .. |
|---|
| 117 | 124 | return ret; |
|---|
| 118 | 125 | pid_query_error: |
|---|
| 119 | 126 | pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); |
|---|
| 120 | | - if (skb) |
|---|
| 121 | | - dev_kfree_skb(skb); |
|---|
| 127 | + dev_kfree_skb(skb); |
|---|
| 122 | 128 | if (nlmsg_request) |
|---|
| 123 | 129 | iwpm_free_nlmsg_request(&nlmsg_request->kref); |
|---|
| 124 | 130 | return ret; |
|---|
| 125 | 131 | } |
|---|
| 126 | 132 | |
|---|
| 127 | | -/* |
|---|
| 128 | | - * iwpm_add_mapping - Send a netlink add mapping message |
|---|
| 129 | | - * to the port mapper |
|---|
| 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 | + * |
|---|
| 130 | 139 | * nlmsg attributes: |
|---|
| 131 | 140 | * [IWPM_NLA_MANAGE_MAPPING_SEQ] |
|---|
| 132 | 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) |
|---|
| 133 | 146 | */ |
|---|
| 134 | 147 | int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) |
|---|
| 135 | 148 | { |
|---|
| .. | .. |
|---|
| 173 | 186 | if (ret) |
|---|
| 174 | 187 | goto add_mapping_error; |
|---|
| 175 | 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 | + |
|---|
| 176 | 201 | nlmsg_end(skb, nlh); |
|---|
| 177 | 202 | nlmsg_request->req_buffer = pm_msg; |
|---|
| 178 | 203 | |
|---|
| 179 | | - ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); |
|---|
| 204 | + ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid); |
|---|
| 180 | 205 | if (ret) { |
|---|
| 181 | 206 | skb = NULL; /* skb is freed in the netlink send-op handling */ |
|---|
| 182 | 207 | iwpm_user_pid = IWPM_PID_UNDEFINED; |
|---|
| .. | .. |
|---|
| 187 | 212 | return ret; |
|---|
| 188 | 213 | add_mapping_error: |
|---|
| 189 | 214 | pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); |
|---|
| 190 | | - if (skb) |
|---|
| 191 | | - dev_kfree_skb(skb); |
|---|
| 215 | +add_mapping_error_nowarn: |
|---|
| 216 | + dev_kfree_skb(skb); |
|---|
| 192 | 217 | if (nlmsg_request) |
|---|
| 193 | 218 | iwpm_free_nlmsg_request(&nlmsg_request->kref); |
|---|
| 194 | 219 | return ret; |
|---|
| 195 | 220 | } |
|---|
| 196 | 221 | |
|---|
| 197 | | -/* |
|---|
| 198 | | - * iwpm_add_and_query_mapping - Send a netlink add and query |
|---|
| 199 | | - * mapping message to the port mapper |
|---|
| 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 | + * |
|---|
| 200 | 228 | * nlmsg attributes: |
|---|
| 201 | 229 | * [IWPM_NLA_QUERY_MAPPING_SEQ] |
|---|
| 202 | 230 | * [IWPM_NLA_QUERY_LOCAL_ADDR] |
|---|
| 203 | 231 | * [IWPM_NLA_QUERY_REMOTE_ADDR] |
|---|
| 232 | + * [IWPM_NLA_QUERY_FLAGS] |
|---|
| 204 | 233 | */ |
|---|
| 205 | 234 | int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) |
|---|
| 206 | 235 | { |
|---|
| .. | .. |
|---|
| 251 | 280 | if (ret) |
|---|
| 252 | 281 | goto query_mapping_error; |
|---|
| 253 | 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 | + |
|---|
| 254 | 295 | nlmsg_end(skb, nlh); |
|---|
| 255 | 296 | nlmsg_request->req_buffer = pm_msg; |
|---|
| 256 | 297 | |
|---|
| 257 | | - ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); |
|---|
| 298 | + ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid); |
|---|
| 258 | 299 | if (ret) { |
|---|
| 259 | 300 | skb = NULL; /* skb is freed in the netlink send-op handling */ |
|---|
| 260 | 301 | err_str = "Unable to send a nlmsg"; |
|---|
| .. | .. |
|---|
| 264 | 305 | return ret; |
|---|
| 265 | 306 | query_mapping_error: |
|---|
| 266 | 307 | pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client); |
|---|
| 267 | | - if (skb) |
|---|
| 268 | | - dev_kfree_skb(skb); |
|---|
| 308 | +query_mapping_error_nowarn: |
|---|
| 309 | + dev_kfree_skb(skb); |
|---|
| 269 | 310 | if (nlmsg_request) |
|---|
| 270 | 311 | iwpm_free_nlmsg_request(&nlmsg_request->kref); |
|---|
| 271 | 312 | return ret; |
|---|
| 272 | 313 | } |
|---|
| 273 | 314 | |
|---|
| 274 | | -/* |
|---|
| 275 | | - * iwpm_remove_mapping - Send a netlink remove mapping message |
|---|
| 276 | | - * to the port mapper |
|---|
| 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 | + * |
|---|
| 277 | 322 | * nlmsg attributes: |
|---|
| 278 | 323 | * [IWPM_NLA_MANAGE_MAPPING_SEQ] |
|---|
| 279 | 324 | * [IWPM_NLA_MANAGE_ADDR] |
|---|
| .. | .. |
|---|
| 316 | 361 | |
|---|
| 317 | 362 | nlmsg_end(skb, nlh); |
|---|
| 318 | 363 | |
|---|
| 319 | | - ret = rdma_nl_unicast_wait(skb, iwpm_user_pid); |
|---|
| 364 | + ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid); |
|---|
| 320 | 365 | if (ret) { |
|---|
| 321 | 366 | skb = NULL; /* skb is freed in the netlink send-op handling */ |
|---|
| 322 | 367 | iwpm_user_pid = IWPM_PID_UNDEFINED; |
|---|
| .. | .. |
|---|
| 344 | 389 | [IWPM_NLA_RREG_PID_ERR] = { .type = NLA_U16 } |
|---|
| 345 | 390 | }; |
|---|
| 346 | 391 | |
|---|
| 347 | | -/* |
|---|
| 348 | | - * iwpm_register_pid_cb - Process a port mapper response to |
|---|
| 349 | | - * iwpm_register_pid() |
|---|
| 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 |
|---|
| 350 | 400 | */ |
|---|
| 351 | 401 | int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) |
|---|
| 352 | 402 | { |
|---|
| .. | .. |
|---|
| 379 | 429 | /* check device name, ulib name and version */ |
|---|
| 380 | 430 | if (strcmp(pm_msg->dev_name, dev_name) || |
|---|
| 381 | 431 | strcmp(iwpm_ulib_name, iwpm_name) || |
|---|
| 382 | | - iwpm_version != iwpm_ulib_version) { |
|---|
| 432 | + iwpm_version < IWPM_UABI_VERSION_MIN) { |
|---|
| 383 | 433 | |
|---|
| 384 | 434 | pr_info("%s: Incorrect info (dev = %s name = %s version = %d)\n", |
|---|
| 385 | 435 | __func__, dev_name, iwpm_name, iwpm_version); |
|---|
| .. | .. |
|---|
| 387 | 437 | goto register_pid_response_exit; |
|---|
| 388 | 438 | } |
|---|
| 389 | 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); |
|---|
| 390 | 444 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); |
|---|
| 391 | 445 | pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", |
|---|
| 392 | 446 | __func__, iwpm_user_pid); |
|---|
| .. | .. |
|---|
| 403 | 457 | |
|---|
| 404 | 458 | /* netlink attribute policy for the received response to add mapping request */ |
|---|
| 405 | 459 | static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = { |
|---|
| 406 | | - [IWPM_NLA_MANAGE_MAPPING_SEQ] = { .type = NLA_U32 }, |
|---|
| 407 | | - [IWPM_NLA_MANAGE_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
|---|
| 408 | | - [IWPM_NLA_MANAGE_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
|---|
| 409 | | - [IWPM_NLA_RMANAGE_MAPPING_ERR] = { .type = NLA_U16 } |
|---|
| 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 } |
|---|
| 410 | 466 | }; |
|---|
| 411 | 467 | |
|---|
| 412 | | -/* |
|---|
| 413 | | - * iwpm_add_mapping_cb - Process a port mapper response to |
|---|
| 414 | | - * iwpm_add_mapping() |
|---|
| 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) |
|---|
| 415 | 473 | */ |
|---|
| 416 | 474 | int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb) |
|---|
| 417 | 475 | { |
|---|
| .. | .. |
|---|
| 430 | 488 | |
|---|
| 431 | 489 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); |
|---|
| 432 | 490 | |
|---|
| 433 | | - msg_seq = nla_get_u32(nltb[IWPM_NLA_MANAGE_MAPPING_SEQ]); |
|---|
| 491 | + msg_seq = nla_get_u32(nltb[IWPM_NLA_RMANAGE_MAPPING_SEQ]); |
|---|
| 434 | 492 | nlmsg_request = iwpm_find_nlmsg_request(msg_seq); |
|---|
| 435 | 493 | if (!nlmsg_request) { |
|---|
| 436 | 494 | pr_info("%s: Could not find a matching request (seq = %u)\n", |
|---|
| .. | .. |
|---|
| 439 | 497 | } |
|---|
| 440 | 498 | pm_msg = nlmsg_request->req_buffer; |
|---|
| 441 | 499 | local_sockaddr = (struct sockaddr_storage *) |
|---|
| 442 | | - nla_data(nltb[IWPM_NLA_MANAGE_ADDR]); |
|---|
| 500 | + nla_data(nltb[IWPM_NLA_RMANAGE_ADDR]); |
|---|
| 443 | 501 | mapped_sockaddr = (struct sockaddr_storage *) |
|---|
| 444 | | - nla_data(nltb[IWPM_NLA_MANAGE_MAPPED_LOC_ADDR]); |
|---|
| 502 | + nla_data(nltb[IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR]); |
|---|
| 445 | 503 | |
|---|
| 446 | 504 | if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) { |
|---|
| 447 | 505 | nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR; |
|---|
| .. | .. |
|---|
| 472 | 530 | /* netlink attribute policy for the response to add and query mapping request |
|---|
| 473 | 531 | * and response with remote address info */ |
|---|
| 474 | 532 | static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = { |
|---|
| 475 | | - [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 }, |
|---|
| 476 | | - [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
|---|
| 477 | | - [IWPM_NLA_QUERY_REMOTE_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
|---|
| 478 | | - [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
|---|
| 479 | | - [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = { .len = sizeof(struct sockaddr_storage) }, |
|---|
| 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) }, |
|---|
| 480 | 542 | [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 } |
|---|
| 481 | 543 | }; |
|---|
| 482 | 544 | |
|---|
| 483 | | -/* |
|---|
| 484 | | - * iwpm_add_and_query_mapping_cb - Process a port mapper response to |
|---|
| 485 | | - * iwpm_add_and_query_mapping() |
|---|
| 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) |
|---|
| 486 | 550 | */ |
|---|
| 487 | 551 | int iwpm_add_and_query_mapping_cb(struct sk_buff *skb, |
|---|
| 488 | 552 | struct netlink_callback *cb) |
|---|
| .. | .. |
|---|
| 502 | 566 | return -EINVAL; |
|---|
| 503 | 567 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); |
|---|
| 504 | 568 | |
|---|
| 505 | | - msg_seq = nla_get_u32(nltb[IWPM_NLA_QUERY_MAPPING_SEQ]); |
|---|
| 569 | + msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]); |
|---|
| 506 | 570 | nlmsg_request = iwpm_find_nlmsg_request(msg_seq); |
|---|
| 507 | 571 | if (!nlmsg_request) { |
|---|
| 508 | 572 | pr_info("%s: Could not find a matching request (seq = %u)\n", |
|---|
| .. | .. |
|---|
| 511 | 575 | } |
|---|
| 512 | 576 | pm_msg = nlmsg_request->req_buffer; |
|---|
| 513 | 577 | local_sockaddr = (struct sockaddr_storage *) |
|---|
| 514 | | - nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); |
|---|
| 578 | + nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]); |
|---|
| 515 | 579 | remote_sockaddr = (struct sockaddr_storage *) |
|---|
| 516 | | - nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); |
|---|
| 580 | + nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]); |
|---|
| 517 | 581 | mapped_loc_sockaddr = (struct sockaddr_storage *) |
|---|
| 518 | 582 | nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); |
|---|
| 519 | 583 | mapped_rem_sockaddr = (struct sockaddr_storage *) |
|---|
| .. | .. |
|---|
| 560 | 624 | return 0; |
|---|
| 561 | 625 | } |
|---|
| 562 | 626 | |
|---|
| 563 | | -/* |
|---|
| 564 | | - * iwpm_remote_info_cb - Process a port mapper message, containing |
|---|
| 565 | | - * the remote connecting peer address info |
|---|
| 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 |
|---|
| 566 | 634 | */ |
|---|
| 567 | 635 | int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) |
|---|
| 568 | 636 | { |
|---|
| .. | .. |
|---|
| 588 | 656 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); |
|---|
| 589 | 657 | |
|---|
| 590 | 658 | local_sockaddr = (struct sockaddr_storage *) |
|---|
| 591 | | - nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]); |
|---|
| 659 | + nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]); |
|---|
| 592 | 660 | remote_sockaddr = (struct sockaddr_storage *) |
|---|
| 593 | | - nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]); |
|---|
| 661 | + nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]); |
|---|
| 594 | 662 | mapped_loc_sockaddr = (struct sockaddr_storage *) |
|---|
| 595 | 663 | nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]); |
|---|
| 596 | 664 | mapped_rem_sockaddr = (struct sockaddr_storage *) |
|---|
| .. | .. |
|---|
| 635 | 703 | [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 } |
|---|
| 636 | 704 | }; |
|---|
| 637 | 705 | |
|---|
| 638 | | -/* |
|---|
| 639 | | - * iwpm_mapping_info_cb - Process a port mapper request for mapping info |
|---|
| 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 |
|---|
| 640 | 714 | */ |
|---|
| 641 | 715 | int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) |
|---|
| 642 | 716 | { |
|---|
| .. | .. |
|---|
| 655 | 729 | iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]); |
|---|
| 656 | 730 | iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]); |
|---|
| 657 | 731 | if (strcmp(iwpm_ulib_name, iwpm_name) || |
|---|
| 658 | | - iwpm_version != iwpm_ulib_version) { |
|---|
| 732 | + iwpm_version < IWPM_UABI_VERSION_MIN) { |
|---|
| 659 | 733 | pr_info("%s: Invalid port mapper name = %s version = %d\n", |
|---|
| 660 | 734 | __func__, iwpm_name, iwpm_version); |
|---|
| 661 | 735 | return ret; |
|---|
| .. | .. |
|---|
| 669 | 743 | iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); |
|---|
| 670 | 744 | atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); |
|---|
| 671 | 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 | + |
|---|
| 672 | 751 | if (!iwpm_mapinfo_available()) |
|---|
| 673 | 752 | return 0; |
|---|
| 674 | 753 | pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", |
|---|
| .. | .. |
|---|
| 684 | 763 | [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 } |
|---|
| 685 | 764 | }; |
|---|
| 686 | 765 | |
|---|
| 687 | | -/* |
|---|
| 688 | | - * iwpm_ack_mapping_info_cb - Process a port mapper ack for |
|---|
| 689 | | - * the provided mapping info records |
|---|
| 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) |
|---|
| 690 | 771 | */ |
|---|
| 691 | 772 | int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) |
|---|
| 692 | 773 | { |
|---|
| .. | .. |
|---|
| 712 | 793 | [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 }, |
|---|
| 713 | 794 | }; |
|---|
| 714 | 795 | |
|---|
| 715 | | -/* |
|---|
| 716 | | - * iwpm_mapping_error_cb - Process a port mapper error message |
|---|
| 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) |
|---|
| 717 | 801 | */ |
|---|
| 718 | 802 | int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb) |
|---|
| 719 | 803 | { |
|---|
| .. | .. |
|---|
| 748 | 832 | up(&nlmsg_request->sem); |
|---|
| 749 | 833 | return 0; |
|---|
| 750 | 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 | +} |
|---|