From patchwork Tue Jan 14 17:29:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz.Dziedzic@tieto.com X-Patchwork-Id: 3487111 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D8F2AC02DC for ; Tue, 14 Jan 2014 17:29:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C046A20225 for ; Tue, 14 Jan 2014 17:29:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EE8E920221 for ; Tue, 14 Jan 2014 17:29:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751576AbaANR3q (ORCPT ); Tue, 14 Jan 2014 12:29:46 -0500 Received: from mail-ee0-f48.google.com ([74.125.83.48]:33417 "EHLO mail-ee0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751512AbaANR3q (ORCPT ); Tue, 14 Jan 2014 12:29:46 -0500 Received: by mail-ee0-f48.google.com with SMTP id t10so371222eei.7 for ; Tue, 14 Jan 2014 09:29:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tieto.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YskGzYhZMyj7U8pit242Z40zfOK+QFTUMczKGKHUW/E=; b=B9pshy8R8tQGQRASDWDmlYPS03LB5bfuZFlduaFY9mCSK6i1sz/ZrmyYXi5V0x2RjM 8aaqTiD//KVR/N1mQEu458sdIGIru51mXBoLVHYY/IuC5CL24w9xAPpn+qOSCgyk32lE 5UTwnDXeczgsRcXsupyBe0EIWrWMJBsoNER5k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=YskGzYhZMyj7U8pit242Z40zfOK+QFTUMczKGKHUW/E=; b=iaeUaXYYWZ/4hG4oExvh5id02nsVKomexXD8YFd4LBKA0Z/pmvQN4k4+6wo4rJVgjn 4gem35/BShNbCbEakYexTf0MdvRQDtsLW9OyphXQ43Pvs4ws3Jp01qXY2EMK7u/N2GNH 2zDUeuG5pE4mcpgu5Lv98CqSt5V73zDda6yrfZe8CLdW0Z07EY0DMDTzeK9VQ/VBoxDZ IAhXLDfcaKOndfBg6Ks7hHFympnHurSo7MLULlGtVsH+FMFS2zrUurIecKrnEW3KUxFY XOeGDfYbVFzt9F169A6gVM6juhX4UKiVFBzH2gpo2nAKsc9DeLn+SIcZ4JRoDUlOFivT umLw== X-Gm-Message-State: ALoCoQmVMe1U9XRgSU/WZp3ztJgm+Y4lB2rBb/HvnJHBBEpgoZMtcioPxmztfzRhDwcpPRsBuTX8nq+AZ/K9llNSWnZ1+aSKTagjSw/hbOc5354g28NkKJM= X-Received: by 10.14.99.66 with SMTP id w42mr3514296eef.63.1389720584031; Tue, 14 Jan 2014 09:29:44 -0800 (PST) Received: from localhost.localdomain (host-62-141-194-198.swidnica.mm.pl. [62.141.194.198]) by mx.google.com with ESMTPSA id x2sm680440eeo.8.2014.01.14.09.29.43 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 14 Jan 2014 09:29:43 -0800 (PST) From: Janusz Dziedzic To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, mcgrof@do-not-panic.com, Janusz Dziedzic Subject: [RFC 1/5] cfg80211: regulatory rules, fix bw checking Date: Tue, 14 Jan 2014 18:29:26 +0100 Message-Id: <1389720570-2430-2-git-send-email-janusz.dziedzic@tieto.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1389720570-2430-1-git-send-email-janusz.dziedzic@tieto.com> References: <1389720570-2430-1-git-send-email-janusz.dziedzic@tieto.com> X-DomainID: tieto.com 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,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,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 Allow BW cross over REG_RULES if rules continous. Signed-off-by: Janusz Dziedzic --- I am not sure about rule_intersect() here ... net/wireless/reg.c | 68 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7d20d84..4414fa5 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -522,9 +522,55 @@ bool reg_is_valid_request(const char *alpha2) return alpha2_equal(lr->alpha2, alpha2); } +static u32 get_frequency_diff(const struct ieee80211_reg_rule *rules, + unsigned int rule_no, + unsigned int rule_max) +{ + u32 start_freq, end_freq; + u32 no = rule_no; + const struct ieee80211_reg_rule *rule = &rules[rule_no]; + const struct ieee80211_freq_range *freq_range = &rule->freq_range; + const struct ieee80211_freq_range *freq_range_tmp; + + /* get start_freq */ + while (no) { + rule = &rules[--no]; + freq_range_tmp = &rule->freq_range; + + if (freq_range_tmp->end_freq_khz != freq_range->start_freq_khz) + break; + + freq_range = freq_range_tmp; + }; + + start_freq = freq_range->start_freq_khz; + + /* get end_freq */ + rule = &rules[rule_no]; + freq_range = &rule->freq_range; + no = rule_no; + + while (no < rule_max - 1) { + rule = &rules[++no]; + freq_range_tmp = &rule->freq_range; + + if (freq_range_tmp->start_freq_khz != freq_range->end_freq_khz) + break; + + freq_range = freq_range_tmp; + } + + end_freq = freq_range->end_freq_khz; + + return end_freq - start_freq; +} + /* Sanity check on a regulatory rule */ -static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule) +static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rules, + unsigned int rule_no, + unsigned int rule_max) { + const struct ieee80211_reg_rule *rule = &rules[rule_no]; const struct ieee80211_freq_range *freq_range = &rule->freq_range; u32 freq_diff; @@ -534,10 +580,17 @@ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule) if (freq_range->start_freq_khz > freq_range->end_freq_khz) return false; + if (freq_range->end_freq_khz <= freq_range->start_freq_khz) + return false; + + /* First do quick check */ freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; + if (freq_range->max_bandwidth_khz <= freq_diff) + return true; - if (freq_range->end_freq_khz <= freq_range->start_freq_khz || - freq_range->max_bandwidth_khz > freq_diff) + /* Next check adjacent rules (if continous) */ + freq_diff = get_frequency_diff(rules, rule_no, rule_max); + if (freq_range->max_bandwidth_khz > freq_diff) return false; return true; @@ -545,7 +598,6 @@ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule) static bool is_valid_rd(const struct ieee80211_regdomain *rd) { - const struct ieee80211_reg_rule *reg_rule = NULL; unsigned int i; if (!rd->n_reg_rules) @@ -554,11 +606,9 @@ static bool is_valid_rd(const struct ieee80211_regdomain *rd) if (WARN_ON(rd->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) return false; - for (i = 0; i < rd->n_reg_rules; i++) { - reg_rule = &rd->reg_rules[i]; - if (!is_valid_reg_rule(reg_rule)) + for (i = 0; i < rd->n_reg_rules; i++) + if (!is_valid_reg_rule(rd->reg_rules, i, rd->n_reg_rules)) return false; - } return true; } @@ -666,7 +716,7 @@ static int reg_rules_intersect(const struct ieee80211_reg_rule *rule1, intersected_rule->flags = rule1->flags | rule2->flags; - if (!is_valid_reg_rule(intersected_rule)) + if (!is_valid_reg_rule(intersected_rule, 0, 1)) return -EINVAL; return 0;