@@ -203,19 +203,33 @@ static inline u32 netvsc_get_hash(
203
203
const struct net_device_context * ndc )
204
204
{
205
205
struct flow_keys flow ;
206
- u32 hash ;
206
+ u32 hash , pkt_proto = 0 ;
207
207
static u32 hashrnd __read_mostly ;
208
208
209
209
net_get_random_once (& hashrnd , sizeof (hashrnd ));
210
210
211
211
if (!skb_flow_dissect_flow_keys (skb , & flow , 0 ))
212
212
return 0 ;
213
213
214
- if (flow .basic .ip_proto == IPPROTO_TCP ||
215
- (flow .basic .ip_proto == IPPROTO_UDP &&
216
- ((flow .basic .n_proto == htons (ETH_P_IP ) && ndc -> udp4_l4_hash ) ||
217
- (flow .basic .n_proto == htons (ETH_P_IPV6 ) &&
218
- ndc -> udp6_l4_hash )))) {
214
+ switch (flow .basic .ip_proto ) {
215
+ case IPPROTO_TCP :
216
+ if (flow .basic .n_proto == htons (ETH_P_IP ))
217
+ pkt_proto = HV_TCP4_L4HASH ;
218
+ else if (flow .basic .n_proto == htons (ETH_P_IPV6 ))
219
+ pkt_proto = HV_TCP6_L4HASH ;
220
+
221
+ break ;
222
+
223
+ case IPPROTO_UDP :
224
+ if (flow .basic .n_proto == htons (ETH_P_IP ))
225
+ pkt_proto = HV_UDP4_L4HASH ;
226
+ else if (flow .basic .n_proto == htons (ETH_P_IPV6 ))
227
+ pkt_proto = HV_UDP6_L4HASH ;
228
+
229
+ break ;
230
+ }
231
+
232
+ if (pkt_proto & ndc -> l4_hash ) {
219
233
return skb_get_hash (skb );
220
234
} else {
221
235
if (flow .basic .n_proto == htons (ETH_P_IP ))
@@ -898,8 +912,7 @@ static void netvsc_init_settings(struct net_device *dev)
898
912
{
899
913
struct net_device_context * ndc = netdev_priv (dev );
900
914
901
- ndc -> udp4_l4_hash = true;
902
- ndc -> udp6_l4_hash = true;
915
+ ndc -> l4_hash = HV_DEFAULT_L4HASH ;
903
916
904
917
ndc -> speed = SPEED_UNKNOWN ;
905
918
ndc -> duplex = DUPLEX_FULL ;
@@ -1245,23 +1258,32 @@ static int
1245
1258
netvsc_get_rss_hash_opts (struct net_device_context * ndc ,
1246
1259
struct ethtool_rxnfc * info )
1247
1260
{
1261
+ const u32 l4_flag = RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
1262
+
1248
1263
info -> data = RXH_IP_SRC | RXH_IP_DST ;
1249
1264
1250
1265
switch (info -> flow_type ) {
1251
1266
case TCP_V4_FLOW :
1267
+ if (ndc -> l4_hash & HV_TCP4_L4HASH )
1268
+ info -> data |= l4_flag ;
1269
+
1270
+ break ;
1271
+
1252
1272
case TCP_V6_FLOW :
1253
- info -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
1273
+ if (ndc -> l4_hash & HV_TCP6_L4HASH )
1274
+ info -> data |= l4_flag ;
1275
+
1254
1276
break ;
1255
1277
1256
1278
case UDP_V4_FLOW :
1257
- if (ndc -> udp4_l4_hash )
1258
- info -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
1279
+ if (ndc -> l4_hash & HV_UDP4_L4HASH )
1280
+ info -> data |= l4_flag ;
1259
1281
1260
1282
break ;
1261
1283
1262
1284
case UDP_V6_FLOW :
1263
- if (ndc -> udp6_l4_hash )
1264
- info -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
1285
+ if (ndc -> l4_hash & HV_UDP6_L4HASH )
1286
+ info -> data |= l4_flag ;
1265
1287
1266
1288
break ;
1267
1289
@@ -1302,23 +1324,51 @@ static int netvsc_set_rss_hash_opts(struct net_device_context *ndc,
1302
1324
{
1303
1325
if (info -> data == (RXH_IP_SRC | RXH_IP_DST |
1304
1326
RXH_L4_B_0_1 | RXH_L4_B_2_3 )) {
1305
- if (info -> flow_type == UDP_V4_FLOW )
1306
- ndc -> udp4_l4_hash = true;
1307
- else if (info -> flow_type == UDP_V6_FLOW )
1308
- ndc -> udp6_l4_hash = true;
1309
- else
1327
+ switch (info -> flow_type ) {
1328
+ case TCP_V4_FLOW :
1329
+ ndc -> l4_hash |= HV_TCP4_L4HASH ;
1330
+ break ;
1331
+
1332
+ case TCP_V6_FLOW :
1333
+ ndc -> l4_hash |= HV_TCP6_L4HASH ;
1334
+ break ;
1335
+
1336
+ case UDP_V4_FLOW :
1337
+ ndc -> l4_hash |= HV_UDP4_L4HASH ;
1338
+ break ;
1339
+
1340
+ case UDP_V6_FLOW :
1341
+ ndc -> l4_hash |= HV_UDP6_L4HASH ;
1342
+ break ;
1343
+
1344
+ default :
1310
1345
return - EOPNOTSUPP ;
1346
+ }
1311
1347
1312
1348
return 0 ;
1313
1349
}
1314
1350
1315
1351
if (info -> data == (RXH_IP_SRC | RXH_IP_DST )) {
1316
- if (info -> flow_type == UDP_V4_FLOW )
1317
- ndc -> udp4_l4_hash = false;
1318
- else if (info -> flow_type == UDP_V6_FLOW )
1319
- ndc -> udp6_l4_hash = false;
1320
- else
1352
+ switch (info -> flow_type ) {
1353
+ case TCP_V4_FLOW :
1354
+ ndc -> l4_hash &= ~HV_TCP4_L4HASH ;
1355
+ break ;
1356
+
1357
+ case TCP_V6_FLOW :
1358
+ ndc -> l4_hash &= ~HV_TCP6_L4HASH ;
1359
+ break ;
1360
+
1361
+ case UDP_V4_FLOW :
1362
+ ndc -> l4_hash &= ~HV_UDP4_L4HASH ;
1363
+ break ;
1364
+
1365
+ case UDP_V6_FLOW :
1366
+ ndc -> l4_hash &= ~HV_UDP6_L4HASH ;
1367
+ break ;
1368
+
1369
+ default :
1321
1370
return - EOPNOTSUPP ;
1371
+ }
1322
1372
1323
1373
return 0 ;
1324
1374
}
0 commit comments