iwpm_msg.c 29 KB

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