0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "iwpm_util.h"
0035
0036 static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser";
0037 u16 iwpm_ulib_version = IWPM_UABI_VERSION_MIN;
0038 static int iwpm_user_pid = IWPM_PID_UNDEFINED;
0039 static atomic_t echo_nlmsg_seq;
0040
0041
0042
0043
0044
0045
0046 int iwpm_valid_pid(void)
0047 {
0048 return iwpm_user_pid > 0;
0049 }
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
0064 {
0065 struct sk_buff *skb = NULL;
0066 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0067 struct nlmsghdr *nlh;
0068 u32 msg_seq;
0069 const char *err_str = "";
0070 int ret = -EINVAL;
0071
0072 if (iwpm_check_registration(nl_client, IWPM_REG_VALID) ||
0073 iwpm_user_pid == IWPM_PID_UNAVAILABLE)
0074 return 0;
0075 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client);
0076 if (!skb) {
0077 err_str = "Unable to create a nlmsg";
0078 goto pid_query_error;
0079 }
0080 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
0081 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
0082 if (!nlmsg_request) {
0083 err_str = "Unable to allocate netlink request";
0084 goto pid_query_error;
0085 }
0086 msg_seq = atomic_read(&echo_nlmsg_seq);
0087
0088
0089 err_str = "Unable to put attribute of the nlmsg";
0090 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_REG_PID_SEQ);
0091 if (ret)
0092 goto pid_query_error;
0093 ret = ibnl_put_attr(skb, nlh, IFNAMSIZ,
0094 pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
0095 if (ret)
0096 goto pid_query_error;
0097 ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
0098 pm_msg->dev_name, IWPM_NLA_REG_IBDEV_NAME);
0099 if (ret)
0100 goto pid_query_error;
0101 ret = ibnl_put_attr(skb, nlh, IWPM_ULIBNAME_SIZE,
0102 (char *)iwpm_ulib_name, IWPM_NLA_REG_ULIB_NAME);
0103 if (ret)
0104 goto pid_query_error;
0105
0106 nlmsg_end(skb, nlh);
0107
0108 pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
0109 __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);
0110
0111 ret = rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
0112 if (ret) {
0113 skb = NULL;
0114 iwpm_user_pid = IWPM_PID_UNAVAILABLE;
0115 err_str = "Unable to send a nlmsg";
0116 goto pid_query_error;
0117 }
0118 nlmsg_request->req_buffer = pm_msg;
0119 ret = iwpm_wait_complete_req(nlmsg_request);
0120 return ret;
0121 pid_query_error:
0122 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
0123 dev_kfree_skb(skb);
0124 if (nlmsg_request)
0125 iwpm_free_nlmsg_request(&nlmsg_request->kref);
0126 return ret;
0127 }
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
0144 {
0145 struct sk_buff *skb = NULL;
0146 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0147 struct nlmsghdr *nlh;
0148 u32 msg_seq;
0149 const char *err_str = "";
0150 int ret = -EINVAL;
0151
0152 if (!iwpm_valid_pid())
0153 return 0;
0154 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
0155 err_str = "Unregistered port mapper client";
0156 goto add_mapping_error;
0157 }
0158 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
0159 if (!skb) {
0160 err_str = "Unable to create a nlmsg";
0161 goto add_mapping_error;
0162 }
0163 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
0164 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
0165 if (!nlmsg_request) {
0166 err_str = "Unable to allocate netlink request";
0167 goto add_mapping_error;
0168 }
0169 msg_seq = atomic_read(&echo_nlmsg_seq);
0170
0171 err_str = "Unable to put attribute of the nlmsg";
0172 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
0173 IWPM_NLA_MANAGE_MAPPING_SEQ);
0174 if (ret)
0175 goto add_mapping_error;
0176 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
0177 &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR);
0178 if (ret)
0179 goto add_mapping_error;
0180
0181
0182 if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
0183 ret = -EINVAL;
0184 goto add_mapping_error_nowarn;
0185 }
0186 if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
0187 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
0188 IWPM_NLA_MANAGE_FLAGS);
0189 if (ret)
0190 goto add_mapping_error;
0191 }
0192
0193 nlmsg_end(skb, nlh);
0194 nlmsg_request->req_buffer = pm_msg;
0195
0196 ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
0197 if (ret) {
0198 skb = NULL;
0199 iwpm_user_pid = IWPM_PID_UNDEFINED;
0200 err_str = "Unable to send a nlmsg";
0201 goto add_mapping_error;
0202 }
0203 ret = iwpm_wait_complete_req(nlmsg_request);
0204 return ret;
0205 add_mapping_error:
0206 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
0207 add_mapping_error_nowarn:
0208 dev_kfree_skb(skb);
0209 if (nlmsg_request)
0210 iwpm_free_nlmsg_request(&nlmsg_request->kref);
0211 return ret;
0212 }
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
0227 {
0228 struct sk_buff *skb = NULL;
0229 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0230 struct nlmsghdr *nlh;
0231 u32 msg_seq;
0232 const char *err_str = "";
0233 int ret = -EINVAL;
0234
0235 if (!iwpm_valid_pid())
0236 return 0;
0237 if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
0238 err_str = "Unregistered port mapper client";
0239 goto query_mapping_error;
0240 }
0241 ret = -ENOMEM;
0242 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client);
0243 if (!skb) {
0244 err_str = "Unable to create a nlmsg";
0245 goto query_mapping_error;
0246 }
0247 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
0248 nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq,
0249 nl_client, GFP_KERNEL);
0250 if (!nlmsg_request) {
0251 err_str = "Unable to allocate netlink request";
0252 goto query_mapping_error;
0253 }
0254 msg_seq = atomic_read(&echo_nlmsg_seq);
0255
0256
0257 err_str = "Unable to put attribute of the nlmsg";
0258 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
0259 IWPM_NLA_QUERY_MAPPING_SEQ);
0260 if (ret)
0261 goto query_mapping_error;
0262 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
0263 &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR);
0264 if (ret)
0265 goto query_mapping_error;
0266 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
0267 &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR);
0268 if (ret)
0269 goto query_mapping_error;
0270
0271
0272 if (pm_msg->flags && iwpm_ulib_version == IWPM_UABI_VERSION_MIN) {
0273 ret = -EINVAL;
0274 goto query_mapping_error_nowarn;
0275 }
0276 if (iwpm_ulib_version > IWPM_UABI_VERSION_MIN) {
0277 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &pm_msg->flags,
0278 IWPM_NLA_QUERY_FLAGS);
0279 if (ret)
0280 goto query_mapping_error;
0281 }
0282
0283 nlmsg_end(skb, nlh);
0284 nlmsg_request->req_buffer = pm_msg;
0285
0286 ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
0287 if (ret) {
0288 skb = NULL;
0289 err_str = "Unable to send a nlmsg";
0290 goto query_mapping_error;
0291 }
0292 ret = iwpm_wait_complete_req(nlmsg_request);
0293 return ret;
0294 query_mapping_error:
0295 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
0296 query_mapping_error_nowarn:
0297 dev_kfree_skb(skb);
0298 if (nlmsg_request)
0299 iwpm_free_nlmsg_request(&nlmsg_request->kref);
0300 return ret;
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
0315 {
0316 struct sk_buff *skb = NULL;
0317 struct nlmsghdr *nlh;
0318 u32 msg_seq;
0319 const char *err_str = "";
0320 int ret = -EINVAL;
0321
0322 if (!iwpm_valid_pid())
0323 return 0;
0324 if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
0325 err_str = "Unregistered port mapper client";
0326 goto remove_mapping_error;
0327 }
0328 skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
0329 if (!skb) {
0330 ret = -ENOMEM;
0331 err_str = "Unable to create a nlmsg";
0332 goto remove_mapping_error;
0333 }
0334 msg_seq = atomic_read(&echo_nlmsg_seq);
0335 nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
0336 err_str = "Unable to put attribute of the nlmsg";
0337 ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
0338 IWPM_NLA_MANAGE_MAPPING_SEQ);
0339 if (ret)
0340 goto remove_mapping_error;
0341 ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
0342 local_addr, IWPM_NLA_MANAGE_ADDR);
0343 if (ret)
0344 goto remove_mapping_error;
0345
0346 nlmsg_end(skb, nlh);
0347
0348 ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
0349 if (ret) {
0350 skb = NULL;
0351 iwpm_user_pid = IWPM_PID_UNDEFINED;
0352 err_str = "Unable to send a nlmsg";
0353 goto remove_mapping_error;
0354 }
0355 iwpm_print_sockaddr(local_addr,
0356 "remove_mapping: Local sockaddr:");
0357 return 0;
0358 remove_mapping_error:
0359 pr_info("%s: %s (client = %u)\n", __func__, err_str, nl_client);
0360 if (skb)
0361 dev_kfree_skb_any(skb);
0362 return ret;
0363 }
0364
0365
0366 static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = {
0367 [IWPM_NLA_RREG_PID_SEQ] = { .type = NLA_U32 },
0368 [IWPM_NLA_RREG_IBDEV_NAME] = { .type = NLA_STRING,
0369 .len = IWPM_DEVNAME_SIZE - 1 },
0370 [IWPM_NLA_RREG_ULIB_NAME] = { .type = NLA_STRING,
0371 .len = IWPM_ULIBNAME_SIZE - 1 },
0372 [IWPM_NLA_RREG_ULIB_VER] = { .type = NLA_U16 },
0373 [IWPM_NLA_RREG_PID_ERR] = { .type = NLA_U16 }
0374 };
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
0386 {
0387 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0388 struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX];
0389 struct iwpm_dev_data *pm_msg;
0390 char *dev_name, *iwpm_name;
0391 u32 msg_seq;
0392 u8 nl_client;
0393 u16 iwpm_version;
0394 const char *msg_type = "Register Pid response";
0395
0396 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX,
0397 resp_reg_policy, nltb, msg_type))
0398 return -EINVAL;
0399
0400 msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]);
0401 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
0402 if (!nlmsg_request) {
0403 pr_info("%s: Could not find a matching request (seq = %u)\n",
0404 __func__, msg_seq);
0405 return -EINVAL;
0406 }
0407 pm_msg = nlmsg_request->req_buffer;
0408 nl_client = nlmsg_request->nl_client;
0409 dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]);
0410 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]);
0411 iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]);
0412
0413
0414 if (strcmp(pm_msg->dev_name, dev_name) ||
0415 strcmp(iwpm_ulib_name, iwpm_name) ||
0416 iwpm_version < IWPM_UABI_VERSION_MIN) {
0417
0418 pr_info("%s: Incorrect info (dev = %s name = %s version = %u)\n",
0419 __func__, dev_name, iwpm_name, iwpm_version);
0420 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
0421 goto register_pid_response_exit;
0422 }
0423 iwpm_user_pid = cb->nlh->nlmsg_pid;
0424 iwpm_ulib_version = iwpm_version;
0425 if (iwpm_ulib_version < IWPM_UABI_VERSION)
0426 pr_warn_once("%s: Down level iwpmd/pid %d. Continuing...",
0427 __func__, iwpm_user_pid);
0428 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0429 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
0430 __func__, iwpm_user_pid);
0431 iwpm_set_registration(nl_client, IWPM_REG_VALID);
0432 register_pid_response_exit:
0433 nlmsg_request->request_done = 1;
0434
0435 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
0436 barrier();
0437 up(&nlmsg_request->sem);
0438 return 0;
0439 }
0440
0441
0442 static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = {
0443 [IWPM_NLA_RMANAGE_MAPPING_SEQ] = { .type = NLA_U32 },
0444 [IWPM_NLA_RMANAGE_ADDR] = {
0445 .len = sizeof(struct sockaddr_storage) },
0446 [IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR] = {
0447 .len = sizeof(struct sockaddr_storage) },
0448 [IWPM_NLA_RMANAGE_MAPPING_ERR] = { .type = NLA_U16 }
0449 };
0450
0451
0452
0453
0454
0455
0456
0457 int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb)
0458 {
0459 struct iwpm_sa_data *pm_msg;
0460 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0461 struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX];
0462 struct sockaddr_storage *local_sockaddr;
0463 struct sockaddr_storage *mapped_sockaddr;
0464 const char *msg_type;
0465 u32 msg_seq;
0466
0467 msg_type = "Add Mapping response";
0468 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX,
0469 resp_add_policy, nltb, msg_type))
0470 return -EINVAL;
0471
0472 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0473
0474 msg_seq = nla_get_u32(nltb[IWPM_NLA_RMANAGE_MAPPING_SEQ]);
0475 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
0476 if (!nlmsg_request) {
0477 pr_info("%s: Could not find a matching request (seq = %u)\n",
0478 __func__, msg_seq);
0479 return -EINVAL;
0480 }
0481 pm_msg = nlmsg_request->req_buffer;
0482 local_sockaddr = (struct sockaddr_storage *)
0483 nla_data(nltb[IWPM_NLA_RMANAGE_ADDR]);
0484 mapped_sockaddr = (struct sockaddr_storage *)
0485 nla_data(nltb[IWPM_NLA_RMANAGE_MAPPED_LOC_ADDR]);
0486
0487 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) {
0488 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
0489 goto add_mapping_response_exit;
0490 }
0491 if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) {
0492 pr_info("%s: Sockaddr family doesn't match the requested one\n",
0493 __func__);
0494 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
0495 goto add_mapping_response_exit;
0496 }
0497 memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr,
0498 sizeof(*mapped_sockaddr));
0499 iwpm_print_sockaddr(&pm_msg->loc_addr,
0500 "add_mapping: Local sockaddr:");
0501 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
0502 "add_mapping: Mapped local sockaddr:");
0503
0504 add_mapping_response_exit:
0505 nlmsg_request->request_done = 1;
0506
0507 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
0508 barrier();
0509 up(&nlmsg_request->sem);
0510 return 0;
0511 }
0512
0513
0514
0515
0516 static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = {
0517 [IWPM_NLA_RQUERY_MAPPING_SEQ] = { .type = NLA_U32 },
0518 [IWPM_NLA_RQUERY_LOCAL_ADDR] = {
0519 .len = sizeof(struct sockaddr_storage) },
0520 [IWPM_NLA_RQUERY_REMOTE_ADDR] = {
0521 .len = sizeof(struct sockaddr_storage) },
0522 [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = {
0523 .len = sizeof(struct sockaddr_storage) },
0524 [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = {
0525 .len = sizeof(struct sockaddr_storage) },
0526 [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 }
0527 };
0528
0529
0530
0531
0532
0533
0534
0535 int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
0536 struct netlink_callback *cb)
0537 {
0538 struct iwpm_sa_data *pm_msg;
0539 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0540 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
0541 struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
0542 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
0543 const char *msg_type;
0544 u32 msg_seq;
0545 u16 err_code;
0546
0547 msg_type = "Query Mapping response";
0548 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
0549 resp_query_policy, nltb, msg_type))
0550 return -EINVAL;
0551 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0552
0553 msg_seq = nla_get_u32(nltb[IWPM_NLA_RQUERY_MAPPING_SEQ]);
0554 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
0555 if (!nlmsg_request) {
0556 pr_info("%s: Could not find a matching request (seq = %u)\n",
0557 __func__, msg_seq);
0558 return -EINVAL;
0559 }
0560 pm_msg = nlmsg_request->req_buffer;
0561 local_sockaddr = (struct sockaddr_storage *)
0562 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
0563 remote_sockaddr = (struct sockaddr_storage *)
0564 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
0565 mapped_loc_sockaddr = (struct sockaddr_storage *)
0566 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
0567 mapped_rem_sockaddr = (struct sockaddr_storage *)
0568 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
0569
0570 err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]);
0571 if (err_code == IWPM_REMOTE_QUERY_REJECT) {
0572 pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
0573 __func__, cb->nlh->nlmsg_pid, msg_seq);
0574 nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT;
0575 }
0576 if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) ||
0577 iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) {
0578 pr_info("%s: Incorrect local sockaddr\n", __func__);
0579 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
0580 goto query_mapping_response_exit;
0581 }
0582 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
0583 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
0584 pr_info("%s: Sockaddr family doesn't match the requested one\n",
0585 __func__);
0586 nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
0587 goto query_mapping_response_exit;
0588 }
0589 memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr,
0590 sizeof(*mapped_loc_sockaddr));
0591 memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr,
0592 sizeof(*mapped_rem_sockaddr));
0593
0594 iwpm_print_sockaddr(&pm_msg->loc_addr,
0595 "query_mapping: Local sockaddr:");
0596 iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
0597 "query_mapping: Mapped local sockaddr:");
0598 iwpm_print_sockaddr(&pm_msg->rem_addr,
0599 "query_mapping: Remote sockaddr:");
0600 iwpm_print_sockaddr(&pm_msg->mapped_rem_addr,
0601 "query_mapping: Mapped remote sockaddr:");
0602 query_mapping_response_exit:
0603 nlmsg_request->request_done = 1;
0604
0605 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
0606 barrier();
0607 up(&nlmsg_request->sem);
0608 return 0;
0609 }
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619 int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
0620 {
0621 struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
0622 struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
0623 struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
0624 struct iwpm_remote_info *rem_info;
0625 const char *msg_type;
0626 u8 nl_client;
0627 int ret = -EINVAL;
0628
0629 msg_type = "Remote Mapping info";
0630 if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
0631 resp_query_policy, nltb, msg_type))
0632 return ret;
0633
0634 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
0635 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0636
0637 local_sockaddr = (struct sockaddr_storage *)
0638 nla_data(nltb[IWPM_NLA_RQUERY_LOCAL_ADDR]);
0639 remote_sockaddr = (struct sockaddr_storage *)
0640 nla_data(nltb[IWPM_NLA_RQUERY_REMOTE_ADDR]);
0641 mapped_loc_sockaddr = (struct sockaddr_storage *)
0642 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
0643 mapped_rem_sockaddr = (struct sockaddr_storage *)
0644 nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
0645
0646 if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
0647 mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
0648 pr_info("%s: Sockaddr family doesn't match the requested one\n",
0649 __func__);
0650 return ret;
0651 }
0652 rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
0653 if (!rem_info) {
0654 ret = -ENOMEM;
0655 return ret;
0656 }
0657 memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr,
0658 sizeof(struct sockaddr_storage));
0659 memcpy(&rem_info->remote_sockaddr, remote_sockaddr,
0660 sizeof(struct sockaddr_storage));
0661 memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr,
0662 sizeof(struct sockaddr_storage));
0663 rem_info->nl_client = nl_client;
0664
0665 iwpm_add_remote_info(rem_info);
0666
0667 iwpm_print_sockaddr(local_sockaddr,
0668 "remote_info: Local sockaddr:");
0669 iwpm_print_sockaddr(mapped_loc_sockaddr,
0670 "remote_info: Mapped local sockaddr:");
0671 iwpm_print_sockaddr(remote_sockaddr,
0672 "remote_info: Remote sockaddr:");
0673 iwpm_print_sockaddr(mapped_rem_sockaddr,
0674 "remote_info: Mapped remote sockaddr:");
0675 return ret;
0676 }
0677
0678
0679 static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
0680 [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING,
0681 .len = IWPM_ULIBNAME_SIZE - 1 },
0682 [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 }
0683 };
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
0695 {
0696 struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
0697 const char *msg_type = "Mapping Info response";
0698 u8 nl_client;
0699 char *iwpm_name;
0700 u16 iwpm_version;
0701 int ret = -EINVAL;
0702
0703 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX,
0704 resp_mapinfo_policy, nltb, msg_type)) {
0705 pr_info("%s: Unable to parse nlmsg\n", __func__);
0706 return ret;
0707 }
0708 iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]);
0709 iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]);
0710 if (strcmp(iwpm_ulib_name, iwpm_name) ||
0711 iwpm_version < IWPM_UABI_VERSION_MIN) {
0712 pr_info("%s: Invalid port mapper name = %s version = %u\n",
0713 __func__, iwpm_name, iwpm_version);
0714 return ret;
0715 }
0716 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
0717 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
0718 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0719 iwpm_user_pid = cb->nlh->nlmsg_pid;
0720
0721 if (iwpm_ulib_version < IWPM_UABI_VERSION)
0722 pr_warn_once("%s: Down level iwpmd/pid %d. Continuing...",
0723 __func__, iwpm_user_pid);
0724
0725 if (!iwpm_mapinfo_available())
0726 return 0;
0727 pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
0728 __func__, iwpm_user_pid);
0729 ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
0730 return ret;
0731 }
0732
0733
0734 static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
0735 [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 },
0736 [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 },
0737 [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 }
0738 };
0739
0740
0741
0742
0743
0744
0745
0746 int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
0747 {
0748 struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX];
0749 u32 mapinfo_send, mapinfo_ack;
0750 const char *msg_type = "Mapping Info Ack";
0751
0752 if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX,
0753 ack_mapinfo_policy, nltb, msg_type))
0754 return -EINVAL;
0755 mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]);
0756 mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]);
0757 if (mapinfo_ack != mapinfo_send)
0758 pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
0759 __func__, mapinfo_send, mapinfo_ack);
0760 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0761 return 0;
0762 }
0763
0764
0765 static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
0766 [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 },
0767 [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 },
0768 };
0769
0770
0771
0772
0773
0774
0775
0776 int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
0777 {
0778 struct iwpm_nlmsg_request *nlmsg_request = NULL;
0779 int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
0780 struct nlattr *nltb[IWPM_NLA_ERR_MAX];
0781 u32 msg_seq;
0782 u16 err_code;
0783 const char *msg_type = "Mapping Error Msg";
0784
0785 if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX,
0786 map_error_policy, nltb, msg_type))
0787 return -EINVAL;
0788
0789 msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]);
0790 err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]);
0791 pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
0792 __func__, msg_seq, err_code, nl_client);
0793
0794 nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
0795 if (!nlmsg_request) {
0796
0797 pr_debug("Could not find matching req (seq = %u)\n", msg_seq);
0798 return 0;
0799 }
0800 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0801 nlmsg_request->err_code = err_code;
0802 nlmsg_request->request_done = 1;
0803
0804 kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
0805 barrier();
0806 up(&nlmsg_request->sem);
0807 return 0;
0808 }
0809
0810
0811 static const struct nla_policy hello_policy[IWPM_NLA_HELLO_MAX] = {
0812 [IWPM_NLA_HELLO_ABI_VERSION] = { .type = NLA_U16 }
0813 };
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824 int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb)
0825 {
0826 struct nlattr *nltb[IWPM_NLA_HELLO_MAX];
0827 const char *msg_type = "Hello request";
0828 u8 nl_client;
0829 u16 abi_version;
0830 int ret = -EINVAL;
0831
0832 if (iwpm_parse_nlmsg(cb, IWPM_NLA_HELLO_MAX, hello_policy, nltb,
0833 msg_type)) {
0834 pr_info("%s: Unable to parse nlmsg\n", __func__);
0835 return ret;
0836 }
0837 abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]);
0838 nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
0839 iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
0840 atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
0841 iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version);
0842 pr_debug("Using ABI version %u\n", iwpm_ulib_version);
0843 iwpm_user_pid = cb->nlh->nlmsg_pid;
0844 ret = iwpm_send_hello(nl_client, iwpm_user_pid, iwpm_ulib_version);
0845 return ret;
0846 }