root/include/net/iw_handler.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. wireless_nlevent_flush
  2. iwe_stream_lcp_len
  3. iwe_stream_point_len
  4. iwe_stream_event_len_adjust
  5. iwe_stream_add_event_check
  6. iwe_stream_add_point_check

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /*
   3  * This file define the new driver API for Wireless Extensions
   4  *
   5  * Version :    8       16.3.07
   6  *
   7  * Authors :    Jean Tourrilhes - HPL - <jt@hpl.hp.com>
   8  * Copyright (c) 2001-2007 Jean Tourrilhes, All Rights Reserved.
   9  */
  10 
  11 #ifndef _IW_HANDLER_H
  12 #define _IW_HANDLER_H
  13 
  14 /************************** DOCUMENTATION **************************/
  15 /*
  16  * Initial driver API (1996 -> onward) :
  17  * -----------------------------------
  18  * The initial API just sends the IOCTL request received from user space
  19  * to the driver (via the driver ioctl handler). The driver has to
  20  * handle all the rest...
  21  *
  22  * The initial API also defines a specific handler in struct net_device
  23  * to handle wireless statistics.
  24  *
  25  * The initial APIs served us well and has proven a reasonably good design.
  26  * However, there is a few shortcommings :
  27  *      o No events, everything is a request to the driver.
  28  *      o Large ioctl function in driver with gigantic switch statement
  29  *        (i.e. spaghetti code).
  30  *      o Driver has to mess up with copy_to/from_user, and in many cases
  31  *        does it unproperly. Common mistakes are :
  32  *              * buffer overflows (no checks or off by one checks)
  33  *              * call copy_to/from_user with irq disabled
  34  *      o The user space interface is tied to ioctl because of the use
  35  *        copy_to/from_user.
  36  *
  37  * New driver API (2002 -> onward) :
  38  * -------------------------------
  39  * The new driver API is just a bunch of standard functions (handlers),
  40  * each handling a specific Wireless Extension. The driver just export
  41  * the list of handler it supports, and those will be called apropriately.
  42  *
  43  * I tried to keep the main advantage of the previous API (simplicity,
  44  * efficiency and light weight), and also I provide a good dose of backward
  45  * compatibility (most structures are the same, driver can use both API
  46  * simultaneously, ...).
  47  * Hopefully, I've also addressed the shortcomming of the initial API.
  48  *
  49  * The advantage of the new API are :
  50  *      o Handling of Extensions in driver broken in small contained functions
  51  *      o Tighter checks of ioctl before calling the driver
  52  *      o Flexible commit strategy (at least, the start of it)
  53  *      o Backward compatibility (can be mixed with old API)
  54  *      o Driver doesn't have to worry about memory and user-space issues
  55  * The last point is important for the following reasons :
  56  *      o You are now able to call the new driver API from any API you
  57  *              want (including from within other parts of the kernel).
  58  *      o Common mistakes are avoided (buffer overflow, user space copy
  59  *              with irq disabled and so on).
  60  *
  61  * The Drawback of the new API are :
  62  *      o bloat (especially kernel)
  63  *      o need to migrate existing drivers to new API
  64  * My initial testing shows that the new API adds around 3kB to the kernel
  65  * and save between 0 and 5kB from a typical driver.
  66  * Also, as all structures and data types are unchanged, the migration is
  67  * quite straightforward (but tedious).
  68  *
  69  * ---
  70  *
  71  * The new driver API is defined below in this file. User space should
  72  * not be aware of what's happening down there...
  73  *
  74  * A new kernel wrapper is in charge of validating the IOCTLs and calling
  75  * the appropriate driver handler. This is implemented in :
  76  *      # net/core/wireless.c
  77  *
  78  * The driver export the list of handlers in :
  79  *      # include/linux/netdevice.h (one place)
  80  *
  81  * The new driver API is available for WIRELESS_EXT >= 13.
  82  * Good luck with migration to the new API ;-)
  83  */
  84 
  85 /* ---------------------- THE IMPLEMENTATION ---------------------- */
  86 /*
  87  * Some of the choice I've made are pretty controversials. Defining an
  88  * API is very much weighting compromises. This goes into some of the
  89  * details and the thinking behind the implementation.
  90  *
  91  * Implementation goals :
  92  * --------------------
  93  * The implementation goals were as follow :
  94  *      o Obvious : you should not need a PhD to understand what's happening,
  95  *              the benefit is easier maintenance.
  96  *      o Flexible : it should accommodate a wide variety of driver
  97  *              implementations and be as flexible as the old API.
  98  *      o Lean : it should be efficient memory wise to minimise the impact
  99  *              on kernel footprint.
 100  *      o Transparent to user space : the large number of user space
 101  *              applications that use Wireless Extensions should not need
 102  *              any modifications.
 103  *
 104  * Array of functions versus Struct of functions
 105  * ---------------------------------------------
 106  * 1) Having an array of functions allow the kernel code to access the
 107  * handler in a single lookup, which is much more efficient (think hash
 108  * table here).
 109  * 2) The only drawback is that driver writer may put their handler in
 110  * the wrong slot. This is trivial to test (I set the frequency, the
 111  * bitrate changes). Once the handler is in the proper slot, it will be
 112  * there forever, because the array is only extended at the end.
 113  * 3) Backward/forward compatibility : adding new handler just require
 114  * extending the array, so you can put newer driver in older kernel
 115  * without having to patch the kernel code (and vice versa).
 116  *
 117  * All handler are of the same generic type
 118  * ----------------------------------------
 119  * That's a feature !!!
 120  * 1) Having a generic handler allow to have generic code, which is more
 121  * efficient. If each of the handler was individually typed I would need
 122  * to add a big switch in the kernel (== more bloat). This solution is
 123  * more scalable, adding new Wireless Extensions doesn't add new code.
 124  * 2) You can use the same handler in different slots of the array. For
 125  * hardware, it may be more efficient or logical to handle multiple
 126  * Wireless Extensions with a single function, and the API allow you to
 127  * do that. (An example would be a single record on the card to control
 128  * both bitrate and frequency, the handler would read the old record,
 129  * modify it according to info->cmd and rewrite it).
 130  *
 131  * Functions prototype uses union iwreq_data
 132  * -----------------------------------------
 133  * Some would have preferred functions defined this way :
 134  *      static int mydriver_ioctl_setrate(struct net_device *dev, 
 135  *                                        long rate, int auto)
 136  * 1) The kernel code doesn't "validate" the content of iwreq_data, and
 137  * can't do it (different hardware may have different notion of what a
 138  * valid frequency is), so we don't pretend that we do it.
 139  * 2) The above form is not extendable. If I want to add a flag (for
 140  * example to distinguish setting max rate and basic rate), I would
 141  * break the prototype. Using iwreq_data is more flexible.
 142  * 3) Also, the above form is not generic (see above).
 143  * 4) I don't expect driver developper using the wrong field of the
 144  * union (Doh !), so static typechecking doesn't add much value.
 145  * 5) Lastly, you can skip the union by doing :
 146  *      static int mydriver_ioctl_setrate(struct net_device *dev,
 147  *                                        struct iw_request_info *info,
 148  *                                        struct iw_param *rrq,
 149  *                                        char *extra)
 150  * And then adding the handler in the array like this :
 151  *        (iw_handler) mydriver_ioctl_setrate,             // SIOCSIWRATE
 152  *
 153  * Using functions and not a registry
 154  * ----------------------------------
 155  * Another implementation option would have been for every instance to
 156  * define a registry (a struct containing all the Wireless Extensions)
 157  * and only have a function to commit the registry to the hardware.
 158  * 1) This approach can be emulated by the current code, but not
 159  * vice versa.
 160  * 2) Some drivers don't keep any configuration in the driver, for them
 161  * adding such a registry would be a significant bloat.
 162  * 3) The code to translate from Wireless Extension to native format is
 163  * needed anyway, so it would not reduce significantely the amount of code.
 164  * 4) The current approach only selectively translate Wireless Extensions
 165  * to native format and only selectively set, whereas the registry approach
 166  * would require to translate all WE and set all parameters for any single
 167  * change.
 168  * 5) For many Wireless Extensions, the GET operation return the current
 169  * dynamic value, not the value that was set.
 170  *
 171  * This header is <net/iw_handler.h>
 172  * ---------------------------------
 173  * 1) This header is kernel space only and should not be exported to
 174  * user space. Headers in "include/linux/" are exported, headers in
 175  * "include/net/" are not.
 176  *
 177  * Mixed 32/64 bit issues
 178  * ----------------------
 179  * The Wireless Extensions are designed to be 64 bit clean, by using only
 180  * datatypes with explicit storage size.
 181  * There are some issues related to kernel and user space using different
 182  * memory model, and in particular 64bit kernel with 32bit user space.
 183  * The problem is related to struct iw_point, that contains a pointer
 184  * that *may* need to be translated.
 185  * This is quite messy. The new API doesn't solve this problem (it can't),
 186  * but is a step in the right direction :
 187  * 1) Meta data about each ioctl is easily available, so we know what type
 188  * of translation is needed.
 189  * 2) The move of data between kernel and user space is only done in a single
 190  * place in the kernel, so adding specific hooks in there is possible.
 191  * 3) In the long term, it allows to move away from using ioctl as the
 192  * user space API.
 193  *
 194  * So many comments and so few code
 195  * --------------------------------
 196  * That's a feature. Comments won't bloat the resulting kernel binary.
 197  */
 198 
 199 /***************************** INCLUDES *****************************/
 200 
 201 #include <linux/wireless.h>             /* IOCTL user space API */
 202 #include <linux/if_ether.h>
 203 
 204 /***************************** VERSION *****************************/
 205 /*
 206  * This constant is used to know which version of the driver API is
 207  * available. Hopefully, this will be pretty stable and no changes
 208  * will be needed...
 209  * I just plan to increment with each new version.
 210  */
 211 #define IW_HANDLER_VERSION      8
 212 
 213 /*
 214  * Changes :
 215  *
 216  * V2 to V3
 217  * --------
 218  *      - Move event definition in <linux/wireless.h>
 219  *      - Add Wireless Event support :
 220  *              o wireless_send_event() prototype
 221  *              o iwe_stream_add_event/point() inline functions
 222  * V3 to V4
 223  * --------
 224  *      - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
 225  *
 226  * V4 to V5
 227  * --------
 228  *      - Add new spy support : struct iw_spy_data & prototypes
 229  *
 230  * V5 to V6
 231  * --------
 232  *      - Change the way we get to spy_data method for added safety
 233  *      - Remove spy #ifdef, they are always on -> cleaner code
 234  *      - Add IW_DESCR_FLAG_NOMAX flag for very large requests
 235  *      - Start migrating get_wireless_stats to struct iw_handler_def
 236  *
 237  * V6 to V7
 238  * --------
 239  *      - Add struct ieee80211_device pointer in struct iw_public_data
 240  *      - Remove (struct iw_point *)->pointer from events and streams
 241  *      - Remove spy_offset from struct iw_handler_def
 242  *      - Add "check" version of event macros for ieee802.11 stack
 243  *
 244  * V7 to V8
 245  * ----------
 246  *      - Prevent leaking of kernel space in stream on 64 bits.
 247  */
 248 
 249 /**************************** CONSTANTS ****************************/
 250 
 251 /* Enhanced spy support available */
 252 #define IW_WIRELESS_SPY
 253 #define IW_WIRELESS_THRSPY
 254 
 255 /* Special error message for the driver to indicate that we
 256  * should do a commit after return from the iw_handler */
 257 #define EIWCOMMIT       EINPROGRESS
 258 
 259 /* Flags available in struct iw_request_info */
 260 #define IW_REQUEST_FLAG_COMPAT  0x0001  /* Compat ioctl call */
 261 
 262 /* Type of headers we know about (basically union iwreq_data) */
 263 #define IW_HEADER_TYPE_NULL     0       /* Not available */
 264 #define IW_HEADER_TYPE_CHAR     2       /* char [IFNAMSIZ] */
 265 #define IW_HEADER_TYPE_UINT     4       /* __u32 */
 266 #define IW_HEADER_TYPE_FREQ     5       /* struct iw_freq */
 267 #define IW_HEADER_TYPE_ADDR     6       /* struct sockaddr */
 268 #define IW_HEADER_TYPE_POINT    8       /* struct iw_point */
 269 #define IW_HEADER_TYPE_PARAM    9       /* struct iw_param */
 270 #define IW_HEADER_TYPE_QUAL     10      /* struct iw_quality */
 271 
 272 /* Handling flags */
 273 /* Most are not implemented. I just use them as a reminder of some
 274  * cool features we might need one day ;-) */
 275 #define IW_DESCR_FLAG_NONE      0x0000  /* Obvious */
 276 /* Wrapper level flags */
 277 #define IW_DESCR_FLAG_DUMP      0x0001  /* Not part of the dump command */
 278 #define IW_DESCR_FLAG_EVENT     0x0002  /* Generate an event on SET */
 279 #define IW_DESCR_FLAG_RESTRICT  0x0004  /* GET : request is ROOT only */
 280                                 /* SET : Omit payload from generated iwevent */
 281 #define IW_DESCR_FLAG_NOMAX     0x0008  /* GET : no limit on request size */
 282 /* Driver level flags */
 283 #define IW_DESCR_FLAG_WAIT      0x0100  /* Wait for driver event */
 284 
 285 /****************************** TYPES ******************************/
 286 
 287 /* ----------------------- WIRELESS HANDLER ----------------------- */
 288 /*
 289  * A wireless handler is just a standard function, that looks like the
 290  * ioctl handler.
 291  * We also define there how a handler list look like... As the Wireless
 292  * Extension space is quite dense, we use a simple array, which is faster
 293  * (that's the perfect hash table ;-).
 294  */
 295 
 296 /*
 297  * Meta data about the request passed to the iw_handler.
 298  * Most handlers can safely ignore what's in there.
 299  * The 'cmd' field might come handy if you want to use the same handler
 300  * for multiple command...
 301  * This struct is also my long term insurance. I can add new fields here
 302  * without breaking the prototype of iw_handler...
 303  */
 304 struct iw_request_info {
 305         __u16           cmd;            /* Wireless Extension command */
 306         __u16           flags;          /* More to come ;-) */
 307 };
 308 
 309 struct net_device;
 310 
 311 /*
 312  * This is how a function handling a Wireless Extension should look
 313  * like (both get and set, standard and private).
 314  */
 315 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
 316                           union iwreq_data *wrqu, char *extra);
 317 
 318 /*
 319  * This define all the handler that the driver export.
 320  * As you need only one per driver type, please use a static const
 321  * shared by all driver instances... Same for the members...
 322  * This will be linked from net_device in <linux/netdevice.h>
 323  */
 324 struct iw_handler_def {
 325 
 326         /* Array of handlers for standard ioctls
 327          * We will call dev->wireless_handlers->standard[ioctl - SIOCIWFIRST]
 328          */
 329         const iw_handler *      standard;
 330         /* Number of handlers defined (more precisely, index of the
 331          * last defined handler + 1) */
 332         __u16                   num_standard;
 333 
 334 #ifdef CONFIG_WEXT_PRIV
 335         __u16                   num_private;
 336         /* Number of private arg description */
 337         __u16                   num_private_args;
 338         /* Array of handlers for private ioctls
 339          * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
 340          */
 341         const iw_handler *      private;
 342 
 343         /* Arguments of private handler. This one is just a list, so you
 344          * can put it in any order you want and should not leave holes...
 345          * We will automatically export that to user space... */
 346         const struct iw_priv_args *     private_args;
 347 #endif
 348 
 349         /* New location of get_wireless_stats, to de-bloat struct net_device.
 350          * The old pointer in struct net_device will be gradually phased
 351          * out, and drivers are encouraged to use this one... */
 352         struct iw_statistics*   (*get_wireless_stats)(struct net_device *dev);
 353 };
 354 
 355 /* ---------------------- IOCTL DESCRIPTION ---------------------- */
 356 /*
 357  * One of the main goal of the new interface is to deal entirely with
 358  * user space/kernel space memory move.
 359  * For that, we need to know :
 360  *      o if iwreq is a pointer or contain the full data
 361  *      o what is the size of the data to copy
 362  *
 363  * For private IOCTLs, we use the same rules as used by iwpriv and
 364  * defined in struct iw_priv_args.
 365  *
 366  * For standard IOCTLs, things are quite different and we need to
 367  * use the structures below. Actually, this struct is also more
 368  * efficient, but that's another story...
 369  */
 370 
 371 /*
 372  * Describe how a standard IOCTL looks like.
 373  */
 374 struct iw_ioctl_description {
 375         __u8    header_type;            /* NULL, iw_point or other */
 376         __u8    token_type;             /* Future */
 377         __u16   token_size;             /* Granularity of payload */
 378         __u16   min_tokens;             /* Min acceptable token number */
 379         __u16   max_tokens;             /* Max acceptable token number */
 380         __u32   flags;                  /* Special handling of the request */
 381 };
 382 
 383 /* Need to think of short header translation table. Later. */
 384 
 385 /* --------------------- ENHANCED SPY SUPPORT --------------------- */
 386 /*
 387  * In the old days, the driver was handling spy support all by itself.
 388  * Now, the driver can delegate this task to Wireless Extensions.
 389  * It needs to include this struct in its private part and use the
 390  * standard spy iw_handler.
 391  */
 392 
 393 /*
 394  * Instance specific spy data, i.e. addresses spied and quality for them.
 395  */
 396 struct iw_spy_data {
 397         /* --- Standard spy support --- */
 398         int                     spy_number;
 399         u_char                  spy_address[IW_MAX_SPY][ETH_ALEN];
 400         struct iw_quality       spy_stat[IW_MAX_SPY];
 401         /* --- Enhanced spy support (event) */
 402         struct iw_quality       spy_thr_low;    /* Low threshold */
 403         struct iw_quality       spy_thr_high;   /* High threshold */
 404         u_char                  spy_thr_under[IW_MAX_SPY];
 405 };
 406 
 407 /* --------------------- DEVICE WIRELESS DATA --------------------- */
 408 /*
 409  * This is all the wireless data specific to a device instance that
 410  * is managed by the core of Wireless Extensions or the 802.11 layer.
 411  * We only keep pointer to those structures, so that a driver is free
 412  * to share them between instances.
 413  * This structure should be initialised before registering the device.
 414  * Access to this data follow the same rules as any other struct net_device
 415  * data (i.e. valid as long as struct net_device exist, same locking rules).
 416  */
 417 /* Forward declaration */
 418 struct libipw_device;
 419 /* The struct */
 420 struct iw_public_data {
 421         /* Driver enhanced spy support */
 422         struct iw_spy_data *            spy_data;
 423         /* Legacy structure managed by the ipw2x00-specific IEEE 802.11 layer */
 424         struct libipw_device *          libipw;
 425 };
 426 
 427 /**************************** PROTOTYPES ****************************/
 428 /*
 429  * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
 430  * Those may be called only within the kernel.
 431  */
 432 
 433 /* First : function strictly used inside the kernel */
 434 
 435 /* Handle /proc/net/wireless, called in net/code/dev.c */
 436 int dev_get_wireless_info(char *buffer, char **start, off_t offset, int length);
 437 
 438 /* Second : functions that may be called by driver modules */
 439 
 440 /* Send a single event to user space */
 441 void wireless_send_event(struct net_device *dev, unsigned int cmd,
 442                          union iwreq_data *wrqu, const char *extra);
 443 #ifdef CONFIG_WEXT_CORE
 444 /* flush all previous wext events - if work is done from netdev notifiers */
 445 void wireless_nlevent_flush(void);
 446 #else
 447 static inline void wireless_nlevent_flush(void) {}
 448 #endif
 449 
 450 /* We may need a function to send a stream of events to user space.
 451  * More on that later... */
 452 
 453 /* Standard handler for SIOCSIWSPY */
 454 int iw_handler_set_spy(struct net_device *dev, struct iw_request_info *info,
 455                        union iwreq_data *wrqu, char *extra);
 456 /* Standard handler for SIOCGIWSPY */
 457 int iw_handler_get_spy(struct net_device *dev, struct iw_request_info *info,
 458                        union iwreq_data *wrqu, char *extra);
 459 /* Standard handler for SIOCSIWTHRSPY */
 460 int iw_handler_set_thrspy(struct net_device *dev, struct iw_request_info *info,
 461                           union iwreq_data *wrqu, char *extra);
 462 /* Standard handler for SIOCGIWTHRSPY */
 463 int iw_handler_get_thrspy(struct net_device *dev, struct iw_request_info *info,
 464                           union iwreq_data *wrqu, char *extra);
 465 /* Driver call to update spy records */
 466 void wireless_spy_update(struct net_device *dev, unsigned char *address,
 467                          struct iw_quality *wstats);
 468 
 469 /************************* INLINE FUNTIONS *************************/
 470 /*
 471  * Function that are so simple that it's more efficient inlining them
 472  */
 473 
 474 static inline int iwe_stream_lcp_len(struct iw_request_info *info)
 475 {
 476 #ifdef CONFIG_COMPAT
 477         if (info->flags & IW_REQUEST_FLAG_COMPAT)
 478                 return IW_EV_COMPAT_LCP_LEN;
 479 #endif
 480         return IW_EV_LCP_LEN;
 481 }
 482 
 483 static inline int iwe_stream_point_len(struct iw_request_info *info)
 484 {
 485 #ifdef CONFIG_COMPAT
 486         if (info->flags & IW_REQUEST_FLAG_COMPAT)
 487                 return IW_EV_COMPAT_POINT_LEN;
 488 #endif
 489         return IW_EV_POINT_LEN;
 490 }
 491 
 492 static inline int iwe_stream_event_len_adjust(struct iw_request_info *info,
 493                                               int event_len)
 494 {
 495 #ifdef CONFIG_COMPAT
 496         if (info->flags & IW_REQUEST_FLAG_COMPAT) {
 497                 event_len -= IW_EV_LCP_LEN;
 498                 event_len += IW_EV_COMPAT_LCP_LEN;
 499         }
 500 #endif
 501 
 502         return event_len;
 503 }
 504 
 505 /*------------------------------------------------------------------*/
 506 /*
 507  * Wrapper to add an Wireless Event to a stream of events.
 508  */
 509 char *iwe_stream_add_event(struct iw_request_info *info, char *stream,
 510                            char *ends, struct iw_event *iwe, int event_len);
 511 
 512 static inline char *
 513 iwe_stream_add_event_check(struct iw_request_info *info, char *stream,
 514                            char *ends, struct iw_event *iwe, int event_len)
 515 {
 516         char *res = iwe_stream_add_event(info, stream, ends, iwe, event_len);
 517 
 518         if (res == stream)
 519                 return ERR_PTR(-E2BIG);
 520         return res;
 521 }
 522 
 523 /*------------------------------------------------------------------*/
 524 /*
 525  * Wrapper to add an short Wireless Event containing a pointer to a
 526  * stream of events.
 527  */
 528 char *iwe_stream_add_point(struct iw_request_info *info, char *stream,
 529                            char *ends, struct iw_event *iwe, char *extra);
 530 
 531 static inline char *
 532 iwe_stream_add_point_check(struct iw_request_info *info, char *stream,
 533                            char *ends, struct iw_event *iwe, char *extra)
 534 {
 535         char *res = iwe_stream_add_point(info, stream, ends, iwe, extra);
 536 
 537         if (res == stream)
 538                 return ERR_PTR(-E2BIG);
 539         return res;
 540 }
 541 
 542 /*------------------------------------------------------------------*/
 543 /*
 544  * Wrapper to add a value to a Wireless Event in a stream of events.
 545  * Be careful, this one is tricky to use properly :
 546  * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
 547  */
 548 char *iwe_stream_add_value(struct iw_request_info *info, char *event,
 549                            char *value, char *ends, struct iw_event *iwe,
 550                            int event_len);
 551 
 552 #endif  /* _IW_HANDLER_H */

/* [<][>][^][v][top][bottom][index][help] */