linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback
@ 2019-07-29 16:11 Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 1/5] staging: fsl-dpaa2/ethsw: remove unused structure Ioana Ciornei
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-29 16:11 UTC (permalink / raw)
  To: gregkh, linux-kernel
  Cc: netdev, davem, andrew, f.fainelli, jiri, Ioana Ciornei

This patch set adds some features and small fixes in the
FDB table manipulation area.

First of all, we implement the .ndo_fdb_dump netdev callback so that all
offloaded FDB entries, either static or learnt, are available to the user.
This is necessary because the DPAA2 switch does not emit interrupts when a
new FDB is learnt or deleted, thus we are not able to keep the software
bridge state and the HW in sync by calling the switchdev notifiers.

The patch set also adds the .ndo_fdb_[add|del] callbacks in order to
facilitate adding FDB entries not associated with any master device.

One interesting thing that I observed is that when adding an FDB entry
associated with a bridge (ie using the 'master' keywork appended to the
bridge command) and then dumping the FDB entries, there will be duplicates
of the same entry: one listed by the bridge device and one by the
driver's .ndo_fdb_dump).
It raises the question whether this is the expected behavior or not.

Another concern is regarding the correct/desired machanism for drivers to
signal errors back to switchdev on adding or deleting an FDB entry.
In the switchdev documentation, there is a TODO in the place of this topic.

Ioana Ciornei (5):
  staging: fsl-dpaa2/ethsw: remove unused structure
  staging: fsl-dpaa2/ethsw: notify switchdev of offloaded entry
  staging: fsl-dpaa2/ethsw: add .ndo_fdb_dump callback
  staging: fsl-dpaa2/ethsw: check added_by_user flag
  staging: fsl-dpaa2/ethsw: add .ndo_fdb[add|del] callbacks

 drivers/staging/fsl-dpaa2/ethsw/TODO       |   1 -
 drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h |  15 ++-
 drivers/staging/fsl-dpaa2/ethsw/dpsw.c     |  51 +++++++++
 drivers/staging/fsl-dpaa2/ethsw/dpsw.h     |  56 ++++-----
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c    | 178 ++++++++++++++++++++++++++++-
 5 files changed, 265 insertions(+), 36 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] staging: fsl-dpaa2/ethsw: remove unused structure
  2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
@ 2019-07-29 16:11 ` Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 2/5] staging: fsl-dpaa2/ethsw: notify switchdev of offloaded entry Ioana Ciornei
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-29 16:11 UTC (permalink / raw)
  To: gregkh, linux-kernel
  Cc: netdev, davem, andrew, f.fainelli, jiri, Ioana Ciornei

The dpsw_cfg structure is only used when creating a new dpsw DPAA2
object. In the DPAA2 architecture, objects are created at boot time by
the firmware or dynamically from userspace while drivers on the fsl-mc
bus only configure those objects.
Remove the structure since it's of no use.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/dpsw.h | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
index 25635259ce44..0d9330e01915 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
+++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
@@ -75,37 +75,6 @@ enum dpsw_component_type {
 	DPSW_COMPONENT_TYPE_S_VLAN
 };
 
-/**
- * struct dpsw_cfg - DPSW configuration
- * @num_ifs: Number of external and internal interfaces
- * @adv: Advanced parameters; default is all zeros;
- *	 use this structure to change default settings
- * @adv.options: Enable/Disable DPSW features (bitmap)
- * @adv.max_vlans: Maximum Number of VLAN's; 0 - indicates default 16
- * @adv.max_meters_per_if: Number of meters per interface
- * @adv.max_fdbs: Maximum Number of FDB's; 0 - indicates default 16
- * @adv.max_fdb_entries: Number of FDB entries for default FDB table;
- *	0 - indicates default 1024 entries.
- * @adv.fdb_aging_time: Default FDB aging time for default FDB table;
- *	0 - indicates default 300 seconds
- * @adv.max_fdb_mc_groups: Number of multicast groups in each FDB table;
- *	0 - indicates default 32
- * @adv.component_type: Indicates the component type of this bridge
- */
-struct dpsw_cfg {
-	u16 num_ifs;
-	struct {
-		u64 options;
-		u16 max_vlans;
-		u8 max_meters_per_if;
-		u8 max_fdbs;
-		u16 max_fdb_entries;
-		u16 fdb_aging_time;
-		u16 max_fdb_mc_groups;
-		enum dpsw_component_type component_type;
-	} adv;
-};
-
 int dpsw_enable(struct fsl_mc_io *mc_io,
 		u32 cmd_flags,
 		u16 token);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] staging: fsl-dpaa2/ethsw: notify switchdev of offloaded entry
  2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 1/5] staging: fsl-dpaa2/ethsw: remove unused structure Ioana Ciornei
@ 2019-07-29 16:11 ` Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 3/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb_dump callback Ioana Ciornei
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-29 16:11 UTC (permalink / raw)
  To: gregkh, linux-kernel
  Cc: netdev, davem, andrew, f.fainelli, jiri, Ioana Ciornei

Notify switchdev in case the FDB entry was successfully offloaded.
This will help users to make the distinction between entries known to
the HW switch and those that are held only on the software bridge.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 341c36b3a76d..d6953ac427b1 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1039,6 +1039,7 @@ static void ethsw_switchdev_event_work(struct work_struct *work)
 		container_of(work, struct ethsw_switchdev_event_work, work);
 	struct net_device *dev = switchdev_work->dev;
 	struct switchdev_notifier_fdb_info *fdb_info;
+	int err;
 
 	rtnl_lock();
 	fdb_info = &switchdev_work->fdb_info;
@@ -1046,9 +1047,16 @@ static void ethsw_switchdev_event_work(struct work_struct *work)
 	switch (switchdev_work->event) {
 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 		if (is_unicast_ether_addr(fdb_info->addr))
-			ethsw_port_fdb_add_uc(netdev_priv(dev), fdb_info->addr);
+			err = ethsw_port_fdb_add_uc(netdev_priv(dev),
+						    fdb_info->addr);
 		else
-			ethsw_port_fdb_add_mc(netdev_priv(dev), fdb_info->addr);
+			err = ethsw_port_fdb_add_mc(netdev_priv(dev),
+						    fdb_info->addr);
+		if (err)
+			break;
+		fdb_info->offloaded = true;
+		call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, dev,
+					 &fdb_info->info, NULL);
 		break;
 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 		if (is_unicast_ether_addr(fdb_info->addr))
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb_dump callback
  2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 1/5] staging: fsl-dpaa2/ethsw: remove unused structure Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 2/5] staging: fsl-dpaa2/ethsw: notify switchdev of offloaded entry Ioana Ciornei
@ 2019-07-29 16:11 ` Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 4/5] staging: fsl-dpaa2/ethsw: check added_by_user flag Ioana Ciornei
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-29 16:11 UTC (permalink / raw)
  To: gregkh, linux-kernel
  Cc: netdev, davem, andrew, f.fainelli, jiri, Ioana Ciornei

Implement the .ndo_fdb_dump callback for the switch net devices.  The
list of all offloaded FDB entries is retrieved through the dpsw_fdb_dump()
firmware call. Filter the entries by the switch port on which the
callback was called and for each of them create a new neighbour message.
Also remove the requirement from the TODO list.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/TODO       |   1 -
 drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h |  15 +++-
 drivers/staging/fsl-dpaa2/ethsw/dpsw.c     |  51 +++++++++++
 drivers/staging/fsl-dpaa2/ethsw/dpsw.h     |  25 ++++++
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c    | 135 ++++++++++++++++++++++++++++-
 5 files changed, 224 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/TODO b/drivers/staging/fsl-dpaa2/ethsw/TODO
index 24b5e95a96f8..4d46857b0b2b 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/TODO
+++ b/drivers/staging/fsl-dpaa2/ethsw/TODO
@@ -1,7 +1,6 @@
 * Add I/O capabilities on switch port netdevices. This will allow control
 traffic to reach the CPU.
 * Add ACL to redirect control traffic to CPU.
-* Add support for displaying learned FDB entries
 * Add support for multiple FDBs and switch port partitioning
 * MC firmware uprev; the DPAA2 objects used by the Ethernet Switch driver
 need to be kept in sync with binary interface changes in MC
diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
index 14b974defa3a..5e1339daa7c7 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
+++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h
@@ -10,7 +10,7 @@
 
 /* DPSW Version */
 #define DPSW_VER_MAJOR		8
-#define DPSW_VER_MINOR		0
+#define DPSW_VER_MINOR		1
 
 #define DPSW_CMD_BASE_VERSION	1
 #define DPSW_CMD_ID_OFFSET	4
@@ -67,6 +67,7 @@
 #define DPSW_CMDID_FDB_ADD_MULTICAST        DPSW_CMD_ID(0x086)
 #define DPSW_CMDID_FDB_REMOVE_MULTICAST     DPSW_CMD_ID(0x087)
 #define DPSW_CMDID_FDB_SET_LEARNING_MODE    DPSW_CMD_ID(0x088)
+#define DPSW_CMDID_FDB_DUMP                 DPSW_CMD_ID(0x08A)
 
 /* Macros for accessing command fields smaller than 1byte */
 #define DPSW_MASK(field)        \
@@ -351,6 +352,18 @@ struct dpsw_cmd_fdb_set_learning_mode {
 	u8 mode;
 };
 
+struct dpsw_cmd_fdb_dump {
+	__le16 fdb_id;
+	__le16 pad0;
+	__le32 pad1;
+	__le64 iova_addr;
+	__le32 iova_size;
+};
+
+struct dpsw_rsp_fdb_dump {
+	__le16 num_entries;
+};
+
 struct dpsw_rsp_get_api_version {
 	__le16 version_major;
 	__le16 version_minor;
diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.c b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c
index cabed77b445d..56b0fa789a67 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c
@@ -981,6 +981,57 @@ int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
 }
 
 /**
+ * dpsw_fdb_dump() - Dump the content of FDB table into memory.
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:	Token of DPSW object
+ * @fdb_id:	Forwarding Database Identifier
+ * @iova_addr:	Data will be stored here as an array of struct fdb_dump_entry
+ * @iova_size:	Memory size allocated at iova_addr
+ * @num_entries:Number of entries written at iova_addr
+ *
+ * Return:	Completion status. '0' on Success; Error code otherwise.
+ *
+ * The memory allocated at iova_addr must be initialized with zero before
+ * command execution. If the FDB table does not fit into memory MC will stop
+ * after the memory is filled up.
+ * The struct fdb_dump_entry array must be parsed until the end of memory
+ * area or until an entry with mac_addr set to zero is found.
+ */
+int dpsw_fdb_dump(struct fsl_mc_io *mc_io,
+		  u32 cmd_flags,
+		  u16 token,
+		  u16 fdb_id,
+		  u64 iova_addr,
+		  u32 iova_size,
+		  u16 *num_entries)
+{
+	struct dpsw_cmd_fdb_dump *cmd_params;
+	struct dpsw_rsp_fdb_dump *rsp_params;
+	struct fsl_mc_command cmd = { 0 };
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP,
+					  cmd_flags,
+					  token);
+	cmd_params = (struct dpsw_cmd_fdb_dump *)cmd.params;
+	cmd_params->fdb_id = cpu_to_le16(fdb_id);
+	cmd_params->iova_addr = cpu_to_le64(iova_addr);
+	cmd_params->iova_size = cpu_to_le32(iova_size);
+
+	/* send command to mc */
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params;
+	*num_entries = le16_to_cpu(rsp_params->num_entries);
+
+	return 0;
+}
+
+/**
  * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
  * @mc_io:	Pointer to MC portal's I/O object
  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
index 0d9330e01915..25b45850925c 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
+++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h
@@ -465,6 +465,31 @@ int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
 			    u16 fdb_id,
 			    const struct dpsw_fdb_unicast_cfg *cfg);
 
+#define DPSW_FDB_ENTRY_TYPE_DYNAMIC  BIT(0)
+#define DPSW_FDB_ENTRY_TYPE_UNICAST  BIT(1)
+
+/**
+ * struct fdb_dump_entry - fdb snapshot entry
+ * @mac_addr: MAC address
+ * @type: bit0 - DINAMIC(1)/STATIC(0), bit1 - UNICAST(1)/MULTICAST(0)
+ * @if_info: unicast - egress interface, multicast - number of egress interfaces
+ * @if_mask: multicast - egress interface mask
+ */
+struct fdb_dump_entry {
+	u8 mac_addr[6];
+	u8 type;
+	u8 if_info;
+	u8 if_mask[8];
+};
+
+int dpsw_fdb_dump(struct fsl_mc_io *mc_io,
+		  u32 cmd_flags,
+		  u16 token,
+		  u16 fdb_id,
+		  u64 iova_addr,
+		  u32 iova_size,
+		  u16 *num_entries);
+
 /**
  * struct dpsw_fdb_multicast_cfg - Multi-cast entry configuration
  * @type: Select static or dynamic entry
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index d6953ac427b1..e6423f1e190d 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -22,7 +22,7 @@
 
 /* Minimal supported DPSW version */
 #define DPSW_MIN_VER_MAJOR		8
-#define DPSW_MIN_VER_MINOR		0
+#define DPSW_MIN_VER_MINOR		1
 
 #define DEFAULT_VLAN_ID			1
 
@@ -529,6 +529,138 @@ static int port_get_phys_name(struct net_device *netdev, char *name,
 	return 0;
 }
 
+struct ethsw_dump_ctx {
+	struct net_device *dev;
+	struct sk_buff *skb;
+	struct netlink_callback *cb;
+	int idx;
+};
+
+static int ethsw_fdb_do_dump(struct fdb_dump_entry *entry,
+			     struct ethsw_dump_ctx *dump)
+{
+	int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC;
+	u32 portid = NETLINK_CB(dump->cb->skb).portid;
+	u32 seq = dump->cb->nlh->nlmsg_seq;
+	struct nlmsghdr *nlh;
+	struct ndmsg *ndm;
+
+	if (dump->idx < dump->cb->args[2])
+		goto skip;
+
+	nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
+			sizeof(*ndm), NLM_F_MULTI);
+	if (!nlh)
+		return -EMSGSIZE;
+
+	ndm = nlmsg_data(nlh);
+	ndm->ndm_family  = AF_BRIDGE;
+	ndm->ndm_pad1    = 0;
+	ndm->ndm_pad2    = 0;
+	ndm->ndm_flags   = NTF_SELF;
+	ndm->ndm_type    = 0;
+	ndm->ndm_ifindex = dump->dev->ifindex;
+	ndm->ndm_state   = is_dynamic ? NUD_REACHABLE : NUD_NOARP;
+
+	if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, entry->mac_addr))
+		goto nla_put_failure;
+
+	nlmsg_end(dump->skb, nlh);
+
+skip:
+	dump->idx++;
+	return 0;
+
+nla_put_failure:
+	nlmsg_cancel(dump->skb, nlh);
+	return -EMSGSIZE;
+}
+
+static int port_fdb_valid_entry(struct fdb_dump_entry *entry,
+				struct ethsw_port_priv *port_priv)
+{
+	int idx = port_priv->idx;
+	int valid;
+
+	if (entry->type & DPSW_FDB_ENTRY_TYPE_UNICAST)
+		valid = entry->if_info == port_priv->idx;
+	else
+		valid = entry->if_mask[idx / 8] & BIT(idx % 8);
+
+	return valid;
+}
+
+static int 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_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;
+	int err = 0, i;
+	u8 *dma_mem;
+
+	fdb_dump_size = ethsw->sw_attr.max_fdb_entries * sizeof(fdb_entry);
+	dma_mem = kzalloc(fdb_dump_size, GFP_KERNEL);
+	if (!dma_mem)
+		return -ENOMEM;
+
+	memset(dma_mem, 0, fdb_dump_size);
+
+	fdb_dump_iova = dma_map_single(dev, dma_mem, fdb_dump_size,
+				       DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, fdb_dump_iova)) {
+		netdev_err(net_dev, "dma_map_single() failed\n");
+		err = -ENOMEM;
+		goto err_map;
+	}
+
+	err = dpsw_fdb_dump(ethsw->mc_io, 0, ethsw->dpsw_handle, 0,
+			    fdb_dump_iova, fdb_dump_size, &num_fdb_entries);
+	if (err) {
+		netdev_err(net_dev, "dpsw_fdb_dump() = %d\n", err);
+		goto err_dump;
+	}
+
+	dma_unmap_single(dev, fdb_dump_iova, fdb_dump_size, DMA_FROM_DEVICE);
+
+	fdb_entries = (struct fdb_dump_entry *)dma_mem;
+	for (i = 0; i < num_fdb_entries; i++) {
+		fdb_entry = fdb_entries[i];
+
+		if (!port_fdb_valid_entry(&fdb_entry, port_priv))
+			continue;
+
+		err = ethsw_fdb_do_dump(&fdb_entry, &dump);
+		if (err)
+			goto end;
+	}
+
+end:
+	*idx = dump.idx;
+
+	kfree(dma_mem);
+
+	return 0;
+
+err_dump:
+	dma_unmap_single(dev, fdb_dump_iova, fdb_dump_size, DMA_TO_DEVICE);
+err_map:
+	kfree(dma_mem);
+	return err;
+}
+
 static const struct net_device_ops ethsw_port_ops = {
 	.ndo_open		= port_open,
 	.ndo_stop		= port_stop,
@@ -538,6 +670,7 @@ static int port_get_phys_name(struct net_device *netdev, char *name,
 	.ndo_change_mtu		= port_change_mtu,
 	.ndo_has_offload_stats	= port_has_offload_stats,
 	.ndo_get_offload_stats	= port_get_offload_stats,
+	.ndo_fdb_dump		= port_fdb_dump,
 
 	.ndo_start_xmit		= port_dropframe,
 	.ndo_get_port_parent_id	= swdev_get_port_parent_id,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] staging: fsl-dpaa2/ethsw: check added_by_user flag
  2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
                   ` (2 preceding siblings ...)
  2019-07-29 16:11 ` [PATCH 3/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb_dump callback Ioana Ciornei
@ 2019-07-29 16:11 ` Ioana Ciornei
  2019-07-29 16:11 ` [PATCH 5/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb[add|del] callbacks Ioana Ciornei
  2019-07-29 16:35 ` [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Andrew Lunn
  5 siblings, 0 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-29 16:11 UTC (permalink / raw)
  To: gregkh, linux-kernel
  Cc: netdev, davem, andrew, f.fainelli, jiri, Ioana Ciornei

We do not want to offload FDB entries if not added by user as static
entries. Check the added_by_user flag and break if not set.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index e6423f1e190d..2d3179c6bad8 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1179,6 +1179,8 @@ static void ethsw_switchdev_event_work(struct work_struct *work)
 
 	switch (switchdev_work->event) {
 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
+		if (!fdb_info->added_by_user)
+			break;
 		if (is_unicast_ether_addr(fdb_info->addr))
 			err = ethsw_port_fdb_add_uc(netdev_priv(dev),
 						    fdb_info->addr);
@@ -1192,6 +1194,8 @@ static void ethsw_switchdev_event_work(struct work_struct *work)
 					 &fdb_info->info, NULL);
 		break;
 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
+		if (!fdb_info->added_by_user)
+			break;
 		if (is_unicast_ether_addr(fdb_info->addr))
 			ethsw_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr);
 		else
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb[add|del] callbacks
  2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
                   ` (3 preceding siblings ...)
  2019-07-29 16:11 ` [PATCH 4/5] staging: fsl-dpaa2/ethsw: check added_by_user flag Ioana Ciornei
@ 2019-07-29 16:11 ` Ioana Ciornei
  2019-07-29 16:35 ` [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Andrew Lunn
  5 siblings, 0 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-29 16:11 UTC (permalink / raw)
  To: gregkh, linux-kernel
  Cc: netdev, davem, andrew, f.fainelli, jiri, Ioana Ciornei

Add the .ndo_fdb_[add|del] callbacks so that FDB entries not associated
with a master device still end up offloaded.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 2d3179c6bad8..4b94a01513a7 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -316,6 +316,31 @@ static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv,
 	return err;
 }
 
+static int port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+			struct net_device *dev, const unsigned char *addr,
+			u16 vid, u16 flags,
+			struct netlink_ext_ack *extack)
+{
+	if (is_unicast_ether_addr(addr))
+		return ethsw_port_fdb_add_uc(netdev_priv(dev),
+					     addr);
+	else
+		return ethsw_port_fdb_add_mc(netdev_priv(dev),
+					     addr);
+}
+
+static int port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
+			struct net_device *dev,
+			const unsigned char *addr, u16 vid)
+{
+	if (is_unicast_ether_addr(addr))
+		return ethsw_port_fdb_del_uc(netdev_priv(dev),
+					     addr);
+	else
+		return ethsw_port_fdb_del_mc(netdev_priv(dev),
+					     addr);
+}
+
 static void port_get_stats(struct net_device *netdev,
 			   struct rtnl_link_stats64 *stats)
 {
@@ -670,6 +695,8 @@ static int port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
 	.ndo_change_mtu		= port_change_mtu,
 	.ndo_has_offload_stats	= port_has_offload_stats,
 	.ndo_get_offload_stats	= port_get_offload_stats,
+	.ndo_fdb_add		= port_fdb_add,
+	.ndo_fdb_del		= port_fdb_del,
 	.ndo_fdb_dump		= port_fdb_dump,
 
 	.ndo_start_xmit		= port_dropframe,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback
  2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
                   ` (4 preceding siblings ...)
  2019-07-29 16:11 ` [PATCH 5/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb[add|del] callbacks Ioana Ciornei
@ 2019-07-29 16:35 ` Andrew Lunn
  2019-07-30  9:13   ` Ioana Ciornei
  5 siblings, 1 reply; 8+ messages in thread
From: Andrew Lunn @ 2019-07-29 16:35 UTC (permalink / raw)
  To: Ioana Ciornei; +Cc: gregkh, linux-kernel, netdev, davem, f.fainelli, jiri

On Mon, Jul 29, 2019 at 07:11:47PM +0300, Ioana Ciornei wrote:
> This patch set adds some features and small fixes in the
> FDB table manipulation area.
> 
> First of all, we implement the .ndo_fdb_dump netdev callback so that all
> offloaded FDB entries, either static or learnt, are available to the user.
> This is necessary because the DPAA2 switch does not emit interrupts when a
> new FDB is learnt or deleted, thus we are not able to keep the software
> bridge state and the HW in sync by calling the switchdev notifiers.
> 
> The patch set also adds the .ndo_fdb_[add|del] callbacks in order to
> facilitate adding FDB entries not associated with any master device.
> 
> One interesting thing that I observed is that when adding an FDB entry
> associated with a bridge (ie using the 'master' keywork appended to the
> bridge command) and then dumping the FDB entries, there will be duplicates
> of the same entry: one listed by the bridge device and one by the
> driver's .ndo_fdb_dump).
> It raises the question whether this is the expected behavior or not.

DSA devices are the same, they don't provide an interrupt when a new
entry is added by the hardware. So we can have two entries, or just
the SW bridge entry, or just the HW entry, depending on ageing.
 
> Another concern is regarding the correct/desired machanism for drivers to
> signal errors back to switchdev on adding or deleting an FDB entry.
> In the switchdev documentation, there is a TODO in the place of this topic.

It used to be a two state prepare/commit transaction, but that was
changed a while back.

Maybe the DSA core code can give you ideas?

      Andrew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback
  2019-07-29 16:35 ` [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Andrew Lunn
@ 2019-07-30  9:13   ` Ioana Ciornei
  0 siblings, 0 replies; 8+ messages in thread
From: Ioana Ciornei @ 2019-07-30  9:13 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: gregkh, linux-kernel, netdev, davem, f.fainelli, jiri

On 7/29/19 7:35 PM, Andrew Lunn wrote:
> On Mon, Jul 29, 2019 at 07:11:47PM +0300, Ioana Ciornei wrote:
>> This patch set adds some features and small fixes in the
>> FDB table manipulation area.
>>
>> First of all, we implement the .ndo_fdb_dump netdev callback so that all
>> offloaded FDB entries, either static or learnt, are available to the user.
>> This is necessary because the DPAA2 switch does not emit interrupts when a
>> new FDB is learnt or deleted, thus we are not able to keep the software
>> bridge state and the HW in sync by calling the switchdev notifiers.
>>
>> The patch set also adds the .ndo_fdb_[add|del] callbacks in order to
>> facilitate adding FDB entries not associated with any master device.
>>
>> One interesting thing that I observed is that when adding an FDB entry
>> associated with a bridge (ie using the 'master' keywork appended to the
>> bridge command) and then dumping the FDB entries, there will be duplicates
>> of the same entry: one listed by the bridge device and one by the
>> driver's .ndo_fdb_dump).
>> It raises the question whether this is the expected behavior or not.
> 
> DSA devices are the same, they don't provide an interrupt when a new
> entry is added by the hardware. So we can have two entries, or just
> the SW bridge entry, or just the HW entry, depending on ageing.
>

This also happens when dealing with static entries (not just dynamic 
ones that can be affected by ageing). All in all, the basic actions of 
adding/deleting entries and then dumping them works. It was just a 
question about switchdev's architecture.


>> Another concern is regarding the correct/desired machanism for drivers to
>> signal errors back to switchdev on adding or deleting an FDB entry.
>> In the switchdev documentation, there is a TODO in the place of this topic.
> 
> It used to be a two state prepare/commit transaction, but that was
> changed a while back.
> 
> Maybe the DSA core code can give you ideas?
>

I looked in the DSA core before sending these patches out and it's doing 
the exact same thing as ethsw - even though it notifies switchdev if the 
entry could be offloaded (ie no error) all entries will still be present 
in the 'bridge fdb' output. In the SWITCHDEV_FDB_DEL_TO_DEVICE case, it 
seems that it just closes the netdev without any further action.

On the other hand, the mlxsw_spectrum also calls the notifiers when an 
offloaded entry is deleted (on SWITCHDEV_FDB_DEL_TO_DEVICE). This seems 
like a reasonable thing to do, maybe in another patch set.

Ioana C


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-07-30  9:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-29 16:11 [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Ioana Ciornei
2019-07-29 16:11 ` [PATCH 1/5] staging: fsl-dpaa2/ethsw: remove unused structure Ioana Ciornei
2019-07-29 16:11 ` [PATCH 2/5] staging: fsl-dpaa2/ethsw: notify switchdev of offloaded entry Ioana Ciornei
2019-07-29 16:11 ` [PATCH 3/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb_dump callback Ioana Ciornei
2019-07-29 16:11 ` [PATCH 4/5] staging: fsl-dpaa2/ethsw: check added_by_user flag Ioana Ciornei
2019-07-29 16:11 ` [PATCH 5/5] staging: fsl-dpaa2/ethsw: add .ndo_fdb[add|del] callbacks Ioana Ciornei
2019-07-29 16:35 ` [PATCH 0/5] staging: fsl-dpaa2/ethsw: add the .ndo_fdb_dump callback Andrew Lunn
2019-07-30  9:13   ` Ioana Ciornei

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).