op-msg.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * Linux WiMAX
  3. * Generic messaging interface between userspace and driver/device
  4. *
  5. *
  6. * Copyright (C) 2007-2008 Intel Corporation <linux-wimax@intel.com>
  7. * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License version
  11. * 2 as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301, USA.
  22. *
  23. *
  24. * This implements a direct communication channel between user space and
  25. * the driver/device, by which free form messages can be sent back and
  26. * forth.
  27. *
  28. * This is intended for device-specific features, vendor quirks, etc.
  29. *
  30. * See include/net/wimax.h
  31. *
  32. * GENERIC NETLINK ENCODING AND CAPACITY
  33. *
  34. * A destination "pipe name" is added to each message; it is up to the
  35. * drivers to assign or use those names (if using them at all).
  36. *
  37. * Messages are encoded as a binary netlink attribute using nla_put()
  38. * using type NLA_UNSPEC (as some versions of libnl still in
  39. * deployment don't yet understand NLA_BINARY).
  40. *
  41. * The maximum capacity of this transport is PAGESIZE per message (so
  42. * the actual payload will be bit smaller depending on the
  43. * netlink/generic netlink attributes and headers).
  44. *
  45. * RECEPTION OF MESSAGES
  46. *
  47. * When a message is received from user space, it is passed verbatim
  48. * to the driver calling wimax_dev->op_msg_from_user(). The return
  49. * value from this function is passed back to user space as an ack
  50. * over the generic netlink protocol.
  51. *
  52. * The stack doesn't do any processing or interpretation of these
  53. * messages.
  54. *
  55. * SENDING MESSAGES
  56. *
  57. * Messages can be sent with wimax_msg().
  58. *
  59. * If the message delivery needs to happen on a different context to
  60. * that of its creation, wimax_msg_alloc() can be used to get a
  61. * pointer to the message that can be delivered later on with
  62. * wimax_msg_send().
  63. *
  64. * ROADMAP
  65. *
  66. * wimax_gnl_doit_msg_from_user() Process a message from user space
  67. * wimax_dev_get_by_genl_info()
  68. * wimax_dev->op_msg_from_user() Delivery of message to the driver
  69. *
  70. * wimax_msg() Send a message to user space
  71. * wimax_msg_alloc()
  72. * wimax_msg_send()
  73. */
  74. #include <linux/device.h>
  75. #include <linux/slab.h>
  76. #include <net/genetlink.h>
  77. #include <linux/netdevice.h>
  78. #include <linux/wimax.h>
  79. #include <linux/security.h>
  80. #include "wimax-internal.h"
  81. #define D_SUBMODULE op_msg
  82. #include "debug-levels.h"
  83. /**
  84. * wimax_msg_alloc - Create a new skb for sending a message to userspace
  85. *
  86. * @wimax_dev: WiMAX device descriptor
  87. * @pipe_name: "named pipe" the message will be sent to
  88. * @msg: pointer to the message data to send
  89. * @size: size of the message to send (in bytes), including the header.
  90. * @gfp_flags: flags for memory allocation.
  91. *
  92. * Returns: %0 if ok, negative errno code on error
  93. *
  94. * Description:
  95. *
  96. * Allocates an skb that will contain the message to send to user
  97. * space over the messaging pipe and initializes it, copying the
  98. * payload.
  99. *
  100. * Once this call is done, you can deliver it with
  101. * wimax_msg_send().
  102. *
  103. * IMPORTANT:
  104. *
  105. * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
  106. * wimax_msg_send() depends on skb->data being placed at the
  107. * beginning of the user message.
  108. *
  109. * Unlike other WiMAX stack calls, this call can be used way early,
  110. * even before wimax_dev_add() is called, as long as the
  111. * wimax_dev->net_dev pointer is set to point to a proper
  112. * net_dev. This is so that drivers can use it early in case they need
  113. * to send stuff around or communicate with user space.
  114. */
  115. struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
  116. const char *pipe_name,
  117. const void *msg, size_t size,
  118. gfp_t gfp_flags)
  119. {
  120. int result;
  121. struct device *dev = wimax_dev_to_dev(wimax_dev);
  122. size_t msg_size;
  123. void *genl_msg;
  124. struct sk_buff *skb;
  125. msg_size = nla_total_size(size)
  126. + nla_total_size(sizeof(u32))
  127. + (pipe_name ? nla_total_size(strlen(pipe_name)) : 0);
  128. result = -ENOMEM;
  129. skb = genlmsg_new(msg_size, gfp_flags);
  130. if (skb == NULL)
  131. goto error_new;
  132. genl_msg = genlmsg_put(skb, 0, 0, &wimax_gnl_family,
  133. 0, WIMAX_GNL_OP_MSG_TO_USER);
  134. if (genl_msg == NULL) {
  135. dev_err(dev, "no memory to create generic netlink message\n");
  136. goto error_genlmsg_put;
  137. }
  138. result = nla_put_u32(skb, WIMAX_GNL_MSG_IFIDX,
  139. wimax_dev->net_dev->ifindex);
  140. if (result < 0) {
  141. dev_err(dev, "no memory to add ifindex attribute\n");
  142. goto error_nla_put;
  143. }
  144. if (pipe_name) {
  145. result = nla_put_string(skb, WIMAX_GNL_MSG_PIPE_NAME,
  146. pipe_name);
  147. if (result < 0) {
  148. dev_err(dev, "no memory to add pipe_name attribute\n");
  149. goto error_nla_put;
  150. }
  151. }
  152. result = nla_put(skb, WIMAX_GNL_MSG_DATA, size, msg);
  153. if (result < 0) {
  154. dev_err(dev, "no memory to add payload (msg %p size %zu) in "
  155. "attribute: %d\n", msg, size, result);
  156. goto error_nla_put;
  157. }
  158. genlmsg_end(skb, genl_msg);
  159. return skb;
  160. error_nla_put:
  161. error_genlmsg_put:
  162. error_new:
  163. nlmsg_free(skb);
  164. return ERR_PTR(result);
  165. }
  166. EXPORT_SYMBOL_GPL(wimax_msg_alloc);
  167. /**
  168. * wimax_msg_data_len - Return a pointer and size of a message's payload
  169. *
  170. * @msg: Pointer to a message created with wimax_msg_alloc()
  171. * @size: Pointer to where to store the message's size
  172. *
  173. * Returns the pointer to the message data.
  174. */
  175. const void *wimax_msg_data_len(struct sk_buff *msg, size_t *size)
  176. {
  177. struct nlmsghdr *nlh = (void *) msg->head;
  178. struct nlattr *nla;
  179. nla = nlmsg_find_attr(nlh, sizeof(struct genlmsghdr),
  180. WIMAX_GNL_MSG_DATA);
  181. if (nla == NULL) {
  182. printk(KERN_ERR "Cannot find attribute WIMAX_GNL_MSG_DATA\n");
  183. return NULL;
  184. }
  185. *size = nla_len(nla);
  186. return nla_data(nla);
  187. }
  188. EXPORT_SYMBOL_GPL(wimax_msg_data_len);
  189. /**
  190. * wimax_msg_data - Return a pointer to a message's payload
  191. *
  192. * @msg: Pointer to a message created with wimax_msg_alloc()
  193. */
  194. const void *wimax_msg_data(struct sk_buff *msg)
  195. {
  196. struct nlmsghdr *nlh = (void *) msg->head;
  197. struct nlattr *nla;
  198. nla = nlmsg_find_attr(nlh, sizeof(struct genlmsghdr),
  199. WIMAX_GNL_MSG_DATA);
  200. if (nla == NULL) {
  201. printk(KERN_ERR "Cannot find attribute WIMAX_GNL_MSG_DATA\n");
  202. return NULL;
  203. }
  204. return nla_data(nla);
  205. }
  206. EXPORT_SYMBOL_GPL(wimax_msg_data);
  207. /**
  208. * wimax_msg_len - Return a message's payload length
  209. *
  210. * @msg: Pointer to a message created with wimax_msg_alloc()
  211. */
  212. ssize_t wimax_msg_len(struct sk_buff *msg)
  213. {
  214. struct nlmsghdr *nlh = (void *) msg->head;
  215. struct nlattr *nla;
  216. nla = nlmsg_find_attr(nlh, sizeof(struct genlmsghdr),
  217. WIMAX_GNL_MSG_DATA);
  218. if (nla == NULL) {
  219. printk(KERN_ERR "Cannot find attribute WIMAX_GNL_MSG_DATA\n");
  220. return -EINVAL;
  221. }
  222. return nla_len(nla);
  223. }
  224. EXPORT_SYMBOL_GPL(wimax_msg_len);
  225. /**
  226. * wimax_msg_send - Send a pre-allocated message to user space
  227. *
  228. * @wimax_dev: WiMAX device descriptor
  229. *
  230. * @skb: &struct sk_buff returned by wimax_msg_alloc(). Note the
  231. * ownership of @skb is transferred to this function.
  232. *
  233. * Returns: 0 if ok, < 0 errno code on error
  234. *
  235. * Description:
  236. *
  237. * Sends a free-form message that was preallocated with
  238. * wimax_msg_alloc() and filled up.
  239. *
  240. * Assumes that once you pass an skb to this function for sending, it
  241. * owns it and will release it when done (on success).
  242. *
  243. * IMPORTANT:
  244. *
  245. * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
  246. * wimax_msg_send() depends on skb->data being placed at the
  247. * beginning of the user message.
  248. *
  249. * Unlike other WiMAX stack calls, this call can be used way early,
  250. * even before wimax_dev_add() is called, as long as the
  251. * wimax_dev->net_dev pointer is set to point to a proper
  252. * net_dev. This is so that drivers can use it early in case they need
  253. * to send stuff around or communicate with user space.
  254. */
  255. int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb)
  256. {
  257. struct device *dev = wimax_dev_to_dev(wimax_dev);
  258. void *msg = skb->data;
  259. size_t size = skb->len;
  260. might_sleep();
  261. d_printf(1, dev, "CTX: wimax msg, %zu bytes\n", size);
  262. d_dump(2, dev, msg, size);
  263. genlmsg_multicast(skb, 0, wimax_gnl_mcg.id, GFP_KERNEL);
  264. d_printf(1, dev, "CTX: genl multicast done\n");
  265. return 0;
  266. }
  267. EXPORT_SYMBOL_GPL(wimax_msg_send);
  268. /**
  269. * wimax_msg - Send a message to user space
  270. *
  271. * @wimax_dev: WiMAX device descriptor (properly referenced)
  272. * @pipe_name: "named pipe" the message will be sent to
  273. * @buf: pointer to the message to send.
  274. * @size: size of the buffer pointed to by @buf (in bytes).
  275. * @gfp_flags: flags for memory allocation.
  276. *
  277. * Returns: %0 if ok, negative errno code on error.
  278. *
  279. * Description:
  280. *
  281. * Sends a free-form message to user space on the device @wimax_dev.
  282. *
  283. * NOTES:
  284. *
  285. * Once the @skb is given to this function, who will own it and will
  286. * release it when done (unless it returns error).
  287. */
  288. int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name,
  289. const void *buf, size_t size, gfp_t gfp_flags)
  290. {
  291. int result = -ENOMEM;
  292. struct sk_buff *skb;
  293. skb = wimax_msg_alloc(wimax_dev, pipe_name, buf, size, gfp_flags);
  294. if (IS_ERR(skb))
  295. result = PTR_ERR(skb);
  296. else
  297. result = wimax_msg_send(wimax_dev, skb);
  298. return result;
  299. }
  300. EXPORT_SYMBOL_GPL(wimax_msg);
  301. static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
  302. [WIMAX_GNL_MSG_IFIDX] = {
  303. .type = NLA_U32,
  304. },
  305. [WIMAX_GNL_MSG_DATA] = {
  306. .type = NLA_UNSPEC, /* libnl doesn't grok BINARY yet */
  307. },
  308. };
  309. /*
  310. * Relays a message from user space to the driver
  311. *
  312. * The skb is passed to the driver-specific function with the netlink
  313. * and generic netlink headers already stripped.
  314. *
  315. * This call will block while handling/relaying the message.
  316. */
  317. static
  318. int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info)
  319. {
  320. int result, ifindex;
  321. struct wimax_dev *wimax_dev;
  322. struct device *dev;
  323. struct nlmsghdr *nlh = info->nlhdr;
  324. char *pipe_name;
  325. void *msg_buf;
  326. size_t msg_len;
  327. might_sleep();
  328. d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info);
  329. result = -ENODEV;
  330. if (info->attrs[WIMAX_GNL_MSG_IFIDX] == NULL) {
  331. printk(KERN_ERR "WIMAX_GNL_MSG_FROM_USER: can't find IFIDX "
  332. "attribute\n");
  333. goto error_no_wimax_dev;
  334. }
  335. ifindex = nla_get_u32(info->attrs[WIMAX_GNL_MSG_IFIDX]);
  336. wimax_dev = wimax_dev_get_by_genl_info(info, ifindex);
  337. if (wimax_dev == NULL)
  338. goto error_no_wimax_dev;
  339. dev = wimax_dev_to_dev(wimax_dev);
  340. /* Unpack arguments */
  341. result = -EINVAL;
  342. if (info->attrs[WIMAX_GNL_MSG_DATA] == NULL) {
  343. dev_err(dev, "WIMAX_GNL_MSG_FROM_USER: can't find MSG_DATA "
  344. "attribute\n");
  345. goto error_no_data;
  346. }
  347. msg_buf = nla_data(info->attrs[WIMAX_GNL_MSG_DATA]);
  348. msg_len = nla_len(info->attrs[WIMAX_GNL_MSG_DATA]);
  349. if (info->attrs[WIMAX_GNL_MSG_PIPE_NAME] == NULL)
  350. pipe_name = NULL;
  351. else {
  352. struct nlattr *attr = info->attrs[WIMAX_GNL_MSG_PIPE_NAME];
  353. size_t attr_len = nla_len(attr);
  354. /* libnl-1.1 does not yet support NLA_NUL_STRING */
  355. result = -ENOMEM;
  356. pipe_name = kstrndup(nla_data(attr), attr_len + 1, GFP_KERNEL);
  357. if (pipe_name == NULL)
  358. goto error_alloc;
  359. pipe_name[attr_len] = 0;
  360. }
  361. mutex_lock(&wimax_dev->mutex);
  362. result = wimax_dev_is_ready(wimax_dev);
  363. if (result == -ENOMEDIUM)
  364. result = 0;
  365. if (result < 0)
  366. goto error_not_ready;
  367. result = -ENOSYS;
  368. if (wimax_dev->op_msg_from_user == NULL)
  369. goto error_noop;
  370. d_printf(1, dev,
  371. "CRX: nlmsghdr len %u type %u flags 0x%04x seq 0x%x pid %u\n",
  372. nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags,
  373. nlh->nlmsg_seq, nlh->nlmsg_pid);
  374. d_printf(1, dev, "CRX: wimax message %zu bytes\n", msg_len);
  375. d_dump(2, dev, msg_buf, msg_len);
  376. result = wimax_dev->op_msg_from_user(wimax_dev, pipe_name,
  377. msg_buf, msg_len, info);
  378. error_noop:
  379. error_not_ready:
  380. mutex_unlock(&wimax_dev->mutex);
  381. error_alloc:
  382. kfree(pipe_name);
  383. error_no_data:
  384. dev_put(wimax_dev->net_dev);
  385. error_no_wimax_dev:
  386. d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
  387. return result;
  388. }
  389. /*
  390. * Generic Netlink glue
  391. */
  392. struct genl_ops wimax_gnl_msg_from_user = {
  393. .cmd = WIMAX_GNL_OP_MSG_FROM_USER,
  394. .flags = GENL_ADMIN_PERM,
  395. .policy = wimax_gnl_msg_policy,
  396. .doit = wimax_gnl_doit_msg_from_user,
  397. .dumpit = NULL,
  398. };