staging: dpaa2-switch: add fast-ageing on bridge leave
Upon leaving a bridge, any MAC addresses learnt on the switch port prior to this point have to be removed so that we preserve the bridging domain configuration. Restructure the dpaa2_switch_port_fdb_dump() function in order to have a common dpaa2_switch_fdb_iterate() function between the FDB dump callback and the fast age procedure. To accomplish this, add a new callback - dpaa2_switch_fdb_cb_t - which will be called on each MAC addr and, depending on the situation, will either dump the FDB entry into a netlink message or will delete the address from the FDB table, in case of the fast-age. Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d671407fcc
commit
685b480145
@ -729,21 +729,14 @@ static int dpaa2_switch_port_fdb_valid_entry(struct fdb_dump_entry *entry,
|
||||
return valid;
|
||||
}
|
||||
|
||||
static int dpaa2_switch_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
struct net_device *net_dev,
|
||||
struct net_device *filter_dev, int *idx)
|
||||
static int dpaa2_switch_fdb_iterate(struct ethsw_port_priv *port_priv,
|
||||
dpaa2_switch_fdb_cb_t cb, void *data)
|
||||
{
|
||||
struct ethsw_port_priv *port_priv = netdev_priv(net_dev);
|
||||
struct net_device *net_dev = port_priv->netdev;
|
||||
struct ethsw_core *ethsw = port_priv->ethsw_data;
|
||||
struct device *dev = net_dev->dev.parent;
|
||||
struct fdb_dump_entry *fdb_entries;
|
||||
struct fdb_dump_entry fdb_entry;
|
||||
struct ethsw_dump_ctx dump = {
|
||||
.dev = net_dev,
|
||||
.skb = skb,
|
||||
.cb = cb,
|
||||
.idx = *idx,
|
||||
};
|
||||
dma_addr_t fdb_dump_iova;
|
||||
u16 num_fdb_entries;
|
||||
u32 fdb_dump_size;
|
||||
@ -778,17 +771,12 @@ static int dpaa2_switch_port_fdb_dump(struct sk_buff *skb, struct netlink_callba
|
||||
for (i = 0; i < num_fdb_entries; i++) {
|
||||
fdb_entry = fdb_entries[i];
|
||||
|
||||
if (!dpaa2_switch_port_fdb_valid_entry(&fdb_entry, port_priv))
|
||||
continue;
|
||||
|
||||
err = dpaa2_switch_fdb_dump_nl(&fdb_entry, &dump);
|
||||
err = cb(port_priv, &fdb_entry, data);
|
||||
if (err)
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
*idx = dump.idx;
|
||||
|
||||
kfree(dma_mem);
|
||||
|
||||
return 0;
|
||||
@ -800,6 +788,59 @@ err_map:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dpaa2_switch_fdb_entry_dump(struct ethsw_port_priv *port_priv,
|
||||
struct fdb_dump_entry *fdb_entry,
|
||||
void *data)
|
||||
{
|
||||
if (!dpaa2_switch_port_fdb_valid_entry(fdb_entry, port_priv))
|
||||
return 0;
|
||||
|
||||
return dpaa2_switch_fdb_dump_nl(fdb_entry, data);
|
||||
}
|
||||
|
||||
static int dpaa2_switch_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
struct net_device *net_dev,
|
||||
struct net_device *filter_dev, int *idx)
|
||||
{
|
||||
struct ethsw_port_priv *port_priv = netdev_priv(net_dev);
|
||||
struct ethsw_dump_ctx dump = {
|
||||
.dev = net_dev,
|
||||
.skb = skb,
|
||||
.cb = cb,
|
||||
.idx = *idx,
|
||||
};
|
||||
int err;
|
||||
|
||||
err = dpaa2_switch_fdb_iterate(port_priv, dpaa2_switch_fdb_entry_dump, &dump);
|
||||
*idx = dump.idx;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dpaa2_switch_fdb_entry_fast_age(struct ethsw_port_priv *port_priv,
|
||||
struct fdb_dump_entry *fdb_entry,
|
||||
void *data __always_unused)
|
||||
{
|
||||
if (!dpaa2_switch_port_fdb_valid_entry(fdb_entry, port_priv))
|
||||
return 0;
|
||||
|
||||
if (!(fdb_entry->type & DPSW_FDB_ENTRY_TYPE_DYNAMIC))
|
||||
return 0;
|
||||
|
||||
if (fdb_entry->type & DPSW_FDB_ENTRY_TYPE_UNICAST)
|
||||
dpaa2_switch_port_fdb_del_uc(port_priv, fdb_entry->mac_addr);
|
||||
else
|
||||
dpaa2_switch_port_fdb_del_mc(port_priv, fdb_entry->mac_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dpaa2_switch_port_fast_age(struct ethsw_port_priv *port_priv)
|
||||
{
|
||||
dpaa2_switch_fdb_iterate(port_priv,
|
||||
dpaa2_switch_fdb_entry_fast_age, NULL);
|
||||
}
|
||||
|
||||
static int dpaa2_switch_port_vlan_add(struct net_device *netdev, __be16 proto,
|
||||
u16 vid)
|
||||
{
|
||||
@ -1511,6 +1552,9 @@ static int dpaa2_switch_port_bridge_leave(struct net_device *netdev)
|
||||
struct ethsw_core *ethsw = port_priv->ethsw_data;
|
||||
int err;
|
||||
|
||||
/* First of all, fast age any learn FDB addresses on this switch port */
|
||||
dpaa2_switch_port_fast_age(port_priv);
|
||||
|
||||
/* Clear all RX VLANs installed through vlan_vid_add() either as VLAN
|
||||
* upper devices or otherwise from the FDB table that we are about to
|
||||
* leave
|
||||
|
@ -172,4 +172,7 @@ int dpaa2_switch_port_vlans_add(struct net_device *netdev,
|
||||
int dpaa2_switch_port_vlans_del(struct net_device *netdev,
|
||||
const struct switchdev_obj_port_vlan *vlan);
|
||||
|
||||
typedef int dpaa2_switch_fdb_cb_t(struct ethsw_port_priv *port_priv,
|
||||
struct fdb_dump_entry *fdb_entry,
|
||||
void *data);
|
||||
#endif /* __ETHSW_H */
|
||||
|
Loading…
Reference in New Issue
Block a user