PERFORCE change 39768 for review
Sam Leffler
sam at FreeBSD.org
Wed Oct 15 21:15:24 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=39768
Change 39768 by sam at sam_ebb on 2003/10/15 21:14:38
support for fragment reassembly on receive
Affected files ...
.. //depot/projects/netperf/sys/net80211/ieee80211_input.c#9 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_node.c#12 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_node.h#9 edit
Differences ...
==== //depot/projects/netperf/sys/net80211/ieee80211_input.c#9 (text+ko) ====
@@ -66,6 +66,9 @@
#include <netinet/if_ether.h>
#endif
+static struct mbuf *ieee80211_reass(struct ieee80211com *,
+ struct ieee80211_node *, struct mbuf *);
+
/*
* Process a received frame. The node associated with the sender
* should be supplied. If nothing was found in the node table then
@@ -259,6 +262,9 @@
/* copy to listener after decrypt */
if (ic->ic_rawbpf)
bpf_mtap(ic->ic_rawbpf, m);
+ m = ieee80211_reass(ic, ni, m);
+ if (m == NULL)
+ goto out;
m = ieee80211_decap(ifp, m);
if (m == NULL) {
ic->ic_stats.is_rx_decap++;
@@ -357,6 +363,9 @@
}
if (ic->ic_rawbpf)
bpf_mtap(ic->ic_rawbpf, m);
+ m = ieee80211_reass(ic, ni, m);
+ if (m == NULL)
+ goto out;
(*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
m_freem(m);
return;
@@ -379,6 +388,73 @@
}
}
+/*
+ * Reassemble fragments as necessary.
+ */
+static struct mbuf *
+ieee80211_reass(struct ieee80211com *ic, struct ieee80211_node *ni, struct mbuf *m)
+{
+ struct ieee80211_frame *wh, *lwh;
+ u_int16_t rxseq, lseq;
+ u_int8_t fragno, more;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1))
+ return m; /* no mcast frames */
+
+ more = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
+ rxseq = le16toh(*(u_int16_t *)wh->i_seq);
+ fragno = rxseq & IEEE80211_SEQ_FRAG_MASK;
+ if (!more && fragno == 0)
+ return m; /* not fragmented */
+
+ /*
+ * Validate that fragment is in order and
+ * related to the previous ones.
+ */
+ if (ni->ni_rxfrag != NULL) {
+ lwh = mtod(ni->ni_rxfrag, struct ieee80211_frame *);
+ lseq = le16toh(*(u_int16_t *)lwh->i_seq);
+ /* NB: this checks seq#'s and frag number together */
+ if (rxseq != lseq+1 ||
+ !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) ||
+ !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) {
+ /* Unrelated fragment, clear existing data */
+ /* XXX stat */
+ m_freem(ni->ni_rxfrag);
+ ni->ni_rxfrag = NULL;
+ }
+ } else {
+ if (fragno != 0) { /* out of order fragment */
+ /* XXX stat */
+ m_freem(m);
+ return NULL;
+ }
+ }
+ /*
+ * Add new fragment to existing data, if any.
+ */
+ if (ni->ni_rxfrag != NULL) {
+ /*
+ * We know this is the next sequential fragment
+ * because of the check done above; append the data.
+ */
+ lwh = mtod(ni->ni_rxfrag, struct ieee80211_frame *);
+ m_cat(ni->ni_rxfrag, m);
+ /* record last sequence and fragno */
+ *(u_int16_t *) lwh->i_seq = rxseq;
+ if (!more) { /* reassembly complete */
+ m = ni->ni_rxfrag;
+ ni->ni_rxfrag = NULL;
+ } else /* frame incomplete */
+ m = NULL;
+ } else {
+ ni->ni_rxfrag = m;
+ m = NULL;
+ }
+ return m;
+}
+
struct mbuf *
ieee80211_decap(struct ifnet *ifp, struct mbuf *m)
{
==== //depot/projects/netperf/sys/net80211/ieee80211_node.c#12 (text+ko) ====
@@ -110,8 +110,11 @@
{
struct ieee80211com *ic = (void *)ifp;
- if (ic->ic_bss != NULL)
+ if (ic->ic_bss != NULL) {
+ if (ic->ic_bss->ni_rxfrag != NULL)
+ m_freem(ic->ic_bss->ni_rxfrag);
(*ic->ic_node_free)(ic, ic->ic_bss);
+ }
ieee80211_free_allnodes(ic);
IEEE80211_NODE_LOCK_DESTROY(ic);
}
@@ -517,6 +520,8 @@
LIST_REMOVE(ni, ni_hash);
if (TAILQ_EMPTY(&ic->ic_node))
ic->ic_inact_timer = 0;
+ if (ni->ni_rxfrag != NULL)
+ m_freem(ni->ni_rxfrag);
(*ic->ic_node_free)(ic, ni);
}
==== //depot/projects/netperf/sys/net80211/ieee80211_node.h#9 (text+ko) ====
@@ -102,6 +102,7 @@
int ni_fails; /* failure count to associate */
int ni_inact; /* inactivity mark count */
int ni_txrate; /* index to ni_rates[] */
+ struct mbuf *ni_rxfrag; /* rx frag reassembly */
};
static __inline struct ieee80211_node *
More information about the p4-projects
mailing list