@@ -379,90 +379,125 @@ static struct mlx5e_ethtool_rule *get_ethtool_rule(struct mlx5e_priv *priv,
379
379
#define all_zeros_or_all_ones (field ) \
380
380
((field) == 0 || (field) == (__force typeof(field))-1)
381
381
382
+ static int validate_ethter (struct ethtool_rx_flow_spec * fs )
383
+ {
384
+ struct ethhdr * eth_mask = & fs -> m_u .ether_spec ;
385
+ int ntuples = 0 ;
386
+
387
+ if (!is_zero_ether_addr (eth_mask -> h_dest ))
388
+ ntuples ++ ;
389
+ if (!is_zero_ether_addr (eth_mask -> h_source ))
390
+ ntuples ++ ;
391
+ if (eth_mask -> h_proto )
392
+ ntuples ++ ;
393
+ return ntuples ;
394
+ }
395
+
396
+ static int validate_tcpudp4 (struct ethtool_rx_flow_spec * fs )
397
+ {
398
+ struct ethtool_tcpip4_spec * l4_mask = & fs -> m_u .tcp_ip4_spec ;
399
+ int ntuples = 0 ;
400
+
401
+ if (l4_mask -> tos )
402
+ return - EINVAL ;
403
+
404
+ if (l4_mask -> ip4src ) {
405
+ if (!all_ones (l4_mask -> ip4src ))
406
+ return - EINVAL ;
407
+ ntuples ++ ;
408
+ }
409
+ if (l4_mask -> ip4dst ) {
410
+ if (!all_ones (l4_mask -> ip4dst ))
411
+ return - EINVAL ;
412
+ ntuples ++ ;
413
+ }
414
+ if (l4_mask -> psrc ) {
415
+ if (!all_ones (l4_mask -> psrc ))
416
+ return - EINVAL ;
417
+ ntuples ++ ;
418
+ }
419
+ if (l4_mask -> pdst ) {
420
+ if (!all_ones (l4_mask -> pdst ))
421
+ return - EINVAL ;
422
+ ntuples ++ ;
423
+ }
424
+ /* Flow is TCP/UDP */
425
+ return ++ ntuples ;
426
+ }
427
+
428
+ static int validate_ip4 (struct ethtool_rx_flow_spec * fs )
429
+ {
430
+ struct ethtool_usrip4_spec * l3_mask = & fs -> m_u .usr_ip4_spec ;
431
+ int ntuples = 0 ;
432
+
433
+ if (l3_mask -> l4_4_bytes || l3_mask -> tos || l3_mask -> proto ||
434
+ fs -> h_u .usr_ip4_spec .ip_ver != ETH_RX_NFC_IP4 )
435
+ return - EINVAL ;
436
+ if (l3_mask -> ip4src ) {
437
+ if (!all_ones (l3_mask -> ip4src ))
438
+ return - EINVAL ;
439
+ ntuples ++ ;
440
+ }
441
+ if (l3_mask -> ip4dst ) {
442
+ if (!all_ones (l3_mask -> ip4dst ))
443
+ return - EINVAL ;
444
+ ntuples ++ ;
445
+ }
446
+ /* Flow is IPv4 */
447
+ return ++ ntuples ;
448
+ }
449
+
450
+ static int validate_vlan (struct ethtool_rx_flow_spec * fs )
451
+ {
452
+ if (fs -> m_ext .vlan_etype ||
453
+ fs -> m_ext .vlan_tci != cpu_to_be16 (VLAN_VID_MASK ))
454
+ return - EINVAL ;
455
+
456
+ if (fs -> m_ext .vlan_tci &&
457
+ (be16_to_cpu (fs -> h_ext .vlan_tci ) >= VLAN_N_VID ))
458
+ return - EINVAL ;
459
+
460
+ return 1 ;
461
+ }
462
+
382
463
static int validate_flow (struct mlx5e_priv * priv ,
383
464
struct ethtool_rx_flow_spec * fs )
384
465
{
385
- struct ethtool_tcpip4_spec * l4_mask ;
386
- struct ethtool_usrip4_spec * l3_mask ;
387
- struct ethhdr * eth_mask ;
388
466
int num_tuples = 0 ;
467
+ int ret = 0 ;
389
468
390
469
if (fs -> location >= MAX_NUM_OF_ETHTOOL_RULES )
391
- return - EINVAL ;
470
+ return - ENOSPC ;
392
471
393
472
if (fs -> ring_cookie >= priv -> channels .params .num_channels &&
394
473
fs -> ring_cookie != RX_CLS_FLOW_DISC )
395
474
return - EINVAL ;
396
475
397
476
switch (fs -> flow_type & ~(FLOW_EXT | FLOW_MAC_EXT )) {
398
477
case ETHER_FLOW :
399
- eth_mask = & fs -> m_u .ether_spec ;
400
- if (!is_zero_ether_addr (eth_mask -> h_dest ))
401
- num_tuples ++ ;
402
- if (!is_zero_ether_addr (eth_mask -> h_source ))
403
- num_tuples ++ ;
404
- if (eth_mask -> h_proto )
405
- num_tuples ++ ;
478
+ num_tuples += validate_ethter (fs );
406
479
break ;
407
480
case TCP_V4_FLOW :
408
481
case UDP_V4_FLOW :
409
- if (fs -> m_u .tcp_ip4_spec .tos )
410
- return - EINVAL ;
411
- l4_mask = & fs -> m_u .tcp_ip4_spec ;
412
- if (l4_mask -> ip4src ) {
413
- if (!all_ones (l4_mask -> ip4src ))
414
- return - EINVAL ;
415
- num_tuples ++ ;
416
- }
417
- if (l4_mask -> ip4dst ) {
418
- if (!all_ones (l4_mask -> ip4dst ))
419
- return - EINVAL ;
420
- num_tuples ++ ;
421
- }
422
- if (l4_mask -> psrc ) {
423
- if (!all_ones (l4_mask -> psrc ))
424
- return - EINVAL ;
425
- num_tuples ++ ;
426
- }
427
- if (l4_mask -> pdst ) {
428
- if (!all_ones (l4_mask -> pdst ))
429
- return - EINVAL ;
430
- num_tuples ++ ;
431
- }
432
- /* Flow is TCP/UDP */
433
- num_tuples ++ ;
482
+ ret = validate_tcpudp4 (fs );
483
+ if (ret < 0 )
484
+ return ret ;
485
+ num_tuples += ret ;
434
486
break ;
435
487
case IP_USER_FLOW :
436
- l3_mask = & fs -> m_u .usr_ip4_spec ;
437
- if (l3_mask -> l4_4_bytes || l3_mask -> tos || l3_mask -> proto ||
438
- fs -> h_u .usr_ip4_spec .ip_ver != ETH_RX_NFC_IP4 )
439
- return - EINVAL ;
440
- if (l3_mask -> ip4src ) {
441
- if (!all_ones (l3_mask -> ip4src ))
442
- return - EINVAL ;
443
- num_tuples ++ ;
444
- }
445
- if (l3_mask -> ip4dst ) {
446
- if (!all_ones (l3_mask -> ip4dst ))
447
- return - EINVAL ;
448
- num_tuples ++ ;
449
- }
450
- /* Flow is IPv4 */
451
- num_tuples ++ ;
488
+ ret = validate_ip4 (fs );
489
+ if (ret < 0 )
490
+ return ret ;
491
+ num_tuples += ret ;
452
492
break ;
453
493
default :
454
- return - EINVAL ;
494
+ return - ENOTSUPP ;
455
495
}
456
496
if ((fs -> flow_type & FLOW_EXT )) {
457
- if (fs -> m_ext .vlan_etype ||
458
- (fs -> m_ext .vlan_tci != cpu_to_be16 (VLAN_VID_MASK )))
459
- return - EINVAL ;
460
-
461
- if (fs -> m_ext .vlan_tci ) {
462
- if (be16_to_cpu (fs -> h_ext .vlan_tci ) >= VLAN_N_VID )
463
- return - EINVAL ;
464
- }
465
- num_tuples ++ ;
497
+ ret = validate_vlan (fs );
498
+ if (ret < 0 )
499
+ return ret ;
500
+ num_tuples += ret ;
466
501
}
467
502
468
503
if (fs -> flow_type & FLOW_MAC_EXT &&
@@ -483,8 +518,9 @@ int mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
483
518
484
519
num_tuples = validate_flow (priv , fs );
485
520
if (num_tuples <= 0 ) {
486
- netdev_warn (priv -> netdev , "%s: flow is not valid\n" , __func__ );
487
- return - EINVAL ;
521
+ netdev_warn (priv -> netdev , "%s: flow is not valid %d\n" ,
522
+ __func__ , num_tuples );
523
+ return num_tuples ;
488
524
}
489
525
490
526
eth_ft = get_flow_table (priv , fs , num_tuples );
0 commit comments