mlxsw: spectrum: Seed LAG hash function
authorIdo Schimmel <idosch@mellanox.com>
Thu, 11 Oct 2018 07:47:57 +0000 (07:47 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 11 Oct 2018 17:08:22 +0000 (10:08 -0700)
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 <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/reg.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c

index a0441f3d4284eda47bbd0b8541aef50568141864..4988d24a628c3c7de0719333763d70ada5d2221c 100644 (file)
@@ -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
index 2b14fd0dcc4282966828143be4507f9de3165acb..d42980df57b713c5582e411be10fa60c2a659690 100644 (file)
@@ -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;