From owner-p4-projects@FreeBSD.ORG Wed Oct 15 21:15:23 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8758016A4C0; Wed, 15 Oct 2003 21:15:23 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 49AB916A4B3 for ; Wed, 15 Oct 2003 21:15:23 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id B450143F93 for ; Wed, 15 Oct 2003 21:15:22 -0700 (PDT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.9/8.12.9) with ESMTP id h9G4FMXJ045190 for ; Wed, 15 Oct 2003 21:15:22 -0700 (PDT) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.9/8.12.9/Submit) id h9G4FMkQ045178 for perforce@freebsd.org; Wed, 15 Oct 2003 21:15:22 -0700 (PDT) (envelope-from sam@freebsd.org) Date: Wed, 15 Oct 2003 21:15:22 -0700 (PDT) Message-Id: <200310160415.h9G4FMkQ045178@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 39768 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Oct 2003 04:15:24 -0000 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 #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 *