iwpm_msg.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  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. #include "iwpm_util.h"
  34. static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser";
  35. static int iwpm_ulib_version = 3;
  36. static int iwpm_user_pid = IWPM_PID_UNDEFINED;
  37. static atomic_t echo_nlmsg_seq;
  38. int iwpm_valid_pid(void)
  39. {
  40. return iwpm_user_pid > 0;
  41. }
  42. EXPORT_SYMBOL(iwpm_valid_pid);
  43. /*
  44. * iwpm_register_pid - Send a netlink query to user space
  45. * for the iwarp port mapper pid
  46. *
  47. * nlmsg attributes:
  48. * [IWPM_NLA_REG_PID_SEQ]
  49. * [IWPM_NLA_REG_IF_NAME]
  50. * [IWPM_NLA_REG_IBDEV_NAME]
  51. * [IWPM_NLA_REG_ULIB_NAME]
  52. */
  53. int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
  54. {
  55. struct sk_buff *skb = NULL;
  56. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  57. struct nlmsghdr *nlh;
  58. u32 msg_seq;
  59. const char *err_str = "";
  60. int ret = -EINVAL;
  61. if (!iwpm_valid_client(nl_client)) {
  62. err_str = "Invalid port mapper client";
  63. goto pid_query_error;
  64. }
  65. if (iwpm_check_registration(nl_client, IWPM_REG_VALID) ||
  66. iwpm_user_pid == IWPM_PID_UNAVAILABLE)
  67. return 0;
  68. skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client);
  69. if (!skb) {
  70. err_str = "Unable to create a nlmsg";
  71. goto pid_query_error;
  72. }
  73. nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
  74. nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
  75. if (!nlmsg_request) {
  76. err_str = "Unable to allocate netlink request";
  77. goto pid_query_error;
  78. }
  79. msg_seq = atomic_read(&echo_nlmsg_seq);
  80. /* fill in the pid request message */
  81. err_str = "Unable to put attribute of the nlmsg";
  82. ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_REG_PID_SEQ);
  83. if (ret)
  84. goto pid_query_error;
  85. ret = ibnl_put_attr(skb, nlh, IWPM_IFNAME_SIZE,
  86. pm_msg->if_name, IWPM_NLA_REG_IF_NAME);
  87. if (ret)
  88. goto pid_query_error;
  89. ret = ibnl_put_attr(skb, nlh, IWPM_DEVNAME_SIZE,
  90. pm_msg->dev_name, IWPM_NLA_REG_IBDEV_NAME);
  91. if (ret)
  92. goto pid_query_error;
  93. ret = ibnl_put_attr(skb, nlh, IWPM_ULIBNAME_SIZE,
  94. (char *)iwpm_ulib_name, IWPM_NLA_REG_ULIB_NAME);
  95. if (ret)
  96. goto pid_query_error;
  97. pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
  98. __func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);
  99. ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
  100. if (ret) {
  101. skb = NULL; /* skb is freed in the netlink send-op handling */
  102. iwpm_user_pid = IWPM_PID_UNAVAILABLE;
  103. err_str = "Unable to send a nlmsg";
  104. goto pid_query_error;
  105. }
  106. nlmsg_request->req_buffer = pm_msg;
  107. ret = iwpm_wait_complete_req(nlmsg_request);
  108. return ret;
  109. pid_query_error:
  110. pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
  111. if (skb)
  112. dev_kfree_skb(skb);
  113. if (nlmsg_request)
  114. iwpm_free_nlmsg_request(&nlmsg_request->kref);
  115. return ret;
  116. }
  117. EXPORT_SYMBOL(iwpm_register_pid);
  118. /*
  119. * iwpm_add_mapping - Send a netlink add mapping message
  120. * to the port mapper
  121. * nlmsg attributes:
  122. * [IWPM_NLA_MANAGE_MAPPING_SEQ]
  123. * [IWPM_NLA_MANAGE_ADDR]
  124. */
  125. int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
  126. {
  127. struct sk_buff *skb = NULL;
  128. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  129. struct nlmsghdr *nlh;
  130. u32 msg_seq;
  131. const char *err_str = "";
  132. int ret = -EINVAL;
  133. if (!iwpm_valid_client(nl_client)) {
  134. err_str = "Invalid port mapper client";
  135. goto add_mapping_error;
  136. }
  137. if (!iwpm_valid_pid())
  138. return 0;
  139. if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
  140. err_str = "Unregistered port mapper client";
  141. goto add_mapping_error;
  142. }
  143. skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
  144. if (!skb) {
  145. err_str = "Unable to create a nlmsg";
  146. goto add_mapping_error;
  147. }
  148. nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
  149. nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq, nl_client, GFP_KERNEL);
  150. if (!nlmsg_request) {
  151. err_str = "Unable to allocate netlink request";
  152. goto add_mapping_error;
  153. }
  154. msg_seq = atomic_read(&echo_nlmsg_seq);
  155. /* fill in the add mapping message */
  156. err_str = "Unable to put attribute of the nlmsg";
  157. ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
  158. IWPM_NLA_MANAGE_MAPPING_SEQ);
  159. if (ret)
  160. goto add_mapping_error;
  161. ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
  162. &pm_msg->loc_addr, IWPM_NLA_MANAGE_ADDR);
  163. if (ret)
  164. goto add_mapping_error;
  165. nlmsg_request->req_buffer = pm_msg;
  166. ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
  167. if (ret) {
  168. skb = NULL; /* skb is freed in the netlink send-op handling */
  169. iwpm_user_pid = IWPM_PID_UNDEFINED;
  170. err_str = "Unable to send a nlmsg";
  171. goto add_mapping_error;
  172. }
  173. ret = iwpm_wait_complete_req(nlmsg_request);
  174. return ret;
  175. add_mapping_error:
  176. pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
  177. if (skb)
  178. dev_kfree_skb(skb);
  179. if (nlmsg_request)
  180. iwpm_free_nlmsg_request(&nlmsg_request->kref);
  181. return ret;
  182. }
  183. EXPORT_SYMBOL(iwpm_add_mapping);
  184. /*
  185. * iwpm_add_and_query_mapping - Send a netlink add and query
  186. * mapping message to the port mapper
  187. * nlmsg attributes:
  188. * [IWPM_NLA_QUERY_MAPPING_SEQ]
  189. * [IWPM_NLA_QUERY_LOCAL_ADDR]
  190. * [IWPM_NLA_QUERY_REMOTE_ADDR]
  191. */
  192. int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
  193. {
  194. struct sk_buff *skb = NULL;
  195. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  196. struct nlmsghdr *nlh;
  197. u32 msg_seq;
  198. const char *err_str = "";
  199. int ret = -EINVAL;
  200. if (!iwpm_valid_client(nl_client)) {
  201. err_str = "Invalid port mapper client";
  202. goto query_mapping_error;
  203. }
  204. if (!iwpm_valid_pid())
  205. return 0;
  206. if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
  207. err_str = "Unregistered port mapper client";
  208. goto query_mapping_error;
  209. }
  210. ret = -ENOMEM;
  211. skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client);
  212. if (!skb) {
  213. err_str = "Unable to create a nlmsg";
  214. goto query_mapping_error;
  215. }
  216. nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
  217. nlmsg_request = iwpm_get_nlmsg_request(nlh->nlmsg_seq,
  218. nl_client, GFP_KERNEL);
  219. if (!nlmsg_request) {
  220. err_str = "Unable to allocate netlink request";
  221. goto query_mapping_error;
  222. }
  223. msg_seq = atomic_read(&echo_nlmsg_seq);
  224. /* fill in the query message */
  225. err_str = "Unable to put attribute of the nlmsg";
  226. ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
  227. IWPM_NLA_QUERY_MAPPING_SEQ);
  228. if (ret)
  229. goto query_mapping_error;
  230. ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
  231. &pm_msg->loc_addr, IWPM_NLA_QUERY_LOCAL_ADDR);
  232. if (ret)
  233. goto query_mapping_error;
  234. ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
  235. &pm_msg->rem_addr, IWPM_NLA_QUERY_REMOTE_ADDR);
  236. if (ret)
  237. goto query_mapping_error;
  238. nlmsg_request->req_buffer = pm_msg;
  239. ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
  240. if (ret) {
  241. skb = NULL; /* skb is freed in the netlink send-op handling */
  242. err_str = "Unable to send a nlmsg";
  243. goto query_mapping_error;
  244. }
  245. ret = iwpm_wait_complete_req(nlmsg_request);
  246. return ret;
  247. query_mapping_error:
  248. pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
  249. if (skb)
  250. dev_kfree_skb(skb);
  251. if (nlmsg_request)
  252. iwpm_free_nlmsg_request(&nlmsg_request->kref);
  253. return ret;
  254. }
  255. EXPORT_SYMBOL(iwpm_add_and_query_mapping);
  256. /*
  257. * iwpm_remove_mapping - Send a netlink remove mapping message
  258. * to the port mapper
  259. * nlmsg attributes:
  260. * [IWPM_NLA_MANAGE_MAPPING_SEQ]
  261. * [IWPM_NLA_MANAGE_ADDR]
  262. */
  263. int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
  264. {
  265. struct sk_buff *skb = NULL;
  266. struct nlmsghdr *nlh;
  267. u32 msg_seq;
  268. const char *err_str = "";
  269. int ret = -EINVAL;
  270. if (!iwpm_valid_client(nl_client)) {
  271. err_str = "Invalid port mapper client";
  272. goto remove_mapping_error;
  273. }
  274. if (!iwpm_valid_pid())
  275. return 0;
  276. if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
  277. err_str = "Unregistered port mapper client";
  278. goto remove_mapping_error;
  279. }
  280. skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
  281. if (!skb) {
  282. ret = -ENOMEM;
  283. err_str = "Unable to create a nlmsg";
  284. goto remove_mapping_error;
  285. }
  286. msg_seq = atomic_read(&echo_nlmsg_seq);
  287. nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
  288. err_str = "Unable to put attribute of the nlmsg";
  289. ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq,
  290. IWPM_NLA_MANAGE_MAPPING_SEQ);
  291. if (ret)
  292. goto remove_mapping_error;
  293. ret = ibnl_put_attr(skb, nlh, sizeof(struct sockaddr_storage),
  294. local_addr, IWPM_NLA_MANAGE_ADDR);
  295. if (ret)
  296. goto remove_mapping_error;
  297. ret = ibnl_unicast(skb, nlh, iwpm_user_pid);
  298. if (ret) {
  299. skb = NULL; /* skb is freed in the netlink send-op handling */
  300. iwpm_user_pid = IWPM_PID_UNDEFINED;
  301. err_str = "Unable to send a nlmsg";
  302. goto remove_mapping_error;
  303. }
  304. iwpm_print_sockaddr(local_addr,
  305. "remove_mapping: Local sockaddr:");
  306. return 0;
  307. remove_mapping_error:
  308. pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
  309. if (skb)
  310. dev_kfree_skb_any(skb);
  311. return ret;
  312. }
  313. EXPORT_SYMBOL(iwpm_remove_mapping);
  314. /* netlink attribute policy for the received response to register pid request */
  315. static const struct nla_policy resp_reg_policy[IWPM_NLA_RREG_PID_MAX] = {
  316. [IWPM_NLA_RREG_PID_SEQ] = { .type = NLA_U32 },
  317. [IWPM_NLA_RREG_IBDEV_NAME] = { .type = NLA_STRING,
  318. .len = IWPM_DEVNAME_SIZE - 1 },
  319. [IWPM_NLA_RREG_ULIB_NAME] = { .type = NLA_STRING,
  320. .len = IWPM_ULIBNAME_SIZE - 1 },
  321. [IWPM_NLA_RREG_ULIB_VER] = { .type = NLA_U16 },
  322. [IWPM_NLA_RREG_PID_ERR] = { .type = NLA_U16 }
  323. };
  324. /*
  325. * iwpm_register_pid_cb - Process a port mapper response to
  326. * iwpm_register_pid()
  327. */
  328. int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
  329. {
  330. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  331. struct nlattr *nltb[IWPM_NLA_RREG_PID_MAX];
  332. struct iwpm_dev_data *pm_msg;
  333. char *dev_name, *iwpm_name;
  334. u32 msg_seq;
  335. u8 nl_client;
  336. u16 iwpm_version;
  337. const char *msg_type = "Register Pid response";
  338. if (iwpm_parse_nlmsg(cb, IWPM_NLA_RREG_PID_MAX,
  339. resp_reg_policy, nltb, msg_type))
  340. return -EINVAL;
  341. msg_seq = nla_get_u32(nltb[IWPM_NLA_RREG_PID_SEQ]);
  342. nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
  343. if (!nlmsg_request) {
  344. pr_info("%s: Could not find a matching request (seq = %u)\n",
  345. __func__, msg_seq);
  346. return -EINVAL;
  347. }
  348. pm_msg = nlmsg_request->req_buffer;
  349. nl_client = nlmsg_request->nl_client;
  350. dev_name = (char *)nla_data(nltb[IWPM_NLA_RREG_IBDEV_NAME]);
  351. iwpm_name = (char *)nla_data(nltb[IWPM_NLA_RREG_ULIB_NAME]);
  352. iwpm_version = nla_get_u16(nltb[IWPM_NLA_RREG_ULIB_VER]);
  353. /* check device name, ulib name and version */
  354. if (strcmp(pm_msg->dev_name, dev_name) ||
  355. strcmp(iwpm_ulib_name, iwpm_name) ||
  356. iwpm_version != iwpm_ulib_version) {
  357. pr_info("%s: Incorrect info (dev = %s name = %s version = %d)\n",
  358. __func__, dev_name, iwpm_name, iwpm_version);
  359. nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
  360. goto register_pid_response_exit;
  361. }
  362. iwpm_user_pid = cb->nlh->nlmsg_pid;
  363. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  364. pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
  365. __func__, iwpm_user_pid);
  366. if (iwpm_valid_client(nl_client))
  367. iwpm_set_registration(nl_client, IWPM_REG_VALID);
  368. register_pid_response_exit:
  369. nlmsg_request->request_done = 1;
  370. /* always for found nlmsg_request */
  371. kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
  372. barrier();
  373. wake_up(&nlmsg_request->waitq);
  374. return 0;
  375. }
  376. EXPORT_SYMBOL(iwpm_register_pid_cb);
  377. /* netlink attribute policy for the received response to add mapping request */
  378. static const struct nla_policy resp_add_policy[IWPM_NLA_RMANAGE_MAPPING_MAX] = {
  379. [IWPM_NLA_MANAGE_MAPPING_SEQ] = { .type = NLA_U32 },
  380. [IWPM_NLA_MANAGE_ADDR] = { .len = sizeof(struct sockaddr_storage) },
  381. [IWPM_NLA_MANAGE_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) },
  382. [IWPM_NLA_RMANAGE_MAPPING_ERR] = { .type = NLA_U16 }
  383. };
  384. /*
  385. * iwpm_add_mapping_cb - Process a port mapper response to
  386. * iwpm_add_mapping()
  387. */
  388. int iwpm_add_mapping_cb(struct sk_buff *skb, struct netlink_callback *cb)
  389. {
  390. struct iwpm_sa_data *pm_msg;
  391. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  392. struct nlattr *nltb[IWPM_NLA_RMANAGE_MAPPING_MAX];
  393. struct sockaddr_storage *local_sockaddr;
  394. struct sockaddr_storage *mapped_sockaddr;
  395. const char *msg_type;
  396. u32 msg_seq;
  397. msg_type = "Add Mapping response";
  398. if (iwpm_parse_nlmsg(cb, IWPM_NLA_RMANAGE_MAPPING_MAX,
  399. resp_add_policy, nltb, msg_type))
  400. return -EINVAL;
  401. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  402. msg_seq = nla_get_u32(nltb[IWPM_NLA_MANAGE_MAPPING_SEQ]);
  403. nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
  404. if (!nlmsg_request) {
  405. pr_info("%s: Could not find a matching request (seq = %u)\n",
  406. __func__, msg_seq);
  407. return -EINVAL;
  408. }
  409. pm_msg = nlmsg_request->req_buffer;
  410. local_sockaddr = (struct sockaddr_storage *)
  411. nla_data(nltb[IWPM_NLA_MANAGE_ADDR]);
  412. mapped_sockaddr = (struct sockaddr_storage *)
  413. nla_data(nltb[IWPM_NLA_MANAGE_MAPPED_LOC_ADDR]);
  414. if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr)) {
  415. nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
  416. goto add_mapping_response_exit;
  417. }
  418. if (mapped_sockaddr->ss_family != local_sockaddr->ss_family) {
  419. pr_info("%s: Sockaddr family doesn't match the requested one\n",
  420. __func__);
  421. nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
  422. goto add_mapping_response_exit;
  423. }
  424. memcpy(&pm_msg->mapped_loc_addr, mapped_sockaddr,
  425. sizeof(*mapped_sockaddr));
  426. iwpm_print_sockaddr(&pm_msg->loc_addr,
  427. "add_mapping: Local sockaddr:");
  428. iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
  429. "add_mapping: Mapped local sockaddr:");
  430. add_mapping_response_exit:
  431. nlmsg_request->request_done = 1;
  432. /* always for found request */
  433. kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
  434. barrier();
  435. wake_up(&nlmsg_request->waitq);
  436. return 0;
  437. }
  438. EXPORT_SYMBOL(iwpm_add_mapping_cb);
  439. /* netlink attribute policy for the response to add and query mapping request
  440. * and response with remote address info */
  441. static const struct nla_policy resp_query_policy[IWPM_NLA_RQUERY_MAPPING_MAX] = {
  442. [IWPM_NLA_QUERY_MAPPING_SEQ] = { .type = NLA_U32 },
  443. [IWPM_NLA_QUERY_LOCAL_ADDR] = { .len = sizeof(struct sockaddr_storage) },
  444. [IWPM_NLA_QUERY_REMOTE_ADDR] = { .len = sizeof(struct sockaddr_storage) },
  445. [IWPM_NLA_RQUERY_MAPPED_LOC_ADDR] = { .len = sizeof(struct sockaddr_storage) },
  446. [IWPM_NLA_RQUERY_MAPPED_REM_ADDR] = { .len = sizeof(struct sockaddr_storage) },
  447. [IWPM_NLA_RQUERY_MAPPING_ERR] = { .type = NLA_U16 }
  448. };
  449. /*
  450. * iwpm_add_and_query_mapping_cb - Process a port mapper response to
  451. * iwpm_add_and_query_mapping()
  452. */
  453. int iwpm_add_and_query_mapping_cb(struct sk_buff *skb,
  454. struct netlink_callback *cb)
  455. {
  456. struct iwpm_sa_data *pm_msg;
  457. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  458. struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
  459. struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
  460. struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
  461. const char *msg_type;
  462. u32 msg_seq;
  463. u16 err_code;
  464. msg_type = "Query Mapping response";
  465. if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
  466. resp_query_policy, nltb, msg_type))
  467. return -EINVAL;
  468. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  469. msg_seq = nla_get_u32(nltb[IWPM_NLA_QUERY_MAPPING_SEQ]);
  470. nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
  471. if (!nlmsg_request) {
  472. pr_info("%s: Could not find a matching request (seq = %u)\n",
  473. __func__, msg_seq);
  474. return -EINVAL;
  475. }
  476. pm_msg = nlmsg_request->req_buffer;
  477. local_sockaddr = (struct sockaddr_storage *)
  478. nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]);
  479. remote_sockaddr = (struct sockaddr_storage *)
  480. nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]);
  481. mapped_loc_sockaddr = (struct sockaddr_storage *)
  482. nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
  483. mapped_rem_sockaddr = (struct sockaddr_storage *)
  484. nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
  485. err_code = nla_get_u16(nltb[IWPM_NLA_RQUERY_MAPPING_ERR]);
  486. if (err_code == IWPM_REMOTE_QUERY_REJECT) {
  487. pr_info("%s: Received a Reject (pid = %u, echo seq = %u)\n",
  488. __func__, cb->nlh->nlmsg_pid, msg_seq);
  489. nlmsg_request->err_code = IWPM_REMOTE_QUERY_REJECT;
  490. }
  491. if (iwpm_compare_sockaddr(local_sockaddr, &pm_msg->loc_addr) ||
  492. iwpm_compare_sockaddr(remote_sockaddr, &pm_msg->rem_addr)) {
  493. pr_info("%s: Incorrect local sockaddr\n", __func__);
  494. nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
  495. goto query_mapping_response_exit;
  496. }
  497. if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
  498. mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
  499. pr_info("%s: Sockaddr family doesn't match the requested one\n",
  500. __func__);
  501. nlmsg_request->err_code = IWPM_USER_LIB_INFO_ERR;
  502. goto query_mapping_response_exit;
  503. }
  504. memcpy(&pm_msg->mapped_loc_addr, mapped_loc_sockaddr,
  505. sizeof(*mapped_loc_sockaddr));
  506. memcpy(&pm_msg->mapped_rem_addr, mapped_rem_sockaddr,
  507. sizeof(*mapped_rem_sockaddr));
  508. iwpm_print_sockaddr(&pm_msg->loc_addr,
  509. "query_mapping: Local sockaddr:");
  510. iwpm_print_sockaddr(&pm_msg->mapped_loc_addr,
  511. "query_mapping: Mapped local sockaddr:");
  512. iwpm_print_sockaddr(&pm_msg->rem_addr,
  513. "query_mapping: Remote sockaddr:");
  514. iwpm_print_sockaddr(&pm_msg->mapped_rem_addr,
  515. "query_mapping: Mapped remote sockaddr:");
  516. query_mapping_response_exit:
  517. nlmsg_request->request_done = 1;
  518. /* always for found request */
  519. kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
  520. barrier();
  521. wake_up(&nlmsg_request->waitq);
  522. return 0;
  523. }
  524. EXPORT_SYMBOL(iwpm_add_and_query_mapping_cb);
  525. /*
  526. * iwpm_remote_info_cb - Process a port mapper message, containing
  527. * the remote connecting peer address info
  528. */
  529. int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
  530. {
  531. struct nlattr *nltb[IWPM_NLA_RQUERY_MAPPING_MAX];
  532. struct sockaddr_storage *local_sockaddr, *remote_sockaddr;
  533. struct sockaddr_storage *mapped_loc_sockaddr, *mapped_rem_sockaddr;
  534. struct iwpm_remote_info *rem_info;
  535. const char *msg_type;
  536. u8 nl_client;
  537. int ret = -EINVAL;
  538. msg_type = "Remote Mapping info";
  539. if (iwpm_parse_nlmsg(cb, IWPM_NLA_RQUERY_MAPPING_MAX,
  540. resp_query_policy, nltb, msg_type))
  541. return ret;
  542. nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
  543. if (!iwpm_valid_client(nl_client)) {
  544. pr_info("%s: Invalid port mapper client = %d\n",
  545. __func__, nl_client);
  546. return ret;
  547. }
  548. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  549. local_sockaddr = (struct sockaddr_storage *)
  550. nla_data(nltb[IWPM_NLA_QUERY_LOCAL_ADDR]);
  551. remote_sockaddr = (struct sockaddr_storage *)
  552. nla_data(nltb[IWPM_NLA_QUERY_REMOTE_ADDR]);
  553. mapped_loc_sockaddr = (struct sockaddr_storage *)
  554. nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_LOC_ADDR]);
  555. mapped_rem_sockaddr = (struct sockaddr_storage *)
  556. nla_data(nltb[IWPM_NLA_RQUERY_MAPPED_REM_ADDR]);
  557. if (mapped_loc_sockaddr->ss_family != local_sockaddr->ss_family ||
  558. mapped_rem_sockaddr->ss_family != remote_sockaddr->ss_family) {
  559. pr_info("%s: Sockaddr family doesn't match the requested one\n",
  560. __func__);
  561. return ret;
  562. }
  563. rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC);
  564. if (!rem_info) {
  565. pr_err("%s: Unable to allocate a remote info\n", __func__);
  566. ret = -ENOMEM;
  567. return ret;
  568. }
  569. memcpy(&rem_info->mapped_loc_sockaddr, mapped_loc_sockaddr,
  570. sizeof(struct sockaddr_storage));
  571. memcpy(&rem_info->remote_sockaddr, remote_sockaddr,
  572. sizeof(struct sockaddr_storage));
  573. memcpy(&rem_info->mapped_rem_sockaddr, mapped_rem_sockaddr,
  574. sizeof(struct sockaddr_storage));
  575. rem_info->nl_client = nl_client;
  576. iwpm_add_remote_info(rem_info);
  577. iwpm_print_sockaddr(local_sockaddr,
  578. "remote_info: Local sockaddr:");
  579. iwpm_print_sockaddr(mapped_loc_sockaddr,
  580. "remote_info: Mapped local sockaddr:");
  581. iwpm_print_sockaddr(remote_sockaddr,
  582. "remote_info: Remote sockaddr:");
  583. iwpm_print_sockaddr(mapped_rem_sockaddr,
  584. "remote_info: Mapped remote sockaddr:");
  585. return ret;
  586. }
  587. EXPORT_SYMBOL(iwpm_remote_info_cb);
  588. /* netlink attribute policy for the received request for mapping info */
  589. static const struct nla_policy resp_mapinfo_policy[IWPM_NLA_MAPINFO_REQ_MAX] = {
  590. [IWPM_NLA_MAPINFO_ULIB_NAME] = { .type = NLA_STRING,
  591. .len = IWPM_ULIBNAME_SIZE - 1 },
  592. [IWPM_NLA_MAPINFO_ULIB_VER] = { .type = NLA_U16 }
  593. };
  594. /*
  595. * iwpm_mapping_info_cb - Process a port mapper request for mapping info
  596. */
  597. int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
  598. {
  599. struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
  600. const char *msg_type = "Mapping Info response";
  601. u8 nl_client;
  602. char *iwpm_name;
  603. u16 iwpm_version;
  604. int ret = -EINVAL;
  605. if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_REQ_MAX,
  606. resp_mapinfo_policy, nltb, msg_type)) {
  607. pr_info("%s: Unable to parse nlmsg\n", __func__);
  608. return ret;
  609. }
  610. iwpm_name = (char *)nla_data(nltb[IWPM_NLA_MAPINFO_ULIB_NAME]);
  611. iwpm_version = nla_get_u16(nltb[IWPM_NLA_MAPINFO_ULIB_VER]);
  612. if (strcmp(iwpm_ulib_name, iwpm_name) ||
  613. iwpm_version != iwpm_ulib_version) {
  614. pr_info("%s: Invalid port mapper name = %s version = %d\n",
  615. __func__, iwpm_name, iwpm_version);
  616. return ret;
  617. }
  618. nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
  619. if (!iwpm_valid_client(nl_client)) {
  620. pr_info("%s: Invalid port mapper client = %d\n",
  621. __func__, nl_client);
  622. return ret;
  623. }
  624. iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
  625. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  626. iwpm_user_pid = cb->nlh->nlmsg_pid;
  627. if (!iwpm_mapinfo_available())
  628. return 0;
  629. pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
  630. __func__, iwpm_user_pid);
  631. ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
  632. return ret;
  633. }
  634. EXPORT_SYMBOL(iwpm_mapping_info_cb);
  635. /* netlink attribute policy for the received mapping info ack */
  636. static const struct nla_policy ack_mapinfo_policy[IWPM_NLA_MAPINFO_NUM_MAX] = {
  637. [IWPM_NLA_MAPINFO_SEQ] = { .type = NLA_U32 },
  638. [IWPM_NLA_MAPINFO_SEND_NUM] = { .type = NLA_U32 },
  639. [IWPM_NLA_MAPINFO_ACK_NUM] = { .type = NLA_U32 }
  640. };
  641. /*
  642. * iwpm_ack_mapping_info_cb - Process a port mapper ack for
  643. * the provided mapping info records
  644. */
  645. int iwpm_ack_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
  646. {
  647. struct nlattr *nltb[IWPM_NLA_MAPINFO_NUM_MAX];
  648. u32 mapinfo_send, mapinfo_ack;
  649. const char *msg_type = "Mapping Info Ack";
  650. if (iwpm_parse_nlmsg(cb, IWPM_NLA_MAPINFO_NUM_MAX,
  651. ack_mapinfo_policy, nltb, msg_type))
  652. return -EINVAL;
  653. mapinfo_send = nla_get_u32(nltb[IWPM_NLA_MAPINFO_SEND_NUM]);
  654. mapinfo_ack = nla_get_u32(nltb[IWPM_NLA_MAPINFO_ACK_NUM]);
  655. if (mapinfo_ack != mapinfo_send)
  656. pr_info("%s: Invalid mapinfo number (sent = %u ack-ed = %u)\n",
  657. __func__, mapinfo_send, mapinfo_ack);
  658. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  659. return 0;
  660. }
  661. EXPORT_SYMBOL(iwpm_ack_mapping_info_cb);
  662. /* netlink attribute policy for the received port mapper error message */
  663. static const struct nla_policy map_error_policy[IWPM_NLA_ERR_MAX] = {
  664. [IWPM_NLA_ERR_SEQ] = { .type = NLA_U32 },
  665. [IWPM_NLA_ERR_CODE] = { .type = NLA_U16 },
  666. };
  667. /*
  668. * iwpm_mapping_error_cb - Process a port mapper error message
  669. */
  670. int iwpm_mapping_error_cb(struct sk_buff *skb, struct netlink_callback *cb)
  671. {
  672. struct iwpm_nlmsg_request *nlmsg_request = NULL;
  673. int nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type);
  674. struct nlattr *nltb[IWPM_NLA_ERR_MAX];
  675. u32 msg_seq;
  676. u16 err_code;
  677. const char *msg_type = "Mapping Error Msg";
  678. if (iwpm_parse_nlmsg(cb, IWPM_NLA_ERR_MAX,
  679. map_error_policy, nltb, msg_type))
  680. return -EINVAL;
  681. msg_seq = nla_get_u32(nltb[IWPM_NLA_ERR_SEQ]);
  682. err_code = nla_get_u16(nltb[IWPM_NLA_ERR_CODE]);
  683. pr_info("%s: Received msg seq = %u err code = %u client = %d\n",
  684. __func__, msg_seq, err_code, nl_client);
  685. /* look for nlmsg_request */
  686. nlmsg_request = iwpm_find_nlmsg_request(msg_seq);
  687. if (!nlmsg_request) {
  688. /* not all errors have associated requests */
  689. pr_debug("Could not find matching req (seq = %u)\n", msg_seq);
  690. return 0;
  691. }
  692. atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
  693. nlmsg_request->err_code = err_code;
  694. nlmsg_request->request_done = 1;
  695. /* always for found request */
  696. kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
  697. barrier();
  698. wake_up(&nlmsg_request->waitq);
  699. return 0;
  700. }
  701. EXPORT_SYMBOL(iwpm_mapping_error_cb);