From patchwork Fri May 3 02:33:55 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 2514841 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 3DB62DF215 for ; Fri, 3 May 2013 02:36:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762274Ab3ECCgV (ORCPT ); Thu, 2 May 2013 22:36:21 -0400 Received: from mail-da0-f49.google.com ([209.85.210.49]:45403 "EHLO mail-da0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753873Ab3ECCgU (ORCPT ); Thu, 2 May 2013 22:36:20 -0400 Received: by mail-da0-f49.google.com with SMTP id p5so590102dak.36 for ; Thu, 02 May 2013 19:36:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=JDIxdpYsQElzZVo2d5+rPCtlJZHX1Z+fMlPdPVrXax8=; b=pn7ZVDii8rNLl/aOWiDgJBxJOGjMx1yENzPmCdV2JdTQfOeIGg0zPA9mMclIQWE6JZ NLDdrOYdpuo/Vu9NosYB8JNZ1cLALOtURTgnnDiARcsdTA+qRDdJ1aBtRF5//Au8LFIl NM994F+gF8ShdxOSjKIhbF1luuqW+aupmfxQoEEo9WhkG2wg6VPu03/rBXTC0V7BceLl 182knCMxznE8muKwFfO0CMqxyL4Zbz6nAgIFjoV1kWVA2LS/j/8/ALX8nX9dxqKZr3RJ 8+Am9/6McYC5yLYaeiNQlIpG7QQJvmEhYfj+vnEg1hpHuLFXWl28Uf+GsE4Af0OAmjIU wUJA== X-Received: by 10.68.216.165 with SMTP id or5mr11731282pbc.152.1367548580143; Thu, 02 May 2013 19:36:20 -0700 (PDT) Received: from cable.lan (70-35-43-50.static.wiline.com. [70.35.43.50]) by mx.google.com with ESMTPSA id az5sm7391484pbc.18.2013.05.02.19.36.17 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 02 May 2013 19:36:19 -0700 (PDT) From: Thomas Pedersen To: Johannes Berg Cc: linux-wirelss , me@bobcopeland.com, open80211s , Thomas Pedersen Subject: [RFC 05/12] mac80211: forward frames on correct mbss-shared interface Date: Thu, 2 May 2013 19:33:55 -0700 Message-Id: <1367548442-8229-6-git-send-email-thomas@cozybit.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1367548442-8229-1-git-send-email-thomas@cozybit.com> References: <1367548442-8229-1-git-send-email-thomas@cozybit.com> X-Gm-Message-State: ALoCoQmJCLcFa1R0/2f6nIamtRg66es8DOfPkWi0RAy4DtwvU+HzdhwOxOVT2TilwljmE0aG8C7I Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org A forwarded frame may have a destination STA which resides on a vif other than the RX interface. Have mesh_nexthop_lookup() fill in the right outgoing sdata in the skb control block. Also update the congestion detection logic to take into account a possibly different outgoing interface. Signed-off-by: Thomas Pedersen --- net/mac80211/rx.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 4e7886d..d86f0df 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2077,13 +2077,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ether_addr_equal(sdata->vif.addr, hdr->addr3)) return RX_CONTINUE; - q = ieee80211_select_queue_80211(sdata, skb, hdr); - if (ieee80211_queue_stopped(&local->hw, q)) { - IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); - return RX_DROP_MONITOR; - } - skb_set_queue_mapping(skb, q); - if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); goto out; @@ -2106,21 +2099,45 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; info->control.vif = &rx->sdata->vif; info->control.jiffies = jiffies; + + /* unicast frame may go out on a different HW, so resolve now */ + if (!is_multicast_ether_addr(fwd_hdr->addr1)) { + if (!mesh_nexthop_lookup(mbss, fwd_skb)) + /* next hop may be on a different interface */ + local = vif_to_sdata(info->control.vif)->local; + else { + /* unable to resolve next hop */ + mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, + fwd_hdr->addr3, 0, reason, + fwd_hdr->addr2); + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, + dropped_frames_no_route); + kfree_skb(fwd_skb); + return RX_DROP_MONITOR; + } + } + + /* + * note: ifmsh still points to RX iface (for forwarded frame + * statistics), while local is sending HW + */ + q = ieee80211_select_queue_80211(vif_to_sdata(info->control.vif), + fwd_skb, fwd_hdr); + if (ieee80211_queue_stopped(&local->hw, q)) { + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); + kfree_skb(fwd_skb); + return RX_DROP_MONITOR; + } + skb_set_queue_mapping(fwd_skb, q); + if (is_multicast_ether_addr(fwd_hdr->addr1)) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); /* update power mode indication when forwarding */ ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); - } else if (!mesh_nexthop_lookup(mbss, fwd_skb)) { + } else { /* mesh power mode flags updated in mesh_nexthop_lookup */ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); - } else { - /* unable to resolve next hop */ - mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, - fwd_hdr->addr3, 0, reason, fwd_hdr->addr2); - IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); - kfree_skb(fwd_skb); - return RX_DROP_MONITOR; } IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);