ieee80211_alq.c revision 220908
1220908Sadrian/*-
2220908Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Lty Ltd
3220908Sadrian * All rights reserved.
4220908Sadrian *
5220908Sadrian * Redistribution and use in source and binary forms, with or without
6220908Sadrian * modification, are permitted provided that the following conditions
7220908Sadrian * are met:
8220908Sadrian * 1. Redistributions of source code must retain the above copyright
9220908Sadrian *    notice, this list of conditions and the following disclaimer.
10220908Sadrian * 2. Redistributions in binary form must reproduce the above copyright
11220908Sadrian *    notice, this list of conditions and the following disclaimer in the
12220908Sadrian *    documentation and/or other materials provided with the distribution.
13220908Sadrian *
14220908Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15220908Sadrian * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16220908Sadrian * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17220908Sadrian * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18220908Sadrian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19220908Sadrian * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20220908Sadrian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21220908Sadrian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22220908Sadrian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23220908Sadrian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24220908Sadrian */
25220908Sadrian
26220908Sadrian#include <sys/cdefs.h>
27220908Sadrian#ifdef __FreeBSD__
28220908Sadrian__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_alq.c 220908 2011-04-21 03:59:37Z adrian $");
29220908Sadrian#endif
30220908Sadrian
31220908Sadrian/*
32220908Sadrian * net80211 fast-logging support, primarily for debugging.
33220908Sadrian *
34220908Sadrian * This implements a single debugging queue which includes
35220908Sadrian * per-device enumeration where needed.
36220908Sadrian */
37220908Sadrian
38220908Sadrian#include "opt_wlan.h"
39220908Sadrian
40220908Sadrian#include <sys/param.h>
41220908Sadrian#include <sys/systm.h>
42220908Sadrian#include <sys/mbuf.h>
43220908Sadrian#include <sys/malloc.h>
44220908Sadrian#include <sys/endian.h>
45220908Sadrian#include <sys/kernel.h>
46220908Sadrian#include <sys/sysctl.h>
47220908Sadrian#include <sys/pcpu.h>
48220908Sadrian#include <sys/proc.h>
49220908Sadrian#include <sys/ucred.h>
50220908Sadrian#include <sys/alq.h>
51220908Sadrian
52220908Sadrian#include <sys/socket.h>
53220908Sadrian
54220908Sadrian#include <net/if.h>
55220908Sadrian#include <net/if_var.h>
56220908Sadrian#include <net/if_dl.h>
57220908Sadrian#include <net/if_clone.h>
58220908Sadrian#include <net/if_media.h>
59220908Sadrian#include <net/if_types.h>
60220908Sadrian
61220908Sadrian#include <net80211/ieee80211_var.h>
62220908Sadrian#include <net80211/ieee80211_freebsd.h>
63220908Sadrian#include <net80211/ieee80211_alq.h>
64220908Sadrian
65220908Sadrianstatic struct alq *ieee80211_alq;
66220908Sadrianstatic int ieee80211_alq_lost;
67220908Sadrianstatic char ieee80211_alq_logfile[MAXPATHLEN] = "/tmp/net80211.log";
68220908Sadrianstatic unsigned int ieee80211_alq_qsize = 64*1024;
69220908Sadrian
70220908Sadrianstatic int
71220908Sadrianieee80211_alq_setlogging(int enable)
72220908Sadrian{
73220908Sadrian	int error;
74220908Sadrian
75220908Sadrian	if (enable) {
76220908Sadrian		if (ieee80211_alq)
77220908Sadrian			alq_close(ieee80211_alq);
78220908Sadrian
79220908Sadrian		error = alq_open(&ieee80211_alq,
80220908Sadrian		    ieee80211_alq_logfile,
81220908Sadrian		    curthread->td_ucred,
82220908Sadrian		    ALQ_DEFAULT_CMODE,
83220908Sadrian		    sizeof (struct ieee80211_alq_rec),
84220908Sadrian		    ieee80211_alq_qsize);
85220908Sadrian		ieee80211_alq_lost = 0;
86220908Sadrian		printf("net80211: logging to %s enabled\n", ieee80211_alq_logfile);
87220908Sadrian	} else {
88220908Sadrian		if (ieee80211_alq)
89220908Sadrian			alq_close(ieee80211_alq);
90220908Sadrian		ieee80211_alq = NULL;
91220908Sadrian		printf("net80211: logging disabled\n");
92220908Sadrian		error = 0;
93220908Sadrian	}
94220908Sadrian	return (error);
95220908Sadrian}
96220908Sadrian
97220908Sadrianstatic int
98220908Sadriansysctl_ieee80211_alq_log(SYSCTL_HANDLER_ARGS)
99220908Sadrian{
100220908Sadrian        int error, enable;
101220908Sadrian
102220908Sadrian        enable = (ieee80211_alq != NULL);
103220908Sadrian        error = sysctl_handle_int(oidp, &enable, 0, req);
104220908Sadrian        if (error || !req->newptr)
105220908Sadrian                return (error);
106220908Sadrian        else
107220908Sadrian                return (ieee80211_alq_setlogging(enable));
108220908Sadrian}
109220908Sadrian
110220908SadrianSYSCTL_PROC(_net_wlan, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
111220908Sadrian	0, 0, sysctl_ieee80211_alq_log, "I", "Enable net80211 alq logging");
112220908SadrianSYSCTL_INT(_net_wlan, OID_AUTO, alq_size, CTLFLAG_RW,
113220908Sadrian	&ieee80211_alq_qsize, 0, "In-memory log size (#records)");
114220908SadrianSYSCTL_INT(_net_wlan, OID_AUTO, alq_lost, CTLFLAG_RW,
115220908Sadrian	&ieee80211_alq_lost, 0, "Debugging operations not logged");
116220908Sadrian
117220908Sadrianstatic struct ale *
118220908Sadrianieee80211_alq_get(void)
119220908Sadrian{
120220908Sadrian	struct ale *ale;
121220908Sadrian
122220908Sadrian	ale = alq_get(ieee80211_alq, ALQ_NOWAIT);
123220908Sadrian	if (!ale)
124220908Sadrian		ieee80211_alq_lost++;
125220908Sadrian	return ale;
126220908Sadrian}
127220908Sadrian
128220908Sadrianvoid
129220908Sadrianieee80211_alq_log(struct ieee80211vap *vap, uint8_t op, u_char *p, int l)
130220908Sadrian{
131220908Sadrian	struct ale *ale;
132220908Sadrian	struct ieee80211_alq_rec *r;
133220908Sadrian
134220908Sadrian	ale = ieee80211_alq_get();
135220908Sadrian	if (! ale)
136220908Sadrian		return;
137220908Sadrian
138220908Sadrian	r = (struct ieee80211_alq_rec *) ale;
139220908Sadrian	r->r_timestamp = ticks;
140220908Sadrian	r->r_version = 1;
141220908Sadrian	r->r_wlan = vap->iv_ifp->if_dunit;
142220908Sadrian	r->r_op = op;
143220908Sadrian	memcpy(&r->r_payload, p, MIN(l, sizeof(r->r_payload)));
144220908Sadrian}
145