Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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