aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-11-16 15:59:19 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-16 15:59:19 -0500
commit65622ed40eef5ce2732365077b22416593fec4c8 (patch)
tree3feae5512b57c55e708107e6c191fd5d611d17f9
parentca245024349c0d44434a6381583b99f0eb559c7c (diff)
parent6bf79cdddd50e90cbba7471623c129dadf9c873b (diff)
Merge branch 'rss_key_fill'
Eric Dumazet says: ==================== net: provide common RSS key infrastructure RSS (Receive Side Scaling) uses a 40 bytes key to provide hash for incoming packets to select appropriate incoming queue on NIC. Hash algo (Toeplitz) is also well known and documented by Microsoft (search for "Verifying the RSS Hash Calculation") Problem is that some drivers use a well known key. It makes very easy for attackers to target one particular RX queue, knowing that number of RX queues is a power of two, or at least some small number. Other drivers use a random value per port, making difficult tuning on bonding setups. Lets add a common infrastructure, so that host gets an unique RSS key, and drivers do not have to worry about this. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/sysctl/net.txt22
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c2
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c17
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c10
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c9
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c10
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c10
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c11
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c9
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c6
-rw-r--r--drivers/net/ethernet/sfc/efx.c2
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c9
-rw-r--r--include/linux/mlx4/qp.h4
-rw-r--r--include/linux/netdevice.h6
-rw-r--r--net/core/ethtool.c11
-rw-r--r--net/core/sysctl_net_core.c19
20 files changed, 104 insertions, 73 deletions
diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt
index e26c607468a6..666594b43cff 100644
--- a/Documentation/sysctl/net.txt
+++ b/Documentation/sysctl/net.txt
@@ -142,6 +142,28 @@ netdev_max_backlog
142Maximum number of packets, queued on the INPUT side, when the interface 142Maximum number of packets, queued on the INPUT side, when the interface
143receives packets faster than kernel can process them. 143receives packets faster than kernel can process them.
144 144
145netdev_rss_key
146--------------
147
148RSS (Receive Side Scaling) enabled drivers use a 40 bytes host key that is
149randomly generated.
150Some user space might need to gather its content even if drivers do not
151provide ethtool -x support yet.
152
153myhost:~# cat /proc/sys/net/core/netdev_rss_key
15484:50:f4:00:a8:15:d1:a7:e9:7f:1d:60:35:c7:47:25:42:97:74:ca:56:bb:b6:a1:d8: ... (52 bytes total)
155
156File contains nul bytes if no driver ever called netdev_rss_key_fill() function.
157Note:
158/proc/sys/net/core/netdev_rss_key contains 52 bytes of key,
159but most drivers only use 40 bytes of it.
160
161myhost:~# ethtool -x eth0
162RX flow hash indirection table for eth0 with 8 RX ring(s):
163 0: 0 1 2 3 4 5 6 7
164RSS hash key:
16584:50:f4:00:a8:15:d1:a7:e9:7f:1d:60:35:c7:47:25:42:97:74:ca:56:bb:b6:a1:d8:43:e3:c9:0c:fd:17:55:c2:3a:4d:69:ed:f1:42:89
166
145netdev_tstamp_prequeue 167netdev_tstamp_prequeue
146---------------------- 168----------------------
147 169
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index 05fbdf96e77e..dbd3850b8b0a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -338,7 +338,7 @@ static int xgbe_probe(struct platform_device *pdev)
338 } 338 }
339 339
340 /* Initialize RSS hash key and lookup table */ 340 /* Initialize RSS hash key and lookup table */
341 get_random_bytes(pdata->rss_key, sizeof(pdata->rss_key)); 341 netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key));
342 342
343 for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++) 343 for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++)
344 XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH, 344 XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index e9af4af5edba..b4d71fd909ee 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2099,7 +2099,7 @@ int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
2099 2099
2100 if (config_hash) { 2100 if (config_hash) {
2101 /* RSS keys */ 2101 /* RSS keys */
2102 prandom_bytes(params.rss_key, T_ETH_RSS_KEY * 4); 2102 netdev_rss_key_fill(params.rss_key, T_ETH_RSS_KEY * 4);
2103 __set_bit(BNX2X_RSS_SET_SRCH, &params.rss_flags); 2103 __set_bit(BNX2X_RSS_SET_SRCH, &params.rss_flags);
2104 } 2104 }
2105 2105
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index dbb41c1923e6..2dc001559a97 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -10540,19 +10540,14 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
10540 udelay(100); 10540 udelay(100);
10541 10541
10542 if (tg3_flag(tp, ENABLE_RSS)) { 10542 if (tg3_flag(tp, ENABLE_RSS)) {
10543 u32 rss_key[10];
10544
10543 tg3_rss_write_indir_tbl(tp); 10545 tg3_rss_write_indir_tbl(tp);
10544 10546
10545 /* Setup the "secret" hash key. */ 10547 netdev_rss_key_fill(rss_key, 10 * sizeof(u32));
10546 tw32(MAC_RSS_HASH_KEY_0, 0x5f865437); 10548
10547 tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc); 10549 for (i = 0; i < 10 ; i++)
10548 tw32(MAC_RSS_HASH_KEY_2, 0x50103a45); 10550 tw32(MAC_RSS_HASH_KEY_0 + i*4, rss_key[i]);
10549 tw32(MAC_RSS_HASH_KEY_3, 0x36621985);
10550 tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8);
10551 tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e);
10552 tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556);
10553 tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe);
10554 tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7);
10555 tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481);
10556 } 10551 }
10557 10552
10558 tp->rx_mode = RX_MODE_ENABLE; 10553 tp->rx_mode = RX_MODE_ENABLE;
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index c3861de9dc81..323721838cf9 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -2054,7 +2054,7 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
2054 BFI_ENET_RSS_IPV4_TCP); 2054 BFI_ENET_RSS_IPV4_TCP);
2055 rx_config->rss_config.hash_mask = 2055 rx_config->rss_config.hash_mask =
2056 bnad->num_rxp_per_rx - 1; 2056 bnad->num_rxp_per_rx - 1;
2057 get_random_bytes(rx_config->rss_config.toeplitz_hash_key, 2057 netdev_rss_key_fill(rx_config->rss_config.toeplitz_hash_key,
2058 sizeof(rx_config->rss_config.toeplitz_hash_key)); 2058 sizeof(rx_config->rss_config.toeplitz_hash_key));
2059 } else { 2059 } else {
2060 rx_config->rss_status = BNA_STATUS_T_DISABLED; 2060 rx_config->rss_status = BNA_STATUS_T_DISABLED;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 9a18e7930b31..54160cc62656 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2853,10 +2853,10 @@ static int be_close(struct net_device *netdev)
2853 2853
2854static int be_rx_qs_create(struct be_adapter *adapter) 2854static int be_rx_qs_create(struct be_adapter *adapter)
2855{ 2855{
2856 struct rss_info *rss = &adapter->rss_info;
2857 u8 rss_key[RSS_HASH_KEY_LEN];
2856 struct be_rx_obj *rxo; 2858 struct be_rx_obj *rxo;
2857 int rc, i, j; 2859 int rc, i, j;
2858 u8 rss_hkey[RSS_HASH_KEY_LEN];
2859 struct rss_info *rss = &adapter->rss_info;
2860 2860
2861 for_all_rx_queues(adapter, rxo, i) { 2861 for_all_rx_queues(adapter, rxo, i) {
2862 rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN, 2862 rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN,
@@ -2901,15 +2901,15 @@ static int be_rx_qs_create(struct be_adapter *adapter)
2901 rss->rss_flags = RSS_ENABLE_NONE; 2901 rss->rss_flags = RSS_ENABLE_NONE;
2902 } 2902 }
2903 2903
2904 get_random_bytes(rss_hkey, RSS_HASH_KEY_LEN); 2904 netdev_rss_key_fill(rss_key, RSS_HASH_KEY_LEN);
2905 rc = be_cmd_rss_config(adapter, rss->rsstable, rss->rss_flags, 2905 rc = be_cmd_rss_config(adapter, rss->rsstable, rss->rss_flags,
2906 128, rss_hkey); 2906 128, rss_key);
2907 if (rc) { 2907 if (rc) {
2908 rss->rss_flags = RSS_ENABLE_NONE; 2908 rss->rss_flags = RSS_ENABLE_NONE;
2909 return rc; 2909 return rc;
2910 } 2910 }
2911 2911
2912 memcpy(rss->rss_hkey, rss_hkey, RSS_HASH_KEY_LEN); 2912 memcpy(rss->rss_hkey, rss_key, RSS_HASH_KEY_LEN);
2913 2913
2914 /* First time posting */ 2914 /* First time posting */
2915 for_all_rx_queues(adapter, rxo, i) 2915 for_all_rx_queues(adapter, rxo, i)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 247335d2c7ec..370cfa275ddb 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -3449,15 +3449,12 @@ static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
3449{ 3449{
3450 struct e1000_hw *hw = &adapter->hw; 3450 struct e1000_hw *hw = &adapter->hw;
3451 u32 mrqc, rxcsum; 3451 u32 mrqc, rxcsum;
3452 u32 rss_key[10];
3452 int i; 3453 int i;
3453 static const u32 rsskey[10] = {
3454 0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
3455 0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
3456 };
3457 3454
3458 /* Fill out hash function seed */ 3455 netdev_rss_key_fill(rss_key, sizeof(rss_key));
3459 for (i = 0; i < 10; i++) 3456 for (i = 0; i < 10; i++)
3460 ew32(RSSRK(i), rsskey[i]); 3457 ew32(RSSRK(i), rss_key[i]);
3461 3458
3462 /* Direct all traffic to queue 0 */ 3459 /* Direct all traffic to queue 0 */
3463 for (i = 0; i < 32; i++) 3460 for (i = 0; i < 32; i++)
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index a0cb74ab3dc6..4f5892cc32d7 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -1551,15 +1551,11 @@ void fm10k_down(struct fm10k_intfc *interface)
1551static int fm10k_sw_init(struct fm10k_intfc *interface, 1551static int fm10k_sw_init(struct fm10k_intfc *interface,
1552 const struct pci_device_id *ent) 1552 const struct pci_device_id *ent)
1553{ 1553{
1554 static const u32 seed[FM10K_RSSRK_SIZE] = { 0xda565a6d, 0xc20e5b25,
1555 0x3d256741, 0xb08fa343,
1556 0xcb2bcad0, 0xb4307bae,
1557 0xa32dcb77, 0x0cf23080,
1558 0x3bb7426a, 0xfa01acbe };
1559 const struct fm10k_info *fi = fm10k_info_tbl[ent->driver_data]; 1554 const struct fm10k_info *fi = fm10k_info_tbl[ent->driver_data];
1560 struct fm10k_hw *hw = &interface->hw; 1555 struct fm10k_hw *hw = &interface->hw;
1561 struct pci_dev *pdev = interface->pdev; 1556 struct pci_dev *pdev = interface->pdev;
1562 struct net_device *netdev = interface->netdev; 1557 struct net_device *netdev = interface->netdev;
1558 u32 rss_key[FM10K_RSSRK_SIZE];
1563 unsigned int rss; 1559 unsigned int rss;
1564 int err; 1560 int err;
1565 1561
@@ -1673,8 +1669,8 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
1673 /* initialize vxlan_port list */ 1669 /* initialize vxlan_port list */
1674 INIT_LIST_HEAD(&interface->vxlan_port); 1670 INIT_LIST_HEAD(&interface->vxlan_port);
1675 1671
1676 /* initialize RSS key */ 1672 netdev_rss_key_fill(rss_key, sizeof(rss_key));
1677 memcpy(interface->rssrk, seed, sizeof(seed)); 1673 memcpy(interface->rssrk, rss_key, sizeof(rss_key));
1678 1674
1679 /* Start off interface as being down */ 1675 /* Start off interface as being down */
1680 set_bit(__FM10K_DOWN, &interface->state); 1676 set_bit(__FM10K_DOWN, &interface->state);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index de664631c807..a0bee83ab2de 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7002,20 +7002,16 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
7002 **/ 7002 **/
7003static int i40e_config_rss(struct i40e_pf *pf) 7003static int i40e_config_rss(struct i40e_pf *pf)
7004{ 7004{
7005 /* Set of random keys generated using kernel random number generator */ 7005 u32 rss_key[I40E_PFQF_HKEY_MAX_INDEX + 1];
7006 static const u32 seed[I40E_PFQF_HKEY_MAX_INDEX + 1] = {0x41b01687,
7007 0x183cfd8c, 0xce880440, 0x580cbc3c, 0x35897377,
7008 0x328b25e1, 0x4fa98922, 0xb7d90c14, 0xd5bad70d,
7009 0xcd15a2c1, 0xe8580225, 0x4a1e9d11, 0xfe5731be};
7010 struct i40e_hw *hw = &pf->hw; 7006 struct i40e_hw *hw = &pf->hw;
7011 u32 lut = 0; 7007 u32 lut = 0;
7012 int i, j; 7008 int i, j;
7013 u64 hena; 7009 u64 hena;
7014 u32 reg_val; 7010 u32 reg_val;
7015 7011
7016 /* Fill out hash function seed */ 7012 netdev_rss_key_fill(rss_key, sizeof(rss_key));
7017 for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) 7013 for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
7018 wr32(hw, I40E_PFQF_HKEY(i), seed[i]); 7014 wr32(hw, I40E_PFQF_HKEY(i), rss_key[i]);
7019 7015
7020 /* By default we enable TCP/UDP with IPv4/IPv6 ptypes */ 7016 /* By default we enable TCP/UDP with IPv4/IPv6 ptypes */
7021 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) | 7017 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index f0d07ad54198..489227891ffb 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -1434,18 +1434,12 @@ static int next_queue(struct i40evf_adapter *adapter, int j)
1434 **/ 1434 **/
1435static void i40evf_configure_rss(struct i40evf_adapter *adapter) 1435static void i40evf_configure_rss(struct i40evf_adapter *adapter)
1436{ 1436{
1437 u32 rss_key[I40E_VFQF_HKEY_MAX_INDEX + 1];
1437 struct i40e_hw *hw = &adapter->hw; 1438 struct i40e_hw *hw = &adapter->hw;
1438 u32 lut = 0; 1439 u32 lut = 0;
1439 int i, j; 1440 int i, j;
1440 u64 hena; 1441 u64 hena;
1441 1442
1442 /* Set of random keys generated using kernel random number generator */
1443 static const u32 seed[I40E_VFQF_HKEY_MAX_INDEX + 1] = {
1444 0x794221b4, 0xbca0c5ab, 0x6cd5ebd9, 0x1ada6127,
1445 0x983b3aa1, 0x1c4e71eb, 0x7f6328b2, 0xfcdc0da0,
1446 0xc135cafa, 0x7a6f7e2d, 0xe7102d28, 0x163cd12e,
1447 0x4954b126 };
1448
1449 /* No RSS for single queue. */ 1443 /* No RSS for single queue. */
1450 if (adapter->num_active_queues == 1) { 1444 if (adapter->num_active_queues == 1) {
1451 wr32(hw, I40E_VFQF_HENA(0), 0); 1445 wr32(hw, I40E_VFQF_HENA(0), 0);
@@ -1454,8 +1448,9 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
1454 } 1448 }
1455 1449
1456 /* Hash type is configured by the PF - we just supply the key */ 1450 /* Hash type is configured by the PF - we just supply the key */
1451 netdev_rss_key_fill(rss_key, sizeof(rss_key));
1457 for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) 1452 for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
1458 wr32(hw, I40E_VFQF_HKEY(i), seed[i]); 1453 wr32(hw, I40E_VFQF_HKEY(i), rss_key[i]);
1459 1454
1460 /* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */ 1455 /* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */
1461 hena = I40E_DEFAULT_RSS_HENA; 1456 hena = I40E_DEFAULT_RSS_HENA;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 1e35fae7a62b..b0e12e7c4a3d 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -3372,14 +3372,11 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
3372 struct e1000_hw *hw = &adapter->hw; 3372 struct e1000_hw *hw = &adapter->hw;
3373 u32 mrqc, rxcsum; 3373 u32 mrqc, rxcsum;
3374 u32 j, num_rx_queues; 3374 u32 j, num_rx_queues;
3375 static const u32 rsskey[10] = { 0xDA565A6D, 0xC20E5B25, 0x3D256741, 3375 u32 rss_key[10];
3376 0xB08FA343, 0xCB2BCAD0, 0xB4307BAE,
3377 0xA32DCB77, 0x0CF23080, 0x3BB7426A,
3378 0xFA01ACBE };
3379 3376
3380 /* Fill out hash function seeds */ 3377 netdev_rss_key_fill(rss_key, sizeof(rss_key));
3381 for (j = 0; j < 10; j++) 3378 for (j = 0; j < 10; j++)
3382 wr32(E1000_RSSRK(j), rsskey[j]); 3379 wr32(E1000_RSSRK(j), rss_key[j]);
3383 3380
3384 num_rx_queues = adapter->rss_queues; 3381 num_rx_queues = adapter->rss_queues;
3385 3382
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index f5fcba4f9d21..932f77961d66 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3243,10 +3243,8 @@ static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
3243static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) 3243static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
3244{ 3244{
3245 struct ixgbe_hw *hw = &adapter->hw; 3245 struct ixgbe_hw *hw = &adapter->hw;
3246 static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D,
3247 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
3248 0x6A3E67EA, 0x14364D17, 0x3BED200D};
3249 u32 mrqc = 0, rss_field = 0; 3246 u32 mrqc = 0, rss_field = 0;
3247 u32 rss_key[10];
3250 u32 rxcsum; 3248 u32 rxcsum;
3251 3249
3252 /* Disable indicating checksum in descriptor, enables RSS hash */ 3250 /* Disable indicating checksum in descriptor, enables RSS hash */
@@ -3290,7 +3288,8 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
3290 if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) 3288 if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
3291 rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; 3289 rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
3292 3290
3293 ixgbe_setup_reta(adapter, seed); 3291 netdev_rss_key_fill(rss_key, sizeof(rss_key));
3292 ixgbe_setup_reta(adapter, rss_key);
3294 mrqc |= rss_field; 3293 mrqc |= rss_field;
3295 IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); 3294 IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
3296} 3295}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 6c643230a5ed..710cf309962a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -973,6 +973,11 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
973 return priv->rx_ring_num; 973 return priv->rx_ring_num;
974} 974}
975 975
976static u32 mlx4_en_get_rxfh_key_size(struct net_device *netdev)
977{
978 return MLX4_EN_RSS_KEY_SIZE;
979}
980
976static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) 981static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key)
977{ 982{
978 struct mlx4_en_priv *priv = netdev_priv(dev); 983 struct mlx4_en_priv *priv = netdev_priv(dev);
@@ -988,7 +993,8 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key)
988 ring_index[n] = rss_map->qps[n % rss_rings].qpn - 993 ring_index[n] = rss_map->qps[n % rss_rings].qpn -
989 rss_map->base_qpn; 994 rss_map->base_qpn;
990 } 995 }
991 996 if (key)
997 netdev_rss_key_fill(key, MLX4_EN_RSS_KEY_SIZE);
992 return err; 998 return err;
993} 999}
994 1000
@@ -1799,6 +1805,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
1799 .get_rxnfc = mlx4_en_get_rxnfc, 1805 .get_rxnfc = mlx4_en_get_rxnfc,
1800 .set_rxnfc = mlx4_en_set_rxnfc, 1806 .set_rxnfc = mlx4_en_set_rxnfc,
1801 .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, 1807 .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
1808 .get_rxfh_key_size = mlx4_en_get_rxfh_key_size,
1802 .get_rxfh = mlx4_en_get_rxfh, 1809 .get_rxfh = mlx4_en_get_rxfh,
1803 .set_rxfh = mlx4_en_set_rxfh, 1810 .set_rxfh = mlx4_en_set_rxfh,
1804 .get_channels = mlx4_en_get_channels, 1811 .get_channels = mlx4_en_get_channels,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index ccd95177ea7c..b7bda8956011 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -1169,9 +1169,6 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
1169 int i, qpn; 1169 int i, qpn;
1170 int err = 0; 1170 int err = 0;
1171 int good_qps = 0; 1171 int good_qps = 0;
1172 static const u32 rsskey[10] = { 0xD181C62C, 0xF7F4DB5B, 0x1983A2FC,
1173 0x943E1ADB, 0xD9389E6B, 0xD1039C2C, 0xA74499AD,
1174 0x593D56D9, 0xF3253C06, 0x2ADC1FFC};
1175 1172
1176 en_dbg(DRV, priv, "Configuring rss steering\n"); 1173 en_dbg(DRV, priv, "Configuring rss steering\n");
1177 err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num, 1174 err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num,
@@ -1226,8 +1223,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
1226 1223
1227 rss_context->flags = rss_mask; 1224 rss_context->flags = rss_mask;
1228 rss_context->hash_fn = MLX4_RSS_HASH_TOP; 1225 rss_context->hash_fn = MLX4_RSS_HASH_TOP;
1229 for (i = 0; i < 10; i++) 1226 netdev_rss_key_fill(rss_context->rss_key, MLX4_EN_RSS_KEY_SIZE);
1230 rss_context->rss_key[i] = cpu_to_be32(rsskey[i]);
1231 1227
1232 err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, 1228 err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
1233 &rss_map->indir_qp, &rss_map->indir_state); 1229 &rss_map->indir_qp, &rss_map->indir_state);
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index b49d04886d4f..238482495e81 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1616,7 +1616,7 @@ static int efx_probe_nic(struct efx_nic *efx)
1616 goto fail2; 1616 goto fail2;
1617 1617
1618 if (efx->n_channels > 1) 1618 if (efx->n_channels > 1)
1619 get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key)); 1619 netdev_rss_key_fill(&efx->rx_hash_key, sizeof(efx->rx_hash_key));
1620 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) 1620 for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++)
1621 efx->rx_indir_table[i] = 1621 efx->rx_indir_table[i] =
1622 ethtool_rxfh_indir_default(i, efx->rss_spread); 1622 ethtool_rxfh_indir_default(i, efx->rss_spread);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 6dfcbf523936..afd295348ddb 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2199,13 +2199,6 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
2199 2199
2200 if (adapter->rss) { 2200 if (adapter->rss) {
2201 struct UPT1_RSSConf *rssConf = adapter->rss_conf; 2201 struct UPT1_RSSConf *rssConf = adapter->rss_conf;
2202 static const uint8_t rss_key[UPT1_RSS_MAX_KEY_SIZE] = {
2203 0x3b, 0x56, 0xd1, 0x56, 0x13, 0x4a, 0xe7, 0xac,
2204 0xe8, 0x79, 0x09, 0x75, 0xe8, 0x65, 0x79, 0x28,
2205 0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70,
2206 0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3,
2207 0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9,
2208 };
2209 2202
2210 devRead->misc.uptFeatures |= UPT1_F_RSS; 2203 devRead->misc.uptFeatures |= UPT1_F_RSS;
2211 devRead->misc.numRxQueues = adapter->num_rx_queues; 2204 devRead->misc.numRxQueues = adapter->num_rx_queues;
@@ -2216,7 +2209,7 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
2216 rssConf->hashFunc = UPT1_RSS_HASH_FUNC_TOEPLITZ; 2209 rssConf->hashFunc = UPT1_RSS_HASH_FUNC_TOEPLITZ;
2217 rssConf->hashKeySize = UPT1_RSS_MAX_KEY_SIZE; 2210 rssConf->hashKeySize = UPT1_RSS_MAX_KEY_SIZE;
2218 rssConf->indTableSize = VMXNET3_RSS_IND_TABLE_SIZE; 2211 rssConf->indTableSize = VMXNET3_RSS_IND_TABLE_SIZE;
2219 memcpy(rssConf->hashKey, rss_key, sizeof(rss_key)); 2212 netdev_rss_key_fill(rssConf->hashKey, sizeof(rssConf->hashKey));
2220 2213
2221 for (i = 0; i < rssConf->indTableSize; i++) 2214 for (i = 0; i < rssConf->indTableSize; i++)
2222 rssConf->indTable[i] = ethtool_rxfh_indir_default( 2215 rssConf->indTable[i] = ethtool_rxfh_indir_default(
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 5f4e36cf0091..467ccdf94c98 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -120,13 +120,15 @@ enum {
120 MLX4_RSS_QPC_FLAG_OFFSET = 13, 120 MLX4_RSS_QPC_FLAG_OFFSET = 13,
121}; 121};
122 122
123#define MLX4_EN_RSS_KEY_SIZE 40
124
123struct mlx4_rss_context { 125struct mlx4_rss_context {
124 __be32 base_qpn; 126 __be32 base_qpn;
125 __be32 default_qpn; 127 __be32 default_qpn;
126 u16 reserved; 128 u16 reserved;
127 u8 hash_fn; 129 u8 hash_fn;
128 u8 flags; 130 u8 flags;
129 __be32 rss_key[10]; 131 __be32 rss_key[MLX4_EN_RSS_KEY_SIZE / sizeof(__be32)];
130 __be32 base_qpn_udp; 132 __be32 base_qpn_udp;
131}; 133};
132 134
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4a6f770377d3..db63cf459ba1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3422,6 +3422,12 @@ void netdev_upper_dev_unlink(struct net_device *dev,
3422void netdev_adjacent_rename_links(struct net_device *dev, char *oldname); 3422void netdev_adjacent_rename_links(struct net_device *dev, char *oldname);
3423void *netdev_lower_dev_get_private(struct net_device *dev, 3423void *netdev_lower_dev_get_private(struct net_device *dev,
3424 struct net_device *lower_dev); 3424 struct net_device *lower_dev);
3425
3426/* RSS keys are 40 or 52 bytes long */
3427#define NETDEV_RSS_KEY_LEN 52
3428extern u8 netdev_rss_key[NETDEV_RSS_KEY_LEN];
3429void netdev_rss_key_fill(void *buffer, size_t len);
3430
3425int dev_get_nest_level(struct net_device *dev, 3431int dev_get_nest_level(struct net_device *dev,
3426 bool (*type_check)(struct net_device *dev)); 3432 bool (*type_check)(struct net_device *dev));
3427int skb_checksum_help(struct sk_buff *skb); 3433int skb_checksum_help(struct sk_buff *skb);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index b0f84f5ddda8..715f51f321e9 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/rtnetlink.h> 26#include <linux/rtnetlink.h>
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/net.h>
28 29
29/* 30/*
30 * Some useful ethtool_ops methods that're device independent. 31 * Some useful ethtool_ops methods that're device independent.
@@ -573,6 +574,16 @@ static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr,
573 return 0; 574 return 0;
574} 575}
575 576
577u8 netdev_rss_key[NETDEV_RSS_KEY_LEN];
578
579void netdev_rss_key_fill(void *buffer, size_t len)
580{
581 BUG_ON(len > sizeof(netdev_rss_key));
582 net_get_random_once(netdev_rss_key, sizeof(netdev_rss_key));
583 memcpy(buffer, netdev_rss_key, len);
584}
585EXPORT_SYMBOL(netdev_rss_key_fill);
586
576static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, 587static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
577 void __user *useraddr) 588 void __user *useraddr)
578{ 589{
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index f93f092fe226..31baba2a71ce 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -217,6 +217,18 @@ static int set_default_qdisc(struct ctl_table *table, int write,
217} 217}
218#endif 218#endif
219 219
220static int proc_do_rss_key(struct ctl_table *table, int write,
221 void __user *buffer, size_t *lenp, loff_t *ppos)
222{
223 struct ctl_table fake_table;
224 char buf[NETDEV_RSS_KEY_LEN * 3];
225
226 snprintf(buf, sizeof(buf), "%*phC", NETDEV_RSS_KEY_LEN, netdev_rss_key);
227 fake_table.data = buf;
228 fake_table.maxlen = sizeof(buf);
229 return proc_dostring(&fake_table, write, buffer, lenp, ppos);
230}
231
220static struct ctl_table net_core_table[] = { 232static struct ctl_table net_core_table[] = {
221#ifdef CONFIG_NET 233#ifdef CONFIG_NET
222 { 234 {
@@ -265,6 +277,13 @@ static struct ctl_table net_core_table[] = {
265 .mode = 0644, 277 .mode = 0644,
266 .proc_handler = proc_dointvec 278 .proc_handler = proc_dointvec
267 }, 279 },
280 {
281 .procname = "netdev_rss_key",
282 .data = &netdev_rss_key,
283 .maxlen = sizeof(int),
284 .mode = 0444,
285 .proc_handler = proc_do_rss_key,
286 },
268#ifdef CONFIG_BPF_JIT 287#ifdef CONFIG_BPF_JIT
269 { 288 {
270 .procname = "bpf_jit_enable", 289 .procname = "bpf_jit_enable",