Date: Wed, 15 Oct 2003 21:15:22 -0700 (PDT) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 39768 for review Message-ID: <200310160415.h9G4FMkQ045178@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39768 Change 39768 by sam@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 *
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310160415.h9G4FMkQ045178>