From patchwork Fri Jun 5 18:31:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexis Green X-Patchwork-Id: 6557221 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A7AB09F1CC for ; Fri, 5 Jun 2015 18:31:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ABD1620628 for ; Fri, 5 Jun 2015 18:31:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8A536205B3 for ; Fri, 5 Jun 2015 18:31:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752018AbbFESbj (ORCPT ); Fri, 5 Jun 2015 14:31:39 -0400 Received: from mail-lb0-f177.google.com ([209.85.217.177]:36054 "EHLO mail-lb0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754686AbbFESbi (ORCPT ); Fri, 5 Jun 2015 14:31:38 -0400 Received: by lbbqq2 with SMTP id qq2so50966152lbb.3 for ; Fri, 05 Jun 2015 11:31:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to:cc :content-type; bh=5xUVaUB+7Qdf1+cO2Y3ohTJwhonF/XRzjBc+r2xmzNg=; b=aikK8Q6ebjQcpa60gbOLtR5H0qx6X5milQTZX9tuUu/N2+lP4heyK4d4B69qgiFjCX iqffeoMMs9SxCMgZ4TFintNAU1hljUxSmMMdW/tAJ3AnCvJ/BDUyJoP9i91GBd2Zg8/y 0xRPWo5CcYS+uRGmM/AzhfzlDYmpF79Pjuf8N7nlBwn8V8mh9XL3S4hxHpI4n+DxkzwD 3ABqE2LXiWNeJy83PQZH69zt1rozlRUtij/n15wYlU0quZfdR307uT3wD/Prdxx2N4I6 fev8HZGLjKeRs2DVmPOsp4ICIuvP+m7Ko6m0jMiVwyPTu9gbdPZSBU4IZUU7wTAxL3i8 udcA== X-Gm-Message-State: ALoCoQmiI1FWRE252LiZKQnIrLspV/3GdrPQaJxXHrBEX+/m8l48m+F3pO1Y06e3lYl4M6GAZ8o5 MIME-Version: 1.0 X-Received: by 10.112.219.70 with SMTP id pm6mr4475113lbc.41.1433529096843; Fri, 05 Jun 2015 11:31:36 -0700 (PDT) Received: by 10.152.7.35 with HTTP; Fri, 5 Jun 2015 11:31:36 -0700 (PDT) Date: Fri, 5 Jun 2015 11:31:36 -0700 Message-ID: Subject: [PATCH] mac80211: Fix a case of incorrect metric used when forwarding a PREQ From: Alexis Green To: Johannes Berg Cc: linux-wireless , Jesse Jones Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch fixes a bug in hwmp_preq_frame_process where the wrong metric can be used when forwarding a PREQ. This happens because the code uses the same metric variable to record the value of the metric to the source of the PREQ and the value of the metric to the target of the PREQ. This comes into play when both reply and forward are set which happens when IEEE80211_PREQ_PROACTIVE_PREP_FLAG is set and when MP_F_DO | MP_F_RF is set. The original code had a special case to handle the first case but not the second. The patch uses distinct variables for the two metrics which makes the code flow much clearer and removes the need to restore the original value of metric when forwarding. Signed-off-by: Alexis Green CC: Jesse Jones --- bool root_is_gate; @@ -528,7 +528,6 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = PREQ_IE_TARGET_SN(preq_elem); orig_sn = PREQ_IE_ORIG_SN(preq_elem); target_flags = PREQ_IE_TARGET_F(preq_elem); - orig_metric = metric; /* Proactive PREQ gate announcements */ flags = PREQ_IE_FLAGS(preq_elem); root_is_gate = !!(flags & RANN_FLAG_IS_GATE); @@ -539,7 +538,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, mhwmp_dbg(sdata, "PREQ is for us\n"); forward = false; reply = true; - metric = 0; + target_metric = 0; if (time_after(jiffies, ifmsh->last_sn_update + net_traversal_jiffies(sdata)) || time_before(jiffies, ifmsh->last_sn_update)) { @@ -556,7 +555,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, reply = true; target_addr = sdata->vif.addr; target_sn = ++ifmsh->sn; - metric = 0; + target_metric = 0; ifmsh->last_sn_update = jiffies; } if (root_is_gate) @@ -574,7 +573,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, } else if ((!(target_flags & MP_F_DO)) && (mpath->flags & MESH_PATH_ACTIVE)) { reply = true; - metric = mpath->metric; + target_metric = mpath->metric; target_sn = mpath->sn; if (target_flags & MP_F_RF) target_flags |= MP_F_DO; @@ -593,7 +592,8 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, orig_sn, 0, target_addr, target_sn, mgmt->sa, 0, ttl, - lifetime, metric, 0, sdata); + lifetime, target_metric, + 0, sdata); } else { ifmsh->mshstats.dropped_frames_ttl++; } @@ -619,13 +619,12 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { target_addr = PREQ_IE_TARGET_ADDR(preq_elem); target_sn = PREQ_IE_TARGET_SN(preq_elem); - metric = orig_metric; } mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, orig_sn, target_flags, target_addr, target_sn, da, hopcount, ttl, lifetime, - metric, preq_id, sdata); + orig_metric, preq_id, sdata); if (!is_multicast_ether_addr(da)) ifmsh->mshstats.fwded_unicast++; else -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 214e63b..bb93170 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -510,14 +510,14 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, - const u8 *preq_elem, u32 metric) + const u8 *preq_elem, u32 orig_metric) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct mesh_path *mpath = NULL; const u8 *target_addr, *orig_addr; const u8 *da; u8 target_flags, ttl, flags; - u32 orig_sn, target_sn, lifetime, orig_metric; + u32 orig_sn, target_sn, lifetime, target_metric; bool reply = false; bool forward = true;