aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJamal Hadi Salim <jhs@mojatatu.com>2014-07-10 07:01:59 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-10 15:37:33 -0400
commit5e6d243587990a588143b9da3974833649595587 (patch)
tree8d42638be83b6904e1a2a8f58f41988ee9390430 /net/core
parent5d5eacb34c9e1fdc0a47b885d832eaa4de860dc7 (diff)
bridge: netlink dump interface at par with brctl
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 (as they say in New Brunswick), 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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/rtnetlink.c74
1 files changed, 58 insertions, 16 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 90a906e7ac26..1f8a59e02c48 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2535,30 +2535,72 @@ EXPORT_SYMBOL(ndo_dflt_fdb_dump);
2535 2535
2536static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) 2536static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
2537{ 2537{
2538 int idx = 0;
2539 struct net *net = sock_net(skb->sk);
2540 struct net_device *dev; 2538 struct net_device *dev;
2539 struct nlattr *tb[IFLA_MAX+1];
2540 struct net_device *bdev = NULL;
2541 struct net_device *br_dev = NULL;
2542 const struct net_device_ops *ops = NULL;
2543 const struct net_device_ops *cops = NULL;
2544 struct ifinfomsg *ifm = nlmsg_data(cb->nlh);
2545 struct net *net = sock_net(skb->sk);
2546 int brport_idx = 0;
2547 int br_idx = 0;
2548 int idx = 0;
2549
2550 if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
2551 ifla_policy) == 0) {
2552 if (tb[IFLA_MASTER])
2553 br_idx = nla_get_u32(tb[IFLA_MASTER]);
2554 }
2555
2556 brport_idx = ifm->ifi_index;
2557
2558 if (br_idx) {
2559 br_dev = __dev_get_by_index(net, br_idx);
2560 if (!br_dev)
2561 return -ENODEV;
2562
2563 ops = br_dev->netdev_ops;
2564 bdev = br_dev;
2565 }
2566
2567 for_each_netdev(net, dev) {
2568 if (brport_idx && (dev->ifindex != brport_idx))
2569 continue;
2570
2571 if (!br_idx) { /* user did not specify a specific bridge */
2572 if (dev->priv_flags & IFF_BRIDGE_PORT) {
2573 br_dev = netdev_master_upper_dev_get(dev);
2574 cops = br_dev->netdev_ops;
2575 }
2576
2577 bdev = dev;
2578 } else {
2579 if (dev != br_dev &&
2580 !(dev->priv_flags & IFF_BRIDGE_PORT))
2581 continue;
2582
2583 if (br_dev != netdev_master_upper_dev_get(dev) &&
2584 !(dev->priv_flags & IFF_EBRIDGE))
2585 continue;
2586
2587 bdev = br_dev;
2588 cops = ops;
2589 }
2541 2590
2542 rcu_read_lock();
2543 for_each_netdev_rcu(net, dev) {
2544 if (dev->priv_flags & IFF_BRIDGE_PORT) { 2591 if (dev->priv_flags & IFF_BRIDGE_PORT) {
2545 struct net_device *br_dev; 2592 if (cops && cops->ndo_fdb_dump)
2546 const struct net_device_ops *ops; 2593 idx = cops->ndo_fdb_dump(skb, cb, br_dev, dev,
2547 2594 idx);
2548 br_dev = netdev_master_upper_dev_get(dev);
2549 ops = br_dev->netdev_ops;
2550 if (ops->ndo_fdb_dump)
2551 idx = ops->ndo_fdb_dump(skb, cb, dev, NULL,
2552 idx);
2553 } 2595 }
2554 2596
2597 idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
2555 if (dev->netdev_ops->ndo_fdb_dump) 2598 if (dev->netdev_ops->ndo_fdb_dump)
2556 idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, 2599 idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, bdev, dev,
2557 idx); 2600 idx);
2558 else 2601
2559 idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx); 2602 cops = NULL;
2560 } 2603 }
2561 rcu_read_unlock();
2562 2604
2563 cb->args[0] = idx; 2605 cb->args[0] = idx;
2564 return skb->len; 2606 return skb->len;