summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-07-18 20:19:53 +0000
committersam <sam@FreeBSD.org>2009-07-18 20:19:53 +0000
commitc70ad2698e22375c9f47db2c3e6a5ee7f3fc937c (patch)
tree8baf10048cb5037506a7d77ca47bebe123dc1343 /sys
parent630d769cdb32ec5f2d2fd6e11a19a5328c322a45 (diff)
downloadFreeBSD-src-c70ad2698e22375c9f47db2c3e6a5ee7f3fc937c.zip
FreeBSD-src-c70ad2698e22375c9f47db2c3e6a5ee7f3fc937c.tar.gz
Move code that does payload realigment to a new routine, ieee80211_realign,
so it can be reused. While here rewrite the logic to always use a single mbuf. Reviewed by: rpaulo Approved by: re (kib)
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_freebsd.c38
-rw-r--r--sys/net80211/ieee80211_input.c50
-rw-r--r--sys/net80211/ieee80211_input.h1
-rw-r--r--sys/net80211/ieee80211_ioctl.h3
4 files changed, 44 insertions, 48 deletions
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index ee3022f..51a86fd 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_input.h>
SYSCTL_NODE(_net, OID_AUTO, wlan, CTLFLAG_RD, 0, "IEEE 80211 parameters");
@@ -408,6 +409,43 @@ ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen)
return m;
}
+/*
+ * Re-align the payload in the mbuf. This is mainly used (right now)
+ * to handle IP header alignment requirements on certain architectures.
+ */
+struct mbuf *
+ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align)
+{
+ int pktlen, space;
+ struct mbuf *n;
+
+ pktlen = m->m_pkthdr.len;
+ space = pktlen + align;
+ if (space < MINCLSIZE)
+ n = m_gethdr(M_DONTWAIT, MT_DATA);
+ else {
+ n = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
+ space <= MCLBYTES ? MCLBYTES :
+#if MJUMPAGESIZE != MCLBYTES
+ space <= MJUMPAGESIZE ? MJUMPAGESIZE :
+#endif
+ space <= MJUM9BYTES ? MJUM9BYTES : MJUM16BYTES);
+ }
+ if (__predict_true(n != NULL)) {
+ m_move_pkthdr(n, m);
+ n->m_data = (caddr_t)(ALIGN(n->m_data + align) - align);
+ m_copydata(m, 0, pktlen, mtod(n, caddr_t));
+ n->m_len = pktlen;
+ } else {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
+ mtod(m, const struct ieee80211_frame *), NULL,
+ "%s", "no mbuf to realign");
+ vap->iv_stats.is_rx_badalign++;
+ }
+ m_freem(m);
+ return n;
+}
+
int
ieee80211_add_callback(struct mbuf *m,
void (*func)(struct ieee80211_node *, void *, int), void *arg)
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 8209d2e..b2b6368 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -285,53 +285,9 @@ ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen)
}
#ifdef ALIGNED_POINTER
if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) {
- struct mbuf *n, *n0, **np;
- caddr_t newdata;
- int off, pktlen;
-
- n0 = NULL;
- np = &n0;
- off = 0;
- pktlen = m->m_pkthdr.len;
- while (pktlen > off) {
- if (n0 == NULL) {
- MGETHDR(n, M_DONTWAIT, MT_DATA);
- if (n == NULL) {
- m_freem(m);
- return NULL;
- }
- M_MOVE_PKTHDR(n, m);
- n->m_len = MHLEN;
- } else {
- MGET(n, M_DONTWAIT, MT_DATA);
- if (n == NULL) {
- m_freem(m);
- m_freem(n0);
- return NULL;
- }
- n->m_len = MLEN;
- }
- if (pktlen - off >= MINCLSIZE) {
- MCLGET(n, M_DONTWAIT);
- if (n->m_flags & M_EXT)
- n->m_len = n->m_ext.ext_size;
- }
- if (n0 == NULL) {
- newdata =
- (caddr_t)ALIGN(n->m_data + sizeof(*eh)) -
- sizeof(*eh);
- n->m_len -= newdata - n->m_data;
- n->m_data = newdata;
- }
- if (n->m_len > pktlen - off)
- n->m_len = pktlen - off;
- m_copydata(m, off, n->m_len, mtod(n, caddr_t));
- off += n->m_len;
- *np = n;
- np = &n->m_next;
- }
- m_freem(m);
- m = n0;
+ m = ieee80211_realign(vap, m, sizeof(*eh));
+ if (m == NULL)
+ return NULL;
}
#endif /* ALIGNED_POINTER */
if (llc != NULL) {
diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h
index f19b934..5b38ddd 100644
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -146,6 +146,7 @@ void ieee80211_deliver_data(struct ieee80211vap *,
struct ieee80211_node *, struct mbuf *);
struct mbuf *ieee80211_defrag(struct ieee80211_node *,
struct mbuf *, int);
+struct mbuf *ieee80211_realign(struct ieee80211vap *, struct mbuf *, size_t);
struct mbuf *ieee80211_decap(struct ieee80211vap *, struct mbuf *, int);
struct mbuf *ieee80211_decap1(struct mbuf *, int *);
int ieee80211_setup_rates(struct ieee80211_node *ni,
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index 723d3da..8105990 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -235,8 +235,9 @@ struct ieee80211_stats {
uint32_t is_hwmp_wrongseq; /* wrong hwmp seq no. */
uint32_t is_hwmp_rootreqs; /* root PREQs sent */
uint32_t is_hwmp_rootrann; /* root RANNs sent */
+ uint32_t is_rx_badalign; /* dropped 'cuz misaligned */
- uint32_t is_spare[16];
+ uint32_t is_spare[15];
};
/*
OpenPOWER on IntegriCloud