From patchwork Tue Oct 16 18:20:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 148982 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp5435509lji; Tue, 16 Oct 2018 11:21:13 -0700 (PDT) X-Google-Smtp-Source: ACcGV62UiNs+fX9JDYoPoaGQMVB5qcqRDUdYVVEAwJTlAyv3uI+bcOyglgJl4Lp5PwvapiKOvNia X-Received: by 2002:a63:3c46:: with SMTP id i6-v6mr21048013pgn.286.1539714073282; Tue, 16 Oct 2018 11:21:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539714073; cv=none; d=google.com; s=arc-20160816; b=wFXkfBd8SZy+6zFDR2MZvK6qqiQ5PgRNIYgSFo8N2cjU2l7iWMR4hUfvl1h8BIYwlQ VVpdZFigL1wKYMHngnMtbfYIgp44SUjAj2J7HwzH3XVgYhBgIUbZ9JWZ0ouaWuwuO74Q WSSzqnRBCVIrkDYgrpAyO38lriJRJlzzVskeLndak55f3yzPn0zqSd0NEjrk1SZcqJAH hWtucxrgqhY2y8df8v7V0y5B+mnTGhNpRVwkVb0m3fUK5daSi22aOnW8njIGeg0xVCnL Ku+pRpS9FGACXsIX2Q+MAcIFz/F2y+5AQrl1O8S1nx3RIFkYsAyFsNFlfpxt40RRbox+ YuOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=UY3go5N1XkoYGbYQ+I2v/woXzZQofslDCysYUjuM+2c=; b=deda4KbPNp2GsQbjhEJKnV9k/0nQIZZSFc/Hc7AAKmaFbh24tJVRBeafFIYre/TKgy QL8nGO9Yc2iagoLQmA7OMSokb8VuNtsJl8c/ZvxKUa220hhf3SOm5BzS2r/EG4xj5wi/ bB7cd4O+BV97B83OBJEO73WpVsJ2gX8lzeeqoCIs5HN+ofdS2v80mdPKZVU8hiza23BE 2dWYGs33VtnHPzqvmHj8ALpmDfhJ5mU7yC0tTKcUAQ8hmhRH751BY7gFgEmxqfZcdlYk rHGHdDdvD2Q7PTk/S1GcwVtFWyTae95VkslDkspYkZiZWd9QzxL+SKuHJC3AB/RDNnFB UvJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dJH8U1PJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a127-v6si15813314pfb.24.2018.10.16.11.21.12; Tue, 16 Oct 2018 11:21:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dJH8U1PJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727703AbeJQCMw (ORCPT + 32 others); Tue, 16 Oct 2018 22:12:52 -0400 Received: from mail-lf1-f68.google.com ([209.85.167.68]:43387 "EHLO mail-lf1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727348AbeJQCMW (ORCPT ); Tue, 16 Oct 2018 22:12:22 -0400 Received: by mail-lf1-f68.google.com with SMTP id p34-v6so17729167lfg.10 for ; Tue, 16 Oct 2018 11:20:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UY3go5N1XkoYGbYQ+I2v/woXzZQofslDCysYUjuM+2c=; b=dJH8U1PJ/BNay3RDFioWP26l0qJrNM9u6DCNd1A5aZhrVn5sRESYG4A9S8nG4bHRmR dTGIx9Pt0AEHZ1awjb/erEJo9BxfvPZN/oOY1iAgiFZSYLLkEe2S6Ey+YUFWlNpcsZpC zL8a95KcAvI9rathAbiZ9TYbzYnA5ZCn0CMPI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UY3go5N1XkoYGbYQ+I2v/woXzZQofslDCysYUjuM+2c=; b=AoOIdz+TXuaULTG4b2wS2ZPnJhUs8XpInCmfk+tWbQiTn9PapN1cFRpHpLTpGnSX0x 3RSqgYHYxfSBu6GkXc4eLdd0ISKu6pQoEjgPRqfGVcyhC2KbwhAE3IHhZ9MSTfv/OIL9 VQ742lwpieLT16ee/IcrPzFlpmznWKaHgUGIO2ntd8kmg+cV9e6iRW57UO9JcgykPs8y YbEOv6tLf4REy8YhomjTXqQh3bIrq1sL4oOyFwjUVq+33cpFmXf+vLv+A0Imyqlt+lkm JQIzK7ZHI30lKDklyISa5gEIu3Fgtc7TTcOzbLfwAIaZ3n9t24TCgcioPzbw7zpFlSvi RJnA== X-Gm-Message-State: ABuFfohIlIFPLDhP1dBkameAf3+xHCOb9MHsEEkU2HUA4pUsYBSMfLzr xvKCBv1Y4ifUsw7iu0/AAq275Q== X-Received: by 2002:a19:db84:: with SMTP id t4-v6mr7532859lfi.74.1539714039774; Tue, 16 Oct 2018 11:20:39 -0700 (PDT) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id i27-v6sm3207844lfc.22.2018.10.16.11.20.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Oct 2018 11:20:38 -0700 (PDT) From: Ivan Khoronzhuk To: grygorii.strashko@ti.com, davem@davemloft.net Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexander.h.duyck@intel.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 1/4] net: core: dev_addr_lists: add auxiliary func to handle reference address updates Date: Tue, 16 Oct 2018 21:20:32 +0300 Message-Id: <20181016182035.18234-2-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> References: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to avoid all table update, and only remove or add new address, the auxiliary function exists, named __hw_addr_sync_dev(). It allows end driver do nothing when nothing changed and add/rm when concrete address is firstly added or lastly removed. But it doesn't include cases when an address of real device or vlan was reused by other vlans or vlan/macval devices. For handaling events when address was reused/unreused the patch adds new auxiliary routine - __hw_addr_ref_sync_dev(). It allows to do nothing when nothing was changed and do updates only for an address being added/reused/deleted/unreused. Thus, clone address changes for vlans can be mirrored in the table. The function is exclusive with __hw_addr_sync_dev(). It's responsibility of the end driver to identify address vlan device, if it needs so. Signed-off-by: Ivan Khoronzhuk --- include/linux/netdevice.h | 10 ++++ net/core/dev_addr_lists.c | 97 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) -- 2.17.1 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index dc1d9ed33b31..de95f96a6352 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4048,6 +4048,16 @@ int __hw_addr_sync_dev(struct netdev_hw_addr_list *list, int (*sync)(struct net_device *, const unsigned char *), int (*unsync)(struct net_device *, const unsigned char *)); +int __hw_addr_ref_sync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*sync)(struct net_device *, + const unsigned char *, int), + int (*unsync)(struct net_device *, + const unsigned char *, int)); +void __hw_addr_ref_unsync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*unsync)(struct net_device *, + const unsigned char *, int)); void __hw_addr_unsync_dev(struct netdev_hw_addr_list *list, struct net_device *dev, int (*unsync)(struct net_device *, diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index d884d8f5f0e5..1385d75fe5ea 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -277,6 +277,103 @@ int __hw_addr_sync_dev(struct netdev_hw_addr_list *list, } EXPORT_SYMBOL(__hw_addr_sync_dev); +/** + * __hw_addr_ref_sync_dev - Synchronize device's multicast address list taking + * into account references + * @list: address list to synchronize + * @dev: device to sync + * @sync: function to call if address or reference on it should be added + * @unsync: function to call if address or some reference on it should removed + * + * This function is intended to be called from the ndo_set_rx_mode + * function of devices that require explicit address or references on it + * add/remove notifications. The unsync function may be NULL in which case + * the addresses or references on it requiring removal will simply be + * removed without any notification to the device. That is responsibility of + * the driver to identify and distribute address or references on it between + * internal address tables. + **/ +int __hw_addr_ref_sync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*sync)(struct net_device *, + const unsigned char *, int), + int (*unsync)(struct net_device *, + const unsigned char *, int)) +{ + struct netdev_hw_addr *ha, *tmp; + int err, keep_sync; + + /* first go through and flush out any unsynced/stale entries */ + list_for_each_entry_safe(ha, tmp, &list->list, list) { + /* sync if address is not used */ + if ((ha->sync_cnt << 1) <= ha->refcount) + continue; + + /* if fails defer unsyncing address */ + keep_sync = ha->refcount - ha->sync_cnt; + if (unsync && unsync(dev, ha->addr, keep_sync)) + continue; + + ha->refcount = (keep_sync << 1) + 1; + ha->sync_cnt = keep_sync; + __hw_addr_del_entry(list, ha, false, false); + } + + /* go through and sync updated/new entries to the list */ + list_for_each_entry_safe(ha, tmp, &list->list, list) { + /* sync if address added or reused */ + if ((ha->sync_cnt << 1) >= ha->refcount) + continue; + + keep_sync = ha->refcount - ha->sync_cnt; + err = sync(dev, ha->addr, keep_sync); + if (err) + return err; + + ha->refcount = keep_sync << 1; + ha->sync_cnt = keep_sync; + } + + return 0; +} +EXPORT_SYMBOL(__hw_addr_ref_sync_dev); + +/** + * __hw_addr_ref_unsync_dev - Remove synchronized addresses and references on + * it from device + * @list: address list to remove synchronized addresses (references on it) from + * @dev: device to sync + * @unsync: function to call if address and references on it should be removed + * + * Remove all addresses that were added to the device by + * __hw_addr_ref_sync_dev(). This function is intended to be called from the + * ndo_stop or ndo_open functions on devices that require explicit address (or + * references on it) add/remove notifications. If the unsync function pointer + * is NULL then this function can be used to just reset the sync_cnt for the + * addresses in the list. + **/ +void __hw_addr_ref_unsync_dev(struct netdev_hw_addr_list *list, + struct net_device *dev, + int (*unsync)(struct net_device *, + const unsigned char *, int)) +{ + struct netdev_hw_addr *ha, *tmp; + + list_for_each_entry_safe(ha, tmp, &list->list, list) { + if (!ha->sync_cnt) + continue; + + /* if fails defer unsyncing address */ + if (unsync && unsync(dev, ha->addr, ha->sync_cnt)) + continue; + + ha->refcount -= ha->sync_cnt - 1; + ha->sync_cnt = 0; + __hw_addr_del_entry(list, ha, false, false); + } +} +EXPORT_SYMBOL(__hw_addr_ref_unsync_dev); + /** * __hw_addr_unsync_dev - Remove synchronized addresses from device * @list: address list to remove synchronized addresses from From patchwork Tue Oct 16 18:20:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 148979 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp5435094lji; Tue, 16 Oct 2018 11:20:46 -0700 (PDT) X-Google-Smtp-Source: ACcGV63lHUFsc6qDLNjgWHwoK5Ay2FpPYNql5iO/K9FiVkOEqB51T0FPcKWDmr9pHGxj/kVOTeag X-Received: by 2002:a65:4d03:: with SMTP id i3-v6mr21257299pgt.239.1539714046649; Tue, 16 Oct 2018 11:20:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539714046; cv=none; d=google.com; s=arc-20160816; b=a7IbwgfxyeQ1bEo6QdGrjdxcwZGAkM8OSlv+5mAIBcLTx64n26KXpyFUxl32HMBDnn LkkGlSqIk7+KAC0z/SybSZjgQdYU88viUq0ac6PQMJnM1rTheR/nI/Hu8WS0mCf/67Fl KyqqPjLMi2FtT7aS45YkE9H+BV43PwEeHQLNiP8sHwL0fUaQcrIJLkDB0zlOwgg8ihL+ ch6zL3syKdOHHlr+mOnDqB7KxVPzDMj9BkYt1lj9EIiLa48uc/Rb8hjOEpsDBEJLcMUE z+34B4toF66A49z6nnSzlty6Sirk/9u70xNnZzs6ypGL5E/FBCpMdmtDEaJEbyGp0M36 l5bQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=qMvp12l9HpDMt+3I+o7Ztx63A+0YQDl6lBkSGcvnOGY=; b=y5SuxP4dxYmTYoYDkswAqBLFQg2RQFFOrGO8aAGdrFB4lMCSOgStj7ZIbV5kMVN9Br 7F5ztNRywDyC+NgxfDwATz5dfn4JYVN7/9Khlh7X/DMX/7uNG6GQE/N0xdLMPuphm4IH 76VvuV7m1XndqWQ8umo7H2cScdER5eEWAOCiTKX3nQ3Mta34lup+R7QVIiWasVJUgrxh sL5fcUy+eb6VNihQ+WJjL1j/vq+WNPqsC1PrYIkagUjgQTPbSl1FNRwJ2UtAPXdktiQg n6mhuAKRHCZaxm6mfRDguoq9mBSqPHWDS8cHdxx3Ve+S1v9B6nALzPR+rOas/Cbm1Fkl 7o9g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Si90Rq1s; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1-v6si1797097plj.79.2018.10.16.11.20.46; Tue, 16 Oct 2018 11:20:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Si90Rq1s; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727593AbeJQCMY (ORCPT + 32 others); Tue, 16 Oct 2018 22:12:24 -0400 Received: from mail-lf1-f67.google.com ([209.85.167.67]:39273 "EHLO mail-lf1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727247AbeJQCMX (ORCPT ); Tue, 16 Oct 2018 22:12:23 -0400 Received: by mail-lf1-f67.google.com with SMTP id n14-v6so5884359lfe.6 for ; Tue, 16 Oct 2018 11:20:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qMvp12l9HpDMt+3I+o7Ztx63A+0YQDl6lBkSGcvnOGY=; b=Si90Rq1sZ31V16S2ywoKtMnwHKjTBjCvpfPLoTDD5pjncIPiQhJaQ5/skVfJEiUwQk /vL4E225IMom3GkKtza2Q2O/P0cfzc60X8dognBpB7GKSv/7RgDmK6CJOAmxmQdDz/Uf BqqNBHmdSq/oMECjFfzpYMndPPbHMYGrM9nfw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qMvp12l9HpDMt+3I+o7Ztx63A+0YQDl6lBkSGcvnOGY=; b=DZnfUsGKwMmItj11dRryN0q7807ZpU3NAFDynO1St895qfBp4AEM/kv1+dWPpup3Mb uD/qeWdKRFQRMG43+5ppBubTuNfv8cqP5ij/QEa2nOLQPWEweLACmKWiudL1yiyqtvL7 RCS9GGpSJrqiOERQmKThatfkRoI1B1ujrJdry3a/QI3XOH9Yci+ts2k1HzfEjQ640VgA 4J3HBtUz8gDbbBCtzSdxXs6+AvU7itL3GZ3hpk8i1bhUbEMcFPp1YjON4zRF7y8wxZOF JQ4Ui+3kWaWg/nJwKiOaIztTUPObS5mMFt0CmV3EPB3Rq6SK4VC21PqL9BYht/GqZirI rxyQ== X-Gm-Message-State: ABuFfoieiMAss2h4daxligXCQSfRDKFO4H3nzdYehkxoVOqLHEyecUcM juwA7JqMMRWFVFKbnFCaE9sCsQ== X-Received: by 2002:a19:480c:: with SMTP id v12-v6mr13279098lfa.46.1539714041252; Tue, 16 Oct 2018 11:20:41 -0700 (PDT) Received: from localhost.localdomain (59-201-94-178.pool.ukrtel.net. [178.94.201.59]) by smtp.gmail.com with ESMTPSA id i27-v6sm3207844lfc.22.2018.10.16.11.20.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Oct 2018 11:20:40 -0700 (PDT) From: Ivan Khoronzhuk To: grygorii.strashko@ti.com, davem@davemloft.net Cc: linux-omap@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexander.h.duyck@intel.com, Ivan Khoronzhuk Subject: [RFC PATCH net-next 2/4] net: 8021q: vlan_core: allow use list of vlans for real device Date: Tue, 16 Oct 2018 21:20:33 +0300 Message-Id: <20181016182035.18234-3-ivan.khoronzhuk@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> References: <20181016182035.18234-1-ivan.khoronzhuk@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It's redundancy for the drivers to hold the list of vlans when absolutely the same list exists in vlan core. In most cases it's needed only to traverse the vlan devices, their vids and sync some settings with h/w, so add API to simplify this. At least some of these drivers also can benefit: grep "for_each.*vid" -r drivers/net/ethernet/ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c: drivers/net/ethernet/synopsys/dwc-xlgmac-hw.c: drivers/net/ethernet/qlogic/qlge/qlge_main.c: drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c: drivers/net/ethernet/via/via-rhine.c: drivers/net/ethernet/via/via-velocity.c: drivers/net/ethernet/intel/igb/igb_main.c: drivers/net/ethernet/intel/ice/ice_main.c: drivers/net/ethernet/intel/e1000/e1000_main.c: drivers/net/ethernet/intel/i40e/i40e_main.c: drivers/net/ethernet/intel/e1000e/netdev.c: drivers/net/ethernet/intel/igbvf/netdev.c: drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c: drivers/net/ethernet/intel/ixgb/ixgb_main.c: drivers/net/ethernet/intel/ixgbe/ixgbe_main.c: drivers/net/ethernet/amd/xgbe/xgbe-dev.c: drivers/net/ethernet/emulex/benet/be_main.c: drivers/net/ethernet/neterion/vxge/vxge-main.c: drivers/net/ethernet/adaptec/starfire.c: drivers/net/ethernet/brocade/bna/bnad.c: Signed-off-by: Ivan Khoronzhuk --- include/linux/if_vlan.h | 10 ++++++++++ net/8021q/vlan_core.c | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) -- 2.17.1 diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 83ea4df6ab81..4ae3993f7166 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -133,6 +133,9 @@ struct vlan_pcpu_stats { extern struct net_device *__vlan_find_dev_deep_rcu(struct net_device *real_dev, __be16 vlan_proto, u16 vlan_id); +extern int vlan_for_each(struct net_device *dev, + int (*action)(struct net_device *dev, int vid, + void *arg), void *arg); extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); @@ -236,6 +239,13 @@ __vlan_find_dev_deep_rcu(struct net_device *real_dev, return NULL; } +static inline int +vlan_for_each(struct net_device *dev, + int (*action)(struct net_device *dev, int vid, void *arg), + void *arg) +{ +} + static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) { BUG(); diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 4f60e86f4b8d..6308b5427a66 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -223,6 +223,33 @@ static int vlan_kill_rx_filter_info(struct net_device *dev, __be16 proto, u16 vi return -ENODEV; } +int vlan_for_each(struct net_device *dev, + int (*action)(struct net_device *dev, int vid, void *arg), + void *arg) +{ + struct vlan_vid_info *vid_info; + struct vlan_info *vlan_info; + struct net_device *vdev; + int ret; + + ASSERT_RTNL(); + + vlan_info = rtnl_dereference(dev->vlan_info); + if (!vlan_info) + return 0; + + list_for_each_entry(vid_info, &vlan_info->vid_list, list) { + vdev = vlan_group_get_device(&vlan_info->grp, vid_info->proto, + vid_info->vid); + ret = action(vdev, vid_info->vid, arg); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL(vlan_for_each); + int vlan_filter_push_vids(struct vlan_info *vlan_info, __be16 proto) { struct net_device *real_dev = vlan_info->real_dev;