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 82 83#define D_SUBMODULE op_msg 84#include "debug-levels.h" 85 86 87/** 88 * wimax_msg_alloc - Create a new skb for sending a message to userspace 89 * 90 * @wimax_dev: WiMAX device descriptor 91 * @pipe_name: "named pipe" the message will be sent to 92 * @msg: pointer to the message data to send 93 * @size: size of the message to send (in bytes), including the header. 94 * @gfp_flags: flags for memory allocation. 95 * 96 * Returns: %0 if ok, negative errno code on error 97 * 98 * Description: 99 * 100 * Allocates an skb that will contain the message to send to user 101 * space over the messaging pipe and initializes it, copying the 102 * payload. 103 * 104 * Once this call is done, you can deliver it with 105 * wimax_msg_send(). 106 * 107 * IMPORTANT: 108 * 109 * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as 110 * wimax_msg_send() depends on skb->data being placed at the 111 * beginning of the user message. 112 * 113 * Unlike other WiMAX stack calls, this call can be used way early, 114 * even before wimax_dev_add() is called, as long as the 115 * wimax_dev->net_dev pointer is set to point to a proper 116 * net_dev. This is so that drivers can use it early in case they need 117 * to send stuff around or communicate with user space. 118 */ 119struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev, 120 const char *pipe_name, 121 const void *msg, size_t size, 122 gfp_t gfp_flags) 123{ 124 int result; 125 struct device *dev = wimax_dev_to_dev(wimax_dev); 126 size_t msg_size; 127 void *genl_msg; 128 struct sk_buff *skb; 129 130 msg_size = nla_total_size(size) 131 + nla_total_size(sizeof(u32)) 132 + (pipe_name ? nla_total_size(strlen(pipe_name)) : 0); 133 result = -ENOMEM; 134 skb = genlmsg_new(msg_size, gfp_flags); 135 if (skb == NULL) 136 goto error_new; 137 genl_msg = genlmsg_put(skb, 0, 0, &wimax_gnl_family, 138 0, WIMAX_GNL_OP_MSG_TO_USER); 139 if (genl_msg == NULL) { 140 dev_err(dev, "no memory to create generic netlink message\n"); 141 goto error_genlmsg_put; 142 } 143 result = nla_put_u32(skb, WIMAX_GNL_MSG_IFIDX, 144 wimax_dev->net_dev->ifindex); 145 if (result < 0) { 146 dev_err(dev, "no memory to add ifindex attribute\n"); 147 goto error_nla_put; 148 } 149 if (pipe_name) { 150 result = nla_put_string(skb, WIMAX_GNL_MSG_PIPE_NAME, 151 pipe_name); 152 if (result < 0) { 153 dev_err(dev, "no memory to add pipe_name attribute\n"); 154 goto error_nla_put; 155 } 156 } 157 result = nla_put(skb, WIMAX_GNL_MSG_DATA, size, msg); 158 if (result < 0) { 159 dev_err(dev, "no memory to add payload (msg %p size %zu) in " 160 "attribute: %d\n", msg, size, result); 161 goto error_nla_put; 162 } 163 genlmsg_end(skb, genl_msg); 164 return skb; 165 166error_nla_put: 167error_genlmsg_put: 168error_new: 169 nlmsg_free(skb); 170 return ERR_PTR(result); 171} 172EXPORT_SYMBOL_GPL(wimax_msg_alloc); 173 174 175/** 176 * wimax_msg_data_len - Return a pointer and size of a message's payload 177 * 178 * @msg: Pointer to a message created with wimax_msg_alloc() 179 * @size: Pointer to where to store the message's size 180 * 181 * Returns the pointer to the message data. 182 */ 183const void *wimax_msg_data_len(struct sk_buff *msg, size_t *size) 184{ 185 struct nlmsghdr *nlh = (void *) msg->head; 186 struct nlattr *nla; 187 188 nla = nlmsg_find_attr(nlh, sizeof(struct genlmsghdr), 189 WIMAX_GNL_MSG_DATA); 190 if (nla == NULL) { 191 printk(KERN_ERR "Cannot find attribute WIMAX_GNL_MSG_DATA\n"); 192 return NULL; 193 } 194 *size = nla_len(nla); 195 return nla_data(nla); 196} 197EXPORT_SYMBOL_GPL(wimax_msg_data_len); 198 199 200/** 201 * wimax_msg_data - Return a pointer to a message's payload 202 * 203 * @msg: Pointer to a message created with wimax_msg_alloc() 204 */ 205const void *wimax_msg_data(struct sk_buff *msg) 206{ 207 struct nlmsghdr *nlh = (void *) msg->head; 208 struct nlattr *nla; 209 210 nla = nlmsg_find_attr(nlh, sizeof(struct genlmsghdr), 211 WIMAX_GNL_MSG_DATA); 212 if (nla == NULL) { 213 printk(KERN_ERR "Cannot find attribute WIMAX_GNL_MSG_DATA\n"); 214 return NULL; 215 } 216 return nla_data(nla); 217} 218EXPORT_SYMBOL_GPL(wimax_msg_data); 219 220 221/** 222 * wimax_msg_len - Return a message's payload length 223 * 224 * @msg: Pointer to a message created with wimax_msg_alloc() 225 */ 226ssize_t wimax_msg_len(struct sk_buff *msg) 227{ 228 struct nlmsghdr *nlh = (void *) msg->head; 229 struct nlattr *nla; 230 231 nla = nlmsg_find_attr(nlh, sizeof(struct genlmsghdr), 232 WIMAX_GNL_MSG_DATA); 233 if (nla == NULL) { 234 printk(KERN_ERR "Cannot find attribute WIMAX_GNL_MSG_DATA\n"); 235 return -EINVAL; 236 } 237 return nla_len(nla); 238} 239EXPORT_SYMBOL_GPL(wimax_msg_len); 240 241 242/** 243 * wimax_msg_send - Send a pre-allocated message to user space 244 * 245 * @wimax_dev: WiMAX device descriptor 246 * 247 * @skb: &struct sk_buff returned by wimax_msg_alloc(). Note the 248 * ownership of @skb is transferred to this function. 249 * 250 * Returns: 0 if ok, < 0 errno code on error 251 * 252 * Description: 253 * 254 * Sends a free-form message that was preallocated with 255 * wimax_msg_alloc() and filled up. 256 * 257 * Assumes that once you pass an skb to this function for sending, it 258 * owns it and will release it when done (on success). 259 * 260 * IMPORTANT: 261 * 262 * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as 263 * wimax_msg_send() depends on skb->data being placed at the 264 * beginning of the user message. 265 * 266 * Unlike other WiMAX stack calls, this call can be used way early, 267 * even before wimax_dev_add() is called, as long as the 268 * wimax_dev->net_dev pointer is set to point to a proper 269 * net_dev. This is so that drivers can use it early in case they need 270 * to send stuff around or communicate with user space. 271 */ 272int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb) 273{ 274 struct device *dev = wimax_dev_to_dev(wimax_dev); 275 void *msg = skb->data; 276 size_t size = skb->len; 277 might_sleep(); 278 279 d_printf(1, dev, "CTX: wimax msg, %zu bytes\n", size); 280 d_dump(2, dev, msg, size); 281 genlmsg_multicast(skb, 0, wimax_gnl_mcg.id, GFP_KERNEL); 282 d_printf(1, dev, "CTX: genl multicast done\n"); 283 return 0; 284} 285EXPORT_SYMBOL_GPL(wimax_msg_send); 286 287 288/** 289 * wimax_msg - Send a message to user space 290 * 291 * @wimax_dev: WiMAX device descriptor (properly referenced) 292 * @pipe_name: "named pipe" the message will be sent to 293 * @buf: pointer to the message to send. 294 * @size: size of the buffer pointed to by @buf (in bytes). 295 * @gfp_flags: flags for memory allocation. 296 * 297 * Returns: %0 if ok, negative errno code on error. 298 * 299 * Description: 300 * 301 * Sends a free-form message to user space on the device @wimax_dev. 302 * 303 * NOTES: 304 * 305 * Once the @skb is given to this function, who will own it and will 306 * release it when done (unless it returns error). 307 */ 308int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name, 309 const void *buf, size_t size, gfp_t gfp_flags) 310{ 311 int result = -ENOMEM; 312 struct sk_buff *skb; 313 314 skb = wimax_msg_alloc(wimax_dev, pipe_name, buf, size, gfp_flags); 315 if (IS_ERR(skb)) 316 result = PTR_ERR(skb); 317 else 318 result = wimax_msg_send(wimax_dev, skb); 319 return result; 320} 321EXPORT_SYMBOL_GPL(wimax_msg); 322 323 324static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = { 325 [WIMAX_GNL_MSG_IFIDX] = { 326 .type = NLA_U32, 327 }, 328 [WIMAX_GNL_MSG_DATA] = { 329 .type = NLA_UNSPEC, /* libnl doesn't grok BINARY yet */ 330 }, 331}; 332 333 334/* 335 * Relays a message from user space to the driver 336 * 337 * The skb is passed to the driver-specific function with the netlink 338 * and generic netlink headers already stripped. 339 * 340 * This call will block while handling/relaying the message. 341 */ 342static 343int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info) 344{ 345 int result, ifindex; 346 struct wimax_dev *wimax_dev; 347 struct device *dev; 348 struct nlmsghdr *nlh = info->nlhdr; 349 char *pipe_name; 350 void *msg_buf; 351 size_t msg_len; 352 353 might_sleep(); 354 d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info); 355 result = -ENODEV; 356 if (info->attrs[WIMAX_GNL_MSG_IFIDX] == NULL) { 357 printk(KERN_ERR "WIMAX_GNL_MSG_FROM_USER: can't find IFIDX " 358 "attribute\n"); 359 goto error_no_wimax_dev; 360 } 361 ifindex = nla_get_u32(info->attrs[WIMAX_GNL_MSG_IFIDX]); 362 wimax_dev = wimax_dev_get_by_genl_info(info, ifindex); 363 if (wimax_dev == NULL) 364 goto error_no_wimax_dev; 365 dev = wimax_dev_to_dev(wimax_dev); 366 367 /* Unpack arguments */ 368 result = -EINVAL; 369 if (info->attrs[WIMAX_GNL_MSG_DATA] == NULL) { 370 dev_err(dev, "WIMAX_GNL_MSG_FROM_USER: can't find MSG_DATA " 371 "attribute\n"); 372 goto error_no_data; 373 } 374 msg_buf = nla_data(info->attrs[WIMAX_GNL_MSG_DATA]); 375 msg_len = nla_len(info->attrs[WIMAX_GNL_MSG_DATA]); 376 377 if (info->attrs[WIMAX_GNL_MSG_PIPE_NAME] == NULL) 378 pipe_name = NULL; 379 else { 380 struct nlattr *attr = info->attrs[WIMAX_GNL_MSG_PIPE_NAME]; 381 size_t attr_len = nla_len(attr); 382 /* libnl-1.1 does not yet support NLA_NUL_STRING */ 383 result = -ENOMEM; 384 pipe_name = kstrndup(nla_data(attr), attr_len + 1, GFP_KERNEL); 385 if (pipe_name == NULL) 386 goto error_alloc; 387 pipe_name[attr_len] = 0; 388 } 389 mutex_lock(&wimax_dev->mutex); 390 result = wimax_dev_is_ready(wimax_dev); 391 if (result == -ENOMEDIUM) 392 result = 0; 393 if (result < 0) 394 goto error_not_ready; 395 result = -ENOSYS; 396 if (wimax_dev->op_msg_from_user == NULL) 397 goto error_noop; 398 399 d_printf(1, dev, 400 "CRX: nlmsghdr len %u type %u flags 0x%04x seq 0x%x pid %u\n", 401 nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags, 402 nlh->nlmsg_seq, nlh->nlmsg_pid); 403 d_printf(1, dev, "CRX: wimax message %zu bytes\n", msg_len); 404 d_dump(2, dev, msg_buf, msg_len); 405 406 result = wimax_dev->op_msg_from_user(wimax_dev, pipe_name, 407 msg_buf, msg_len, info); 408error_noop: 409error_not_ready: 410 mutex_unlock(&wimax_dev->mutex); 411error_alloc: 412 kfree(pipe_name); 413error_no_data: 414 dev_put(wimax_dev->net_dev); 415error_no_wimax_dev: 416 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result); 417 return result; 418} 419 420 421/* 422 * Generic Netlink glue 423 */ 424 425struct genl_ops wimax_gnl_msg_from_user = { 426 .cmd = WIMAX_GNL_OP_MSG_FROM_USER, 427 .flags = GENL_ADMIN_PERM, 428 .policy = wimax_gnl_msg_policy, 429 .doit = wimax_gnl_doit_msg_from_user, 430 .dumpit = NULL, 431}; 432