root/drivers/infiniband/core/iwpm_msg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iwpm_valid_pid
  2. iwpm_register_pid
  3. iwpm_add_mapping
  4. iwpm_add_and_query_mapping
  5. iwpm_remove_mapping
  6. iwpm_register_pid_cb
  7. iwpm_add_mapping_cb
  8. iwpm_add_and_query_mapping_cb
  9. iwpm_remote_info_cb
  10. iwpm_mapping_info_cb
  11. iwpm_ack_mapping_info_cb
  12. iwpm_mapping_error_cb
  13. iwpm_hello_cb

   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 }

/* [<][>][^][v][top][bottom][index][help] */