build: create pkginfo dir earlier to avoid build breakage
[openwrt.git] / package / wprobe / src / kernel / linux / wprobe.h
1 /*
2  * wprobe.h: API for the wireless probe interface
3  * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #ifndef __WPROBE_H
17 #define __WPROBE_H
18
19 #ifdef __KERNEL__
20 #include <linux/types.h>
21 #include <linux/if_ether.h>
22 #include <linux/spinlock.h>
23 #include <linux/module.h>
24 #include <linux/list.h>
25 #include <linux/timer.h>
26 #include <linux/filter.h>
27 #include <net/genetlink.h>
28 #endif
29
30 /** 
31  * enum wprobe_attr: netlink attribute list
32  *
33  * @WPROBE_ATTR_UNSPEC: unused
34  *
35  * @WPROBE_ATTR_INTERFACE: interface name to process query on (NLA_STRING)
36  * @WPROBE_ATTR_MAC: mac address (used for wireless links) (NLA_STRING)
37  * @WPROBE_ATTR_FLAGS: interface/link/attribute flags (see enum wprobe_flags) (NLA_U32)a
38  * @WPROBE_ATTR_DURATION: sampling duration (in milliseconds) (NLA_MSECS) 
39  *
40  * @WPROBE_ATTR_ID: attribute id (NLA_U32)
41  * @WPROBE_ATTR_NAME: attribute name (NLA_STRING)
42  * @WPROBE_ATTR_TYPE: attribute type (NLA_U8)
43  *
44  * attribute values:
45  *
46  * @WPROBE_VAL_STRING: string value (NLA_STRING)
47  * @WPROBE_VAL_S8: signed 8-bit integer (NLA_U8)
48  * @WPROBE_VAL_S16: signed 16-bit integer (NLA_U16)
49  * @WPROBE_VAL_S32: signed 32-bit integer (NLA_U32)
50  * @WPROBE_VAL_S64: signed 64-bit integer (NLA_U64)
51  * @WPROBE_VAL_U8: unsigned 8-bit integer (NLA_U8)
52  * @WPROBE_VAL_U16: unsigned 16-bit integer (NLA_U16)
53  * @WPROBE_VAL_U32: unsigned 32-bit integer (NLA_U32)
54  * @WPROBE_VAL_U64: unsigned 64-bit integer (NLA_U64)
55  *
56  * statistics:
57  * @WPROBE_VAL_SUM: sum of all samples
58  * @WPROBE_VAL_SUM_SQ: sum of all samples^2
59  * @WPROBE_VAL_SAMPLES: number of samples
60  * @WPROBE_VAL_SCALE_TIME: last time the samples were scaled down
61  *
62  * configuration:
63  * @WPROBE_ATTR_INTERVAL: (measurement interval in milliseconds) (NLA_MSECS)
64  * @WPROBE_ATTR_SAMPLES_MIN: minimum samples to keep during inactivity (NLA_U32)
65  * @WPROBE_ATTR_SAMPLES_MAX: maximum samples to keep before scaling down (NLA_U32)
66  * @WPROBE_ATTR_SAMPLES_SCALE_M: multiplier for scaling down samples (NLA_U32)
67  * @WPROBE_ATTR_SAMPLES_SCALE_D: divisor for scaling down samples (NLA_U32)
68  *
69  * @WPROBE_ATTR_LAST: unused
70  */
71 enum wprobe_attr {
72         /* query attributes */
73         WPROBE_ATTR_UNSPEC,
74         WPROBE_ATTR_INTERFACE,
75         WPROBE_ATTR_MAC,
76         WPROBE_ATTR_FLAGS,
77
78         /* response data */
79         WPROBE_ATTR_ID,
80         WPROBE_ATTR_NAME,
81         WPROBE_ATTR_TYPE,
82         WPROBE_ATTR_DURATION,
83
84         /* value type attributes */
85         WPROBE_VAL_STRING,
86         WPROBE_VAL_S8,
87         WPROBE_VAL_S16,
88         WPROBE_VAL_S32,
89         WPROBE_VAL_S64,
90         WPROBE_VAL_U8,
91         WPROBE_VAL_U16,
92         WPROBE_VAL_U32,
93         WPROBE_VAL_U64,
94
95         /* aggregates for statistics */
96         WPROBE_VAL_SUM,
97         WPROBE_VAL_SUM_SQ,
98         WPROBE_VAL_SAMPLES,
99         WPROBE_VAL_SCALE_TIME,
100
101         /* config attributes */
102         WPROBE_ATTR_INTERVAL,
103         WPROBE_ATTR_SAMPLES_MIN,
104         WPROBE_ATTR_SAMPLES_MAX,
105         WPROBE_ATTR_SAMPLES_SCALE_M,
106         WPROBE_ATTR_SAMPLES_SCALE_D,
107         WPROBE_ATTR_FILTER,
108
109         WPROBE_ATTR_FILTER_GROUP,
110         WPROBE_ATTR_RXCOUNT,
111         WPROBE_ATTR_TXCOUNT,
112
113         WPROBE_ATTR_LAST
114 };
115
116
117 /**
118  * enum wprobe_cmd: netlink commands for interacting with wprobe
119  *
120  * @WPROBE_CMD_UNSPEC: unused
121  *
122  * @WPROBE_CMD_GET_LIST: get global/link property list
123  * @WPROBE_CMD_GET_INFO: get global/link properties
124  * @WPROBE_CMD_SET_FLAGS: set global/link flags
125  * @WPROBE_CMD_MEASURE: take a snapshot of the current data
126  * @WPROBE_CMD_GET_LINKS: get a list of links
127  * @WPROBE_CMD_CONFIG: set config options
128  * @WPROBE_CMD_GET_FILTER: get counters for active filters
129  *
130  * @WPROBE_CMD_LAST: unused
131  * 
132  * options for GET_INFO and SET_FLAGS:
133  *   - mac address set: per-link
134  *   - mac address unset: globalsa
135  */
136 enum wprobe_cmd {
137         WPROBE_CMD_UNSPEC,
138         WPROBE_CMD_GET_LIST,
139         WPROBE_CMD_GET_INFO,
140         WPROBE_CMD_SET_FLAGS,
141         WPROBE_CMD_MEASURE,
142         WPROBE_CMD_GET_LINKS,
143         WPROBE_CMD_CONFIG,
144         WPROBE_CMD_GET_FILTER,
145         WPROBE_CMD_LAST
146 };
147
148 /**
149  * enum wprobe_flags: flags for wprobe links and items
150  * @WPROBE_F_KEEPSTAT: keep statistics for this link/device
151  * @WPROBE_F_RESET: reset statistics now
152  * @WPROBE_F_NEWDATA: used to indicate that a value has been updated
153  */
154 enum wprobe_flags {
155         WPROBE_F_KEEPSTAT = (1 << 0),
156         WPROBE_F_RESET = (1 << 1),
157         WPROBE_F_NEWDATA = (1 << 2),
158 };
159
160 #ifdef __KERNEL__
161
162 struct wprobe_link;
163 struct wprobe_item;
164 struct wprobe_source;
165 struct wprobe_value;
166
167 /**
168  * struct wprobe_link - data structure describing a wireless link
169  * @iface: pointer to the wprobe_iface that this link belongs to
170  * @addr: BSSID of the remote link partner
171  * @flags: link flags (see wprobe_flags)
172  * @priv: user pointer
173  *
174  * @list: for internal use
175  * @val: for internal use
176  */
177 struct wprobe_link {
178         struct list_head list;
179         struct wprobe_iface *iface;
180         char addr[ETH_ALEN];
181         u32 flags;
182         void *priv;
183         struct wprobe_value *val;
184 };
185
186 /** 
187  * struct wprobe_item - data structure describing the format of wprobe_link::data or wprobe_iface::data
188  * @name: name of the field
189  * @type: data type of this field
190  * @flags: measurement item flags (see wprobe_flags)
191  */
192 struct wprobe_item {
193         const char *name;
194         enum wprobe_attr type;
195         u32 flags;
196 };
197
198 struct wprobe_value {
199         bool pending;
200         union {
201                 /*
202                  * the following are kept uppercase to allow
203                  * for automated checking against WPROBE_VAL_*
204                  * via BUG_ON()
205                  */
206                 const char *STRING;
207                 u8 U8;
208                 u16 U16;
209                 u32 U32;
210                 u64 U64;
211                 s8 S8;
212                 s16 S16;
213                 s32 S32;
214                 s64 S64;
215         };
216         s64 s, ss;
217         unsigned int n;
218
219         /* timestamps */
220         u64 first, last;
221         u64 scale_timestamp;
222 };
223
224 struct wprobe_filter_item_hdr {
225         char name[32];
226         __be32 n_items;
227 } __attribute__((packed));
228
229 struct wprobe_filter_item {
230         struct wprobe_filter_item_hdr hdr;
231         struct sock_filter filter[];
232 } __attribute__((packed));
233
234 struct wprobe_filter_counter {
235         u64 tx;
236         u64 rx;
237 };
238
239 struct wprobe_filter_group {
240         const char *name;
241         int n_items;
242         struct wprobe_filter_item **items;
243         struct wprobe_filter_counter *counters;
244 };
245
246 struct wprobe_filter_hdr {
247         __u8 magic[4];
248         __u8 version;
249         __u8 hdrlen;
250         __u16 n_groups;
251 } __attribute__((packed));
252
253 struct wprobe_filter {
254         spinlock_t lock;
255         struct sk_buff *skb;
256         void *data;
257         int n_groups;
258         int hdrlen;
259         struct wprobe_filter_item **items;
260         struct wprobe_filter_counter *counters;
261         struct wprobe_filter_group groups[];
262 };
263
264 enum {
265         WPROBE_PKT_RX = 0x00,
266         WPROBE_PKT_TX = 0x10,
267 };
268
269 struct wprobe_wlan_hdr {
270         u16 len;
271         u8 snr;
272         u8 type;
273 } __attribute__((packed));
274
275
276 /**
277  * struct wprobe_source - data structure describing a wireless interface
278  *
279  * @name: name of the interface
280  * @addr: local mac address of the interface
281  * @links: list of wireless links to poll
282  * @link_items: description of the per-link data structure
283  * @n_link_items: number of link description items
284  * @global_items: description of the per-interface data structure
285  * @n_global_items: number of per-interface description items
286  * @sync_data: callback allowing the driver to prepare data for the wprobe poll
287  *
288  * @list: head for the list of interfaces
289  * @priv: user pointer
290  * @lock: spinlock protecting value data access
291  * @val: internal use
292  * @query_val: internal use
293  *
294  * if sync_data is NULL, wprobe assumes that it can access the data structure
295  * at any time (in atomic context). if sync_data returns a negative error code,
296  * the poll request will not be handled for the given link
297  */
298 struct wprobe_iface {
299         /* to be filled in by wprobe source drivers */
300         const char *name;
301         const char *addr;
302         const struct wprobe_item *link_items;
303         int n_link_items;
304         const struct wprobe_item *global_items;
305         int n_global_items;
306
307         int (*sync_data)(struct wprobe_iface *dev, struct wprobe_link *l,
308                          struct wprobe_value *val, bool measure);
309         void *priv;
310
311         /* handled by the wprobe core */
312         struct list_head list;
313         struct list_head links;
314         spinlock_t lock;
315         struct wprobe_value *val;
316         struct wprobe_value *query_val;
317         struct wprobe_filter *active_filter;
318
319         u32 measure_interval;
320         struct timer_list measure_timer;
321
322         u32 scale_min;
323         u32 scale_max;
324         u32 scale_m;
325         u32 scale_d;
326 };
327
328
329 #define WPROBE_FILL_BEGIN(_ptr, _list) do {                     \
330         struct wprobe_value *__val = (_ptr);                    \
331         const struct wprobe_item *__item = _list;               \
332         u64 __msecs = jiffies_to_msecs(jiffies)
333
334 #define WPROBE_SET(_idx, _type, _value)                         \
335         if (__item[_idx].type != WPROBE_VAL_##_type) {          \
336                 printk("ERROR: invalid data type at %s:%d\n", __FILE__, __LINE__); \
337                 break;                                          \
338         }                                                       \
339         __val[_idx].pending = true;                             \
340         __val[_idx]._type = _value;                             \
341         if (!__val[_idx].first)                                 \
342                 __val[_idx].first = __msecs;                    \
343         __val[_idx].first = __msecs
344
345 #define WPROBE_FILL_END()                                       \
346 } while(0)
347
348 /**
349  * wprobe_add_iface: register an interface with the wireless probe subsystem
350  * @dev: wprobe_iface structure describing the interface
351  */
352 extern int __weak wprobe_add_iface(struct wprobe_iface *dev);
353
354 /**
355  * wprobe_remove_iface: deregister an interface from the wireless probe subsystem
356  * @dev: wprobe_iface structure describing the interface
357  */
358 extern void __weak wprobe_remove_iface(struct wprobe_iface *dev);
359
360 /**
361  * wprobe_add_link: register a new wireless link
362  * @dev: wprobe_iface structure describing the interface
363  * @l: storage space for the wprobe_link structure
364  * @addr: mac address of the new link
365  *
366  * the entire wprobe_link structure is overwritten by this function call
367  */
368 extern int __weak wprobe_add_link(struct wprobe_iface *dev, struct wprobe_link *l, const char *addr);
369
370 /**
371  * wprobe_remove_link: deregister a previously registered wireless link
372  * @dev: wprobe_iface structure describing the interface
373  * @l: wprobe_link data structure
374  */
375 extern void __weak wprobe_remove_link(struct wprobe_iface *dev, struct wprobe_link *l);
376
377 /**
378  * wprobe_update_stats: update statistics after sampling values
379  * @dev: wprobe_iface structure describing the interface
380  * @l: wprobe_link data structure
381  *
382  * if l == NULL, then the stats for globals are updated
383  */
384 extern void __weak wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l);
385
386 /**
387  * wprobe_add_frame: add frame for layer 2 analysis
388  * @dev: wprobe_iface structure describing the interface
389  * @hdr: metadata for the frame
390  * @data: 802.11 header pointer
391  * @len: length of the 802.11 header
392  */
393 extern int __weak wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len);
394
395 #endif /* __KERNEL__ */
396
397 #endif