[net80211] extend the net80211 ALQ code to support variable payloads.

Also - allow driver specific bits to be added, rather than just net80211.

This still isn't as useful as it should be by default; it needs to
be a standalone struct/instance so it can be done before net80211
registration occurs, and it can log per-device items.

But, it's getting there.
This commit is contained in:
adrian 2016-11-06 19:18:25 +00:00
parent d8cd94b6be
commit 9976c35c3e
2 changed files with 50 additions and 25 deletions

View File

@ -79,14 +79,13 @@ ieee80211_alq_setlogging(int enable)
ieee80211_alq_logfile,
curthread->td_ucred,
ALQ_DEFAULT_CMODE,
sizeof (struct ieee80211_alq_rec),
ieee80211_alq_qsize);
ieee80211_alq_qsize, 0);
ieee80211_alq_lost = 0;
ieee80211_alq_logged = 0;
printf("net80211: logging to %s enabled; "
"struct size %d bytes\n",
ieee80211_alq_logfile,
sizeof(struct ieee80211_alq_rec));
(int) sizeof(struct ieee80211_alq_rec));
} else {
if (ieee80211_alq)
alq_close(ieee80211_alq);
@ -113,18 +112,19 @@ sysctl_ieee80211_alq_log(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_net_wlan, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
0, 0, sysctl_ieee80211_alq_log, "I", "Enable net80211 alq logging");
SYSCTL_INT(_net_wlan, OID_AUTO, alq_size, CTLFLAG_RW,
&ieee80211_alq_qsize, 0, "In-memory log size (#records)");
&ieee80211_alq_qsize, 0, "In-memory log size (bytes)");
SYSCTL_INT(_net_wlan, OID_AUTO, alq_lost, CTLFLAG_RW,
&ieee80211_alq_lost, 0, "Debugging operations not logged");
SYSCTL_INT(_net_wlan, OID_AUTO, alq_logged, CTLFLAG_RW,
&ieee80211_alq_logged, 0, "Debugging operations logged");
static struct ale *
ieee80211_alq_get(void)
ieee80211_alq_get(size_t len)
{
struct ale *ale;
ale = alq_get(ieee80211_alq, ALQ_NOWAIT);
ale = alq_getn(ieee80211_alq, len + sizeof(struct ieee80211_alq_rec),
ALQ_NOWAIT);
if (!ale)
ieee80211_alq_lost++;
else
@ -132,25 +132,44 @@ ieee80211_alq_get(void)
return ale;
}
void
ieee80211_alq_log(struct ieee80211vap *vap, uint8_t op, u_char *p, int l)
int
ieee80211_alq_log(struct ieee80211com *ic, struct ieee80211vap *vap,
uint32_t op, uint32_t flags, uint16_t srcid, const uint8_t *src,
size_t len)
{
struct ale *ale;
struct ieee80211_alq_rec *r;
char *dst;
/* Don't log if we're disabled */
if (ieee80211_alq == NULL)
return;
return (0);
ale = ieee80211_alq_get();
if (len > IEEE80211_ALQ_MAX_PAYLOAD)
return (ENOMEM);
ale = ieee80211_alq_get(len);
if (! ale)
return;
return (ENOMEM);
r = (struct ieee80211_alq_rec *) ale->ae_data;
r->r_timestamp = htonl(ticks);
r->r_version = 1;
r->r_wlan = htons(vap->iv_ifp->if_dunit);
r->r_op = op;
r->r_threadid = htonl((uint32_t) curthread->td_tid);
memcpy(&r->r_payload, p, MIN(l, sizeof(r->r_payload)));
dst = ((char *) r) + sizeof(struct ieee80211_alq_rec);
r->r_timestamp = htobe64(ticks);
if (vap != NULL) {
r->r_wlan = htobe16(vap->iv_ifp->if_dunit);
} else {
r->r_wlan = 0xffff;
}
r->r_src = htobe16(srcid);
r->r_flags = htobe32(flags);
r->r_op = htobe32(op);
r->r_len = htobe32(len + sizeof(struct ieee80211_alq_rec));
r->r_threadid = htobe32((uint32_t) curthread->td_tid);
if (src != NULL)
memcpy(dst, src, len);
alq_post(ieee80211_alq, ale);
return (0);
}

View File

@ -27,7 +27,7 @@
#ifndef __IEEE80211_ALQ_H__
#define __IEEE80211_ALQ_H__
#define IEEE80211_ALQ_PAYLOAD_SIZE 24
#define IEEE80211_ALQ_MAX_PAYLOAD 1024
/*
* timestamp
@ -36,18 +36,24 @@
* sub-operation
* rest of structure - operation specific
*/
#define IEEE80211_ALQ_SRC_NET80211 0x0001
/* Drivers define their own numbers above 0xff */
struct ieee80211_alq_rec {
uint32_t r_timestamp; /* XXX may wrap! */
uint64_t r_timestamp; /* XXX may wrap! */
uint32_t r_threadid; /* current thread id */
uint16_t r_wlan; /* wlan interface number */
uint8_t r_version; /* version */
uint8_t r_op; /* top-level operation id */
u_char r_payload[IEEE80211_ALQ_PAYLOAD_SIZE];
/* operation-specific payload */
uint16_t r_src; /* source - driver, net80211 */
uint32_t r_flags; /* flags */
uint32_t r_op; /* top-level operation id */
uint32_t r_len; /* length of hdr + payload */
/* Operation payload follows here */
};
/* General logging function */
extern void ieee80211_alq_log(struct ieee80211vap *vap, uint8_t op,
u_char *p, int l);
extern int ieee80211_alq_log(struct ieee80211com *ic,
struct ieee80211vap *vap, uint32_t op, uint32_t flags,
uint16_t srcid, const uint8_t *src, size_t len);
#endif /* __IEEE80211_ALQ_H__ */