* [net-next PATCH v3 0/2] bridge: more efficient fdb dumping
@ 2014-06-25 10:21 Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 1/2] bridge: fdb dumping takes a filter device Jamal Hadi Salim
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Jamal Hadi Salim @ 2014-06-25 10:21 UTC (permalink / raw)
To: davem, stephen
Cc: netdev, vyasevic, sfeldma, john.r.fastabend, roopa, eric.dumazet,
Jamal Hadi Salim
From: Jamal Hadi Salim <jhs@mojatatu.com>
Changes:
V3:
Suggestion from Eric D. to use for_each_netdev
Suggestion from Stephen H. to reduce level of indentation
V2:
Suggestions from Vlad
Get rid of rcu read lock since rtnl_lock is being held
simplify for readability
Jamal Hadi Salim (2):
bridge: fdb dumping takes a filter device
bridge: netlink dump interface at par with brctl
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +-
include/linux/netdevice.h | 1 +
include/linux/rtnetlink.h | 1 +
net/bridge/br_fdb.c | 14 ++++
net/bridge/br_private.h | 2 +-
net/core/rtnetlink.c | 77 +++++++++++++++++-----
7 files changed, 84 insertions(+), 19 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 5+ messages in thread
* [net-next PATCH v3 1/2] bridge: fdb dumping takes a filter device
2014-06-25 10:21 [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
@ 2014-06-25 10:21 ` Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 2/2] bridge: netlink dump interface at par with brctl Jamal Hadi Salim
2014-06-25 10:25 ` [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
2 siblings, 0 replies; 5+ messages in thread
From: Jamal Hadi Salim @ 2014-06-25 10:21 UTC (permalink / raw)
To: davem, stephen
Cc: netdev, vyasevic, sfeldma, john.r.fastabend, roopa, eric.dumazet,
Jamal Hadi Salim
From: Jamal Hadi Salim <jhs@mojatatu.com>
Dumping a bridge fdb dumps every fdb entry
held. With this change we are going to filter
on selected bridge port.
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 ++-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +++--
include/linux/netdevice.h | 1 +
include/linux/rtnetlink.h | 1 +
net/bridge/br_fdb.c | 5 +++++
net/bridge/br_private.h | 2 +-
net/core/rtnetlink.c | 7 ++++---
7 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index b167fc2..6d2df6d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7029,13 +7029,14 @@ static int i40e_ndo_fdb_del(struct ndmsg *ndm,
static int i40e_ndo_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
+ struct net_device *filter_dev,
int idx)
{
struct i40e_netdev_priv *np = netdev_priv(dev);
struct i40e_pf *pf = np->vsi->back;
if (pf->flags & I40E_FLAG_SRIOV_ENABLED)
- idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+ idx = ndo_dflt_fdb_dump(skb, cb, dev, filter_dev, idx);
return idx;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 4fc1867..b82179d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -427,12 +427,13 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
}
static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb,
- struct net_device *netdev, int idx)
+ struct net_device *netdev, struct net_device *filter_dev,
+ int idx)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (!adapter->fdb_mac_learn)
- return ndo_dflt_fdb_dump(skb, ncb, netdev, idx);
+ return ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx);
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_sriov_check(adapter))
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 66f9a04..8d46984 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1114,6 +1114,7 @@ struct net_device_ops {
int (*ndo_fdb_dump)(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
+ struct net_device *filter_dev,
int idx);
int (*ndo_bridge_setlink)(struct net_device *dev,
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 953937e..167bae7 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -78,6 +78,7 @@ extern void __rtnl_unlock(void);
extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
+ struct net_device *filter_dev,
int idx);
extern int ndo_dflt_fdb_add(struct ndmsg *ndm,
struct nlattr *tb[],
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 7be3366..6edecd1 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -676,6 +676,7 @@ errout:
int br_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
+ struct net_device *filter_dev,
int idx)
{
struct net_bridge *br = netdev_priv(dev);
@@ -691,6 +692,10 @@ int br_fdb_dump(struct sk_buff *skb,
if (idx < cb->args[0])
goto skip;
+ if (filter_dev && (!f->dst || !f->dst->dev ||
+ f->dst->dev != filter_dev))
+ goto skip;
+
if (fdb_fill_info(skb, br, f,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 23caf5b..62a7fa2 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -399,7 +399,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
const unsigned char *addr, u16 nlh_flags);
int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
- struct net_device *dev, int idx);
+ struct net_device *dev, struct net_device *fdev, int idx);
int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1063996..7471060 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2509,6 +2509,7 @@ skip:
int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
+ struct net_device *filter_dev,
int idx)
{
int err;
@@ -2539,13 +2540,13 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
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);
+ idx = ops->ndo_fdb_dump(skb, cb, dev, NULL, idx);
}
if (dev->netdev_ops->ndo_fdb_dump)
- idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx);
+ idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, idx);
else
- idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+ idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
}
rcu_read_unlock();
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [net-next PATCH v3 2/2] bridge: netlink dump interface at par with brctl
2014-06-25 10:21 [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 1/2] bridge: fdb dumping takes a filter device Jamal Hadi Salim
@ 2014-06-25 10:21 ` Jamal Hadi Salim
2014-06-27 0:45 ` David Miller
2014-06-25 10:25 ` [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
2 siblings, 1 reply; 5+ messages in thread
From: Jamal Hadi Salim @ 2014-06-25 10:21 UTC (permalink / raw)
To: davem, stephen
Cc: netdev, vyasevic, sfeldma, john.r.fastabend, roopa, eric.dumazet,
Jamal Hadi Salim
From: Jamal Hadi Salim <jhs@mojatatu.com>
Actually better than brctl showmacs because we can filter by bridge
port in the kernel.
The current bridge netlink interface doesnt scale when you have many
bridges each with large fdbs or even bridges with many bridge ports
And now for the science non-fiction novel you have all been
waiting for..
//lets see what bridge ports we have
root@moja-1:/configs/may30-iprt/bridge# ./bridge link show
8: eth1 state DOWN : <BROADCAST,MULTICAST> mtu 1500 master br0 state
disabled priority 32 cost 19
17: sw1-p1 state DOWN : <BROADCAST,NOARP> mtu 1500 master br0 state
disabled priority 32 cost 100
// show all..
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show
33:33:00:00:00:01 dev bond0 self permanent
33:33:00:00:00:01 dev dummy0 self permanent
33:33:00:00:00:01 dev ifb0 self permanent
33:33:00:00:00:01 dev ifb1 self permanent
33:33:00:00:00:01 dev eth0 self permanent
01:00:5e:00:00:01 dev eth0 self permanent
33:33:ff:22:01:01 dev eth0 self permanent
02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:07 dev eth1 self permanent
33:33:00:00:00:01 dev eth1 self permanent
33:33:00:00:00:01 dev gretap0 self permanent
da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
33:33:00:00:00:01 dev sw1-p1 self permanent
//filter by bridge
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0
02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:07 dev eth1 self permanent
33:33:00:00:00:01 dev eth1 self permanent
da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
33:33:00:00:00:01 dev sw1-p1 self permanent
// bridge sw1 has no ports attached..
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br sw1
//filter by port
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show brport eth1
02:00:00:12:01:02 vlan 0 master br0 permanent
00:17:42:8a:b4:05 vlan 0 master br0 permanent
00:17:42:8a:b4:07 self permanent
33:33:00:00:00:01 self permanent
// filter by port + bridge
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0 brport
sw1-p1
da:ac:46:27:d9:53 vlan 0 master br0 permanent
33:33:00:00:00:01 self permanent
// for shits and giggles, lets change the mac that br0 uses
// Note: a magical fdb entry with no brport is added ...
root@moja-1:/configs/may30-iprt/bridge# ip link set dev br0 address
02:00:00:12:01:04
// lets see if we can see the unicorn ..
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show
33:33:00:00:00:01 dev bond0 self permanent
33:33:00:00:00:01 dev dummy0 self permanent
33:33:00:00:00:01 dev ifb0 self permanent
33:33:00:00:00:01 dev ifb1 self permanent
33:33:00:00:00:01 dev eth0 self permanent
01:00:5e:00:00:01 dev eth0 self permanent
33:33:ff:22:01:01 dev eth0 self permanent
02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:07 dev eth1 self permanent
33:33:00:00:00:01 dev eth1 self permanent
33:33:00:00:00:01 dev gretap0 self permanent
02:00:00:12:01:04 dev br0 vlan 0 master br0 permanent <=== there it is
da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
33:33:00:00:00:01 dev sw1-p1 self permanent
//can we see it if we filter by bridge?
root@moja-1:/configs/may30-iprt/bridge# ./bridge fdb show br br0
02:00:00:12:01:02 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:05 dev eth1 vlan 0 master br0 permanent
00:17:42:8a:b4:07 dev eth1 self permanent
33:33:00:00:00:01 dev eth1 self permanent
02:00:00:12:01:04 dev br0 vlan 0 master br0 permanent <=== there it is
da:ac:46:27:d9:53 dev sw1-p1 vlan 0 master br0 permanent
33:33:00:00:00:01 dev sw1-p1 self permanent
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
net/bridge/br_fdb.c | 15 ++++++++--
net/core/rtnetlink.c | 76 ++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 73 insertions(+), 18 deletions(-)
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 6edecd1..115fe1c 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -692,9 +692,18 @@ int br_fdb_dump(struct sk_buff *skb,
if (idx < cb->args[0])
goto skip;
- if (filter_dev && (!f->dst || !f->dst->dev ||
- f->dst->dev != filter_dev))
- goto skip;
+ if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) {
+ if (filter_dev != dev)
+ goto skip;
+ /*
+ * !f->dst is a speacial case for bridge
+ * It means the MAC belongs to the bridge
+ * Therefore need a little more filtering
+ * we only want to dump the !f->dst case
+ */
+ if (f->dst)
+ goto skip;
+ }
if (fdb_fill_info(skb, br, f,
NETLINK_CB(cb->skb).portid,
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 7471060..464007e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2527,28 +2527,74 @@ EXPORT_SYMBOL(ndo_dflt_fdb_dump);
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
- int idx = 0;
- struct net *net = sock_net(skb->sk);
struct net_device *dev;
+ struct nlattr *tb[IFLA_MAX+1];
+ struct net_device *bdev = NULL;
+ struct net_device *br_dev = NULL;
+ const struct net_device_ops *ops = NULL;
+ const struct net_device_ops *cops = NULL;
+ struct ifinfomsg *ifm = nlmsg_data(cb->nlh);
+ struct net *net = sock_net(skb->sk);
+ int brport_idx = 0;
+ int br_idx = 0;
+ int idx = 0;
+
+ if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
+ ifla_policy) == 0) {
+ if (tb[IFLA_MASTER])
+ br_idx = nla_get_u32(tb[IFLA_MASTER]);
+ }
+
+ brport_idx = ifm->ifi_index;
+
+ if (br_idx) {
+ br_dev = __dev_get_by_index(net, br_idx);
+ if (!br_dev) {
+ return -ENODEV;
+ }
+ ops = br_dev->netdev_ops;
+ bdev = br_dev;
+ }
+
+ for_each_netdev(net, dev) {
+
+ if (brport_idx && (dev->ifindex != brport_idx))
+ continue;
+
+ if (!br_idx) { /* user did not specify a specific bridge */
+ if (dev->priv_flags & IFF_BRIDGE_PORT) {
+ br_dev = netdev_master_upper_dev_get(dev);
+ cops = br_dev->netdev_ops;
+ }
+
+ bdev = dev;
+ } else {
+ if (dev != br_dev &&
+ !(dev->priv_flags & IFF_BRIDGE_PORT))
+ continue;
+
+ if (br_dev != netdev_master_upper_dev_get(dev) &&
+ !(dev->priv_flags & IFF_EBRIDGE))
+ continue;
+
+ bdev = br_dev;
+ cops = ops;
+ }
- 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;
+ if (cops && cops->ndo_fdb_dump) {
+ idx = cops->ndo_fdb_dump(skb, cb, br_dev, dev, idx);
+ }
+ }
- 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, NULL, idx);
+ idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
+ if (dev->netdev_ops->ndo_fdb_dump) {
+ idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, bdev, dev,
+ idx);
}
- if (dev->netdev_ops->ndo_fdb_dump)
- idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, idx);
- else
- idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
+ cops = NULL;
}
- rcu_read_unlock();
cb->args[0] = idx;
return skb->len;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [net-next PATCH v3 0/2] bridge: more efficient fdb dumping
2014-06-25 10:21 [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 1/2] bridge: fdb dumping takes a filter device Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 2/2] bridge: netlink dump interface at par with brctl Jamal Hadi Salim
@ 2014-06-25 10:25 ` Jamal Hadi Salim
2 siblings, 0 replies; 5+ messages in thread
From: Jamal Hadi Salim @ 2014-06-25 10:25 UTC (permalink / raw)
To: davem, stephen
Cc: netdev, vyasevic, sfeldma, john.r.fastabend, roopa, eric.dumazet
I should say I have tested this version against net-next
(the commit message describes the validation tests)
cheers,
jamal
On 06/25/14 06:21, Jamal Hadi Salim wrote:
> From: Jamal Hadi Salim <jhs@mojatatu.com>
>
> Changes:
> V3:
> Suggestion from Eric D. to use for_each_netdev
> Suggestion from Stephen H. to reduce level of indentation
>
> V2:
> Suggestions from Vlad
> Get rid of rcu read lock since rtnl_lock is being held
> simplify for readability
>
>
> Jamal Hadi Salim (2):
> bridge: fdb dumping takes a filter device
> bridge: netlink dump interface at par with brctl
>
> drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +-
> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +-
> include/linux/netdevice.h | 1 +
> include/linux/rtnetlink.h | 1 +
> net/bridge/br_fdb.c | 14 ++++
> net/bridge/br_private.h | 2 +-
> net/core/rtnetlink.c | 77 +++++++++++++++++-----
> 7 files changed, 84 insertions(+), 19 deletions(-)
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [net-next PATCH v3 2/2] bridge: netlink dump interface at par with brctl
2014-06-25 10:21 ` [net-next PATCH v3 2/2] bridge: netlink dump interface at par with brctl Jamal Hadi Salim
@ 2014-06-27 0:45 ` David Miller
0 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2014-06-27 0:45 UTC (permalink / raw)
To: jhs
Cc: stephen, netdev, vyasevic, sfeldma, john.r.fastabend, roopa,
eric.dumazet
From: Jamal Hadi Salim <jhs@mojatatu.com>
Date: Wed, 25 Jun 2014 06:21:23 -0400
> + /*
> + * !f->dst is a speacial case for bridge
> + * It means the MAC belongs to the bridge
> + * Therefore need a little more filtering
> + * we only want to dump the !f->dst case
> + */
Please format comments:
/* Like
* this.
*/
in the networking.
> + for_each_netdev(net, dev) {
> +
> + if (brport_idx && (dev->ifindex != brport_idx))
Please remove that empty line.
> + if (cops && cops->ndo_fdb_dump) {
> + idx = cops->ndo_fdb_dump(skb, cb, br_dev, dev, idx);
> + }
Single statement basic blocks do not need curly braces.
> + if (dev->netdev_ops->ndo_fdb_dump) {
> + idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, bdev, dev,
> + idx);
> }
Likewise.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-06-27 0:45 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-25 10:21 [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 1/2] bridge: fdb dumping takes a filter device Jamal Hadi Salim
2014-06-25 10:21 ` [net-next PATCH v3 2/2] bridge: netlink dump interface at par with brctl Jamal Hadi Salim
2014-06-27 0:45 ` David Miller
2014-06-25 10:25 ` [net-next PATCH v3 0/2] bridge: more efficient fdb dumping Jamal Hadi Salim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).