[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1401023042-6902-1-git-send-email-jhs@emojatatu.com>
Date: Sun, 25 May 2014 09:04:02 -0400
From: Jamal Hadi Salim <jhs@...atatu.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, stephen@...workplumber.org,
vyasevic@...hat.com, john.r.fastabend@...el.com,
sfeldma@...ulusnetworks.com, Jamal Hadi Salim <jhs@...atatu.com>
Subject: [net-next PATCH 1/1] bridge netlink interface at par with brctl show macs
From: Jamal Hadi Salim <jhs@...atatu.com>
This patch allows something equivalent to
"brctl showmacs <bridge device>" with iproute2
syntax "bridge fdb show br <bridge device>"
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 <jhs@...atatu.com>
---
net/core/rtnetlink.c | 50 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 15 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f31268d..a605742 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2509,26 +2509,46 @@ 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);
+ printk("Requested for bridge <%s>\n", dev->name);
+ 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;
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists