Currently, the seed of the LAG hash function is always set to 0, which
means it is identical across all switches. Instead, use a random number.

This is especially important now that VxLAN is supported, as the LAG
hash function is used to calculate the UDP source port of the
encapsulated packet.

Signed-off-by: Ido Schimmel <ido...@mellanox.com>
Reviewed-by: Petr Machata <pe...@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h      | 9 ++++++++-
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 5 ++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h 
b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index a0441f3d4284..4988d24a628c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -1321,12 +1321,19 @@ MLXSW_ITEM32(reg, slcr, type, 0x00, 0, 4);
  */
 MLXSW_ITEM32(reg, slcr, lag_hash, 0x04, 0, 20);
 
-static inline void mlxsw_reg_slcr_pack(char *payload, u16 lag_hash)
+/* reg_slcr_seed
+ * LAG seed value. The seed is the same for all ports.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, slcr, seed, 0x08, 0, 32);
+
+static inline void mlxsw_reg_slcr_pack(char *payload, u16 lag_hash, u32 seed)
 {
        MLXSW_REG_ZERO(slcr, payload);
        mlxsw_reg_slcr_pp_set(payload, MLXSW_REG_SLCR_PP_GLOBAL);
        mlxsw_reg_slcr_type_set(payload, MLXSW_REG_SLCR_TYPE_CRC);
        mlxsw_reg_slcr_lag_hash_set(payload, lag_hash);
+       mlxsw_reg_slcr_seed_set(payload, seed);
 }
 
 /* SLCOR - Switch LAG Collector Register
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 2b14fd0dcc42..d42980df57b7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -21,6 +21,7 @@
 #include <linux/dcbnl.h>
 #include <linux/inetdevice.h>
 #include <linux/netlink.h>
+#include <linux/random.h>
 #include <net/switchdev.h>
 #include <net/pkt_cls.h>
 #include <net/tc_act/tc_mirred.h>
@@ -3666,8 +3667,10 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp 
*mlxsw_sp)
 static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
 {
        char slcr_pl[MLXSW_REG_SLCR_LEN];
+       u32 seed;
        int err;
 
+       get_random_bytes(&seed, sizeof(seed));
        mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
                                     MLXSW_REG_SLCR_LAG_HASH_DMAC |
                                     MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
@@ -3676,7 +3679,7 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
                                     MLXSW_REG_SLCR_LAG_HASH_DIP |
                                     MLXSW_REG_SLCR_LAG_HASH_SPORT |
                                     MLXSW_REG_SLCR_LAG_HASH_DPORT |
-                                    MLXSW_REG_SLCR_LAG_HASH_IPPROTO);
+                                    MLXSW_REG_SLCR_LAG_HASH_IPPROTO, seed);
        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl);
        if (err)
                return err;
-- 
2.17.1

Reply via email to