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