PERFORCE change 76728 for review
Sam Leffler
sam at FreeBSD.org
Sun May 8 21:35:00 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=76728
Change 76728 by sam at sam_ebb on 2005/05/09 04:34:28
o more tx fragmentation fixups/cleanups
o fixup ath ie addition logic (not entirely right; more tbd)
Affected files ...
.. //depot/projects/vap/sys/net80211/ieee80211_output.c#10 edit
Differences ...
==== //depot/projects/vap/sys/net80211/ieee80211_output.c#10 (text+ko) ====
@@ -63,7 +63,8 @@
static struct mbuf *ieee80211_encap_fastframe(struct ieee80211vap *vap,
struct mbuf *m1, const struct ether_header *eh1,
struct mbuf *m2, const struct ether_header *eh2);
-static int ieee80211_frag(struct ieee80211vap *, struct mbuf *, int hdrsize);
+static int ieee80211_fragment(struct ieee80211vap *, struct mbuf *,
+ u_int hdrsize, u_int ciphdrsize, u_int mtu);
#ifdef IEEE80211_DEBUG
/*
@@ -833,7 +834,8 @@
}
/* check if xmit fragmentation is required */
txfrag = (m->m_pkthdr.len > vap->iv_fragthreshold &&
- !IEEE80211_IS_MULTICAST(wh->i_addr1));
+ !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+ (m->m_flags & M_FF) == 0); /* NB: don't fragment ff's */
if (key != NULL) {
/*
* IEEE 802.1X: send EAPOL frames always in the clear.
@@ -853,7 +855,8 @@
}
}
}
- if (txfrag && !ieee80211_frag(vap, m, hdrsize))
+ if (txfrag && !ieee80211_fragment(vap, m, hdrsize,
+ key != NULL ? key->wk_cipher->ic_header : 0, vap->iv_fragthreshold))
goto bad;
IEEE80211_NODE_STAT(ni, tx_data);
@@ -997,7 +1000,7 @@
}
/*
- * Fragment the frame according to the vap's threshold.
+ * Fragment the frame according to the specified mtu.
* The size of the 802.11 header (w/o padding) is provided
* so we don't need to recalculate it. We create a new
* mbuf for each fragment and chain it through m_nextpkt;
@@ -1005,22 +1008,24 @@
* packet's mbufs but that significantly more complicated.
*/
static int
-ieee80211_frag(struct ieee80211vap *vap, struct mbuf *m0, int hdrsize)
+ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
+ u_int hdrsize, u_int ciphdrsize, u_int mtu)
{
struct ieee80211_frame *wh, *whf;
struct mbuf *m, *prev, *next;
- u_int fragno, fragsize, off, remainder;
+ u_int totalhdrsize, fragno, fragsize, off, remainder;
wh = mtod(m0, struct ieee80211_frame *);
+ totalhdrsize = hdrsize + ciphdrsize;
fragno = 1;
- off = vap->iv_fragthreshold;
+ off = mtu - totalhdrsize;
remainder = m0->m_pkthdr.len - off;
prev = m0;
KASSERT(prev->m_nextpkt == NULL, ("mbuf already chained?"));
do {
fragsize = remainder;
- if (fragsize > vap->iv_fragthreshold)
- fragsize = vap->iv_fragthreshold;
+ if (fragsize > mtu)
+ fragsize = mtu;
KASSERT(fragsize < MCLBYTES,
("fragment size %u too big!", fragsize));
if (fragsize > MHLEN)
@@ -1029,6 +1034,8 @@
m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m == NULL)
goto bad;
+ /* leave room to prepend any cipher header */
+ M_ALIGN(m, fragsize - ciphdrsize);
/* form the header in the fragment */
whf = mtod(m, struct ieee80211_frame *);
@@ -1040,10 +1047,11 @@
/* NB: destination is known to be contiguous */
/* XXX? datapad? */
- m_copydata(m0, off, fragsize - hdrsize,
+ m_copydata(m0, off, fragsize - totalhdrsize,
mtod(m, u_int8_t *) + hdrsize);
- m->m_len = fragsize;
- m->m_pkthdr.len = fragsize;
+ m->m_len = fragsize - ciphdrsize;
+ m->m_pkthdr.len = fragsize - ciphdrsize;
+ m->m_flags |= M_FRAG;
/* chain up the fragment */
prev->m_nextpkt = m;
@@ -1052,12 +1060,13 @@
prev = m;
/* deduct fragment just formed */
- remainder -= fragsize;
- off += fragsize;
+ remainder -= fragsize - totalhdrsize;
+ off += fragsize - totalhdrsize;
} while (remainder != 0);
/* strip first mbuf now that everything has been copied */
- m_adj(m0, m0->m_pkthdr.len - vap->iv_fragthreshold);
+ m_adj(m0, m0->m_pkthdr.len - mtu);
+ m0->m_flags |= M_FIRSTFRAG | M_FRAG;
return 1;
bad:
/* reclaim fragments but leave original frame for caller to free */
@@ -1417,11 +1426,12 @@
.ath_defkeyix = { 0x7f, 0xff, },
};
struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm;
+ struct ieee80211vap *vap = ni->ni_vap;
memcpy(frm, &info, sizeof(info));
- if (ni->ni_flags & IEEE80211_NODE_FF)
+ if (IEEE80211_ATH_CAP(vap, ni, FF))
ath->ath_capability |= ATHEROS_CAP_FAST_FRAME;
- if (ni->ni_flags & IEEE80211_NODE_TURBOP)
+ if (IEEE80211_ATH_CAP(vap, ni, TURBOP))
ath->ath_capability |= ATHEROS_CAP_TURBO_PRIME;
return frm + sizeof(info);
}
@@ -1829,7 +1839,7 @@
frm = ieee80211_add_doth(frm, ic);
if ((vap->iv_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
- if (ni->ni_ath_ie != NULL) /* XXX */
+ if (ni->ni_ath_ie != NULL)
frm = ieee80211_add_ath(frm, ni);
if (vap->iv_opt_ie != NULL) {
memcpy(frm, vap->iv_opt_ie, vap->iv_opt_ie_len);
More information about the p4-projects
mailing list