bridge: fdb dumping takes a filter device

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>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jamal Hadi Salim 2014-07-10 07:01:58 -04:00 committed by David S. Miller
parent 69b4b7a414
commit 5d5eacb34c
8 changed files with 24 additions and 10 deletions

View File

@ -7095,13 +7095,14 @@ static int i40e_ndo_fdb_del(struct ndmsg *ndm,
static int i40e_ndo_fdb_dump(struct sk_buff *skb, static int i40e_ndo_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb, struct netlink_callback *cb,
struct net_device *dev, struct net_device *dev,
struct net_device *filter_dev,
int idx) int idx)
{ {
struct i40e_netdev_priv *np = netdev_priv(dev); struct i40e_netdev_priv *np = netdev_priv(dev);
struct i40e_pf *pf = np->vsi->back; struct i40e_pf *pf = np->vsi->back;
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) 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; return idx;
} }

View File

@ -427,16 +427,17 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
} }
static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb, 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); struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (!adapter->fdb_mac_learn) 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) || if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_sriov_check(adapter)) qlcnic_sriov_check(adapter))
idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx); idx = ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx);
return idx; return idx;
} }

View File

@ -933,7 +933,8 @@ static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
/* Dump forwarding table */ /* Dump forwarding table */
static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct net_device *dev, int idx) struct net_device *dev,
struct net_device *filter_dev, int idx)
{ {
struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned int h; unsigned int h;

View File

@ -943,7 +943,8 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* const unsigned char *addr) * const unsigned char *addr)
* Deletes the FDB entry from dev coresponding to addr. * Deletes the FDB entry from dev coresponding to addr.
* int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb, * int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,
* struct net_device *dev, int idx) * struct net_device *dev, struct net_device *filter_dev,
* int idx)
* Used to add FDB entries to dump requests. Implementers should add * Used to add FDB entries to dump requests. Implementers should add
* entries to skb and update idx with the number of entries. * entries to skb and update idx with the number of entries.
* *
@ -1114,6 +1115,7 @@ struct net_device_ops {
int (*ndo_fdb_dump)(struct sk_buff *skb, int (*ndo_fdb_dump)(struct sk_buff *skb,
struct netlink_callback *cb, struct netlink_callback *cb,
struct net_device *dev, struct net_device *dev,
struct net_device *filter_dev,
int idx); int idx);
int (*ndo_bridge_setlink)(struct net_device *dev, int (*ndo_bridge_setlink)(struct net_device *dev,

View File

@ -78,6 +78,7 @@ extern void __rtnl_unlock(void);
extern int ndo_dflt_fdb_dump(struct sk_buff *skb, extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb, struct netlink_callback *cb,
struct net_device *dev, struct net_device *dev,
struct net_device *filter_dev,
int idx); int idx);
extern int ndo_dflt_fdb_add(struct ndmsg *ndm, extern int ndo_dflt_fdb_add(struct ndmsg *ndm,
struct nlattr *tb[], struct nlattr *tb[],

View File

@ -676,6 +676,7 @@ static void fdb_notify(struct net_bridge *br,
int br_fdb_dump(struct sk_buff *skb, int br_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb, struct netlink_callback *cb,
struct net_device *dev, struct net_device *dev,
struct net_device *filter_dev,
int idx) int idx)
{ {
struct net_bridge *br = netdev_priv(dev); struct net_bridge *br = netdev_priv(dev);
@ -691,6 +692,10 @@ int br_fdb_dump(struct sk_buff *skb,
if (idx < cb->args[0]) if (idx < cb->args[0])
goto skip; goto skip;
if (filter_dev && (!f->dst || !f->dst->dev ||
f->dst->dev != filter_dev))
goto skip;
if (fdb_fill_info(skb, br, f, if (fdb_fill_info(skb, br, f,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,

View File

@ -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, int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
const unsigned char *addr, u16 nlh_flags); const unsigned char *addr, u16 nlh_flags);
int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, 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); 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); void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);

View File

@ -2517,6 +2517,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
int ndo_dflt_fdb_dump(struct sk_buff *skb, int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb, struct netlink_callback *cb,
struct net_device *dev, struct net_device *dev,
struct net_device *filter_dev,
int idx) int idx)
{ {
int err; int err;
@ -2547,13 +2548,15 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
br_dev = netdev_master_upper_dev_get(dev); br_dev = netdev_master_upper_dev_get(dev);
ops = br_dev->netdev_ops; ops = br_dev->netdev_ops;
if (ops->ndo_fdb_dump) 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) 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 else
idx = ndo_dflt_fdb_dump(skb, cb, dev, idx); idx = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
} }
rcu_read_unlock(); rcu_read_unlock();