2 * wprobe.h: API for the wireless probe interface
3 * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
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.
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.
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>
31 * enum wprobe_attr: netlink attribute list
33 * @WPROBE_ATTR_UNSPEC: unused
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)
40 * @WPROBE_ATTR_ID: attribute id (NLA_U32)
41 * @WPROBE_ATTR_NAME: attribute name (NLA_STRING)
42 * @WPROBE_ATTR_TYPE: attribute type (NLA_U8)
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)
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
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)
69 * @WPROBE_ATTR_LAST: unused
72 /* query attributes */
74 WPROBE_ATTR_INTERFACE,
84 /* value type attributes */
95 /* aggregates for statistics */
99 WPROBE_VAL_SCALE_TIME,
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,
109 WPROBE_ATTR_FILTER_GROUP,
118 * enum wprobe_cmd: netlink commands for interacting with wprobe
120 * @WPROBE_CMD_UNSPEC: unused
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
130 * @WPROBE_CMD_LAST: unused
132 * options for GET_INFO and SET_FLAGS:
133 * - mac address set: per-link
134 * - mac address unset: globalsa
140 WPROBE_CMD_SET_FLAGS,
142 WPROBE_CMD_GET_LINKS,
144 WPROBE_CMD_GET_FILTER,
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
155 WPROBE_F_KEEPSTAT = (1 << 0),
156 WPROBE_F_RESET = (1 << 1),
157 WPROBE_F_NEWDATA = (1 << 2),
164 struct wprobe_source;
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
174 * @list: for internal use
175 * @val: for internal use
178 struct list_head list;
179 struct wprobe_iface *iface;
183 struct wprobe_value *val;
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)
194 enum wprobe_attr type;
198 struct wprobe_value {
202 * the following are kept uppercase to allow
203 * for automated checking against WPROBE_VAL_*
224 struct wprobe_filter_item_hdr {
227 } __attribute__((packed));
229 struct wprobe_filter_item {
230 struct wprobe_filter_item_hdr hdr;
231 struct sock_filter filter[];
232 } __attribute__((packed));
234 struct wprobe_filter_counter {
239 struct wprobe_filter_group {
242 struct wprobe_filter_item **items;
243 struct wprobe_filter_counter *counters;
246 struct wprobe_filter_hdr {
251 } __attribute__((packed));
253 struct wprobe_filter {
259 struct wprobe_filter_item **items;
260 struct wprobe_filter_counter *counters;
261 struct wprobe_filter_group groups[];
265 WPROBE_PKT_RX = 0x00,
266 WPROBE_PKT_TX = 0x10,
269 struct wprobe_wlan_hdr {
273 } __attribute__((packed));
277 * struct wprobe_source - data structure describing a wireless interface
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
288 * @list: head for the list of interfaces
289 * @priv: user pointer
290 * @lock: spinlock protecting value data access
292 * @query_val: internal use
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
298 struct wprobe_iface {
299 /* to be filled in by wprobe source drivers */
302 const struct wprobe_item *link_items;
304 const struct wprobe_item *global_items;
307 int (*sync_data)(struct wprobe_iface *dev, struct wprobe_link *l,
308 struct wprobe_value *val, bool measure);
311 /* handled by the wprobe core */
312 struct list_head list;
313 struct list_head links;
315 struct wprobe_value *val;
316 struct wprobe_value *query_val;
317 struct wprobe_filter *active_filter;
319 u32 measure_interval;
320 struct timer_list measure_timer;
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)
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__); \
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
345 #define WPROBE_FILL_END() \
349 * wprobe_add_iface: register an interface with the wireless probe subsystem
350 * @dev: wprobe_iface structure describing the interface
352 extern int __weak wprobe_add_iface(struct wprobe_iface *dev);
355 * wprobe_remove_iface: deregister an interface from the wireless probe subsystem
356 * @dev: wprobe_iface structure describing the interface
358 extern void __weak wprobe_remove_iface(struct wprobe_iface *dev);
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
366 * the entire wprobe_link structure is overwritten by this function call
368 extern int __weak wprobe_add_link(struct wprobe_iface *dev, struct wprobe_link *l, const char *addr);
371 * wprobe_remove_link: deregister a previously registered wireless link
372 * @dev: wprobe_iface structure describing the interface
373 * @l: wprobe_link data structure
375 extern void __weak wprobe_remove_link(struct wprobe_iface *dev, struct wprobe_link *l);
378 * wprobe_update_stats: update statistics after sampling values
379 * @dev: wprobe_iface structure describing the interface
380 * @l: wprobe_link data structure
382 * if l == NULL, then the stats for globals are updated
384 extern void __weak wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l);
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
393 extern int __weak wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len);
395 #endif /* __KERNEL__ */