[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210310121452.552070-14-ciorneiioana@gmail.com>
Date: Wed, 10 Mar 2021 14:14:50 +0200
From: Ioana Ciornei <ciorneiioana@...il.com>
To: davem@...emloft.net, kuba@...nel.org, gregkh@...uxfoundation.org
Cc: andrew@...n.ch, f.fainelli@...il.com, olteanv@...il.com,
jiri@...nulli.us, ruxandra.radulescu@....com,
netdev@...r.kernel.org, Ioana Ciornei <ioana.ciornei@....com>
Subject: [PATCH net-next 13/15] staging: dpaa2-switch: add fast-ageing on bridge leave
From: Ioana Ciornei <ioana.ciornei@....com>
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@....com>
---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 76 +++++++++++++++++++------
drivers/staging/fsl-dpaa2/ethsw/ethsw.h | 3 +
2 files changed, 63 insertions(+), 16 deletions(-)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 8058bc3ed467..5fa7e41f6866 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -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 @@ static int dpaa2_switch_port_fdb_dump(struct sk_buff *skb, struct netlink_callba
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
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h
index ac9335c83357..933563064015 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h
@@ -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 */
--
2.30.0
Powered by blists - more mailing lists