From patchwork Tue Mar 29 09:35:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emmanuel Grumbach X-Patchwork-Id: 8684681 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 AA9199F30C for ; Tue, 29 Mar 2016 09:35:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A19472017D for ; Tue, 29 Mar 2016 09:35:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 06D1120160 for ; Tue, 29 Mar 2016 09:35:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756448AbcC2Jfb (ORCPT ); Tue, 29 Mar 2016 05:35:31 -0400 Received: from mga04.intel.com ([192.55.52.120]:36603 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756353AbcC2JfZ (ORCPT ); Tue, 29 Mar 2016 05:35:25 -0400 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP; 29 Mar 2016 02:35:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,410,1455004800"; d="scan'208";a="677303969" Received: from actlab-pc12.jer.intel.com (HELO egrumbacBOX.ger.corp.intel.com) ([10.12.217.219]) by FMSMGA003.fm.intel.com with ESMTP; 29 Mar 2016 02:35:21 -0700 From: Emmanuel Grumbach To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Andrei Otcheretianski , Emmanuel Grumbach Subject: [PATCHv3 RESEND 07/11] cfg80211: add utility functions to clone and free nan_func Date: Tue, 29 Mar 2016 12:35:05 +0300 Message-Id: <1459244109-16038-7-git-send-email-emmanuel.grumbach@intel.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1459244109-16038-1-git-send-email-emmanuel.grumbach@intel.com> References: <1459244109-16038-1-git-send-email-emmanuel.grumbach@intel.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=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 From: Andrei Otcheretianski Add cfg80211_free_nan_func and cfg80211_clone_nan_func. These helper functions will be used by mac80211 in the next patch. Signed-off-by: Andrei Otcheretianski Signed-off-by: Emmanuel Grumbach --- include/net/cfg80211.h | 21 ++++++++++ net/wireless/util.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3a94b21..5e972f4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5544,6 +5544,27 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev, enum nl80211_nan_func_term_reason reason, u64 cookie, gfp_t gfp); +/** + * cfg80211_free_nan_func_members - free nan function members + * @f: NAN function that should be freed + * + * Frees all the allocated members of the given function, however + * it doesn't frees the pointed memory. This function can be only called if @f + * was cloned using cfg80211_clone_nan_func_members() + */ +void cfg80211_free_nan_func_members(struct cfg80211_nan_func *f); + +/** + * cfg80211_clone_nan_func_members - clone nan function + * @f1: destination + * @f2: source + * + * Clones @f2 to @f1. The function doesn't allocate @f1. Returns 0 on success. + * To free @f1's members cfg80211_free_nan_func_members() should be used. + */ +int cfg80211_clone_nan_func_members(struct cfg80211_nan_func *f1, + const struct cfg80211_nan_func *f2); + /* ethtool helper */ void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); diff --git a/net/wireless/util.c b/net/wireless/util.c index bdf0c40..09f07c7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1757,6 +1757,118 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, } EXPORT_SYMBOL(cfg80211_get_station); +void cfg80211_free_nan_func_members(struct cfg80211_nan_func *f) +{ + int i; + + kfree(f->serv_spec_info); + kfree(f->srf_bf); + kfree(f->srf_macs); + for (i = 0; i < f->num_rx_filters; i++) + kfree(f->rx_filters[i].filter); + + for (i = 0; i < f->num_tx_filters; i++) + kfree(f->tx_filters[i].filter); + + kfree(f->rx_filters); + kfree(f->tx_filters); +} +EXPORT_SYMBOL(cfg80211_free_nan_func_members); + +static int +ieee80211_clone_match_filters(struct cfg80211_nan_func_filter *filt1, + const struct cfg80211_nan_func_filter *filt2, + int num_filters) +{ + int i; + + for (i = 0; i < num_filters; i++) { + filt1[i].filter = kmemdup(filt2[i].filter, filt2[i].len, + GFP_KERNEL); + filt1[i].len = filt2[i].len; + + if (!filt1[i].filter) + return -ENOMEM; + } + + return 0; +} + +int cfg80211_clone_nan_func_members(struct cfg80211_nan_func *f1, + const struct cfg80211_nan_func *f2) +{ + memcpy(f1, f2, sizeof(*f1)); + + /* set all pointers to NULL so we can free them in case of failure */ + f1->serv_spec_info = NULL; + f1->srf_bf = NULL; + f1->srf_macs = NULL; + f1->rx_filters = NULL; + f1->tx_filters = NULL; + f1->num_rx_filters = 0; + f1->num_tx_filters = 0; + + if (f2->serv_spec_info_len) { + f1->serv_spec_info = kmemdup(f2->serv_spec_info, + f2->serv_spec_info_len, + GFP_KERNEL); + if (!f1->serv_spec_info) + goto err; + } + + if (f2->srf_bf_len) { + f1->srf_bf = kmemdup(f2->srf_bf, f2->srf_bf_len, GFP_KERNEL); + if (!f1->srf_bf) + goto err; + } + + if (f2->srf_num_macs) { + f1->srf_macs = kmemdup(f2->srf_macs, + f2->srf_num_macs * + sizeof(*f2->srf_macs), + GFP_KERNEL); + if (!f1->srf_macs) + goto err; + } + + if (f2->num_rx_filters) { + f1->rx_filters = kcalloc(f2->num_rx_filters, + sizeof(*f1->rx_filters), + GFP_KERNEL); + if (!f1->rx_filters) + goto err; + + if (!ieee80211_clone_match_filters(f1->rx_filters, + f2->rx_filters, + f2->num_rx_filters)) + goto err; + + f1->num_rx_filters = f2->num_rx_filters; + } + + if (f2->num_tx_filters) { + f1->tx_filters = kcalloc(f2->num_tx_filters, + sizeof(*f1->tx_filters), + GFP_KERNEL); + if (!f1->tx_filters) + goto err; + + if (!ieee80211_clone_match_filters(f1->tx_filters, + f2->tx_filters, + f2->num_tx_filters)) + goto err; + + f1->num_tx_filters = f2->num_tx_filters; + } + + return 0; +err: + cfg80211_free_nan_func_members(f1); + + return -ENOMEM; +} +EXPORT_SYMBOL(cfg80211_clone_nan_func_members); + /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ const unsigned char rfc1042_header[] __aligned(2) =