All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table
@ 2017-08-24  6:39 Jiri Pirko
  2017-08-24  6:39 ` [patch net-next 01/12] devlink: Add Ethernet header for dpipe Jiri Pirko
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:39 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Arkadi says:

This patchset adds IPv4 host dpipe table support. This will provide the
ability to observe the hardware offloaded IPv4 neighbors.

Arkadi Sharshevsky (12):
  devlink: Add Ethernet header for dpipe
  devlink: Add IPv4 header for dpipe
  mlxsw: spectrum_dpipe: Fix erif table op name space
  devlink: Add support for dynamic table size
  devlink: Move dpipe entry clear function into devlink
  mlxsw: spectrum_router: Add helpers for neighbor access
  mlxsw: spectrum_dpipe: Fix label name
  mlxsw: spectrum_dpipe: Add IPv4 host table initial support
  mlxsw: reg: Make flow counter set type enum to be shared
  mlxsw: spectrum_router: Add support for setting counters on neighbors
  mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  mlxsw: spectrum_dpipe: Add support for controlling neighbor counters

 drivers/net/ethernet/mellanox/mlxsw/reg.h          |  28 +-
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     |  10 +-
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c   | 433 +++++++++++++++++++--
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.h   |   1 +
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 104 +++++
 .../net/ethernet/mellanox/mlxsw/spectrum_router.h  |  20 +
 include/net/devlink.h                              |  15 +-
 include/uapi/linux/devlink.h                       |  13 +
 net/core/devlink.c                                 |  68 +++-
 9 files changed, 636 insertions(+), 56 deletions(-)

-- 
2.9.3

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

* [patch net-next 01/12] devlink: Add Ethernet header for dpipe
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
@ 2017-08-24  6:39 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 02/12] devlink: Add IPv4 " Jiri Pirko
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:39 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

This will be used by the IPv4 host table which will be introduced in the
following patches. This header is global and can be reused by many
drivers.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/devlink.h        |  1 +
 include/uapi/linux/devlink.h |  8 ++++++++
 net/core/devlink.c           | 17 +++++++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/include/net/devlink.h b/include/net/devlink.h
index ed7687b..ddb8b52 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -328,6 +328,7 @@ int devlink_dpipe_action_put(struct sk_buff *skb,
 			     struct devlink_dpipe_action *action);
 int devlink_dpipe_match_put(struct sk_buff *skb,
 			    struct devlink_dpipe_match *match);
+extern struct devlink_dpipe_header devlink_dpipe_header_ethernet;
 
 #else
 
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index b0e807a..a855f8d 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -226,4 +226,12 @@ enum devlink_dpipe_action_type {
 	DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY,
 };
 
+enum devlink_dpipe_field_ethernet_id {
+	DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
+};
+
+enum devlink_dpipe_header_id {
+	DEVLINK_DPIPE_HEADER_ETHERNET,
+};
+
 #endif /* _UAPI_LINUX_DEVLINK_H_ */
diff --git a/net/core/devlink.c b/net/core/devlink.c
index a0adfc3..4f6f3d6 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -29,6 +29,23 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/devlink.h>
 
+static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
+	{
+		.name = "destination_mac",
+		.id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
+		.bitwidth = 48,
+	},
+};
+
+struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
+	.name = "ethernet",
+	.id = DEVLINK_DPIPE_HEADER_ETHERNET,
+	.fields = devlink_dpipe_fields_ethernet,
+	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
+	.global = true,
+};
+EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
+
 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
 
 static LIST_HEAD(devlink_list);
-- 
2.9.3

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

* [patch net-next 02/12] devlink: Add IPv4 header for dpipe
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
  2017-08-24  6:39 ` [patch net-next 01/12] devlink: Add Ethernet header for dpipe Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 03/12] mlxsw: spectrum_dpipe: Fix erif table op name space Jiri Pirko
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

This will be used by the IPv4 host table which will be introduced in the
following patches. This header is global and can be reused by many
drivers.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/devlink.h        |  1 +
 include/uapi/linux/devlink.h |  5 +++++
 net/core/devlink.c           | 17 +++++++++++++++++
 3 files changed, 23 insertions(+)

diff --git a/include/net/devlink.h b/include/net/devlink.h
index ddb8b52..8ff8a6f 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -329,6 +329,7 @@ int devlink_dpipe_action_put(struct sk_buff *skb,
 int devlink_dpipe_match_put(struct sk_buff *skb,
 			    struct devlink_dpipe_match *match);
 extern struct devlink_dpipe_header devlink_dpipe_header_ethernet;
+extern struct devlink_dpipe_header devlink_dpipe_header_ipv4;
 
 #else
 
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index a855f8d..6c17254 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -230,8 +230,13 @@ enum devlink_dpipe_field_ethernet_id {
 	DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
 };
 
+enum devlink_dpipe_field_ipv4_id {
+	DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
+};
+
 enum devlink_dpipe_header_id {
 	DEVLINK_DPIPE_HEADER_ETHERNET,
+	DEVLINK_DPIPE_HEADER_IPV4,
 };
 
 #endif /* _UAPI_LINUX_DEVLINK_H_ */
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 4f6f3d6..fcf5dd6 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -46,6 +46,23 @@ struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
 };
 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
 
+static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
+	{
+		.name = "destination ip",
+		.id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
+		.bitwidth = 32,
+	},
+};
+
+struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
+	.name = "ipv4",
+	.id = DEVLINK_DPIPE_HEADER_IPV4,
+	.fields = devlink_dpipe_fields_ipv4,
+	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
+	.global = true,
+};
+EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
+
 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
 
 static LIST_HEAD(devlink_list);
-- 
2.9.3

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

* [patch net-next 03/12] mlxsw: spectrum_dpipe: Fix erif table op name space
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
  2017-08-24  6:39 ` [patch net-next 01/12] devlink: Add Ethernet header for dpipe Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 02/12] devlink: Add IPv4 " Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 04/12] devlink: Add support for dynamic table size Jiri Pirko
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Fix ERIF's table operations name space.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index af2c65a..e9e1f7a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -215,8 +215,8 @@ static int mlxsw_sp_erif_entry_get(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int
-mlxsw_sp_table_erif_entries_dump(void *priv, bool counters_enabled,
-				 struct devlink_dpipe_dump_ctx *dump_ctx)
+mlxsw_sp_dpipe_table_erif_entries_dump(void *priv, bool counters_enabled,
+				       struct devlink_dpipe_dump_ctx *dump_ctx)
 {
 	struct devlink_dpipe_value match_value, action_value;
 	struct devlink_dpipe_action action = {0};
@@ -279,7 +279,7 @@ mlxsw_sp_table_erif_entries_dump(void *priv, bool counters_enabled,
 	return err;
 }
 
-static int mlxsw_sp_table_erif_counters_update(void *priv, bool enable)
+static int mlxsw_sp_dpipe_table_erif_counters_update(void *priv, bool enable)
 {
 	struct mlxsw_sp *mlxsw_sp = priv;
 	int i;
@@ -304,8 +304,8 @@ static int mlxsw_sp_table_erif_counters_update(void *priv, bool enable)
 static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
 	.matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
 	.actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
-	.entries_dump = mlxsw_sp_table_erif_entries_dump,
-	.counters_set_update = mlxsw_sp_table_erif_counters_update,
+	.entries_dump = mlxsw_sp_dpipe_table_erif_entries_dump,
+	.counters_set_update = mlxsw_sp_dpipe_table_erif_counters_update,
 };
 
 static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
-- 
2.9.3

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

* [patch net-next 04/12] devlink: Add support for dynamic table size
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (2 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 03/12] mlxsw: spectrum_dpipe: Fix erif table op name space Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 05/12] devlink: Move dpipe entry clear function into devlink Jiri Pirko
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Up until now the dpipe table's size was static and known at registration
time. The host table does not have constant size and it is resized in
dynamic manner. In order to support this behavior the size is changed
to be obtained dynamically via an op.

This patch also adjust the current dpipe table for the new API.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 13 +++++++++----
 include/net/devlink.h                                |  7 +++----
 net/core/devlink.c                                   | 12 +++++++-----
 3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index e9e1f7a..9eb265b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -301,24 +301,29 @@ static int mlxsw_sp_dpipe_table_erif_counters_update(void *priv, bool enable)
 	return 0;
 }
 
+static u64 mlxsw_sp_dpipe_table_erif_size_get(void *priv)
+{
+	struct mlxsw_sp *mlxsw_sp = priv;
+
+	return MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
+}
+
 static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
 	.matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
 	.actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
 	.entries_dump = mlxsw_sp_dpipe_table_erif_entries_dump,
 	.counters_set_update = mlxsw_sp_dpipe_table_erif_counters_update,
+	.size_get = mlxsw_sp_dpipe_table_erif_size_get,
 };
 
 static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
 {
 	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
-	u64 table_size;
 
-	table_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
 	return devlink_dpipe_table_register(devlink,
 					    MLXSW_SP_DPIPE_TABLE_NAME_ERIF,
 					    &mlxsw_sp_erif_ops,
-					    mlxsw_sp, table_size,
-					    false);
+					    mlxsw_sp, false);
 }
 
 static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 8ff8a6f..e96272b 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -178,7 +178,6 @@ struct devlink_dpipe_table_ops;
  * struct devlink_dpipe_table - table object
  * @priv: private
  * @name: table name
- * @size: maximum number of entries
  * @counters_enabled: indicates if counters are active
  * @counter_control_extern: indicates if counter control is in dpipe or
  *			    external tool
@@ -189,7 +188,6 @@ struct devlink_dpipe_table {
 	void *priv;
 	struct list_head list;
 	const char *name;
-	u64 size;
 	bool counters_enabled;
 	bool counter_control_extern;
 	struct devlink_dpipe_table_ops *table_ops;
@@ -204,6 +202,7 @@ struct devlink_dpipe_table {
  * @counters_set_update - when changing the counter status hardware sync
  *			  maybe needed to allocate/free counter related
  *			  resources
+ * @size_get - get size
  */
 struct devlink_dpipe_table_ops {
 	int (*actions_dump)(void *priv, struct sk_buff *skb);
@@ -211,6 +210,7 @@ struct devlink_dpipe_table_ops {
 	int (*entries_dump)(void *priv, bool counters_enabled,
 			    struct devlink_dpipe_dump_ctx *dump_ctx);
 	int (*counters_set_update)(void *priv, bool enable);
+	u64 (*size_get)(void *priv);
 };
 
 /**
@@ -311,8 +311,7 @@ void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index);
 int devlink_dpipe_table_register(struct devlink *devlink,
 				 const char *table_name,
 				 struct devlink_dpipe_table_ops *table_ops,
-				 void *priv, u64 size,
-				 bool counter_control_extern);
+				 void *priv, bool counter_control_extern);
 void devlink_dpipe_table_unregister(struct devlink *devlink,
 				    const char *table_name);
 int devlink_dpipe_headers_register(struct devlink *devlink,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index fcf5dd6..87062ff 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -1647,13 +1647,15 @@ static int devlink_dpipe_table_put(struct sk_buff *skb,
 				   struct devlink_dpipe_table *table)
 {
 	struct nlattr *table_attr;
+	u64 table_size;
 
+	table_size = table->table_ops->size_get(table->priv);
 	table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
 	if (!table_attr)
 		return -EMSGSIZE;
 
 	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
-	    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table->size,
+	    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
 			      DEVLINK_ATTR_PAD))
 		goto nla_put_failure;
 	if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
@@ -2718,20 +2720,21 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
  *	@table_name: table name
  *	@table_ops: table ops
  *	@priv: priv
- *	@size: size
  *	@counter_control_extern: external control for counters
  */
 int devlink_dpipe_table_register(struct devlink *devlink,
 				 const char *table_name,
 				 struct devlink_dpipe_table_ops *table_ops,
-				 void *priv, u64 size,
-				 bool counter_control_extern)
+				 void *priv, bool counter_control_extern)
 {
 	struct devlink_dpipe_table *table;
 
 	if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
 		return -EEXIST;
 
+	if (WARN_ON(!table_ops->size_get))
+		return -EINVAL;
+
 	table = kzalloc(sizeof(*table), GFP_KERNEL);
 	if (!table)
 		return -ENOMEM;
@@ -2739,7 +2742,6 @@ int devlink_dpipe_table_register(struct devlink *devlink,
 	table->name = table_name;
 	table->table_ops = table_ops;
 	table->priv = priv;
-	table->size = size;
 	table->counter_control_extern = counter_control_extern;
 
 	mutex_lock(&devlink_mutex);
-- 
2.9.3

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

* [patch net-next 05/12] devlink: Move dpipe entry clear function into devlink
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (3 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 04/12] devlink: Add support for dynamic table size Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 06/12] mlxsw: spectrum_router: Add helpers for neighbor access Jiri Pirko
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

The entry clear routine can be shared between the drivers, thus it is
moved inside devlink.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c   | 24 ++--------------------
 include/net/devlink.h                              |  6 ++++++
 net/core/devlink.c                                 | 22 ++++++++++++++++++++
 3 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 9eb265b..1305df9 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -114,26 +114,6 @@ static int mlxsw_sp_dpipe_table_erif_matches_dump(void *priv,
 	return devlink_dpipe_match_put(skb, &match);
 }
 
-static void mlxsw_sp_erif_entry_clear(struct devlink_dpipe_entry *entry)
-{
-	unsigned int value_count, value_index;
-	struct devlink_dpipe_value *value;
-
-	value = entry->action_values;
-	value_count = entry->action_values_count;
-	for (value_index = 0; value_index < value_count; value_index++) {
-		kfree(value[value_index].value);
-		kfree(value[value_index].mask);
-	}
-
-	value = entry->match_values;
-	value_count = entry->match_values_count;
-	for (value_index = 0; value_index < value_count; value_index++) {
-		kfree(value[value_index].value);
-		kfree(value[value_index].mask);
-	}
-}
-
 static void
 mlxsw_sp_erif_match_action_prepare(struct devlink_dpipe_match *match,
 				   struct devlink_dpipe_action *action)
@@ -270,12 +250,12 @@ mlxsw_sp_dpipe_table_erif_entries_dump(void *priv, bool counters_enabled,
 		goto start_again;
 	rtnl_unlock();
 
-	mlxsw_sp_erif_entry_clear(&entry);
+	devlink_dpipe_entry_clear(&entry);
 	return 0;
 err_entry_append:
 err_entry_get:
 	rtnl_unlock();
-	mlxsw_sp_erif_entry_clear(&entry);
+	devlink_dpipe_entry_clear(&entry);
 	return err;
 }
 
diff --git a/include/net/devlink.h b/include/net/devlink.h
index e96272b..047a0c5 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -323,6 +323,7 @@ int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx);
 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
 				   struct devlink_dpipe_entry *entry);
 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx);
+void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry);
 int devlink_dpipe_action_put(struct sk_buff *skb,
 			     struct devlink_dpipe_action *action);
 int devlink_dpipe_match_put(struct sk_buff *skb,
@@ -448,6 +449,11 @@ devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
 	return 0;
 }
 
+static inline void
+devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
+{
+}
+
 static inline int
 devlink_dpipe_action_put(struct sk_buff *skb,
 			 struct devlink_dpipe_action *action)
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 87062ff..194708a 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -1996,6 +1996,28 @@ int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
 }
 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
 
+void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
+
+{
+	unsigned int value_count, value_index;
+	struct devlink_dpipe_value *value;
+
+	value = entry->action_values;
+	value_count = entry->action_values_count;
+	for (value_index = 0; value_index < value_count; value_index++) {
+		kfree(value[value_index].value);
+		kfree(value[value_index].mask);
+	}
+
+	value = entry->match_values;
+	value_count = entry->match_values_count;
+	for (value_index = 0; value_index < value_count; value_index++) {
+		kfree(value[value_index].value);
+		kfree(value[value_index].mask);
+	}
+}
+EXPORT_SYMBOL(devlink_dpipe_entry_clear);
+
 static int devlink_dpipe_entries_fill(struct genl_info *info,
 				      enum devlink_command cmd, int flags,
 				      struct devlink_dpipe_table *table)
-- 
2.9.3

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

* [patch net-next 06/12] mlxsw: spectrum_router: Add helpers for neighbor access
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (4 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 05/12] devlink: Move dpipe entry clear function into devlink Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 07/12] mlxsw: spectrum_dpipe: Fix label name Jiri Pirko
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

This is done as a preparation before introducing the ability to dump the
host table via dpipe, and to count the table size. The mlxsw's neighbor
representative struct stays private to the router module.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 36 ++++++++++++++++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum_router.h  | 13 ++++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index a0a9728..0b989e1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -909,6 +909,42 @@ static const struct rhashtable_params mlxsw_sp_neigh_ht_params = {
 	.key_len = sizeof(struct mlxsw_sp_neigh_key),
 };
 
+struct mlxsw_sp_neigh_entry *
+mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif,
+			struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+	if (!neigh_entry) {
+		if (list_empty(&rif->neigh_list))
+			return NULL;
+		else
+			return list_first_entry(&rif->neigh_list,
+						typeof(*neigh_entry),
+						rif_list_node);
+	}
+	if (neigh_entry->rif_list_node.next == &rif->neigh_list)
+		return NULL;
+	return list_next_entry(neigh_entry, rif_list_node);
+}
+
+int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+	return neigh_entry->key.n->tbl->family;
+}
+
+unsigned char *
+mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+	return neigh_entry->ha;
+}
+
+u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+	struct neighbour *n;
+
+	n = neigh_entry->key.n;
+	return ntohl(*((__be32 *) n->primary_key));
+}
+
 static struct mlxsw_sp_neigh_entry *
 mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
 			   u16 rif)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index a3e8d2b..80ac032 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -42,6 +42,8 @@ enum mlxsw_sp_rif_counter_dir {
 	MLXSW_SP_RIF_COUNTER_EGRESS,
 };
 
+struct mlxsw_sp_neigh_entry;
+
 struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
 					   u16 rif_index);
 u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif);
@@ -56,5 +58,16 @@ void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
 int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
 			       struct mlxsw_sp_rif *rif,
 			       enum mlxsw_sp_rif_counter_dir dir);
+struct mlxsw_sp_neigh_entry *
+mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif,
+			struct mlxsw_sp_neigh_entry *neigh_entry);
+int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry);
+unsigned char *
+mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry);
+u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
+
+#define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif)				\
+	for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry;	\
+	     neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry))
 
 #endif /* _MLXSW_ROUTER_H_*/
-- 
2.9.3

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

* [patch net-next 07/12] mlxsw: spectrum_dpipe: Fix label name
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (5 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 06/12] mlxsw: spectrum_router: Add helpers for neighbor access Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 08/12] mlxsw: spectrum_dpipe: Add IPv4 host table initial support Jiri Pirko
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Change label name for case of erif table init failure.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 1305df9..6310c2c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -324,10 +324,10 @@ int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
 		return err;
 	err = mlxsw_sp_dpipe_erif_table_init(mlxsw_sp);
 	if (err)
-		goto err_erif_register;
+		goto err_erif_table_init;
 	return 0;
 
-err_erif_register:
+err_erif_table_init:
 	devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
 	return err;
 }
-- 
2.9.3

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

* [patch net-next 08/12] mlxsw: spectrum_dpipe: Add IPv4 host table initial support
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (6 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 07/12] mlxsw: spectrum_dpipe: Fix label name Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 09/12] mlxsw: reg: Make flow counter set type enum to be shared Jiri Pirko
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Add IPv4 host table initial support.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c   | 102 +++++++++++++++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.h   |   1 +
 2 files changed, 103 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 6310c2c..9c2b25a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -74,6 +74,8 @@ static struct devlink_dpipe_header mlxsw_sp_dpipe_header_metadata = {
 
 static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {
 	&mlxsw_sp_dpipe_header_metadata,
+	&devlink_dpipe_header_ethernet,
+	&devlink_dpipe_header_ipv4,
 };
 
 static struct devlink_dpipe_headers mlxsw_sp_dpipe_headers = {
@@ -313,6 +315,99 @@ static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
 	devlink_dpipe_table_unregister(devlink, MLXSW_SP_DPIPE_TABLE_NAME_ERIF);
 }
 
+static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
+{
+	struct devlink_dpipe_match match = {0};
+	int err;
+
+	match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+	match.header = &mlxsw_sp_dpipe_header_metadata;
+	match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
+
+	err = devlink_dpipe_match_put(skb, &match);
+	if (err)
+		return err;
+
+	match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+	match.header = &devlink_dpipe_header_ipv4;
+	match.field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
+
+	return devlink_dpipe_match_put(skb, &match);
+}
+
+static int
+mlxsw_sp_dpipe_table_host4_matches_dump(void *priv, struct sk_buff *skb)
+{
+	return mlxsw_sp_dpipe_table_host_matches_dump(skb, AF_INET);
+}
+
+static int
+mlxsw_sp_dpipe_table_host4_actions_dump(void *priv, struct sk_buff *skb)
+{
+	struct devlink_dpipe_action action = {0};
+
+	action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
+	action.header = &devlink_dpipe_header_ethernet;
+	action.field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC;
+
+	return devlink_dpipe_action_put(skb, &action);
+}
+
+static u64
+mlxsw_sp_dpipe_table_host_size_get(struct mlxsw_sp *mlxsw_sp, int type)
+{
+	u64 size = 0;
+	int i;
+
+	rtnl_lock();
+	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
+		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
+		struct mlxsw_sp_neigh_entry *neigh_entry;
+
+		if (!rif)
+			continue;
+		mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
+			if (mlxsw_sp_neigh_entry_type(neigh_entry) != type)
+				continue;
+			size++;
+		}
+	}
+	rtnl_unlock();
+
+	return size;
+}
+
+static u64 mlxsw_sp_dpipe_table_host4_size_get(void *priv)
+{
+	struct mlxsw_sp *mlxsw_sp = priv;
+
+	return mlxsw_sp_dpipe_table_host_size_get(mlxsw_sp, AF_INET);
+}
+
+static struct devlink_dpipe_table_ops mlxsw_sp_host4_ops = {
+	.matches_dump = mlxsw_sp_dpipe_table_host4_matches_dump,
+	.actions_dump = mlxsw_sp_dpipe_table_host4_actions_dump,
+	.size_get = mlxsw_sp_dpipe_table_host4_size_get,
+};
+
+static int mlxsw_sp_dpipe_host4_table_init(struct mlxsw_sp *mlxsw_sp)
+{
+	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+
+	return devlink_dpipe_table_register(devlink,
+					    MLXSW_SP_DPIPE_TABLE_NAME_HOST4,
+					    &mlxsw_sp_host4_ops,
+					    mlxsw_sp, false);
+}
+
+static void mlxsw_sp_dpipe_host4_table_fini(struct mlxsw_sp *mlxsw_sp)
+{
+	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+
+	devlink_dpipe_table_unregister(devlink,
+				       MLXSW_SP_DPIPE_TABLE_NAME_HOST4);
+}
+
 int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
 {
 	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
@@ -325,8 +420,14 @@ int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
 	err = mlxsw_sp_dpipe_erif_table_init(mlxsw_sp);
 	if (err)
 		goto err_erif_table_init;
+
+	err = mlxsw_sp_dpipe_host4_table_init(mlxsw_sp);
+	if (err)
+		goto err_host4_table_init;
 	return 0;
 
+err_host4_table_init:
+	mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
 err_erif_table_init:
 	devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
 	return err;
@@ -336,6 +437,7 @@ void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
 {
 	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
 
+	mlxsw_sp_dpipe_host4_table_fini(mlxsw_sp);
 	mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
 	devlink_dpipe_headers_unregister(devlink);
 }
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h
index d208929..7785f9e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.h
@@ -39,5 +39,6 @@ int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp);
 
 #define MLXSW_SP_DPIPE_TABLE_NAME_ERIF "mlxsw_erif"
+#define MLXSW_SP_DPIPE_TABLE_NAME_HOST4 "mlxsw_host4"
 
 #endif /* _MLXSW_PIPELINE_H_*/
-- 
2.9.3

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

* [patch net-next 09/12] mlxsw: reg: Make flow counter set type enum to be shared
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (7 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 08/12] mlxsw: spectrum_dpipe: Add IPv4 host table initial support Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 10/12] mlxsw: spectrum_router: Add support for setting counters on neighbors Jiri Pirko
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

This is done as a preparation before introducing support for neighbor
counters. The flow counter's type enum is used by many registers, yet,
until now it was used only by mgpc and thus it was private. This patch
updates the namespace for more generic usage.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h      | 20 ++++++++++----------
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c |  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 7e8ba54..bcf55f6 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -5000,6 +5000,15 @@ enum mlxsw_reg_rauht_trap_id {
  */
 MLXSW_ITEM32(reg, rauht, trap_id, 0x60, 0, 9);
 
+enum mlxsw_reg_flow_counter_set_type {
+	/* No count */
+	MLXSW_REG_FLOW_COUNTER_SET_TYPE_NO_COUNT = 0x00,
+	/* Count packets and bytes */
+	MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES = 0x03,
+	/* Count only packets */
+	MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS = 0x05,
+};
+
 /* reg_rauht_counter_set_type
  * Counter set type for flow counters
  * Access: RW
@@ -6041,15 +6050,6 @@ static inline void mlxsw_reg_mpsc_pack(char *payload, u8 local_port, bool e,
 
 MLXSW_REG_DEFINE(mgpc, MLXSW_REG_MGPC_ID, MLXSW_REG_MGPC_LEN);
 
-enum mlxsw_reg_mgpc_counter_set_type {
-	/* No count */
-	MLXSW_REG_MGPC_COUNTER_SET_TYPE_NO_COUT = 0x00,
-	/* Count packets and bytes */
-	MLXSW_REG_MGPC_COUNTER_SET_TYPE_PACKETS_BYTES = 0x03,
-	/* Count only packets */
-	MLXSW_REG_MGPC_COUNTER_SET_TYPE_PACKETS = 0x05,
-};
-
 /* reg_mgpc_counter_set_type
  * Counter set type.
  * Access: OP
@@ -6089,7 +6089,7 @@ MLXSW_ITEM64(reg, mgpc, packet_counter, 0x10, 0, 64);
 
 static inline void mlxsw_reg_mgpc_pack(char *payload, u32 counter_index,
 				       enum mlxsw_reg_mgpc_opcode opcode,
-				       enum mlxsw_reg_mgpc_counter_set_type set_type)
+				       enum mlxsw_reg_flow_counter_set_type set_type)
 {
 	MLXSW_REG_ZERO(mgpc, payload);
 	mlxsw_reg_mgpc_counter_index_set(payload, counter_index);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 6e641db..5332b8f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -382,7 +382,7 @@ int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
 	int err;
 
 	mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_NOP,
-			    MLXSW_REG_MGPC_COUNTER_SET_TYPE_PACKETS_BYTES);
+			    MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
 	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
 	if (err)
 		return err;
@@ -397,7 +397,7 @@ static int mlxsw_sp_flow_counter_clear(struct mlxsw_sp *mlxsw_sp,
 	char mgpc_pl[MLXSW_REG_MGPC_LEN];
 
 	mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_CLEAR,
-			    MLXSW_REG_MGPC_COUNTER_SET_TYPE_PACKETS_BYTES);
+			    MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
 }
 
-- 
2.9.3

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

* [patch net-next 10/12] mlxsw: spectrum_router: Add support for setting counters on neighbors
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (8 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 09/12] mlxsw: reg: Make flow counter set type enum to be shared Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24  6:40 ` [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump Jiri Pirko
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Add support for setting counters on neighbors based on dpipe's host table
counter status. This patch also adds the ability for getting the counter
value, which will be used by the dpipe host table implementation in the
next patches.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h          |  8 ++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     |  6 ++-
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 56 ++++++++++++++++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum_router.h  |  3 ++
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index bcf55f6..11e290c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -5054,6 +5054,14 @@ static inline void mlxsw_reg_rauht_pack6(char *payload,
 	mlxsw_reg_rauht_dip6_memcpy_to(payload, dip);
 }
 
+static inline void mlxsw_reg_rauht_pack_counter(char *payload,
+						u64 counter_index)
+{
+	mlxsw_reg_rauht_counter_index_set(payload, counter_index);
+	mlxsw_reg_rauht_counter_set_type_set(payload,
+					     MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
+}
+
 /* RALEU - Router Algorithmic LPM ECMP Update Register
  * ---------------------------------------------------
  * The register enables updating the ECMP section in the action for multiple
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 5332b8f..17fc988 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -386,8 +386,10 @@ int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
 	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
 	if (err)
 		return err;
-	*packets = mlxsw_reg_mgpc_packet_counter_get(mgpc_pl);
-	*bytes = mlxsw_reg_mgpc_byte_counter_get(mgpc_pl);
+	if (packets)
+		*packets = mlxsw_reg_mgpc_packet_counter_get(mgpc_pl);
+	if (bytes)
+		*bytes = mlxsw_reg_mgpc_byte_counter_get(mgpc_pl);
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 0b989e1..abccd84 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -901,6 +901,8 @@ struct mlxsw_sp_neigh_entry {
 					* this neigh entry
 					*/
 	struct list_head nexthop_neighs_list_node;
+	unsigned int counter_index;
+	bool counter_valid;
 };
 
 static const struct rhashtable_params mlxsw_sp_neigh_ht_params = {
@@ -945,6 +947,17 @@ u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
 	return ntohl(*((__be32 *) n->primary_key));
 }
 
+int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
+			       struct mlxsw_sp_neigh_entry *neigh_entry,
+			       u64 *p_counter)
+{
+	if (!neigh_entry->counter_valid)
+		return -EINVAL;
+
+	return mlxsw_sp_flow_counter_get(mlxsw_sp, neigh_entry->counter_index,
+					 p_counter, NULL);
+}
+
 static struct mlxsw_sp_neigh_entry *
 mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
 			   u16 rif)
@@ -985,6 +998,41 @@ mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
 			       mlxsw_sp_neigh_ht_params);
 }
 
+static bool
+mlxsw_sp_neigh4_counter_should_alloc(struct mlxsw_sp *mlxsw_sp)
+{
+	struct devlink *devlink;
+
+	devlink = priv_to_devlink(mlxsw_sp->core);
+	return devlink_dpipe_table_counter_enabled(devlink,
+						   MLXSW_SP_DPIPE_TABLE_NAME_HOST4);
+}
+
+static void
+mlxsw_sp_neigh_counter_alloc(struct mlxsw_sp *mlxsw_sp,
+			     struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+	if (mlxsw_sp_neigh_entry_type(neigh_entry) != AF_INET ||
+	    !mlxsw_sp_neigh4_counter_should_alloc(mlxsw_sp))
+		return;
+
+	if (mlxsw_sp_flow_counter_alloc(mlxsw_sp, &neigh_entry->counter_index))
+		return;
+
+	neigh_entry->counter_valid = true;
+}
+
+static void
+mlxsw_sp_neigh_counter_free(struct mlxsw_sp *mlxsw_sp,
+			    struct mlxsw_sp_neigh_entry *neigh_entry)
+{
+	if (!neigh_entry->counter_valid)
+		return;
+	mlxsw_sp_flow_counter_free(mlxsw_sp,
+				   neigh_entry->counter_index);
+	neigh_entry->counter_valid = false;
+}
+
 static struct mlxsw_sp_neigh_entry *
 mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
 {
@@ -1004,6 +1052,7 @@ mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
 	if (err)
 		goto err_neigh_entry_insert;
 
+	mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry);
 	list_add(&neigh_entry->rif_list_node, &rif->neigh_list);
 
 	return neigh_entry;
@@ -1018,6 +1067,7 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp,
 			     struct mlxsw_sp_neigh_entry *neigh_entry)
 {
 	list_del(&neigh_entry->rif_list_node);
+	mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry);
 	mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
 	mlxsw_sp_neigh_entry_free(neigh_entry);
 }
@@ -1323,6 +1373,9 @@ mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp,
 
 	mlxsw_reg_rauht_pack4(rauht_pl, op, neigh_entry->rif, neigh_entry->ha,
 			      dip);
+	if (neigh_entry->counter_valid)
+		mlxsw_reg_rauht_pack_counter(rauht_pl,
+					     neigh_entry->counter_index);
 	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl);
 }
 
@@ -1337,6 +1390,9 @@ mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp,
 
 	mlxsw_reg_rauht_pack6(rauht_pl, op, neigh_entry->rif, neigh_entry->ha,
 			      dip);
+	if (neigh_entry->counter_valid)
+		mlxsw_reg_rauht_pack_counter(rauht_pl,
+					     neigh_entry->counter_index);
 	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl);
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index 80ac032..aafae46 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -69,5 +69,8 @@ u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
 #define mlxsw_sp_rif_neigh_for_each(neigh_entry, rif)				\
 	for (neigh_entry = mlxsw_sp_rif_neigh_next(rif, NULL); neigh_entry;	\
 	     neigh_entry = mlxsw_sp_rif_neigh_next(rif, neigh_entry))
+int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
+			       struct mlxsw_sp_neigh_entry *neigh_entry,
+			       u64 *p_counter);
 
 #endif /* _MLXSW_ROUTER_H_*/
-- 
2.9.3

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

* [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (9 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 10/12] mlxsw: spectrum_router: Add support for setting counters on neighbors Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24 19:26   ` David Ahern
  2017-08-24  6:40 ` [patch net-next 12/12] mlxsw: spectrum_dpipe: Add support for controlling neighbor counters Jiri Pirko
  2017-08-24 16:33 ` [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table David Miller
  12 siblings, 1 reply; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Add support for IPv4 host table dump.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c   | 247 +++++++++++++++++++++
 1 file changed, 247 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 9c2b25a..94d954b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -353,6 +353,252 @@ mlxsw_sp_dpipe_table_host4_actions_dump(void *priv, struct sk_buff *skb)
 	return devlink_dpipe_action_put(skb, &action);
 }
 
+enum mlxsw_sp_dpipe_table_host_match {
+	MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF,
+	MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP,
+	MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT,
+};
+
+static void
+mlxsw_sp_dpipe_table_host_match_action_prepare(struct devlink_dpipe_match *matches,
+					       struct devlink_dpipe_action *action,
+					       int type)
+{
+	struct devlink_dpipe_match *match;
+
+	match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
+	match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+	match->header = &mlxsw_sp_dpipe_header_metadata;
+	match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
+
+	match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
+	match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
+	match->header = &devlink_dpipe_header_ipv4;
+	match->field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP;
+
+	action->type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
+	action->header = &devlink_dpipe_header_ethernet;
+	action->field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC;
+}
+
+static int
+mlxsw_sp_dpipe_table_host_entry_prepare(struct devlink_dpipe_entry *entry,
+					struct devlink_dpipe_value *match_values,
+					struct devlink_dpipe_match *matches,
+					struct devlink_dpipe_value *action_value,
+					struct devlink_dpipe_action *action,
+					int type)
+{
+	struct devlink_dpipe_value *match_value;
+	struct devlink_dpipe_match *match;
+
+	entry->match_values = match_values;
+	entry->match_values_count = MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT;
+
+	entry->action_values = action_value;
+	entry->action_values_count = 1;
+
+	match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
+	match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
+
+	match_value->match = match;
+	match_value->value_size = sizeof(u32);
+	match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
+	if (!match_value->value)
+		return -ENOMEM;
+
+	match = &matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
+	match_value = &match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
+
+	match_value->match = match;
+	match_value->value_size = sizeof(u32);
+	match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
+	if (!match_value->value)
+		return -ENOMEM;
+
+	action_value->action = action;
+	action_value->value_size = sizeof(u64);
+	action_value->value = kmalloc(action_value->value_size, GFP_KERNEL);
+	if (!action_value->value)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void
+__mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
+					struct mlxsw_sp_rif *rif,
+					unsigned char *ha, u32 dip)
+{
+	struct devlink_dpipe_value *value;
+	u32 *rif_value;
+	u32 *dip_value;
+	u8 *ha_value;
+
+	/* Set Match RIF index */
+	value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_RIF];
+
+	rif_value = value->value;
+	*rif_value = mlxsw_sp_rif_index(rif);
+	value->mapping_value = mlxsw_sp_rif_dev_ifindex(rif);
+	value->mapping_valid = true;
+
+	/* Set Match DIP */
+	value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_DIP];
+
+	dip_value = value->value;
+	*dip_value = dip;
+
+	/* Set Action DMAC */
+	value = entry->action_values;
+	ha_value = value->value;
+	ether_addr_copy(ha_value, ha);
+}
+
+static void
+mlxsw_sp_dpipe_table_host4_entry_fill(struct devlink_dpipe_entry *entry,
+				      struct mlxsw_sp_neigh_entry *neigh_entry,
+				      struct mlxsw_sp_rif *rif)
+{
+	unsigned char *ha;
+	u32 dip;
+
+	ha = mlxsw_sp_neigh_entry_ha(neigh_entry);
+	dip = mlxsw_sp_neigh4_entry_dip(neigh_entry);
+	__mlxsw_sp_dpipe_table_host4_entry_fill(entry, rif, ha, dip);
+}
+
+static void
+mlxsw_sp_dpipe_table_host_entry_fill(struct mlxsw_sp *mlxsw_sp,
+				     struct devlink_dpipe_entry *entry,
+				     struct mlxsw_sp_neigh_entry *neigh_entry,
+				     struct mlxsw_sp_rif *rif,
+				     int type)
+{
+	int err;
+
+	mlxsw_sp_dpipe_table_host4_entry_fill(entry, neigh_entry, rif);
+	err = mlxsw_sp_neigh_counter_get(mlxsw_sp, neigh_entry,
+					 &entry->counter);
+	if (!err)
+		entry->counter_valid = true;
+}
+
+static int
+mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
+				      struct devlink_dpipe_entry *entry,
+				      bool counters_enabled,
+				      struct devlink_dpipe_dump_ctx *dump_ctx,
+				      int type)
+{
+	int rif_neigh_count = 0;
+	int rif_neigh_skip = 0;
+	int neigh_count = 0;
+	int rif_count;
+	int i, j;
+	int err;
+
+	rtnl_lock();
+	i = 0;
+	rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
+start_again:
+	err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
+	if (err)
+		goto err_ctx_prepare;
+	j = 0;
+	rif_neigh_skip = rif_neigh_count;
+	for (; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
+		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
+		struct mlxsw_sp_neigh_entry *neigh_entry;
+
+		if (!rif)
+			continue;
+
+		rif_neigh_count = 0;
+		mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
+			if (rif_neigh_count < rif_neigh_skip)
+				goto skip;
+
+			mlxsw_sp_dpipe_table_host_entry_fill(mlxsw_sp, entry,
+							     neigh_entry, rif,
+							     type);
+			entry->index = neigh_count;
+			err = devlink_dpipe_entry_ctx_append(dump_ctx, entry);
+			if (err) {
+				if (err == -EMSGSIZE) {
+					if (!j)
+						goto err_entry_append;
+					else
+						goto out;
+				}
+				goto err_entry_append;
+			}
+			neigh_count++;
+			j++;
+skip:
+			rif_neigh_count++;
+		}
+		rif_neigh_skip = 0;
+	}
+out:
+	devlink_dpipe_entry_ctx_close(dump_ctx);
+	if (i != rif_count)
+		goto start_again;
+
+	rtnl_unlock();
+	return 0;
+
+err_ctx_prepare:
+err_entry_append:
+	rtnl_unlock();
+	return err;
+}
+
+static int
+mlxsw_sp_dpipe_table_host_entries_dump(struct mlxsw_sp *mlxsw_sp,
+				       bool counters_enabled,
+				       struct devlink_dpipe_dump_ctx *dump_ctx,
+				       int type)
+{
+	struct devlink_dpipe_value match_values[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT];
+	struct devlink_dpipe_match matches[MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT];
+	struct devlink_dpipe_value action_value;
+	struct devlink_dpipe_action action = {0};
+	struct devlink_dpipe_entry entry = {0};
+	int err;
+
+	memset(matches, 0, MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT *
+			   sizeof(matches[0]));
+	memset(match_values, 0, MLXSW_SP_DPIPE_TABLE_HOST_MATCH_COUNT *
+				sizeof(match_values[0]));
+	memset(&action_value, 0, sizeof(action_value));
+
+	mlxsw_sp_dpipe_table_host_match_action_prepare(matches, &action, type);
+	err = mlxsw_sp_dpipe_table_host_entry_prepare(&entry, match_values,
+						      matches, &action_value,
+						      &action, type);
+	if (err)
+		goto out;
+
+	err = mlxsw_sp_dpipe_table_host_entries_get(mlxsw_sp, &entry,
+						    counters_enabled, dump_ctx,
+						    type);
+out:
+	devlink_dpipe_entry_clear(&entry);
+	return err;
+}
+
+static int
+mlxsw_sp_dpipe_table_host4_entries_dump(void *priv, bool counters_enabled,
+					struct devlink_dpipe_dump_ctx *dump_ctx)
+{
+	struct mlxsw_sp *mlxsw_sp = priv;
+
+	return mlxsw_sp_dpipe_table_host_entries_dump(mlxsw_sp,
+						      counters_enabled,
+						      dump_ctx, AF_INET);
+}
+
 static u64
 mlxsw_sp_dpipe_table_host_size_get(struct mlxsw_sp *mlxsw_sp, int type)
 {
@@ -387,6 +633,7 @@ static u64 mlxsw_sp_dpipe_table_host4_size_get(void *priv)
 static struct devlink_dpipe_table_ops mlxsw_sp_host4_ops = {
 	.matches_dump = mlxsw_sp_dpipe_table_host4_matches_dump,
 	.actions_dump = mlxsw_sp_dpipe_table_host4_actions_dump,
+	.entries_dump = mlxsw_sp_dpipe_table_host4_entries_dump,
 	.size_get = mlxsw_sp_dpipe_table_host4_size_get,
 };
 
-- 
2.9.3

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

* [patch net-next 12/12] mlxsw: spectrum_dpipe: Add support for controlling neighbor counters
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (10 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump Jiri Pirko
@ 2017-08-24  6:40 ` Jiri Pirko
  2017-08-24 19:28   ` David Ahern
  2017-08-24 16:33 ` [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table David Miller
  12 siblings, 1 reply; 21+ messages in thread
From: Jiri Pirko @ 2017-08-24  6:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, arkadis, idosch, mlxsw

From: Arkadi Sharshevsky <arkadis@mellanox.com>

Add support for controlling neighbor counters via dpipe.

Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_dpipe.c   | 33 ++++++++++++++++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 12 ++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum_router.h  |  4 +++
 3 files changed, 49 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
index 94d954b..3c8599f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -599,6 +599,38 @@ mlxsw_sp_dpipe_table_host4_entries_dump(void *priv, bool counters_enabled,
 						      dump_ctx, AF_INET);
 }
 
+static void
+mlxsw_sp_dpipe_table_host_counters_update(struct mlxsw_sp *mlxsw_sp,
+					  bool enable, int type)
+{
+	int i;
+
+	rtnl_lock();
+	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
+		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
+		struct mlxsw_sp_neigh_entry *neigh_entry;
+
+		if (!rif)
+			continue;
+		mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
+			if (mlxsw_sp_neigh_entry_type(neigh_entry) != type)
+				continue;
+			mlxsw_sp_neigh_entry_counter_update(mlxsw_sp,
+							    neigh_entry,
+							    enable);
+		}
+	}
+	rtnl_unlock();
+}
+
+static int mlxsw_sp_dpipe_table_host4_counters_update(void *priv, bool enable)
+{
+	struct mlxsw_sp *mlxsw_sp = priv;
+
+	mlxsw_sp_dpipe_table_host_counters_update(mlxsw_sp, enable, AF_INET);
+	return 0;
+}
+
 static u64
 mlxsw_sp_dpipe_table_host_size_get(struct mlxsw_sp *mlxsw_sp, int type)
 {
@@ -634,6 +666,7 @@ static struct devlink_dpipe_table_ops mlxsw_sp_host4_ops = {
 	.matches_dump = mlxsw_sp_dpipe_table_host4_matches_dump,
 	.actions_dump = mlxsw_sp_dpipe_table_host4_actions_dump,
 	.entries_dump = mlxsw_sp_dpipe_table_host4_entries_dump,
+	.counters_set_update = mlxsw_sp_dpipe_table_host4_counters_update,
 	.size_get = mlxsw_sp_dpipe_table_host4_size_get,
 };
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index abccd84..377d85c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1429,6 +1429,18 @@ mlxsw_sp_neigh_entry_update(struct mlxsw_sp *mlxsw_sp,
 	}
 }
 
+void
+mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
+				    struct mlxsw_sp_neigh_entry *neigh_entry,
+				    bool adding)
+{
+	if (adding)
+		mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry);
+	else
+		mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry);
+	mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, true);
+}
+
 struct mlxsw_sp_neigh_event_work {
 	struct work_struct work;
 	struct mlxsw_sp *mlxsw_sp;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
index aafae46..fb0f971 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h
@@ -72,5 +72,9 @@ u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry);
 int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
 			       struct mlxsw_sp_neigh_entry *neigh_entry,
 			       u64 *p_counter);
+void
+mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
+				    struct mlxsw_sp_neigh_entry *neigh_entry,
+				    bool adding);
 
 #endif /* _MLXSW_ROUTER_H_*/
-- 
2.9.3

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

* Re: [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table
  2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
                   ` (11 preceding siblings ...)
  2017-08-24  6:40 ` [patch net-next 12/12] mlxsw: spectrum_dpipe: Add support for controlling neighbor counters Jiri Pirko
@ 2017-08-24 16:33 ` David Miller
  12 siblings, 0 replies; 21+ messages in thread
From: David Miller @ 2017-08-24 16:33 UTC (permalink / raw)
  To: jiri; +Cc: netdev, arkadis, idosch, mlxsw

From: Jiri Pirko <jiri@resnulli.us>
Date: Thu, 24 Aug 2017 08:39:58 +0200

> From: Jiri Pirko <jiri@mellanox.com>
> 
> Arkadi says:
> 
> This patchset adds IPv4 host dpipe table support. This will provide the
> ability to observe the hardware offloaded IPv4 neighbors.

Looks really nice, series applied, thanks.

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

* Re: [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-24  6:40 ` [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump Jiri Pirko
@ 2017-08-24 19:26   ` David Ahern
  2017-08-25  9:26     ` Arkadi Sharshevsky
  0 siblings, 1 reply; 21+ messages in thread
From: David Ahern @ 2017-08-24 19:26 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, arkadis, idosch, mlxsw

On 8/23/17 11:40 PM, Jiri Pirko wrote:
> +static int
> +mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
> +				      struct devlink_dpipe_entry *entry,
> +				      bool counters_enabled,
> +				      struct devlink_dpipe_dump_ctx *dump_ctx,
> +				      int type)
> +{
> +	int rif_neigh_count = 0;
> +	int rif_neigh_skip = 0;
> +	int neigh_count = 0;
> +	int rif_count;
> +	int i, j;
> +	int err;
> +
> +	rtnl_lock();

Why does a h/w driver dumping its tables need the rtnl lock?

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

* Re: [patch net-next 12/12] mlxsw: spectrum_dpipe: Add support for controlling neighbor counters
  2017-08-24  6:40 ` [patch net-next 12/12] mlxsw: spectrum_dpipe: Add support for controlling neighbor counters Jiri Pirko
@ 2017-08-24 19:28   ` David Ahern
  0 siblings, 0 replies; 21+ messages in thread
From: David Ahern @ 2017-08-24 19:28 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, arkadis, idosch, mlxsw

On 8/23/17 11:40 PM, Jiri Pirko wrote:
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
> index 94d954b..3c8599f 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
> @@ -599,6 +599,38 @@ mlxsw_sp_dpipe_table_host4_entries_dump(void *priv, bool counters_enabled,
>  						      dump_ctx, AF_INET);
>  }
>  
> +static void
> +mlxsw_sp_dpipe_table_host_counters_update(struct mlxsw_sp *mlxsw_sp,
> +					  bool enable, int type)
> +{
> +	int i;
> +
> +	rtnl_lock();

same question here. Why is rtnl lock needed?

> +	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
> +		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
> +		struct mlxsw_sp_neigh_entry *neigh_entry;
> +
> +		if (!rif)
> +			continue;
> +		mlxsw_sp_rif_neigh_for_each(neigh_entry, rif) {
> +			if (mlxsw_sp_neigh_entry_type(neigh_entry) != type)
> +				continue;
> +			mlxsw_sp_neigh_entry_counter_update(mlxsw_sp,
> +							    neigh_entry,
> +							    enable);
> +		}
> +	}
> +	rtnl_unlock();

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

* Re: [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-24 19:26   ` David Ahern
@ 2017-08-25  9:26     ` Arkadi Sharshevsky
  2017-08-25 19:51       ` David Ahern
  0 siblings, 1 reply; 21+ messages in thread
From: Arkadi Sharshevsky @ 2017-08-25  9:26 UTC (permalink / raw)
  To: David Ahern, Jiri Pirko, netdev; +Cc: davem, idosch, mlxsw



On 08/24/2017 10:26 PM, David Ahern wrote:
> On 8/23/17 11:40 PM, Jiri Pirko wrote:
>> +static int
>> +mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
>> +				      struct devlink_dpipe_entry *entry,
>> +				      bool counters_enabled,
>> +				      struct devlink_dpipe_dump_ctx *dump_ctx,
>> +				      int type)
>> +{
>> +	int rif_neigh_count = 0;
>> +	int rif_neigh_skip = 0;
>> +	int neigh_count = 0;
>> +	int rif_count;
>> +	int i, j;
>> +	int err;
>> +
>> +	rtnl_lock();
> 
> Why does a h/w driver dumping its tables need the rtnl lock?
> 

This table represents the hw IPv4 arp table, and the
driver depends on rtnl to be held.

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

* Re: [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-25  9:26     ` Arkadi Sharshevsky
@ 2017-08-25 19:51       ` David Ahern
  2017-08-27  8:31         ` Arkadi Sharshevsky
  0 siblings, 1 reply; 21+ messages in thread
From: David Ahern @ 2017-08-25 19:51 UTC (permalink / raw)
  To: Arkadi Sharshevsky, Jiri Pirko, netdev; +Cc: davem, idosch, mlxsw

On 8/25/17 2:26 AM, Arkadi Sharshevsky wrote:
> 
> 
> On 08/24/2017 10:26 PM, David Ahern wrote:
>> On 8/23/17 11:40 PM, Jiri Pirko wrote:
>>> +static int
>>> +mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
>>> +				      struct devlink_dpipe_entry *entry,
>>> +				      bool counters_enabled,
>>> +				      struct devlink_dpipe_dump_ctx *dump_ctx,
>>> +				      int type)
>>> +{
>>> +	int rif_neigh_count = 0;
>>> +	int rif_neigh_skip = 0;
>>> +	int neigh_count = 0;
>>> +	int rif_count;
>>> +	int i, j;
>>> +	int err;
>>> +
>>> +	rtnl_lock();
>>
>> Why does a h/w driver dumping its tables need the rtnl lock?
>>
> 
> This table represents the hw IPv4 arp table, and the
> driver depends on rtnl to be held.
> 

Meaning mlxsw does not have its own locks protecting data structures --
e.g., rif adds and deletes, so it is relying on rtnl?

Also, this dpipe capability seems to be just dumping data structures
maintained by the driver. ie., you can compare the mlxsw view of
networking state to IPv4 and IPv6 level tables. Any plans to offer a
command that reads data from the h/w and passes that back to the user?
i.e, a command to compare kernel tables to h/w state?

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

* Re: [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-25 19:51       ` David Ahern
@ 2017-08-27  8:31         ` Arkadi Sharshevsky
  2017-08-29  2:57           ` David Ahern
  0 siblings, 1 reply; 21+ messages in thread
From: Arkadi Sharshevsky @ 2017-08-27  8:31 UTC (permalink / raw)
  To: David Ahern, Jiri Pirko, netdev; +Cc: davem, idosch, mlxsw



On 08/25/2017 10:51 PM, David Ahern wrote:
> On 8/25/17 2:26 AM, Arkadi Sharshevsky wrote:
>>
>>
>> On 08/24/2017 10:26 PM, David Ahern wrote:
>>> On 8/23/17 11:40 PM, Jiri Pirko wrote:
>>>> +static int
>>>> +mlxsw_sp_dpipe_table_host_entries_get(struct mlxsw_sp *mlxsw_sp,
>>>> +				      struct devlink_dpipe_entry *entry,
>>>> +				      bool counters_enabled,
>>>> +				      struct devlink_dpipe_dump_ctx *dump_ctx,
>>>> +				      int type)
>>>> +{
>>>> +	int rif_neigh_count = 0;
>>>> +	int rif_neigh_skip = 0;
>>>> +	int neigh_count = 0;
>>>> +	int rif_count;
>>>> +	int i, j;
>>>> +	int err;
>>>> +
>>>> +	rtnl_lock();
>>>
>>> Why does a h/w driver dumping its tables need the rtnl lock?
>>>
>>
>> This table represents the hw IPv4 arp table, and the
>> driver depends on rtnl to be held.
>>
> 
> Meaning mlxsw does not have its own locks protecting data structures --
> e.g., rif adds and deletes, so it is relying on rtnl?
> 
> Also, this dpipe capability seems to be just dumping data structures
> maintained by the driver. ie., you can compare the mlxsw view of
> networking state to IPv4 and IPv6 level tables. Any plans to offer a
> command that reads data from the h/w and passes that back to the user?
> i.e, a command to compare kernel tables to h/w state?
> 

So this infra should provide several things-

1) Reveal the interactions between various hardware tables
2) Counters for this tables
3) Debugabillity

The first two can be achieved right now. Regarding debugabillity, which
is a bit vague, the current assumption is that the drivers internal data
structures are synced with hardware (which is no always true), and maybe
are not synced with the kernel, so this can be achieved right now by
dumping the internal state of the driver. Furthermore, the counters are
dumped from the hardware and give the user additional indication.

I completely agree that the hardware should be dumped in order to
validate the internal data structures are really synced with HW. This
could be usable for observing data corruptions inside the ASIC and
various complex bugs.

In order to address that I though about maybe add a flag called
"validate_hw" so that during the dump the driver<-->hw state could be
validated.

What do you think about it?

Thanks,
Arkadi

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

* Re: [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-27  8:31         ` Arkadi Sharshevsky
@ 2017-08-29  2:57           ` David Ahern
  2017-08-29  7:55             ` Jiri Pirko
  0 siblings, 1 reply; 21+ messages in thread
From: David Ahern @ 2017-08-29  2:57 UTC (permalink / raw)
  To: Arkadi Sharshevsky, Jiri Pirko, netdev
  Cc: davem, idosch, mlxsw, roopa, Shrijeet Mukherjee

On 8/27/17 2:31 AM, Arkadi Sharshevsky wrote:
>> Also, this dpipe capability seems to be just dumping data structures
>> maintained by the driver. ie., you can compare the mlxsw view of
>> networking state to IPv4 and IPv6 level tables. Any plans to offer a
>> command that reads data from the h/w and passes that back to the user?
>> i.e, a command to compare kernel tables to h/w state?
>>
> 
> So this infra should provide several things-
> 
> 1) Reveal the interactions between various hardware tables
> 2) Counters for this tables
> 3) Debugabillity
> 
> The first two can be achieved right now. Regarding debugabillity, which
> is a bit vague, the current assumption is that the drivers internal data
> structures are synced with hardware (which is no always true), and maybe
> are not synced with the kernel, so this can be achieved right now by
> dumping the internal state of the driver. Furthermore, the counters are
> dumped from the hardware and give the user additional indication.
> 
> I completely agree that the hardware should be dumped in order to
> validate the internal data structures are really synced with HW. This
> could be usable for observing data corruptions inside the ASIC and
> various complex bugs.
> 
> In order to address that I though about maybe add a flag called
> "validate_hw" so that during the dump the driver<-->hw state could be
> validated.
> 
> What do you think about it?

It is not just a matter of dumping hardware state. The data returned by
dump needs to be consistent across platforms and vendors.

If the intent is validating hardware state matches kernel state (ie.,
h/w forwarding matches s/w forwarding), then the hardware state should
be dumped by the driver in a form that parallels kernel state. e.g.,
dump h/w routes, neighbor entries, fdb's in a form and granularity
similar to what is done for kernel tables.

With the recent dpipe changes that allows kernel to driver cache and
kernel to h/w state comparisons.

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

* Re: [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump
  2017-08-29  2:57           ` David Ahern
@ 2017-08-29  7:55             ` Jiri Pirko
  0 siblings, 0 replies; 21+ messages in thread
From: Jiri Pirko @ 2017-08-29  7:55 UTC (permalink / raw)
  To: David Ahern
  Cc: Arkadi Sharshevsky, netdev, davem, idosch, mlxsw, roopa,
	Shrijeet Mukherjee

Tue, Aug 29, 2017 at 04:57:12AM CEST, dsahern@gmail.com wrote:
>On 8/27/17 2:31 AM, Arkadi Sharshevsky wrote:
>>> Also, this dpipe capability seems to be just dumping data structures
>>> maintained by the driver. ie., you can compare the mlxsw view of
>>> networking state to IPv4 and IPv6 level tables. Any plans to offer a
>>> command that reads data from the h/w and passes that back to the user?
>>> i.e, a command to compare kernel tables to h/w state?
>>>
>> 
>> So this infra should provide several things-
>> 
>> 1) Reveal the interactions between various hardware tables
>> 2) Counters for this tables
>> 3) Debugabillity
>> 
>> The first two can be achieved right now. Regarding debugabillity, which
>> is a bit vague, the current assumption is that the drivers internal data
>> structures are synced with hardware (which is no always true), and maybe
>> are not synced with the kernel, so this can be achieved right now by
>> dumping the internal state of the driver. Furthermore, the counters are
>> dumped from the hardware and give the user additional indication.
>> 
>> I completely agree that the hardware should be dumped in order to
>> validate the internal data structures are really synced with HW. This
>> could be usable for observing data corruptions inside the ASIC and
>> various complex bugs.
>> 
>> In order to address that I though about maybe add a flag called
>> "validate_hw" so that during the dump the driver<-->hw state could be
>> validated.
>> 
>> What do you think about it?
>
>It is not just a matter of dumping hardware state. The data returned by
>dump needs to be consistent across platforms and vendors.
>
>If the intent is validating hardware state matches kernel state (ie.,

Nope, that is definitelly not the intent. The intent is to provide user
some more information about how the actual tables in hw look like, so he
knows exactly what is going on there and eventually can optimize things
if needed (resource allocations for example)


>h/w forwarding matches s/w forwarding), then the hardware state should
>be dumped by the driver in a form that parallels kernel state. e.g.,
>dump h/w routes, neighbor entries, fdb's in a form and granularity
>similar to what is done for kernel tables.
>
>With the recent dpipe changes that allows kernel to driver cache and
>kernel to h/w state comparisons.

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

end of thread, other threads:[~2017-08-29  7:55 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-24  6:39 [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table Jiri Pirko
2017-08-24  6:39 ` [patch net-next 01/12] devlink: Add Ethernet header for dpipe Jiri Pirko
2017-08-24  6:40 ` [patch net-next 02/12] devlink: Add IPv4 " Jiri Pirko
2017-08-24  6:40 ` [patch net-next 03/12] mlxsw: spectrum_dpipe: Fix erif table op name space Jiri Pirko
2017-08-24  6:40 ` [patch net-next 04/12] devlink: Add support for dynamic table size Jiri Pirko
2017-08-24  6:40 ` [patch net-next 05/12] devlink: Move dpipe entry clear function into devlink Jiri Pirko
2017-08-24  6:40 ` [patch net-next 06/12] mlxsw: spectrum_router: Add helpers for neighbor access Jiri Pirko
2017-08-24  6:40 ` [patch net-next 07/12] mlxsw: spectrum_dpipe: Fix label name Jiri Pirko
2017-08-24  6:40 ` [patch net-next 08/12] mlxsw: spectrum_dpipe: Add IPv4 host table initial support Jiri Pirko
2017-08-24  6:40 ` [patch net-next 09/12] mlxsw: reg: Make flow counter set type enum to be shared Jiri Pirko
2017-08-24  6:40 ` [patch net-next 10/12] mlxsw: spectrum_router: Add support for setting counters on neighbors Jiri Pirko
2017-08-24  6:40 ` [patch net-next 11/12] mlxsw: spectrum_dpipe: Add support for IPv4 host table dump Jiri Pirko
2017-08-24 19:26   ` David Ahern
2017-08-25  9:26     ` Arkadi Sharshevsky
2017-08-25 19:51       ` David Ahern
2017-08-27  8:31         ` Arkadi Sharshevsky
2017-08-29  2:57           ` David Ahern
2017-08-29  7:55             ` Jiri Pirko
2017-08-24  6:40 ` [patch net-next 12/12] mlxsw: spectrum_dpipe: Add support for controlling neighbor counters Jiri Pirko
2017-08-24 19:28   ` David Ahern
2017-08-24 16:33 ` [patch net-next 00/12] mlxsw: Add IPv4 host dpipe table David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.