From patchwork Fri Aug 12 16:12:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Kenzior X-Patchwork-Id: 9277387 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8001760752 for ; Fri, 12 Aug 2016 16:12:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7078928A85 for ; Fri, 12 Aug 2016 16:12:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 64E6128A94; Fri, 12 Aug 2016 16:12:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 35BD528A85 for ; Fri, 12 Aug 2016 16:12:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752588AbcHLQM2 (ORCPT ); Fri, 12 Aug 2016 12:12:28 -0400 Received: from mail-oi0-f65.google.com ([209.85.218.65]:33637 "EHLO mail-oi0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752575AbcHLQM1 (ORCPT ); Fri, 12 Aug 2016 12:12:27 -0400 Received: by mail-oi0-f65.google.com with SMTP id s207so2436740oie.0 for ; Fri, 12 Aug 2016 09:12:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=v5w/nFXzxyTPzDfCp+BCRiuvnQb4MMMzJ5v7lVwwmPg=; b=pZQQLYBmI7Rc71Q+Rrw/2v7jRVJMNqS6wgHi8R+haktKUEZTSOaNS/JmZ833t2L90J 4QUvzgg4HsUZ6ezBuKCBmfLKKHZ+J+EvJVaRsR7n1lqLOC4xDZgxL9BrmN05LIaktJpd 6TJT+4lIcdKG5KGGPzlZx31SyBXN2/6MqHrwvyIv4QsozlIwRspWcdmwNmmWhmwe56hG 0ZJPuoMBAXgRGYjzJ4THfpXUCKGaQ2Hdq7ld52QejgEN31DPwTchc1TPdWzk3o35gyeq KaBOWz2xnc/K9B4QkbI/Ne9nejZfmFsK3WxT+b996XDs6MQVnsVzhu17RQ1ZTIzk5eGe sWvQ== 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; bh=v5w/nFXzxyTPzDfCp+BCRiuvnQb4MMMzJ5v7lVwwmPg=; b=iCGf6xjywMt3XjBzLfuuVpqyVkRLFn1rWJTvdegbhp+tx1yoEHdOBvrt9jFhFeuMQc hl2CNhcANLKQV8hU2vJfbb2xyM6eryN8hmpmo2tnZTRdybL27ilfi1CGaLDYYZFqIJfR m0Xy++swvjwDUJEnyOjooJy+fHiXYlf/HrjxUpqFBJ2Q1cVMXzg4TwEonRKQVujGflv3 w1r4BLpDl0rr9320TnqVBb+B3jRXoqbny4clWD/El/x2fwNDcVoXBVPLKJefNvACN7rj pSpIEwp9HSIWJdZMXC1SVK06lhVpB7JRNgFALu8YoDiKpNc6u2YinM8BfrEc4sZQGbYQ H3+g== X-Gm-Message-State: AEkoousfP7vTpBITftvVjwcYc5RKkCsDn6ubpr4w1O2Htc3DmclNEFSDmbJUe5uCTL2E4g== X-Received: by 10.202.95.133 with SMTP id t127mr7905215oib.80.1471018346756; Fri, 12 Aug 2016 09:12:26 -0700 (PDT) Received: from localhost.localdomain (cpe-70-114-247-242.austin.res.rr.com. [70.114.247.242]) by smtp.gmail.com with ESMTPSA id t145sm3671414oif.4.2016.08.12.09.12.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Aug 2016 09:12:26 -0700 (PDT) From: Denis Kenzior To: linux-wireless@vger.kernel.org Cc: Denis Kenzior Subject: [PATCH v2] nl80211: Allow GET_INTERFACE dumps to be filtered Date: Fri, 12 Aug 2016 11:12:37 -0500 Message-Id: <1471018357-3047-1-git-send-email-denkenz@gmail.com> X-Mailer: git-send-email 2.7.3 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch allows GET_INTERFACE dumps to be filtered based on NL80211_ATTR_WIPHY or NL80211_ATTR_WDEV. The documentation for GET_INTERFACE mentions that this is possible: "Request an interface's configuration; either a dump request on a %NL80211_ATTR_WIPHY or ..." However, this behavior has not been implemented until now. Signed-off-by: Denis Kenzior --- net/wireless/nl80211.c | 63 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4997857..aa85871 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2519,27 +2519,74 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag return -EMSGSIZE; } +static int nl80211_dump_interface_parse(struct sk_buff *skb, + struct netlink_callback *cb, + int *filter_wiphy) +{ + struct nlattr **tb = nl80211_fam.attrbuf; + int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, + tb, nl80211_fam.maxattr, nl80211_policy); + + /* ignore parse errors for backward compatibility */ + if (ret) + return 0; + + if (tb[NL80211_ATTR_WIPHY]) + *filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); + if (tb[NL80211_ATTR_WDEV]) + *filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32; + + return 0; +} + +struct dump_interface_context { + unsigned int wp_start; + unsigned int if_start; + int filter_wiphy; +}; + static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) { - int wp_idx = 0; - int if_idx = 0; - int wp_start = cb->args[0]; - int if_start = cb->args[1]; struct cfg80211_registered_device *rdev; struct wireless_dev *wdev; + unsigned int wp_idx = 0; + unsigned int if_idx; + static struct dump_interface_context static_ctx; + struct dump_interface_context *ctx = cb->args[0]; + + if (!ctx) { + int ret; + + static_ctx.wp_start = 0; + static_ctx.if_start = 0; + static_ctx.filter_wiphy = -1; + + ret = nl80211_dump_interface_parse(skb, cb, + &static_ctx.filter_wiphy); + if (ret) + return ret; + + ctx = &static_ctx; + cb->args[0] = ctx; + } rtnl_lock(); list_for_each_entry(rdev, &cfg80211_rdev_list, list) { if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) continue; - if (wp_idx < wp_start) { + if (wp_idx < ctx->wp_start) { wp_idx++; continue; } + + if (ctx->filter_wiphy != -1 && + ctx->filter_wiphy != rdev->wiphy_idx) + continue; + if_idx = 0; list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { - if (if_idx < if_start) { + if (if_idx < ctx->if_start) { if_idx++; continue; } @@ -2556,8 +2603,8 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * out: rtnl_unlock(); - cb->args[0] = wp_idx; - cb->args[1] = if_idx; + ctx->wp_start = wp_idx; + ctx->if_start = if_idx; return skb->len; }