@@ -379,90 +379,125 @@ static struct mlx5e_ethtool_rule *get_ethtool_rule(struct mlx5e_priv *priv,
379379#define all_zeros_or_all_ones (field ) \
380380 ((field) == 0 || (field) == (__force typeof(field))-1)
381381
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+
382463static int validate_flow (struct mlx5e_priv * priv ,
383464 struct ethtool_rx_flow_spec * fs )
384465{
385- struct ethtool_tcpip4_spec * l4_mask ;
386- struct ethtool_usrip4_spec * l3_mask ;
387- struct ethhdr * eth_mask ;
388466 int num_tuples = 0 ;
467+ int ret = 0 ;
389468
390469 if (fs -> location >= MAX_NUM_OF_ETHTOOL_RULES )
391- return - EINVAL ;
470+ return - ENOSPC ;
392471
393472 if (fs -> ring_cookie >= priv -> channels .params .num_channels &&
394473 fs -> ring_cookie != RX_CLS_FLOW_DISC )
395474 return - EINVAL ;
396475
397476 switch (fs -> flow_type & ~(FLOW_EXT | FLOW_MAC_EXT )) {
398477 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 );
406479 break ;
407480 case TCP_V4_FLOW :
408481 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 ;
434486 break ;
435487 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 ;
452492 break ;
453493 default :
454- return - EINVAL ;
494+ return - ENOTSUPP ;
455495 }
456496 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 ;
466501 }
467502
468503 if (fs -> flow_type & FLOW_MAC_EXT &&
@@ -483,8 +518,9 @@ int mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
483518
484519 num_tuples = validate_flow (priv , fs );
485520 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 ;
488524 }
489525
490526 eth_ft = get_flow_table (priv , fs , num_tuples );
0 commit comments