From owner-freebsd-net@FreeBSD.ORG Fri Feb 17 08:53:13 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DF4171065686 for ; Fri, 17 Feb 2012 08:53:13 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: from mail-wi0-f182.google.com (mail-wi0-f182.google.com [209.85.212.182]) by mx1.freebsd.org (Postfix) with ESMTP id 745108FC12 for ; Fri, 17 Feb 2012 08:53:13 +0000 (UTC) Received: by wibhn14 with SMTP id hn14so2165311wib.13 for ; Fri, 17 Feb 2012 00:53:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; bh=p08pm5RPwyZ0ju0hldrANdeS4622KtN94m3KntJVlKQ=; b=v9NGhHfNdS1+/FKMfMnfSOVetV8urVaK2vbZXI5fo2EsCoLsFWj4mO/BU8k+GY5+BA BRSdOgDpgViIX5nnJSMx2udL5W7+jY159CJjnpnhxcCM9/ufjEATh9BNcTEEwi1SBPMg S+P8uNsI6y1KyG+8vaaRHgVJ59DLA2SccJnM4= MIME-Version: 1.0 Received: by 10.180.95.105 with SMTP id dj9mr2058845wib.18.1329468792424; Fri, 17 Feb 2012 00:53:12 -0800 (PST) Sender: adrian.chadd@gmail.com Received: by 10.216.154.199 with HTTP; Fri, 17 Feb 2012 00:53:12 -0800 (PST) Date: Fri, 17 Feb 2012 00:53:12 -0800 X-Google-Sender-Auth: JGl_wkbvAAfYwpcAKvBB6FzSXgY Message-ID: From: Adrian Chadd To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: net80211 - how the heck is M_FRAG (mbuf/net80211 fragments) supposed to work? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Feb 2012 08:53:13 -0000 Hi, So ray@ pointed out that fragment handling in net80211 is broken. Yes, 802.11 fragments, not IP fragments. This is specific to ath, but any driver using IFQ_ENQUEUE/IFQ_DEQUEUE is likely broken. The 30 second summary goes something like this: * frame ends up at ieee80211_start() * .. this ends up at ieee80211_encap() * .. this ends up being fragmented via ieee80211_fragment() into multiple fragments. * these are chained together via m->m_nextpkt, with them being marked as M_FRAG. Now, comes the annoying bit: * The parent if->if_transmit is called() * .. which for ath is default, so it gets onto the ifnet send queue via IFQ_ENQUEUE() * .. and that macro clears m->m_nextpkt, totally dropping the rest of the fragments. Yes, they leak. Now even if you fix this, a similar problem in ath_start() exists: * ath_start() uses IFQ_DEQUEUE() to grab a frame; * this clears m->m_nextpkt before returning it; * so.. the ath fragment processing function finds there's not enough fragments (as the rest have been dropped) and it drops it. So my question is - how the heck did this ever work? The behvaiour of clearing m->m_nextpkt in IFQ_ENQUEUE/IFQ_DEQUEUE seems to have been around since forever. What am I missing? I'd really like to repair the fragment behaviour in net80211 so we can TX/RX fragments again. Monthadar has a need for it for supporting 802.11s mesh (legacy) environments so I'd like to give that to him. Thanks! Adrian