All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's
@ 2017-11-02 16:14 Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed Jiri Pirko
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Jiri Pirko <jiri@mellanox.com>

Ido says:

This set makes sure the device is using the same parameters as the
kernel when it computes the multipath hash during IP forwarding.

First patch adds a new netevent to let interested listeners know that
the multipath hash policy has changed.

Next two patches do small and non-functional changes in the mlxsw
driver.

Last patches configure the multipath hash policy upon driver
initialization and as a response to netevents.

Ido Schimmel (6):
  ipv4: Send a netevent whenever multipath hash policy is changed
  mlxsw: spectrum_router: Embed netevent notifier block in router struct
  mlxsw: spectrum_router: Properly name netevent work struct
  mlxsw: reg: Add Router ECMP Configuration Register Version 2
  mlxsw: spectrum_router: Align multipath hash parameters with kernel's
  mlxsw: spectrum_router: Update multipath hash parameters upon
    netevents

 drivers/net/ethernet/mellanox/mlxsw/reg.h          | 132 ++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     |   7 --
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h     |   2 -
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 133 ++++++++++++++++++---
 include/net/netevent.h                             |   1 +
 net/ipv4/sysctl_net_ipv4.c                         |  20 +++-
 6 files changed, 270 insertions(+), 25 deletions(-)

-- 
2.9.5

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

* [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
@ 2017-11-02 16:14 ` Jiri Pirko
  2017-11-02 18:57   ` David Ahern
  2017-11-02 16:14 ` [patch net-next 2/6] mlxsw: spectrum_router: Embed netevent notifier block in router struct Jiri Pirko
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Ido Schimmel <idosch@mellanox.com>

Devices performing IPv4 forwarding need to update their multipath hash
policy whenever it is changed.

Inform these devices by generating a netevent.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/netevent.h     |  1 +
 net/ipv4/sysctl_net_ipv4.c | 20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/net/netevent.h b/include/net/netevent.h
index f440df1..e3f0e8f 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -25,6 +25,7 @@ enum netevent_notif_type {
 	NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */
 	NETEVENT_REDIRECT,	   /* arg is struct netevent_redirect ptr */
 	NETEVENT_DELAY_PROBE_TIME_UPDATE, /* arg is struct neigh_parms ptr */
+	NETEVENT_MULTIPATH_HASH_UPDATE, /* arg is struct net ptr */
 };
 
 int register_netevent_notifier(struct notifier_block *nb);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 4602af6..8dcc2b1 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -25,6 +25,7 @@
 #include <net/inet_frag.h>
 #include <net/ping.h>
 #include <net/protocol.h>
+#include <net/netevent.h>
 
 static int zero;
 static int one = 1;
@@ -385,6 +386,23 @@ static int proc_tcp_available_ulp(struct ctl_table *ctl,
 	return ret;
 }
 
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+static int proc_fib_multipath_hash_policy(struct ctl_table *table, int write,
+					  void __user *buffer, size_t *lenp,
+					  loff_t *ppos)
+{
+	struct net *net = container_of(table->data, struct net,
+	    ipv4.sysctl_fib_multipath_hash_policy);
+	int ret;
+
+	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+	if (write && ret == 0)
+		call_netevent_notifiers(NETEVENT_MULTIPATH_HASH_UPDATE, net);
+
+	return ret;
+}
+#endif
+
 static struct ctl_table ipv4_table[] = {
 	{
 		.procname	= "tcp_max_orphans",
@@ -907,7 +925,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_fib_multipath_hash_policy,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
+		.proc_handler	= proc_fib_multipath_hash_policy,
 		.extra1		= &zero,
 		.extra2		= &one,
 	},
-- 
2.9.5

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

* [patch net-next 2/6] mlxsw: spectrum_router: Embed netevent notifier block in router struct
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed Jiri Pirko
@ 2017-11-02 16:14 ` Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 3/6] mlxsw: spectrum_router: Properly name netevent work struct Jiri Pirko
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Ido Schimmel <idosch@mellanox.com>

We are going to need to respond to netevents notifying us about
multipath hash updates by configuring the device's hash parameters.

Embed the netevent notifier in the router struct so that we could
retrieve it upon notifications and use it to configure the device.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c        |  7 -------
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h        |  2 --
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 14 ++++++++++++--
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 3f4be95..52f38b4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -4574,10 +4574,6 @@ static struct notifier_block mlxsw_sp_inet6addr_nb __read_mostly = {
 	.notifier_call = mlxsw_sp_inet6addr_event,
 };
 
-static struct notifier_block mlxsw_sp_router_netevent_nb __read_mostly = {
-	.notifier_call = mlxsw_sp_router_netevent_event,
-};
-
 static const struct pci_device_id mlxsw_sp_pci_id_table[] = {
 	{PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
 	{0, },
@@ -4596,7 +4592,6 @@ static int __init mlxsw_sp_module_init(void)
 	register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
 	register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
 	register_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
-	register_netevent_notifier(&mlxsw_sp_router_netevent_nb);
 
 	err = mlxsw_core_driver_register(&mlxsw_sp_driver);
 	if (err)
@@ -4611,7 +4606,6 @@ static int __init mlxsw_sp_module_init(void)
 err_pci_driver_register:
 	mlxsw_core_driver_unregister(&mlxsw_sp_driver);
 err_core_driver_register:
-	unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
 	unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
 	unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
 	unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
@@ -4623,7 +4617,6 @@ static void __exit mlxsw_sp_module_exit(void)
 {
 	mlxsw_pci_driver_unregister(&mlxsw_sp_pci_driver);
 	mlxsw_core_driver_unregister(&mlxsw_sp_driver);
-	unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
 	unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
 	unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
 	unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index aa0cefb..b2393bb8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -385,8 +385,6 @@ static inline void mlxsw_sp_port_dcb_fini(struct mlxsw_sp_port *mlxsw_sp_port)
 /* spectrum_router.c */
 int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp);
-int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
-				   unsigned long event, void *ptr);
 int mlxsw_sp_netdevice_router_port_event(struct net_device *dev);
 int mlxsw_sp_inetaddr_event(struct notifier_block *unused,
 			    unsigned long event, void *ptr);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 9fe4cdb..d49c1c9 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -96,6 +96,7 @@ struct mlxsw_sp_router {
 	struct list_head ipip_list;
 	bool aborted;
 	struct notifier_block fib_nb;
+	struct notifier_block netevent_nb;
 	const struct mlxsw_sp_rif_ops **rif_ops_arr;
 	const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
 };
@@ -2076,8 +2077,8 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
 	kfree(neigh_work);
 }
 
-int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
-				   unsigned long event, void *ptr)
+static int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
+					  unsigned long event, void *ptr)
 {
 	struct mlxsw_sp_neigh_event_work *neigh_work;
 	struct mlxsw_sp_port *mlxsw_sp_port;
@@ -6720,6 +6721,12 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
 	if (err)
 		goto err_neigh_init;
 
+	mlxsw_sp->router->netevent_nb.notifier_call =
+		mlxsw_sp_router_netevent_event;
+	err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb);
+	if (err)
+		goto err_register_netevent_notifier;
+
 	mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event;
 	err = register_fib_notifier(&mlxsw_sp->router->fib_nb,
 				    mlxsw_sp_router_fib_dump_flush);
@@ -6729,6 +6736,8 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
 	return 0;
 
 err_register_fib_notifier:
+	unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
+err_register_netevent_notifier:
 	mlxsw_sp_neigh_fini(mlxsw_sp);
 err_neigh_init:
 	mlxsw_sp_vrs_fini(mlxsw_sp);
@@ -6754,6 +6763,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
 void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
 {
 	unregister_fib_notifier(&mlxsw_sp->router->fib_nb);
+	unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
 	mlxsw_sp_neigh_fini(mlxsw_sp);
 	mlxsw_sp_vrs_fini(mlxsw_sp);
 	mlxsw_sp_mr_fini(mlxsw_sp);
-- 
2.9.5

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

* [patch net-next 3/6] mlxsw: spectrum_router: Properly name netevent work struct
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 2/6] mlxsw: spectrum_router: Embed netevent notifier block in router struct Jiri Pirko
@ 2017-11-02 16:14 ` Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 4/6] mlxsw: reg: Add Router ECMP Configuration Register Version 2 Jiri Pirko
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Ido Schimmel <idosch@mellanox.com>

The struct containing the work item queued from the netevent handler is
named after the only event it is currently used for, which is neighbour
updates.

Use a more appropriate name for the struct, as we are going to use it
for more events.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 26 +++++++++++-----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index d49c1c9..d5094b8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -2026,7 +2026,7 @@ mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
 	mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, true);
 }
 
-struct mlxsw_sp_neigh_event_work {
+struct mlxsw_sp_netevent_work {
 	struct work_struct work;
 	struct mlxsw_sp *mlxsw_sp;
 	struct neighbour *n;
@@ -2034,11 +2034,11 @@ struct mlxsw_sp_neigh_event_work {
 
 static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
 {
-	struct mlxsw_sp_neigh_event_work *neigh_work =
-		container_of(work, struct mlxsw_sp_neigh_event_work, work);
-	struct mlxsw_sp *mlxsw_sp = neigh_work->mlxsw_sp;
+	struct mlxsw_sp_netevent_work *net_work =
+		container_of(work, struct mlxsw_sp_netevent_work, work);
+	struct mlxsw_sp *mlxsw_sp = net_work->mlxsw_sp;
 	struct mlxsw_sp_neigh_entry *neigh_entry;
-	struct neighbour *n = neigh_work->n;
+	struct neighbour *n = net_work->n;
 	unsigned char ha[ETH_ALEN];
 	bool entry_connected;
 	u8 nud_state, dead;
@@ -2074,13 +2074,13 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
 out:
 	rtnl_unlock();
 	neigh_release(n);
-	kfree(neigh_work);
+	kfree(net_work);
 }
 
 static int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
 					  unsigned long event, void *ptr)
 {
-	struct mlxsw_sp_neigh_event_work *neigh_work;
+	struct mlxsw_sp_netevent_work *net_work;
 	struct mlxsw_sp_port *mlxsw_sp_port;
 	struct mlxsw_sp *mlxsw_sp;
 	unsigned long interval;
@@ -2119,22 +2119,22 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
 		if (!mlxsw_sp_port)
 			return NOTIFY_DONE;
 
-		neigh_work = kzalloc(sizeof(*neigh_work), GFP_ATOMIC);
-		if (!neigh_work) {
+		net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
+		if (!net_work) {
 			mlxsw_sp_port_dev_put(mlxsw_sp_port);
 			return NOTIFY_BAD;
 		}
 
-		INIT_WORK(&neigh_work->work, mlxsw_sp_router_neigh_event_work);
-		neigh_work->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-		neigh_work->n = n;
+		INIT_WORK(&net_work->work, mlxsw_sp_router_neigh_event_work);
+		net_work->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+		net_work->n = n;
 
 		/* Take a reference to ensure the neighbour won't be
 		 * destructed until we drop the reference in delayed
 		 * work.
 		 */
 		neigh_clone(n);
-		mlxsw_core_schedule_work(&neigh_work->work);
+		mlxsw_core_schedule_work(&net_work->work);
 		mlxsw_sp_port_dev_put(mlxsw_sp_port);
 		break;
 	}
-- 
2.9.5

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

* [patch net-next 4/6] mlxsw: reg: Add Router ECMP Configuration Register Version 2
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
                   ` (2 preceding siblings ...)
  2017-11-02 16:14 ` [patch net-next 3/6] mlxsw: spectrum_router: Properly name netevent work struct Jiri Pirko
@ 2017-11-02 16:14 ` Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 5/6] mlxsw: spectrum_router: Align multipath hash parameters with kernel's Jiri Pirko
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Ido Schimmel <idosch@mellanox.com>

The RECRv2 register is used for setting up the router's ECMP hash
configuration.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 132 ++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index db6cd26..5066553 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -5844,6 +5844,137 @@ static inline void mlxsw_reg_rigr2_erif_entry_pack(char *payload, int index,
 	mlxsw_reg_rigr2_erif_entry_erif_set(payload, index, erif);
 }
 
+/* RECR-V2 - Router ECMP Configuration Version 2 Register
+ * ------------------------------------------------------
+ */
+#define MLXSW_REG_RECR2_ID 0x8025
+#define MLXSW_REG_RECR2_LEN 0x38
+
+MLXSW_REG_DEFINE(recr2, MLXSW_REG_RECR2_ID, MLXSW_REG_RECR2_LEN);
+
+/* reg_recr2_pp
+ * Per-port configuration
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, recr2, pp, 0x00, 24, 1);
+
+/* reg_recr2_sh
+ * Symmetric hash
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, recr2, sh, 0x00, 8, 1);
+
+/* reg_recr2_seed
+ * Seed
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, recr2, seed, 0x08, 0, 32);
+
+enum {
+	/* Enable IPv4 fields if packet is not TCP and not UDP */
+	MLXSW_REG_RECR2_IPV4_EN_NOT_TCP_NOT_UDP	= 3,
+	/* Enable IPv4 fields if packet is TCP or UDP */
+	MLXSW_REG_RECR2_IPV4_EN_TCP_UDP		= 4,
+	/* Enable IPv6 fields if packet is not TCP and not UDP */
+	MLXSW_REG_RECR2_IPV6_EN_NOT_TCP_NOT_UDP	= 5,
+	/* Enable IPv6 fields if packet is TCP or UDP */
+	MLXSW_REG_RECR2_IPV6_EN_TCP_UDP		= 6,
+	/* Enable TCP/UDP header fields if packet is IPv4 */
+	MLXSW_REG_RECR2_TCP_UDP_EN_IPV4		= 7,
+	/* Enable TCP/UDP header fields if packet is IPv6 */
+	MLXSW_REG_RECR2_TCP_UDP_EN_IPV6		= 8,
+};
+
+/* reg_recr2_outer_header_enables
+ * Bit mask where each bit enables a specific layer to be included in
+ * the hash calculation.
+ * Access: RW
+ */
+MLXSW_ITEM_BIT_ARRAY(reg, recr2, outer_header_enables, 0x10, 0x04, 1);
+
+enum {
+	/* IPv4 Source IP */
+	MLXSW_REG_RECR2_IPV4_SIP0			= 9,
+	MLXSW_REG_RECR2_IPV4_SIP3			= 12,
+	/* IPv4 Destination IP */
+	MLXSW_REG_RECR2_IPV4_DIP0			= 13,
+	MLXSW_REG_RECR2_IPV4_DIP3			= 16,
+	/* IP Protocol */
+	MLXSW_REG_RECR2_IPV4_PROTOCOL			= 17,
+	/* IPv6 Source IP */
+	MLXSW_REG_RECR2_IPV6_SIP0_7			= 21,
+	MLXSW_REG_RECR2_IPV6_SIP8			= 29,
+	MLXSW_REG_RECR2_IPV6_SIP15			= 36,
+	/* IPv6 Destination IP */
+	MLXSW_REG_RECR2_IPV6_DIP0_7			= 37,
+	MLXSW_REG_RECR2_IPV6_DIP8			= 45,
+	MLXSW_REG_RECR2_IPV6_DIP15			= 52,
+	/* IPv6 Next Header */
+	MLXSW_REG_RECR2_IPV6_NEXT_HEADER		= 53,
+	/* IPv6 Flow Label */
+	MLXSW_REG_RECR2_IPV6_FLOW_LABEL			= 57,
+	/* TCP/UDP Source Port */
+	MLXSW_REG_RECR2_TCP_UDP_SPORT			= 74,
+	/* TCP/UDP Destination Port */
+	MLXSW_REG_RECR2_TCP_UDP_DPORT			= 75,
+};
+
+/* reg_recr2_outer_header_fields_enable
+ * Packet fields to enable for ECMP hash subject to outer_header_enable.
+ * Access: RW
+ */
+MLXSW_ITEM_BIT_ARRAY(reg, recr2, outer_header_fields_enable, 0x14, 0x14, 1);
+
+static inline void mlxsw_reg_recr2_ipv4_sip_enable(char *payload)
+{
+	int i;
+
+	for (i = MLXSW_REG_RECR2_IPV4_SIP0; i <= MLXSW_REG_RECR2_IPV4_SIP3; i++)
+		mlxsw_reg_recr2_outer_header_fields_enable_set(payload, i,
+							       true);
+}
+
+static inline void mlxsw_reg_recr2_ipv4_dip_enable(char *payload)
+{
+	int i;
+
+	for (i = MLXSW_REG_RECR2_IPV4_DIP0; i <= MLXSW_REG_RECR2_IPV4_DIP3; i++)
+		mlxsw_reg_recr2_outer_header_fields_enable_set(payload, i,
+							       true);
+}
+
+static inline void mlxsw_reg_recr2_ipv6_sip_enable(char *payload)
+{
+	int i = MLXSW_REG_RECR2_IPV6_SIP0_7;
+
+	mlxsw_reg_recr2_outer_header_fields_enable_set(payload, i, true);
+
+	i = MLXSW_REG_RECR2_IPV6_SIP8;
+	for (; i <= MLXSW_REG_RECR2_IPV6_SIP15; i++)
+		mlxsw_reg_recr2_outer_header_fields_enable_set(payload, i,
+							       true);
+}
+
+static inline void mlxsw_reg_recr2_ipv6_dip_enable(char *payload)
+{
+	int i = MLXSW_REG_RECR2_IPV6_DIP0_7;
+
+	mlxsw_reg_recr2_outer_header_fields_enable_set(payload, i, true);
+
+	i = MLXSW_REG_RECR2_IPV6_DIP8;
+	for (; i <= MLXSW_REG_RECR2_IPV6_DIP15; i++)
+		mlxsw_reg_recr2_outer_header_fields_enable_set(payload, i,
+							       true);
+}
+
+static inline void mlxsw_reg_recr2_pack(char *payload, u32 seed)
+{
+	MLXSW_REG_ZERO(recr2, payload);
+	mlxsw_reg_recr2_pp_set(payload, false);
+	mlxsw_reg_recr2_sh_set(payload, true);
+	mlxsw_reg_recr2_seed_set(payload, seed);
+}
+
 /* RMFT-V2 - Router Multicast Forwarding Table Version 2 Register
  * --------------------------------------------------------------
  * The RMFT_V2 register is used to configure and query the multicast table.
@@ -7313,6 +7444,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
 	MLXSW_REG(raleu),
 	MLXSW_REG(rauhtd),
 	MLXSW_REG(rigr2),
+	MLXSW_REG(recr2),
 	MLXSW_REG(rmft2),
 	MLXSW_REG(mfcr),
 	MLXSW_REG(mfsc),
-- 
2.9.5

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

* [patch net-next 5/6] mlxsw: spectrum_router: Align multipath hash parameters with kernel's
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
                   ` (3 preceding siblings ...)
  2017-11-02 16:14 ` [patch net-next 4/6] mlxsw: reg: Add Router ECMP Configuration Register Version 2 Jiri Pirko
@ 2017-11-02 16:14 ` Jiri Pirko
  2017-11-02 16:14 ` [patch net-next 6/6] mlxsw: spectrum_router: Update multipath hash parameters upon netevents Jiri Pirko
  2017-11-03  6:41 ` [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's David Miller
  6 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Ido Schimmel <idosch@mellanox.com>

Up until now we used the hardware's defaults for multipath hash
computation. This patch aligns the hardware's multipath parameters with
the kernel's.

For IPv4 packets, the parameters are determined according to the
'fib_multipath_hash_policy' sysctl during module initialization. In case
L3-mode is requested, only the source and destination IP addresses are
used. There is no special handling of ICMP error packets.

In case L4-mode is requested, a 5-tuple is used: source and destination
IP addresses, source and destination ports and IP protocol. Note that
the layer 4 fields are not considered for fragmented packets.

For IPv6 packets, the source and destination IP addresses are used, as
well as the flow label and the next header fields.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 64 ++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index d5094b8..fe99d24 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -47,6 +47,7 @@
 #include <linux/socket.h>
 #include <linux/route.h>
 #include <linux/gcd.h>
+#include <linux/random.h>
 #include <net/netevent.h>
 #include <net/neighbour.h>
 #include <net/arp.h>
@@ -6644,6 +6645,64 @@ static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb)
 	mlxsw_sp_router_fib_flush(router->mlxsw_sp);
 }
 
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+static void mlxsw_sp_mp_hash_header_set(char *recr2_pl, int header)
+{
+	mlxsw_reg_recr2_outer_header_enables_set(recr2_pl, header, true);
+}
+
+static void mlxsw_sp_mp_hash_field_set(char *recr2_pl, int field)
+{
+	mlxsw_reg_recr2_outer_header_fields_enable_set(recr2_pl, field, true);
+}
+
+static void mlxsw_sp_mp4_hash_init(char *recr2_pl)
+{
+	bool only_l3 = !init_net.ipv4.sysctl_fib_multipath_hash_policy;
+
+	mlxsw_sp_mp_hash_header_set(recr2_pl,
+				    MLXSW_REG_RECR2_IPV4_EN_NOT_TCP_NOT_UDP);
+	mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_IPV4_EN_TCP_UDP);
+	mlxsw_reg_recr2_ipv4_sip_enable(recr2_pl);
+	mlxsw_reg_recr2_ipv4_dip_enable(recr2_pl);
+	if (only_l3)
+		return;
+	mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_TCP_UDP_EN_IPV4);
+	mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV4_PROTOCOL);
+	mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_TCP_UDP_SPORT);
+	mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_TCP_UDP_DPORT);
+}
+
+static void mlxsw_sp_mp6_hash_init(char *recr2_pl)
+{
+	mlxsw_sp_mp_hash_header_set(recr2_pl,
+				    MLXSW_REG_RECR2_IPV6_EN_NOT_TCP_NOT_UDP);
+	mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_IPV6_EN_TCP_UDP);
+	mlxsw_reg_recr2_ipv6_sip_enable(recr2_pl);
+	mlxsw_reg_recr2_ipv6_dip_enable(recr2_pl);
+	mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV6_FLOW_LABEL);
+	mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV6_NEXT_HEADER);
+}
+
+static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
+{
+	char recr2_pl[MLXSW_REG_RECR2_LEN];
+	u32 seed;
+
+	get_random_bytes(&seed, sizeof(seed));
+	mlxsw_reg_recr2_pack(recr2_pl, seed);
+	mlxsw_sp_mp4_hash_init(recr2_pl);
+	mlxsw_sp_mp6_hash_init(recr2_pl);
+
+	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(recr2), recr2_pl);
+}
+#else
+static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
+{
+	return 0;
+}
+#endif
+
 static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
 {
 	char rgcr_pl[MLXSW_REG_RGCR_LEN];
@@ -6727,6 +6786,10 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
 	if (err)
 		goto err_register_netevent_notifier;
 
+	err = mlxsw_sp_mp_hash_init(mlxsw_sp);
+	if (err)
+		goto err_mp_hash_init;
+
 	mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event;
 	err = register_fib_notifier(&mlxsw_sp->router->fib_nb,
 				    mlxsw_sp_router_fib_dump_flush);
@@ -6736,6 +6799,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
 	return 0;
 
 err_register_fib_notifier:
+err_mp_hash_init:
 	unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
 err_register_netevent_notifier:
 	mlxsw_sp_neigh_fini(mlxsw_sp);
-- 
2.9.5

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

* [patch net-next 6/6] mlxsw: spectrum_router: Update multipath hash parameters upon netevents
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
                   ` (4 preceding siblings ...)
  2017-11-02 16:14 ` [patch net-next 5/6] mlxsw: spectrum_router: Align multipath hash parameters with kernel's Jiri Pirko
@ 2017-11-02 16:14 ` Jiri Pirko
  2017-11-03  6:41 ` [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's David Miller
  6 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2017-11-02 16:14 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, mlxsw, dsahern

From: Ido Schimmel <idosch@mellanox.com>

Make sure the device and the kernel are performing the multipath hash
according to the same parameters by updating the device whenever the
relevant netevent is generated.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 31 +++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index fe99d24..d657f01 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -2078,15 +2078,29 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
 	kfree(net_work);
 }
 
-static int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
+static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp);
+
+static void mlxsw_sp_router_mp_hash_event_work(struct work_struct *work)
+{
+	struct mlxsw_sp_netevent_work *net_work =
+		container_of(work, struct mlxsw_sp_netevent_work, work);
+	struct mlxsw_sp *mlxsw_sp = net_work->mlxsw_sp;
+
+	mlxsw_sp_mp_hash_init(mlxsw_sp);
+	kfree(net_work);
+}
+
+static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
 					  unsigned long event, void *ptr)
 {
 	struct mlxsw_sp_netevent_work *net_work;
 	struct mlxsw_sp_port *mlxsw_sp_port;
+	struct mlxsw_sp_router *router;
 	struct mlxsw_sp *mlxsw_sp;
 	unsigned long interval;
 	struct neigh_parms *p;
 	struct neighbour *n;
+	struct net *net;
 
 	switch (event) {
 	case NETEVENT_DELAY_PROBE_TIME_UPDATE:
@@ -2138,6 +2152,21 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
 		mlxsw_core_schedule_work(&net_work->work);
 		mlxsw_sp_port_dev_put(mlxsw_sp_port);
 		break;
+	case NETEVENT_MULTIPATH_HASH_UPDATE:
+		net = ptr;
+
+		if (!net_eq(net, &init_net))
+			return NOTIFY_DONE;
+
+		net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
+		if (!net_work)
+			return NOTIFY_BAD;
+
+		router = container_of(nb, struct mlxsw_sp_router, netevent_nb);
+		INIT_WORK(&net_work->work, mlxsw_sp_router_mp_hash_event_work);
+		net_work->mlxsw_sp = router->mlxsw_sp;
+		mlxsw_core_schedule_work(&net_work->work);
+		break;
 	}
 
 	return NOTIFY_DONE;
-- 
2.9.5

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

* Re: [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed
  2017-11-02 16:14 ` [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed Jiri Pirko
@ 2017-11-02 18:57   ` David Ahern
  0 siblings, 0 replies; 9+ messages in thread
From: David Ahern @ 2017-11-02 18:57 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, idosch, mlxsw

On 11/2/17 9:14 AM, Jiri Pirko wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> 
> Devices performing IPv4 forwarding need to update their multipath hash
> policy whenever it is changed.
> 
> Inform these devices by generating a netevent.
> 
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reviewed-by: Petr Machata <petrm@mellanox.com>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  include/net/netevent.h     |  1 +
>  net/ipv4/sysctl_net_ipv4.c | 20 +++++++++++++++++++-
>  2 files changed, 20 insertions(+), 1 deletion(-)
> 

LGTM.

Acked-by: David Ahern <dsahern@gmail.com>

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

* Re: [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's
  2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
                   ` (5 preceding siblings ...)
  2017-11-02 16:14 ` [patch net-next 6/6] mlxsw: spectrum_router: Update multipath hash parameters upon netevents Jiri Pirko
@ 2017-11-03  6:41 ` David Miller
  6 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2017-11-03  6:41 UTC (permalink / raw)
  To: jiri; +Cc: netdev, idosch, mlxsw, dsahern

From: Jiri Pirko <jiri@resnulli.us>
Date: Thu,  2 Nov 2017 17:14:04 +0100

> From: Jiri Pirko <jiri@mellanox.com>
> 
> Ido says:
> 
> This set makes sure the device is using the same parameters as the
> kernel when it computes the multipath hash during IP forwarding.
> 
> First patch adds a new netevent to let interested listeners know that
> the multipath hash policy has changed.
> 
> Next two patches do small and non-functional changes in the mlxsw
> driver.
> 
> Last patches configure the multipath hash policy upon driver
> initialization and as a response to netevents.

Series applied, thanks everyone.

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

end of thread, other threads:[~2017-11-03  6:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-02 16:14 [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's Jiri Pirko
2017-11-02 16:14 ` [patch net-next 1/6] ipv4: Send a netevent whenever multipath hash policy is changed Jiri Pirko
2017-11-02 18:57   ` David Ahern
2017-11-02 16:14 ` [patch net-next 2/6] mlxsw: spectrum_router: Embed netevent notifier block in router struct Jiri Pirko
2017-11-02 16:14 ` [patch net-next 3/6] mlxsw: spectrum_router: Properly name netevent work struct Jiri Pirko
2017-11-02 16:14 ` [patch net-next 4/6] mlxsw: reg: Add Router ECMP Configuration Register Version 2 Jiri Pirko
2017-11-02 16:14 ` [patch net-next 5/6] mlxsw: spectrum_router: Align multipath hash parameters with kernel's Jiri Pirko
2017-11-02 16:14 ` [patch net-next 6/6] mlxsw: spectrum_router: Update multipath hash parameters upon netevents Jiri Pirko
2017-11-03  6:41 ` [patch net-next 0/6] mlxsw: Align multipath hash parameters with kernel's 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.