From patchwork Sun May 25 13:15:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jamal Hadi Salim X-Patchwork-Id: 352242 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 829F3140084 for ; Sun, 25 May 2014 23:16:13 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751469AbaEYNQH (ORCPT ); Sun, 25 May 2014 09:16:07 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:38518 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751389AbaEYNQF (ORCPT ); Sun, 25 May 2014 09:16:05 -0400 Received: by mail-pa0-f45.google.com with SMTP id ey11so6286158pad.4 for ; Sun, 25 May 2014 06:16:05 -0700 (PDT) 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=VuelH5o6hYmSUK/ICWaJTS2XR5NTFcHUbS1UlVGu7rc=; b=Fz4pcYtyJq1++RWb1cZq84ItQbQ2RiHU1QhmCwDUYPoRj3ZYeJ+zPPATRGO+QyPFf6 oeFVIcxUZMPSNHnygHuy6rNDdMZzMPPRLGCzoRK2CgfGqvWlGJQzc5/2i15gAPrto42M 3TA6WO/l7hGntPQK9zGl66BjUba9ZeUnTY0LcwAtrET29gaIF2viJiCvcSsSZutfP1UP kzH6XCCUMRwJgGsXVmQj3iQcCWz23I+Lq5njVB/s/j9/U7iTMWs+IPjwnIDEFyjG6gQg TmRGEOtE5t+LnzJhK+e/IG0TIFkvTC0lBwOAS/n1Mn8aCszVe6BAJVBshcxV983ki6jS 9TZQ== X-Gm-Message-State: ALoCoQm8g/pJQkDpnxp8gvnChoeYhn2bhUBKqlGfZcZXqeAqimmGrtYzY0/U3aFX7ygF3gyIrW8i X-Received: by 10.68.254.5 with SMTP id ae5mr20278277pbd.83.1401023765175; Sun, 25 May 2014 06:16:05 -0700 (PDT) Received: from jhs-1.lan (198-84-205-203.cpe.teksavvy.com. [198.84.205.203]) by mx.google.com with ESMTPSA id wp3sm13517647pbc.67.2014.05.25.06.16.03 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 25 May 2014 06:16:04 -0700 (PDT) From: Jamal Hadi Salim X-Google-Original-From: Jamal Hadi Salim To: davem@davemloft.net Cc: netdev@vger.kernel.org, stephen@networkplumber.org, vyasevic@redhat.com, john.r.fastabend@intel.com, sfeldma@cumulusnetworks.com, Jamal Hadi Salim Subject: [net-next PATCH v2 1/1] bring netlink interface to par with brctl show macs Date: Sun, 25 May 2014 09:15:55 -0400 Message-Id: <1401023755-8174-1-git-send-email-jhs@emojatatu.com> X-Mailer: git-send-email 1.7.9.5 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jamal Hadi Salim This patch allows something equivalent to "brctl showmacs " with iproute2 syntax "bridge fdb show br " Filtering by bridge is done in the kernel. The current setup doesnt scale when you have many bridges each with large fdbs (preliminary fix with the kernel patch). Signed-off-by: Jamal Hadi Salim --- net/core/rtnetlink.c | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f31268d..1ad4828 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2509,26 +2509,45 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) { int idx = 0; struct net *net = sock_net(skb->sk); + const struct net_device_ops *ops; struct net_device *dev; + struct ndmsg *ndm; - rcu_read_lock(); - for_each_netdev_rcu(net, dev) { - if (dev->priv_flags & IFF_BRIDGE_PORT) { - struct net_device *br_dev; - const struct net_device_ops *ops; - - br_dev = netdev_master_upper_dev_get(dev); - ops = br_dev->netdev_ops; - if (ops->ndo_fdb_dump) - idx = ops->ndo_fdb_dump(skb, cb, dev, idx); + ndm = nlmsg_data(cb->nlh); + if (ndm->ndm_ifindex) { + dev = __dev_get_by_index(net, ndm->ndm_ifindex); + if (dev == NULL) { + pr_info("PF_BRIDGE: RTM_GETNEIGH with unknown ifindex\n"); + return -ENODEV; } - if (dev->netdev_ops->ndo_fdb_dump) - idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx); - else - idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); + ops = dev->netdev_ops; + if (ops->ndo_fdb_dump) { + idx = ops->ndo_fdb_dump(skb, cb, dev, idx); + } else { + pr_info("PF_BRIDGE: RTM_GETNEIGH %s no dumper\n", + dev->name); + return -EINVAL; + } + } else { + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->priv_flags & IFF_BRIDGE_PORT) { + struct net_device *br_dev; + br_dev = netdev_master_upper_dev_get(dev); + ops = br_dev->netdev_ops; + if (ops->ndo_fdb_dump) + idx = ops->ndo_fdb_dump(skb, cb, dev, idx); + } + + if (dev->netdev_ops->ndo_fdb_dump) + idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, + idx); + else + idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); + } + rcu_read_unlock(); } - rcu_read_unlock(); cb->args[0] = idx; return skb->len;